Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ Step with prob=0.333333
- ```CliffWalking```
- ```CartPole```
- ```MountainCar```
- ```Taxi```

## Dependencies

Expand Down
3 changes: 3 additions & 0 deletions execute_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,6 @@ cd ..
echo "Running MountainCar tests"
cd test_mountain_car/ && ./test_mountain_car
cd ..
echo "Running Taxi tests"
cd test_taxi/ && ./test_taxi
cd ..
1 change: 1 addition & 0 deletions src/gymfcpp/mountain_car.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ MountainCar::step(action_t action){

#ifdef GYMFCPP_DEBUG
assert(is_created && "Environment has not been created");
assert(action < n_actions() && "Invalid action index");
#endif

if(current_state.last()){
Expand Down
11 changes: 3 additions & 8 deletions src/gymfcpp/mountain_car.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@
namespace gymfcpp
{

/// Forward declarations
//template<typename StateTp> class TimeStep;


///
/// \brief The MountainCarData struct. Wrapper for the environment data
///
struct MountainCarData
{
///
Expand Down Expand Up @@ -169,12 +170,6 @@ class MountainCar: protected EnvMixin<MountainCarData>
///
time_step_t step(action_t action);

///
/// \brief render
/// \param render_mode
///
//void render(RenderModeType render_mode);

///
/// \brief sample
/// \return
Expand Down
41 changes: 41 additions & 0 deletions src/gymfcpp/names_generator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#ifndef NAMES_GENERATOR_H
#define NAMES_GENERATOR_H

#include <string>

namespace gymfcpp {

///
///
///
inline
std::string get_py_env_name(std::string_view env_name){return "py_" + std::string(env_name);}

///
/// \brief py_step_rslt
/// \param env_name
/// \return
///
inline
std::string get_py_step_rslt_name(std::string_view env_name){return "py_" + std::string(env_name) + "_step_rslt";}

///
/// \brief py_state
/// \param env_name
/// \return
///
inline
std::string get_py_state_name(std::string_view env_name){return "py_" + std::string(env_name) + "_state";}

///
/// \brief py_reset_rslt
/// \param env_name
/// \return
///
inline
std::string get_py_reset_rslt_name(std::string_view env_name){return "py_" + std::string(env_name) + "_reset_rslt";}


}

#endif // NAMES_GENERATOR_H
2 changes: 1 addition & 1 deletion src/gymfcpp/render_mode_enum.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace gymfcpp {
///
/// \brief The RenderModeType enum
///
BETTER_ENUM(RenderModeType, char, human=0, rgb_array, INVALID_TYPE);
BETTER_ENUM(RenderModeType, char, human=0, rgb_array, ansi, INVALID_TYPE);


///
Expand Down
97 changes: 97 additions & 0 deletions src/gymfcpp/taxi.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#include "gymfcpp/taxi.h"
#include "gymfcpp/names_generator.h"

namespace gymfcpp
{

std::string TaxiData::name = "Taxi";
std::string TaxiData::py_env_name = get_py_env_name(TaxiData::name); //"py_mountain_car";
std::string TaxiData::py_step_result_name = get_py_step_rslt_name(TaxiData::name); //"py_mountain_car_step_rslt";
std::string TaxiData::py_reset_result_name = get_py_reset_rslt_name(TaxiData::name); //"py_mountain_car_reset_rslt";
std::string TaxiData::py_state_name = get_py_state_name(TaxiData::name); //"py_mountain_car_state";


TaxiData::state_t
TaxiData::extract_state(obj_t gym_namespace, std::string result_name){

std::string s;
if(result_name == TaxiData::py_reset_result_name){
s = TaxiData::py_state_name + " = " + result_name + "\n";
}
else if(result_name == TaxiData::py_step_result_name){

s = TaxiData::py_state_name + " = " + result_name + "[0]\n";
}
#ifdef GYMFCPP_DEBUG
else{
assert(false && result_name + "not " + TaxiData::py_reset_result_name + " or " + TaxiData::py_step_result_name);
}
#endif

boost::python::exec(s.c_str(), gym_namespace);
auto obs = boost::python::extract<uint_t>(gym_namespace[TaxiData::py_state_name]);
return obs;

}

Taxi::Taxi(std::string version, obj_t main_namespace, bool do_create)
:
EnvMixin<TaxiData>(version, main_namespace)
{
if(do_create){
make();
}
}

void
Taxi::make(){

if(is_created){
return;
}

std::string cpp_str = "import gym \n";
//cpp_str += "import numpy as np \n";
cpp_str += TaxiData::py_env_name + " = gym.make('" + TaxiData::name + "-" + version + "').unwrapped\n";

// create an environment
auto ignored = boost::python::exec(cpp_str.c_str(), gym_namespace);
env = boost::python::extract<boost::python::api::object>(gym_namespace[TaxiData::py_env_name]);
is_created = true;
}


Taxi::time_step_t
Taxi::step(action_t action){

#ifdef GYMFCPP_DEBUG
assert(is_created && "Environment has not been created");
assert(action < n_actions() && "Invalid action index");
#endif

if(current_state.last()){
return reset();
}

std::string s = TaxiData::py_step_result_name + " = " + TaxiData::py_env_name +".step("+std::to_string(action)+")\n";
//s += TaxiData::py_step_result_name + " = (" + TaxiData::py_step_result_name + "[0].tolist(),";
//s += "float(" + TaxiData::py_step_result_name + "[1]),";
//s += TaxiData::py_step_result_name + "[2])\n";

boost::python::exec(s.c_str(), gym_namespace);

auto obs = TaxiData::extract_state(gym_namespace, TaxiData::py_step_result_name);

auto result = boost::python::extract<boost::python::tuple>(gym_namespace[TaxiData::py_step_result_name]);

auto reward = boost::python::extract<real_t>(result()[1]);
auto done = boost::python::extract<bool>(result()[2]);

std::unordered_map<std::string, std::any> extra;

current_state = time_step_t(done() ? TimeStepTp::LAST : TimeStepTp::MID, reward(), obs, std::move(extra));
return current_state;
}


}
166 changes: 166 additions & 0 deletions src/gymfcpp/taxi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
#ifndef TAXI_H
#define TAXI_H

#include "gymfcpp/gymfcpp_config.h"
#include "gymfcpp/gymfcpp_types.h"
#include "gymfcpp/env_mixin.h"
#include "gymfcpp/discrete_space.h"
#include "gymfcpp/continuous_space.h"
#include "gymfcpp/time_step.h"

namespace gymfcpp
{

///
/// \brief The TaxiData struct. Wrapper for the environment data
///
struct TaxiData
{
///
/// \brief action_space_t. The type of the action space
///
typedef DiscreteSpace<6> action_space_t;

///
/// \brief action_t
///
typedef action_space_t::item_t action_t;

///
/// \brief state_space_t
///
typedef ContinuousSpace<4> state_space_t;

///
/// \brief state_t
///
typedef uint_t state_t;

///
/// \brief state_boost_python_t
///
typedef boost::python::list state_boost_python_t;

///
/// \brief name
///
static std::string name;

///
/// \brief py_env_name. The name of the environment in Python REPL
///
static std::string py_env_name;

///
/// \brief py_step_result_name. The name of the result when stepping in the Python REPL
///
static std::string py_step_result_name;

///
/// \brief py_step_reset_result_name
///
static std::string py_reset_result_name;

///
/// \brief py_step_reset_result_name
///
static std::string py_state_name;

///
/// \brief time_step_t. The type of the time step
///
typedef TimeStep<state_t> time_step_t;

///
/// \brief extract_state
/// \param gym_namespace
/// \return
///
static state_t extract_state(obj_t gym_namespace, std::string result_name);

};


///
/// \brief The Taxi class
///
class Taxi: protected EnvMixin<TaxiData>
{
public:

///
/// \brief env_data_t
///
typedef TaxiData env_data_t;

///
/// \brief action_space_t. The type of the action space
///
typedef TaxiData::action_space_t action_space_t;

///
/// \brief action_t
///
typedef TaxiData::action_t action_t;

///
/// \brief state_space_t
///
typedef TaxiData::state_space_t state_space_t;

///
/// \brief state_t
///
typedef TaxiData::state_t state_t;

///
/// \brief time_step_t. The type of the time step
///
typedef TaxiData::time_step_t time_step_t;

///
/// \brief Taxi
/// \param version
/// \param main_namespace
/// \param do_create
///
Taxi(std::string version, obj_t main_namespace, bool do_create=true);

///
/// \brief Expose the functionality this class is using
/// from the Mixin
///
using EnvMixin<TaxiData>::close;
using EnvMixin<TaxiData>::full_name;
using EnvMixin<TaxiData>::reset;
using EnvMixin<TaxiData>::is_created;
using EnvMixin<TaxiData>::version;
using EnvMixin<TaxiData>::gym_namespace;
using EnvMixin<TaxiData>::render;

///
/// \brief make. Build the environment
///
void make();

///
/// \brief n_actions. Returns the number of actions
///
uint_t n_actions()const noexcept{return action_space_t::size;}

///
/// \brief step
///
time_step_t step(action_t action);

///
/// \brief sample
/// \return
///
action_t sample()const noexcept{return action_space_t::sample();}

};


}
#endif // TAXI_H
Loading