rlenvscpp
is an effort to provide implementations and wrappers of environments suitable for training reinforcement learning agents
using C++. In addition, the library provides various utilities such as experiment tracking,
representing trajectories via waypoints and simple implementation of popular dynamics such as
quadrotor dynamics.
Various RL algorithms using the environments can be found at cuberl.
The documentation for the library can be found here.
The following is an example how to use the
FrozenLake
environment from Gymnasium.
#include "rlenvs/rlenvs_types_v2.h"
#include "rlenvs/envs/gymnasium/toy_text/frozen_lake_env.h"
#include "rlenvs/envs/api_server/apiserver.h"
#include <iostream>
#include <string>
#include <unordered_map>
#include <any>
namespace example_1{
const std::string SERVER_URL = "http://0.0.0.0:8001/api";
using rlenvscpp::envs::gymnasium::FrozenLake;
using rlenvscpp::envs::RESTApiServerWrapper;
void test_frozen_lake(const RESTApiServerWrapper& server){
FrozenLake<4> env(server);
std::cout<<"Environame URL: "<<env.get_url()<<std::endl;
// make the environment
std::unordered_map<std::string, std::any> options;
options.insert({"is_slippery", false});
env.make("v1", options);
std::cout<<"Is environment created? "<<env.is_created()<<std::endl;
std::cout<<"Is environment alive? "<<env.is_alive()<<std::endl;
std::cout<<"Number of valid actions? "<<env.n_actions()<<std::endl;
std::cout<<"Number of states? "<<env.n_states()<<std::endl;
// reset the environment
auto time_step = env.reset(42, std::unordered_map<std::string, std::any>());
std::cout<<"Reward on reset: "<<time_step.reward()<<std::endl;
std::cout<<"Observation on reset: "<<time_step.observation()<<std::endl;
std::cout<<"Is terminal state: "<<time_step.done()<<std::endl;
//...print the time_step
std::cout<<time_step<<std::endl;
// take an action in the environment
// 2 = RIGHT
auto new_time_step = env.step(2);
std::cout<<new_time_step<<std::endl;
// get the dynamics of the environment for the given state and action
auto state = 0;
auto action = 1;
auto dynamics = env.p(state, action);
std::cout<<"Dynamics for state="<<state<<" and action="<<action<<std::endl;
for(auto item:dynamics){
std::cout<<std::get<0>(item)<<std::endl;
std::cout<<std::get<1>(item)<<std::endl;
std::cout<<std::get<2>(item)<<std::endl;
std::cout<<std::get<3>(item)<<std::endl;
}
action = env.sample_action();
new_time_step = env.step(action);
std::cout<<new_time_step<<std::endl;
// synchronize the environment
env.sync(std::unordered_map<std::string, std::any>());
auto copy_env = env.make_copy(1);
copy_env.reset();
std::cout<<"Org env cidx: "<<env.cidx()<<std::endl;
std::cout<<"Copy env cidx: "<<copy_env.cidx()<<std::endl;
copy_env.close();
// close the environment
env.close();
}
}
int main(){
using namespace example_1;
RESTApiServerWrapper server(SERVER_URL, true);
std::cout<<"Testing FrozenLake..."<<std::endl;
example_1::test_frozen_lake(server);
std::cout<<"===================="<<std::endl;
return 0;
}
See also Working with Webots
for how to integrate rlenvscpp
with Webots.
Example Using rlenvscpp with Ray
shows how to use Ray with the rlenvscpp
.