From 4627d6fc1e9970014d239e09aba445e516e1a534 Mon Sep 17 00:00:00 2001 From: Shunichi09 Date: Tue, 7 Apr 2020 17:29:55 +0900 Subject: [PATCH] Add: catpole env --- Environments.md | 30 ++- .../configs/cartpole.py | 218 ++++++++++++++++++ .../configs/make_configs.py | 5 +- PythonLinearNonlinearControl/envs/cartpole.py | 51 +++- .../envs/make_envs.py | 4 +- .../envs/two_wheeled.py | 2 +- .../models/cartpole.py | 186 +++++++++++++++ .../models/make_models.py | 5 +- README.md | 6 +- assets/cartpole_score.png | Bin 0 -> 23268 bytes assets/quadratic_score.png | Bin 0 -> 22530 bytes scripts/simple_run.py | 4 +- tests/configs/test_cartpole.py | 31 +++ tests/configs/test_two_wheeled.py | 34 +++ tests/env/test_cartpole.py | 73 ++++++ tests/models/test_cartpole.py | 57 +++++ tests/models/test_first_order_lag.py | 43 ++++ 17 files changed, 723 insertions(+), 26 deletions(-) create mode 100644 PythonLinearNonlinearControl/configs/cartpole.py create mode 100644 PythonLinearNonlinearControl/models/cartpole.py create mode 100644 assets/cartpole_score.png create mode 100644 assets/quadratic_score.png create mode 100644 tests/configs/test_cartpole.py create mode 100644 tests/configs/test_two_wheeled.py create mode 100644 tests/env/test_cartpole.py create mode 100644 tests/models/test_cartpole.py create mode 100644 tests/models/test_first_order_lag.py diff --git a/Environments.md b/Environments.md index 7799db1..70e8bcf 100644 --- a/Environments.md +++ b/Environments.md @@ -9,21 +9,39 @@ ## FistOrderLagEnv -System equations. +### System equation. You can set arbinatry time constant, tau. The default is 0.63 s +### Cost. + + + +Q = diag[1., 1., 1., 1.], +R = diag[1., 1.] + +X_g denote the goal states. + ## TwoWheeledEnv -System equations. +### System equation. +### Cost. + + + +Q = diag[5., 5., 1.], +R = diag[0.1, 0.1] + +X_g denote the goal states. + ## CatpoleEnv (Swing up) -System equations. +System equation. @@ -31,4 +49,8 @@ You can set arbinatry parameters, mc, mp, l and g. Default settings are as follows: -mc = 1, mp = 0.2, l = 0.5, g = 9.8 \ No newline at end of file +mc = 1, mp = 0.2, l = 0.5, g = 9.81 + +### Cost. + + \ No newline at end of file diff --git a/PythonLinearNonlinearControl/configs/cartpole.py b/PythonLinearNonlinearControl/configs/cartpole.py new file mode 100644 index 0000000..64a78db --- /dev/null +++ b/PythonLinearNonlinearControl/configs/cartpole.py @@ -0,0 +1,218 @@ +import numpy as np + +class CartPoleConfigModule(): + # parameters + ENV_NAME = "CartPole-v0" + TYPE = "Nonlinear" + TASK_HORIZON = 500 + PRED_LEN = 50 + STATE_SIZE = 4 + INPUT_SIZE = 1 + DT = 0.02 + # cost parameters + R = np.diag([0.01]) + # bounds + INPUT_LOWER_BOUND = np.array([-3.]) + INPUT_UPPER_BOUND = np.array([3.]) + # parameters + MP = 0.2 + MC = 1. + L = 0.5 + G = 9.81 + + def __init__(self): + """ + """ + # opt configs + self.opt_config = { + "Random": { + "popsize": 5000 + }, + "CEM": { + "popsize": 500, + "num_elites": 50, + "max_iters": 15, + "alpha": 0.3, + "init_var":9., + "threshold":0.001 + }, + "MPPI":{ + "beta" : 0.6, + "popsize": 5000, + "kappa": 0.9, + "noise_sigma": 0.5, + }, + "MPPIWilliams":{ + "popsize": 5000, + "lambda": 1., + "noise_sigma": 0.9, + }, + "iLQR":{ + "max_iter": 500, + "init_mu": 1., + "mu_min": 1e-6, + "mu_max": 1e10, + "init_delta": 2., + "threshold": 1e-6, + }, + "DDP":{ + "max_iter": 500, + "init_mu": 1., + "mu_min": 1e-6, + "mu_max": 1e10, + "init_delta": 2., + "threshold": 1e-6, + }, + "NMPC-CGMRES":{ + }, + "NMPC-Newton":{ + }, + } + + @staticmethod + def input_cost_fn(u): + """ input cost functions + Args: + u (numpy.ndarray): input, shape(pred_len, input_size) + or shape(pop_size, pred_len, input_size) + Returns: + cost (numpy.ndarray): cost of input, shape(pred_len, input_size) or + shape(pop_size, pred_len, input_size) + """ + return (u**2) * np.diag(CartPoleConfigModule.R) + + @staticmethod + def state_cost_fn(x, g_x): + """ state cost function + Args: + x (numpy.ndarray): state, shape(pred_len, state_size) + or shape(pop_size, pred_len, state_size) + g_x (numpy.ndarray): goal state, shape(pred_len, state_size) + or shape(pop_size, pred_len, state_size) + Returns: + cost (numpy.ndarray): cost of state, shape(pred_len, 1) or + shape(pop_size, pred_len, 1) + """ + + if len(x.shape) > 2: + return (6. * (x[:, :, 0]**2) \ + + 12. * ((np.cos(x[:, :, 2]) + 1.)**2) \ + + 0.1 * (x[:, :, 1]**2) \ + + 0.1 * (x[:, :, 3]**2))[:, :, np.newaxis] + + elif len(x.shape) > 1: + return (6. * (x[:, 0]**2) \ + + 12. * ((np.cos(x[:, 2]) + 1.)**2) \ + + 0.1 * (x[:, 1]**2) \ + + 0.1 * (x[:, 3]**2))[:, np.newaxis] + + return 6. * (x[0]**2) \ + + 12. * ((np.cos(x[2]) + 1.)**2) \ + + 0.1 * (x[1]**2) \ + + 0.1 * (x[3]**2) + + @staticmethod + def terminal_state_cost_fn(terminal_x, terminal_g_x): + """ + Args: + terminal_x (numpy.ndarray): terminal state, + shape(state_size, ) or shape(pop_size, state_size) + terminal_g_x (numpy.ndarray): terminal goal state, + shape(state_size, ) or shape(pop_size, state_size) + Returns: + cost (numpy.ndarray): cost of state, shape(pred_len, ) or + shape(pop_size, pred_len) + """ + + if len(terminal_x.shape) > 1: + return (6. * (terminal_x[:, 0]**2) \ + + 12. * ((np.cos(terminal_x[:, 2]) + 1.)**2) \ + + 0.1 * (terminal_x[:, 1]**2) \ + + 0.1 * (terminal_x[:, 3]**2))[:, np.newaxis] + + return 6. * (terminal_x[0]**2) \ + + 12. * ((np.cos(terminal_x[2]) + 1.)**2) \ + + 0.1 * (terminal_x[1]**2) \ + + 0.1 * (terminal_x[3]**2) + + @staticmethod + def gradient_cost_fn_with_state(x, g_x, terminal=False): + """ gradient of costs with respect to the state + + Args: + x (numpy.ndarray): state, shape(pred_len, state_size) + g_x (numpy.ndarray): goal state, shape(pred_len, state_size) + + Returns: + l_x (numpy.ndarray): gradient of cost, shape(pred_len, state_size) + or shape(1, state_size) + """ + if not terminal: + return None + + return None + + @staticmethod + def gradient_cost_fn_with_input(x, u): + """ gradient of costs with respect to the input + + Args: + x (numpy.ndarray): state, shape(pred_len, state_size) + u (numpy.ndarray): goal state, shape(pred_len, input_size) + + Returns: + l_u (numpy.ndarray): gradient of cost, shape(pred_len, input_size) + """ + return None + + @staticmethod + def hessian_cost_fn_with_state(x, g_x, terminal=False): + """ hessian costs with respect to the state + + Args: + x (numpy.ndarray): state, shape(pred_len, state_size) + g_x (numpy.ndarray): goal state, shape(pred_len, state_size) + + Returns: + l_xx (numpy.ndarray): gradient of cost, + shape(pred_len, state_size, state_size) or + shape(1, state_size, state_size) or + """ + if not terminal: + (pred_len, _) = x.shape + return None + + return None + + @staticmethod + def hessian_cost_fn_with_input(x, u): + """ hessian costs with respect to the input + + Args: + x (numpy.ndarray): state, shape(pred_len, state_size) + u (numpy.ndarray): goal state, shape(pred_len, input_size) + + Returns: + l_uu (numpy.ndarray): gradient of cost, + shape(pred_len, input_size, input_size) + """ + (pred_len, _) = u.shape + + return None + + @staticmethod + def hessian_cost_fn_with_input_state(x, u): + """ hessian costs with respect to the state and input + + Args: + x (numpy.ndarray): state, shape(pred_len, state_size) + u (numpy.ndarray): goal state, shape(pred_len, input_size) + + Returns: + l_ux (numpy.ndarray): gradient of cost , + shape(pred_len, input_size, state_size) + """ + (_, state_size) = x.shape + (pred_len, input_size) = u.shape + + return np.zeros((pred_len, input_size, state_size)) \ No newline at end of file diff --git a/PythonLinearNonlinearControl/configs/make_configs.py b/PythonLinearNonlinearControl/configs/make_configs.py index 87e3709..984df94 100644 --- a/PythonLinearNonlinearControl/configs/make_configs.py +++ b/PythonLinearNonlinearControl/configs/make_configs.py @@ -1,5 +1,6 @@ from .first_order_lag import FirstOrderLagConfigModule from .two_wheeled import TwoWheeledConfigModule +from .cartpole import CartPoleConfigModule def make_config(args): """ @@ -9,4 +10,6 @@ def make_config(args): if args.env == "FirstOrderLag": return FirstOrderLagConfigModule() elif args.env == "TwoWheeledConst" or args.env == "TwoWheeled": - return TwoWheeledConfigModule() \ No newline at end of file + return TwoWheeledConfigModule() + elif args.env == "CartPole": + return CartPoleConfigModule() \ No newline at end of file diff --git a/PythonLinearNonlinearControl/envs/cartpole.py b/PythonLinearNonlinearControl/envs/cartpole.py index cd84313..de9becb 100644 --- a/PythonLinearNonlinearControl/envs/cartpole.py +++ b/PythonLinearNonlinearControl/envs/cartpole.py @@ -14,12 +14,16 @@ class CartPoleEnv(Env): def __init__(self): """ """ - self.config = {"state_size" : 4,\ - "input_size" : 1,\ - "dt" : 0.02,\ - "max_step" : 1000,\ - "input_lower_bound": None,\ - "input_upper_bound": None, + self.config = {"state_size" : 4, + "input_size" : 1, + "dt" : 0.02, + "max_step" : 500, + "input_lower_bound": [-3.], + "input_upper_bound": [3.], + "mp": 0.2, + "mc": 1., + "l": 0.5, + "g": 9.81, } super(CartPoleEnv, self).__init__(self.config) @@ -33,13 +37,13 @@ class CartPoleEnv(Env): """ self.step_count = 0 - self.curr_x = np.zeros(self.config["state_size"]) + self.curr_x = np.array([0., 0., 0., 0.]) if init_x is not None: self.curr_x = init_x # goal - self.g_x = np.array([0., 0., np.pi, 0.]) + self.g_x = np.array([0., 0., -np.pi, 0.]) # clear memory self.history_x = [] @@ -65,20 +69,43 @@ class CartPoleEnv(Env): self.config["input_upper_bound"]) # step - next_x = np.zeros(self.config["state_size"]) + # x + d_x0 = self.curr_x[1] + # v_x + d_x1 = (u[0] + self.config["mp"] * np.sin(self.curr_x[2]) \ + * (self.config["l"] * (self.curr_x[3]**2) \ + + self.config["g"] * np.cos(self.curr_x[2]))) \ + / (self.config["mc"] + self.config["mp"] \ + * (np.sin(self.curr_x[2])**2)) + # theta + d_x2 = self.curr_x[3] + + # v_theta + d_x3 = (-u[0] * np.cos(self.curr_x[2]) \ + - self.config["mp"] * self.config["l"] * (self.curr_x[3]**2) \ + * np.cos(self.curr_x[2]) * np.sin(self.curr_x[2]) \ + - (self.config["mc"] + self.config["mp"]) * self.config["g"] \ + * np.sin(self.curr_x[2])) \ + / (self.config["l"] * (self.config["mc"] + self.config["mp"] \ + * (np.sin(self.curr_x[2])**2))) + + next_x = self.curr_x +\ + np.array([d_x0, d_x1, d_x2, d_x3]) * self.config["dt"] # TODO: costs costs = 0. costs += 0.1 * np.sum(u**2) - costs += np.sum((self.curr_x - self.g_x)**2) - + costs += 6. * self.curr_x[0]**2 \ + + 12. * (np.cos(self.curr_x[2]) + 1.)**2 \ + + 0.1 * self.curr_x[1]**2 \ + + 0.1 * self.curr_x[3]**2 # save history self.history_x.append(next_x.flatten()) self.history_g_x.append(self.g_x.flatten()) # update - self.curr_x = next_x.flatten() + self.curr_x = next_x.flatten().copy() # update costs self.step_count += 1 diff --git a/PythonLinearNonlinearControl/envs/make_envs.py b/PythonLinearNonlinearControl/envs/make_envs.py index fd3ea09..4b1adf7 100644 --- a/PythonLinearNonlinearControl/envs/make_envs.py +++ b/PythonLinearNonlinearControl/envs/make_envs.py @@ -1,6 +1,6 @@ from .first_order_lag import FirstOrderLagEnv from .two_wheeled import TwoWheeledConstEnv -from .cartpole import CartpoleEnv +from .cartpole import CartPoleEnv def make_env(args): @@ -9,6 +9,6 @@ def make_env(args): elif args.env == "TwoWheeledConst": return TwoWheeledConstEnv() elif args.env == "CartPole": - return CartpoleEnv() + return CartPoleEnv() raise NotImplementedError("There is not {} Env".format(args.env)) \ No newline at end of file diff --git a/PythonLinearNonlinearControl/envs/two_wheeled.py b/PythonLinearNonlinearControl/envs/two_wheeled.py index c5194cd..8be0d36 100644 --- a/PythonLinearNonlinearControl/envs/two_wheeled.py +++ b/PythonLinearNonlinearControl/envs/two_wheeled.py @@ -86,7 +86,7 @@ class TwoWheeledConstEnv(Env): # TODO: costs costs = 0. costs += 0.1 * np.sum(u**2) - costs += np.sum((self.curr_x - self.g_x)**2) + costs += np.sum(((self.curr_x - self.g_x)**2) * np.array([5., 5., 1.])) # save history self.history_x.append(next_x.flatten()) diff --git a/PythonLinearNonlinearControl/models/cartpole.py b/PythonLinearNonlinearControl/models/cartpole.py new file mode 100644 index 0000000..42c6616 --- /dev/null +++ b/PythonLinearNonlinearControl/models/cartpole.py @@ -0,0 +1,186 @@ +import numpy as np + +from .model import Model + +class CartPoleModel(Model): + """ cartpole model + """ + def __init__(self, config): + """ + """ + super(CartPoleModel, self).__init__() + self.dt = config.DT + self.mc = config.MC + self.mp = config.MP + self.l = config.L + self.g = config.G + + def predict_next_state(self, curr_x, u): + """ predict next state + + Args: + curr_x (numpy.ndarray): current state, shape(state_size, ) or + shape(pop_size, state_size) + u (numpy.ndarray): input, shape(input_size, ) or + shape(pop_size, input_size) + Returns: + next_x (numpy.ndarray): next state, shape(state_size, ) or + shape(pop_size, state_size) + """ + if len(u.shape) == 1: + # x + d_x0 = curr_x[1] + # v_x + d_x1 = (u[0] + self.mp * np.sin(curr_x[2]) \ + * (self.l * (curr_x[3]**2) \ + + self.g * np.cos(curr_x[2]))) \ + / (self.mc + self.mp * (np.sin(curr_x[2])**2)) + # theta + d_x2 = curr_x[3] + # v_theta + d_x3 = (-u[0] * np.cos(curr_x[2]) \ + - self.mp * self.l * (curr_x[3]**2) \ + * np.cos(curr_x[2]) * np.sin(curr_x[2]) \ + - (self.mc + self.mp) * self.g * np.sin(curr_x[2])) \ + / (self.l * (self.mc + self.mp * (np.sin(curr_x[2])**2))) + + next_x = curr_x +\ + np.array([d_x0, d_x1, d_x2, d_x3]) * self.dt + + return next_x + + elif len(u.shape) == 2: + # x + d_x0 = curr_x[:, 1] + # v_x + d_x1 = (u[:, 0] + self.mp * np.sin(curr_x[:, 2]) \ + * (self.l * (curr_x[:, 3]**2) \ + + self.g * np.cos(curr_x[:, 2]))) \ + / (self.mc + self.mp * (np.sin(curr_x[:, 2])**2)) + # theta + d_x2 = curr_x[:, 3] + # v_theta + d_x3 = (-u[:, 0] * np.cos(curr_x[:, 2]) \ + - self.mp * self.l * (curr_x[:, 3]**2) \ + * np.cos(curr_x[:, 2]) * np.sin(curr_x[:, 2]) \ + - (self.mc + self.mp) * self.g * np.sin(curr_x[:, 2])) \ + / (self.l * (self.mc + self.mp * (np.sin(curr_x[:, 2])**2))) + + next_x = curr_x +\ + np.stack((d_x0, d_x1, d_x2, d_x3), axis=1) * self.dt + + return next_x + + def calc_f_x(self, xs, us, dt): + """ gradient of model with respect to the state in batch form + Args: + xs (numpy.ndarray): state, shape(pred_len+1, state_size) + us (numpy.ndarray): input, shape(pred_len, input_size,) + + Return: + f_x (numpy.ndarray): gradient of model with respect to x, + shape(pred_len, state_size, state_size) + + Notes: + This should be discrete form !! + """ + # get size + (_, state_size) = xs.shape + (pred_len, _) = us.shape + + f_x = np.zeros((pred_len, state_size, state_size)) + + f_x[:, 0, 2] = -np.sin(xs[:, 2]) * us[:, 0] + f_x[:, 1, 2] = np.cos(xs[:, 2]) * us[:, 0] + + return f_x * dt + np.eye(state_size) # to discrete form + + def calc_f_u(self, xs, us, dt): + """ gradient of model with respect to the input in batch form + Args: + xs (numpy.ndarray): state, shape(pred_len+1, state_size) + us (numpy.ndarray): input, shape(pred_len, input_size,) + + Return: + f_u (numpy.ndarray): gradient of model with respect to x, + shape(pred_len, state_size, input_size) + + Notes: + This should be discrete form !! + """ + # get size + (_, state_size) = xs.shape + (pred_len, input_size) = us.shape + + f_u = np.zeros((pred_len, state_size, input_size)) + + f_u[:, 1, 0] = 1. / (self.mc + self.mp * (np.sin(xs[:, 2])**2)) + + f_u[:, 3, 0] = -np.cos(xs[:, 2]) \ + / (self.l * (self.mc \ + + self.mp * (np.sin(xs[:, 2])**2))) + + return f_u * dt # to discrete form + + def calc_f_xx(self, xs, us, dt): + """ hessian of model with respect to the state in batch form + + Args: + xs (numpy.ndarray): state, shape(pred_len+1, state_size) + us (numpy.ndarray): input, shape(pred_len, input_size,) + + Return: + f_xx (numpy.ndarray): gradient of model with respect to x, + shape(pred_len, state_size, state_size, state_size) + """ + # get size + (_, state_size) = xs.shape + (pred_len, _) = us.shape + + f_xx = np.zeros((pred_len, state_size, state_size, state_size)) + + f_xx[:, 0, 2, 2] = -np.cos(xs[:, 2]) * us[:, 0] + f_xx[:, 1, 2, 2] = -np.sin(xs[:, 2]) * us[:, 0] + + return f_xx * dt + + def calc_f_ux(self, xs, us, dt): + """ hessian of model with respect to state and input in batch form + + Args: + xs (numpy.ndarray): state, shape(pred_len+1, state_size) + us (numpy.ndarray): input, shape(pred_len, input_size,) + + Return: + f_ux (numpy.ndarray): gradient of model with respect to x, + shape(pred_len, state_size, input_size, state_size) + """ + # get size + (_, state_size) = xs.shape + (pred_len, input_size) = us.shape + + f_ux = np.zeros((pred_len, state_size, input_size, state_size)) + + f_ux[:, 0, 0, 2] = -np.sin(xs[:, 2]) + f_ux[:, 1, 0, 2] = np.cos(xs[:, 2]) + + return f_ux * dt + + def calc_f_uu(self, xs, us, dt): + """ hessian of model with respect to input in batch form + + Args: + xs (numpy.ndarray): state, shape(pred_len+1, state_size) + us (numpy.ndarray): input, shape(pred_len, input_size,) + + Return: + f_uu (numpy.ndarray): gradient of model with respect to x, + shape(pred_len, state_size, input_size, input_size) + """ + # get size + (_, state_size) = xs.shape + (pred_len, input_size) = us.shape + + f_uu = np.zeros((pred_len, state_size, input_size, input_size)) + + return f_uu * dt \ No newline at end of file diff --git a/PythonLinearNonlinearControl/models/make_models.py b/PythonLinearNonlinearControl/models/make_models.py index 7688f93..fcb29ae 100644 --- a/PythonLinearNonlinearControl/models/make_models.py +++ b/PythonLinearNonlinearControl/models/make_models.py @@ -1,5 +1,6 @@ from .first_order_lag import FirstOrderLagModel from .two_wheeled import TwoWheeledModel +from .cartpole import CartPoleModel def make_model(args, config): @@ -7,5 +8,7 @@ def make_model(args, config): return FirstOrderLagModel(config) elif args.env == "TwoWheeledConst" or args.env == "TwoWheeled": return TwoWheeledModel(config) + elif args.env == "CartPole": + return CartPoleModel(config) - raise NotImplementedError("There is not {} Model".format(args.env)) + raise NotImplementedError("There is not {} Model".format(args.env)) \ No newline at end of file diff --git a/README.md b/README.md index 7c1e73d..b177720 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ PythonLinearNonLinearControl is a library implementing the linear and nonlinear | Linear Model Predictive Control (MPC) | ✓ | x | x | x | x | | Cross Entropy Method (CEM) | ✓ | ✓ | x | x | x | | Model Preidictive Path Integral Control of Nagabandi, A. (MPPI) | ✓ | ✓ | x | x | x | -| Model Preidictive Path Integral Control of Williams (MPPIWilliams) | ✓ | ✓ | x | x | x | +| Model Preidictive Path Integral Control of Williams, G. (MPPIWilliams) | ✓ | ✓ | x | x | x | | Random Shooting Method (Random) | ✓ | ✓ | x | x | x | | Iterative LQR (iLQR) | x | ✓ | x | ✓ | x | | Differential Dynamic Programming (DDP) | x | ✓ | x | ✓ | ✓ | @@ -34,7 +34,7 @@ Following algorithms are implemented in PythonLinearNonlinearControl - [Cross Entropy Method (CEM)](https://arxiv.org/abs/1805.12114) - Ref: Chua, K., Calandra, R., McAllister, R., & Levine, S. (2018). Deep reinforcement learning in a handful of trials using probabilistic dynamics models. In Advances in Neural Information Processing Systems (pp. 4754-4765) - [script](PythonLinearNonlinearControl/controllers/cem.py) -- [Model Preidictive Path Integral Control Nagabandi, A. (MPPI)](https://arxiv.org/abs/1909.11652) +- [Model Preidictive Path Integral Control of Nagabandi, A. (MPPI)](https://arxiv.org/abs/1909.11652) - Ref: Nagabandi, A., Konoglie, K., Levine, S., & Kumar, V. (2019). Deep Dynamics Models for Learning Dexterous Manipulation. arXiv preprint arXiv:1909.11652. - [script](PythonLinearNonlinearControl/controllers/mppi.py) - [Model Preidictive Path Integral Control of Williams, G. (MPPIWilliams)](https://ieeexplore.ieee.org/abstract/document/7989202) @@ -71,7 +71,7 @@ Following algorithms are implemented in PythonLinearNonlinearControl All states and inputs of environments are continuous. **It should be noted that the algorithms for linear model could be applied to nonlinear enviroments if you have linealized the model of nonlinear environments.** -You could know abount out environmets more in [Environments.md](Environments.md) +You could know abount our environmets more in [Environments.md](Environments.md) # Usage diff --git a/assets/cartpole_score.png b/assets/cartpole_score.png new file mode 100644 index 0000000000000000000000000000000000000000..ef4d28698467f6526753db4d33b954eba70a44a6 GIT binary patch literal 23268 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