Skip to content

Commit f47ebed

Browse files
authored
Merge pull request #173 from pockerman/feat/169_refactor_ctrl_lib_from_cuberl
Update documentation
2 parents 145b5c6 + a922607 commit f47ebed

File tree

5 files changed

+300
-6
lines changed

5 files changed

+300
-6
lines changed

examples/example_1/example_1.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
\page bitrl_example_1 Example 1 Using Gymnasium environments
1+
\page bitrl_example_1 BitRL Example 1 Using Gymnasium environments (Part 1)
22

33
In this example we will see how to interact with <a href="https://gymnasium.farama.org/index.html">Gymnasium</a> environments and
44
specifically how to create an interact with <a href="https://gymnasium.farama.org/environments/toy_text/frozen_lake/">FroznLake</a> environment.
55

6-
In bitrl, Gymnasium-based environment are interacted over a REST-like API maintained here: <a href="https://github.com/pockerman/bitrl-rest-api">bitrl-envs-api</a>.
7-
bitrl itself implements classes that hide this interaction from the client code.
8-
In general, environment classes in bitrl, have to implement the \ref bitrl::envs::EnvBase "bitrl::envs::EnvBase" API.
6+
In _bitrl_, Gymnasium-based environments are interacted over a REST-like API maintained here: <a href="https://github.com/pockerman/bitrl-rest-api">bitrl-envs-api</a>.
7+
_bitrl_ itself implements classes that hide this interaction from the client code.
8+
In general, environment classes in _bitrl_, have to implement the \ref bitrl::envs::EnvBase "bitrl::envs::EnvBase" API.
99

1010
In this example we will use the \ref bitrl::envs::gymnasium::FrozenLake "bitrl::envs::gymnasium::FrozenLake"
1111
class. This is a template class, see the example below, that itself inherits from \ref bitrl::envs::gymnasium::GymnasiumEnvBase "bitrl::envs::gymnasium::GymnasiumEnvBase"
@@ -132,6 +132,6 @@ int main()
132132
@endcode
133133

134134
In order to run the example you will need an instance of the <a href="https://github.com/pockerman/bitrl-rest-api">bitrl-envs-api</a> server running
135-
on your machine listening at por 8001. Note the actual example also shows how to use \ref bitrl::envs::gymnasium::Taxi "bitrl::envs::gymnasium::Taxi",
135+
on your machine listening at port 8001. Note the actual example also shows how to use \ref bitrl::envs::gymnasium::Taxi "bitrl::envs::gymnasium::Taxi",
136136
\ref bitrl::envs::gymnasium::CliffWorld "bitrl::envs::gymnasium::CliffWorld" and \ref bitrl::envs::gymnasium::BlackJack "bitrl::envs::gymnasium::BlackJack"
137137
environments.

examples/example_2/example_2.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ void test_gymwalk(RESTRLEnvClient &server)
4343
// once the env is created we can get it's id
4444
std::cout << "Environment idx is: " << env.idx() << std::endl;
4545

46-
// the create flag should be true
46+
// the created flag should be true
4747
std::cout << "Is environment created? " << env.is_created() << std::endl;
4848

4949
// environment should be alive on the server

examples/example_2/example_2.md

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
\page bitrl_example_2 BitRL Example 2 Using GymWalk Environment
2+
3+
The \ref bitrl::envs::gdrl::GymWalk "bitrl::envs::gdrl::GymWalk" is an implementation of the
4+
environment from https://github.com/mimoralea/gym-walk. Just like with \ref bitrl_example_1, you will need
5+
an instance of the <a href="https://github.com/pockerman/bitrl-rest-api">bitrl-envs-api</a> server running in order
6+
to actually use the environment. Other than that there isn't much to say for this example.
7+
Below is the driver code.
8+
9+
@code{.cpp}
10+
#include "bitrl/bitrl_types.h"
11+
#include "bitrl/envs/gdrl/gym_walk.h"
12+
#include "bitrl/network/rest_rl_env_client.h"
13+
14+
#include <any>
15+
#include <iostream>
16+
#include <string>
17+
#include <unordered_map>
18+
19+
namespace example_1
20+
{
21+
using namespace bitrl;
22+
23+
const std::string SERVER_URL = "http://0.0.0.0:8001/api";
24+
25+
using bitrl::envs::gdrl::GymWalk;
26+
using bitrl::network::RESTRLEnvClient;
27+
28+
void test_gymwalk(RESTRLEnvClient &server)
29+
{
30+
// the environment is not registered with the server
31+
std::cout << "Is environment registered: " << server.is_env_registered(GymWalk<4>::name)
32+
<< std::endl;
33+
34+
// when the environment is created we register it with the REST client
35+
GymWalk<4> env(server);
36+
37+
// environment name can also be accessed via env.env_name()
38+
std::cout << "Is environment registered: " << server.is_env_registered(env.env_name())
39+
<< std::endl;
40+
std::cout << "Environment URL: " << env.get_url() << std::endl;
41+
42+
// make the environment we pass both make options
43+
// and reset options
44+
std::unordered_map<std::string, std::any> make_ops;
45+
std::unordered_map<std::string, std::any> reset_ops;
46+
reset_ops.insert({"seed", static_cast<uint_t>(42)});
47+
env.make("v1", make_ops, reset_ops);
48+
49+
// query the environemnt version
50+
std::cout << "Environment version: " << env.version() << std::endl;
51+
52+
// once the env is created we can get it's id
53+
std::cout << "Environment idx is: " << env.idx() << std::endl;
54+
55+
// the created flag should be true
56+
std::cout << "Is environment created? " << env.is_created() << std::endl;
57+
58+
// environment should be alive on the server
59+
std::cout << "Is environment alive? " << env.is_alive() << std::endl;
60+
61+
// FrozenLake is a discrete state-action env so we can
62+
// query number of actions and states
63+
std::cout << "Number of valid actions? " << env.n_actions() << std::endl;
64+
std::cout << "Number of states? " << env.n_states() << std::endl;
65+
66+
// reset the environment
67+
auto time_step = env.reset();
68+
69+
std::cout << "Reward on reset: " << time_step.reward() << std::endl;
70+
std::cout << "Observation on reset: " << time_step.observation() << std::endl;
71+
std::cout << "Is terminal state: " << time_step.done() << std::endl;
72+
73+
//...print the time_step
74+
std::cout << time_step << std::endl;
75+
76+
// take an action in the environment
77+
// 2 = RIGHT
78+
auto new_time_step = env.step(1);
79+
std::cout << new_time_step << std::endl;
80+
81+
// get the dynamics of the environment for the given state and action
82+
auto state = 0;
83+
auto action = 1;
84+
auto dynamics = env.p(state, action);
85+
86+
std::cout << "Dynamics for state=" << state << " and action=" << action << std::endl;
87+
for (auto item : dynamics)
88+
{
89+
std::cout << std::get<0>(item) << std::endl;
90+
std::cout << std::get<1>(item) << std::endl;
91+
std::cout << std::get<2>(item) << std::endl;
92+
std::cout << std::get<3>(item) << std::endl;
93+
}
94+
95+
// discrete action environments can sample
96+
// actions
97+
action = env.sample_action();
98+
std::cout << "Action sampled: " << action << std::endl;
99+
100+
new_time_step = env.step(action);
101+
std::cout << new_time_step << std::endl;
102+
103+
// close the environment
104+
env.close();
105+
}
106+
107+
} // namespace example_1
108+
109+
int main()
110+
{
111+
112+
using namespace example_1;
113+
114+
RESTRLEnvClient server(SERVER_URL, false);
115+
116+
std::cout << "Testing GymWalk..." << std::endl;
117+
example_1::test_gymwalk(server);
118+
std::cout << "====================" << std::endl;
119+
return 0;
120+
}
121+
122+
@endcode

examples/example_3/example_3.md

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
\page bitrl_example_3 BitRL Example 3 Using Gymnasium environments (Part 2)
2+
3+
In this example we will see how to interact with <a href="https://gymnasium.farama.org/index.html">Gymnasium</a> environments and
4+
specifically how to create an interact with <a href="https://gymnasium.farama.org/environments/classic_control/cart_pole/">CartPole</a> environment.
5+
6+
As already mentioned in \ref bitrl_example_1, Gymnasium-based environments are interacted over a REST-like API maintained here: <a href="https://github.com/pockerman/bitrl-rest-api">bitrl-envs-api</a>.
7+
_bitrl_ itself implements classes that hide this interaction from the client code.
8+
In general, environment classes in _bitrl_, have to implement the \ref bitrl::envs::EnvBase "bitrl::envs::EnvBase" API.
9+
10+
In this example we will use the \ref bitrl::envs::gymnasium::CartPole "bitrl::envs::gymnasium::CartPole"
11+
class. This is a template class, see the example below, that itself inherits from \ref bitrl::envs::gymnasium::GymnasiumEnvBase "bitrl::envs::gymnasium::GymnasiumEnvBase"
12+
class.
13+
14+
Below is the driver code.
15+
16+
@code{.cpp}
17+
18+
#include "bitrl/bitrl_consts.h"
19+
#include "bitrl/bitrl_types.h"
20+
#include "bitrl/envs/gymnasium/classic_control/cart_pole_env.h"
21+
#include "bitrl/network/rest_rl_env_client.h"
22+
23+
#ifdef BITRL_DEBUG
24+
#include <cassert>
25+
#endif
26+
27+
#include <iostream>
28+
#include <random>
29+
#include <string>
30+
#include <unordered_map>
31+
32+
namespace example
33+
{
34+
using namespace bitrl;
35+
using namespace bitrl::envs::gymnasium;
36+
using bitrl::network::RESTRLEnvClient;
37+
38+
void test_cart_pole(RESTRLEnvClient &server)
39+
{
40+
std::cout << "Is environment registered: " << server.is_env_registered(CartPole::name)
41+
<< std::endl;
42+
43+
// create the environment
44+
CartPole env(server);
45+
46+
std::cout << "Name: " << env.name << std::endl;
47+
std::cout << "Number of actions: " << env.n_actions() << std::endl;
48+
49+
// make the environment
50+
std::unordered_map<std::string, std::any> options;
51+
std::unordered_map<std::string, std::any> reset_ops;
52+
reset_ops.insert({"seed", static_cast<uint_t>(42)});
53+
env.make("v1", options, reset_ops);
54+
55+
auto time_step = env.reset();
56+
std::cout << "Time step: " << time_step << std::endl;
57+
58+
// step in the environment
59+
time_step = env.step(0);
60+
std::cout << "Time step after action: " << time_step << std::endl;
61+
62+
env.close();
63+
}
64+
65+
} // namespace example
66+
67+
int main()
68+
{
69+
70+
using namespace example;
71+
72+
const std::string SERVER_URL = "http://0.0.0.0:8001/api";
73+
74+
RESTRLEnvClient server(SERVER_URL, true);
75+
76+
std::cout << "Testing CartPole..." << std::endl;
77+
example::test_cart_pole(server);
78+
std::cout << "====================" << std::endl;
79+
80+
return 0;
81+
}
82+
@endcode
83+
84+
85+
In order to run the example you will need an instance of the <a href="https://github.com/pockerman/bitrl-rest-api">bitrl-envs-api</a> server running
86+
on your machine listening at port 8001. Note the actual example also shows how to use \ref bitrl::envs::gymnasium::Pendulum "bitrl::envs::gymnasium::Pendulum",
87+
\ref bitrl::envs::gymnasium::Acrobot "bitrl::envs::gymnasium::Acrobot" and \ref bitrl::envs::gymnasium::MountainCar "bitrl::envs::gymnasium::MountainCar"
88+
environments.

examples/example_4/example_4.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
\page bitrl_example_4 BitRL Example 4 Using Gymnasium environments (Part 3)
2+
3+
This example follows \ref bitrl_example_1 and \ref bitrl_example_3 and shows how to use
4+
\ref bitrl::envs::gymnasium::LunarLanderDiscreteEnv "bitrl::envs::gymnasium::LunarLanderDiscreteEnv" and
5+
\ref bitrl::envs::gymnasium::LunarLanderContinuousEnv "bitrl::envs::gymnasium::LunarLanderContinuousEnv".
6+
7+
8+
@code{.cpp}
9+
10+
#include "bitrl/envs/gymnasium/box2d/lunar_lander_env.h"
11+
#include "bitrl/network/rest_rl_env_client.h"
12+
13+
#include <iostream>
14+
#include <unordered_map>
15+
#include <vector>
16+
17+
namespace box2d_example
18+
{
19+
using namespace bitrl;
20+
const std::string SERVER_URL = "http://0.0.0.0:8001/api";
21+
using bitrl::real_t;
22+
using bitrl::envs::gymnasium::LunarLanderContinuousEnv;
23+
using bitrl::envs::gymnasium::LunarLanderDiscreteEnv;
24+
} // namespace box2d_example
25+
26+
int main()
27+
{
28+
using namespace box2d_example;
29+
30+
bitrl::network::RESTRLEnvClient server(SERVER_URL, true);
31+
32+
std::unordered_map<std::string, std::any> options;
33+
options["wind_power"] = std::any(static_cast<bitrl::real_t>(10.0));
34+
options["enable_wind"] = std::any(static_cast<bool>(true));
35+
options["gravity"] = std::any(static_cast<bitrl::real_t>(-9.86));
36+
options["turbulence_power"] = std::any(static_cast<bitrl::real_t>(1.5));
37+
38+
std::unordered_map<std::string, std::any> reset_ops;
39+
reset_ops.insert({"seed", static_cast<uint_t>(42)});
40+
41+
{
42+
std::cout<<"Working with LunarLanderDiscreteEnv..."<<std::endl;
43+
std::cout << "Is environment registered: " << server.is_env_registered(LunarLanderDiscreteEnv::name)
44+
<< std::endl;
45+
LunarLanderDiscreteEnv env(server);
46+
47+
env.make("v3", options, reset_ops);
48+
49+
std::cout<<"Is environment created? "<<env.is_created()<<std::endl;
50+
std::cout<<"Is environment alive? "<<env.is_alive()<<std::endl;
51+
std::cout<<"Number of valid actions? "<<env.n_actions()<<std::endl;
52+
53+
auto time_step = env.reset();
54+
std::cout<<"Time step: "<<time_step<<std::endl;
55+
56+
time_step = env.step(1);
57+
std::cout<<"Time step: "<<time_step<<std::endl;
58+
env.close();
59+
60+
}
61+
{
62+
std::cout << "Working with LunarLanderContinuousEnv..." << std::endl;
63+
64+
LunarLanderContinuousEnv env(server);
65+
env.make("v3", options, reset_ops);
66+
67+
std::cout << "Is environment created? " << env.is_created() << std::endl;
68+
std::cout << "Is environment alive? " << env.is_alive() << std::endl;
69+
std::cout << "Action space size " << env.n_actions() << std::endl;
70+
std::cout << "Environment URI: " << server.get_uri(env.env_name()) << std::endl;
71+
72+
auto time_step = env.reset();
73+
std::cout << "Time step: " << time_step << std::endl;
74+
75+
std::vector<real_t> action = {0.8, 0.9};
76+
time_step = env.step(action);
77+
std::cout << "Time step: " << time_step << std::endl;
78+
env.close();
79+
}
80+
81+
return 0;
82+
}
83+
84+
@endcode

0 commit comments

Comments
 (0)