2021-02-24 15:37:54 +01:00
|
|
|
import os
|
2022-07-06 09:05:35 +02:00
|
|
|
from typing import Optional
|
2021-07-02 13:09:56 +02:00
|
|
|
|
2021-02-24 15:37:54 +01:00
|
|
|
import numpy as np
|
2022-06-28 16:05:09 +02:00
|
|
|
from gym import utils
|
2021-07-02 13:09:56 +02:00
|
|
|
from gym.envs.mujoco import MujocoEnv
|
2022-01-28 19:24:34 +01:00
|
|
|
|
2022-07-05 13:15:43 +02:00
|
|
|
# XML Variables
|
|
|
|
ROBOT_COLLISION_OBJ = ["wrist_palm_link_convex_geom",
|
|
|
|
"wrist_pitch_link_convex_decomposition_p1_geom",
|
|
|
|
"wrist_pitch_link_convex_decomposition_p2_geom",
|
|
|
|
"wrist_pitch_link_convex_decomposition_p3_geom",
|
|
|
|
"wrist_yaw_link_convex_decomposition_p1_geom",
|
|
|
|
"wrist_yaw_link_convex_decomposition_p2_geom",
|
|
|
|
"forearm_link_convex_decomposition_p1_geom",
|
|
|
|
"forearm_link_convex_decomposition_p2_geom",
|
|
|
|
"upper_arm_link_convex_decomposition_p1_geom",
|
|
|
|
"upper_arm_link_convex_decomposition_p2_geom",
|
|
|
|
"shoulder_link_convex_decomposition_p1_geom",
|
|
|
|
"shoulder_link_convex_decomposition_p2_geom",
|
|
|
|
"shoulder_link_convex_decomposition_p3_geom",
|
|
|
|
"base_link_convex_geom", "table_contact_geom"]
|
|
|
|
|
|
|
|
CUP_COLLISION_OBJ = ["cup_geom_table3", "cup_geom_table4", "cup_geom_table5", "cup_geom_table6",
|
|
|
|
"cup_geom_table7", "cup_geom_table8", "cup_geom_table9", "cup_geom_table10",
|
|
|
|
"cup_geom_table15", "cup_geom_table16", "cup_geom_table17", "cup_geom1_table8"]
|
2022-01-28 19:24:34 +01:00
|
|
|
|
2022-04-08 17:32:53 +02:00
|
|
|
|
2022-07-04 11:29:51 +02:00
|
|
|
class BeerPongEnv(MujocoEnv, utils.EzPickle):
|
2022-07-04 19:14:31 +02:00
|
|
|
def __init__(self, frame_skip=2):
|
2022-01-31 17:03:49 +01:00
|
|
|
self._steps = 0
|
2022-07-01 09:54:42 +02:00
|
|
|
# Small Context -> Easier. Todo: Should we do different versions?
|
2022-05-29 11:58:01 +02:00
|
|
|
# self.xml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "assets",
|
|
|
|
# "beerpong_wo_cup" + ".xml")
|
2022-07-04 19:14:31 +02:00
|
|
|
# self._cup_pos_min = np.array([-0.32, -2.2])
|
|
|
|
# self._cup_pos_max = np.array([0.32, -1.2])
|
2022-07-01 09:54:42 +02:00
|
|
|
|
2021-02-24 15:37:54 +01:00
|
|
|
self.xml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "assets",
|
2022-05-29 11:58:01 +02:00
|
|
|
"beerpong_wo_cup_big_table" + ".xml")
|
2022-07-04 11:29:51 +02:00
|
|
|
self._cup_pos_min = np.array([-1.42, -4.05])
|
|
|
|
self._cup_pos_max = np.array([1.42, -1.25])
|
2021-02-24 15:37:54 +01:00
|
|
|
|
2021-11-05 11:04:04 +01:00
|
|
|
self._start_pos = np.array([0.0, 1.35, 0.0, 1.18, 0.0, -0.786, -1.59])
|
|
|
|
self._start_vel = np.zeros(7)
|
|
|
|
|
2022-05-05 18:50:20 +02:00
|
|
|
self.release_step = 100 # time step of ball release
|
2022-06-28 16:05:09 +02:00
|
|
|
self.ep_length = 600 // frame_skip
|
2021-11-05 11:04:04 +01:00
|
|
|
|
2022-05-29 12:15:04 +02:00
|
|
|
self.repeat_action = frame_skip
|
2022-07-06 11:29:04 +02:00
|
|
|
# TODO: If accessing IDs is easier in the (new) official mujoco bindings, remove this
|
2022-07-04 19:14:31 +02:00
|
|
|
self.model = None
|
2022-07-13 13:28:39 +02:00
|
|
|
self.geom_id = lambda x: self._mujoco_bindings.mj_name2id(self.model,
|
|
|
|
self._mujoco_bindings.mjtObj.mjOBJ_GEOM,
|
|
|
|
x)
|
2022-07-05 13:15:43 +02:00
|
|
|
|
|
|
|
# for reward calculation
|
|
|
|
self.dists = []
|
|
|
|
self.dists_final = []
|
|
|
|
self.action_costs = []
|
|
|
|
self.ball_ground_contact_first = False
|
|
|
|
self.ball_table_contact = False
|
|
|
|
self.ball_wall_contact = False
|
|
|
|
self.ball_cup_contact = False
|
|
|
|
self.ball_in_cup = False
|
|
|
|
self.dist_ground_cup = -1 # distance floor to cup if first floor contact
|
2022-07-04 19:14:31 +02:00
|
|
|
|
2022-07-13 13:28:39 +02:00
|
|
|
MujocoEnv.__init__(self, model_path=self.xml_path, frame_skip=1, mujoco_bindings="mujoco")
|
2021-11-05 11:04:04 +01:00
|
|
|
utils.EzPickle.__init__(self)
|
|
|
|
|
|
|
|
@property
|
|
|
|
def start_pos(self):
|
|
|
|
return self._start_pos
|
|
|
|
|
|
|
|
@property
|
|
|
|
def start_vel(self):
|
|
|
|
return self._start_vel
|
2021-02-24 15:37:54 +01:00
|
|
|
|
2022-07-06 09:05:35 +02:00
|
|
|
def reset(self, *, seed: Optional[int] = None, return_info: bool = False, options: Optional[dict] = None):
|
2022-07-05 13:15:43 +02:00
|
|
|
self.dists = []
|
|
|
|
self.dists_final = []
|
|
|
|
self.action_costs = []
|
|
|
|
self.ball_ground_contact_first = False
|
|
|
|
self.ball_table_contact = False
|
|
|
|
self.ball_wall_contact = False
|
|
|
|
self.ball_cup_contact = False
|
|
|
|
self.ball_in_cup = False
|
|
|
|
self.dist_ground_cup = -1 # distance floor to cup if first floor contact
|
2021-11-05 11:04:04 +01:00
|
|
|
return super().reset()
|
2021-02-24 15:37:54 +01:00
|
|
|
|
|
|
|
def reset_model(self):
|
|
|
|
init_pos_all = self.init_qpos.copy()
|
|
|
|
init_pos_robot = self.start_pos
|
|
|
|
init_vel = np.zeros_like(init_pos_all)
|
|
|
|
|
|
|
|
self._steps = 0
|
|
|
|
|
|
|
|
start_pos = init_pos_all
|
|
|
|
start_pos[0:7] = init_pos_robot
|
|
|
|
|
2022-07-01 09:54:42 +02:00
|
|
|
# TODO: Ask Max why we need to set the state twice.
|
2021-02-24 15:37:54 +01:00
|
|
|
self.set_state(start_pos, init_vel)
|
2022-07-13 13:28:39 +02:00
|
|
|
start_pos[7::] = self.data.site("init_ball_pos").xpos.copy()
|
2021-11-05 11:04:04 +01:00
|
|
|
self.set_state(start_pos, init_vel)
|
2022-07-04 11:29:51 +02:00
|
|
|
xy = self.np_random.uniform(self._cup_pos_min, self._cup_pos_max)
|
2022-06-30 17:55:00 +02:00
|
|
|
xyz = np.zeros(3)
|
|
|
|
xyz[:2] = xy
|
|
|
|
xyz[-1] = 0.840
|
2022-07-13 13:28:39 +02:00
|
|
|
self.model.body("cup_table").pos[:] = xyz
|
2021-02-24 15:37:54 +01:00
|
|
|
return self._get_obs()
|
|
|
|
|
|
|
|
def step(self, a):
|
2022-07-01 09:54:42 +02:00
|
|
|
crash = False
|
2022-05-29 12:15:04 +02:00
|
|
|
for _ in range(self.repeat_action):
|
2022-07-06 11:29:04 +02:00
|
|
|
applied_action = a + self.data.qfrc_bias[:len(a)].copy() / self.model.actuator_gear[:, 0]
|
2022-05-29 12:15:04 +02:00
|
|
|
try:
|
|
|
|
self.do_simulation(applied_action, self.frame_skip)
|
2022-07-01 09:54:42 +02:00
|
|
|
# self.reward_function.check_contacts(self.sim) # I assume this is not important?
|
2022-05-29 12:15:04 +02:00
|
|
|
if self._steps < self.release_step:
|
2022-07-13 13:28:39 +02:00
|
|
|
self.data.qpos[7::] = self.data.site('init_ball_pos').xpos.copy()
|
|
|
|
self.data.qvel[7::] = self.data.sensor('init_ball_vel').data.copy()
|
2022-05-29 12:15:04 +02:00
|
|
|
crash = False
|
2022-07-13 13:28:39 +02:00
|
|
|
except Exception as e:
|
2022-05-29 12:15:04 +02:00
|
|
|
crash = True
|
2021-02-24 15:37:54 +01:00
|
|
|
|
|
|
|
ob = self._get_obs()
|
|
|
|
|
2021-11-05 11:04:04 +01:00
|
|
|
if not crash:
|
2022-07-05 13:15:43 +02:00
|
|
|
reward, reward_infos = self._get_reward(applied_action)
|
2021-11-05 11:04:04 +01:00
|
|
|
is_collided = reward_infos['is_collided']
|
|
|
|
done = is_collided or self._steps == self.ep_length - 1
|
2021-02-24 15:37:54 +01:00
|
|
|
self._steps += 1
|
|
|
|
else:
|
2021-11-05 11:04:04 +01:00
|
|
|
reward = -30
|
2021-02-24 15:37:54 +01:00
|
|
|
done = True
|
2022-07-04 19:14:31 +02:00
|
|
|
reward_infos = {"success": False, "ball_pos": np.zeros(3), "ball_vel": np.zeros(3), "is_collided": False}
|
2021-11-05 11:04:04 +01:00
|
|
|
|
2022-06-28 16:05:09 +02:00
|
|
|
infos = dict(
|
|
|
|
reward=reward,
|
|
|
|
action=a,
|
2022-07-06 11:29:04 +02:00
|
|
|
q_pos=self.data.qpos[0:7].ravel().copy(),
|
|
|
|
q_vel=self.data.qvel[0:7].ravel().copy(), sim_crash=crash,
|
2022-06-30 14:08:54 +02:00
|
|
|
)
|
2021-12-07 14:46:31 +01:00
|
|
|
infos.update(reward_infos)
|
|
|
|
return ob, reward, done, infos
|
2021-02-24 15:37:54 +01:00
|
|
|
|
|
|
|
def _get_obs(self):
|
2022-07-13 13:28:39 +02:00
|
|
|
theta = self.data.qpos.flat[:7].copy()
|
|
|
|
theta_dot = self.data.qvel.flat[:7].copy()
|
|
|
|
ball_pos = self.data.qpos.flat[7:].copy()
|
|
|
|
cup_goal_diff_final = ball_pos - self.data.site("cup_goal_final_table").xpos.copy()
|
|
|
|
cup_goal_diff_top = ball_pos - self.data.site("cup_goal_table").xpos.copy()
|
2021-02-24 15:37:54 +01:00
|
|
|
return np.concatenate([
|
|
|
|
np.cos(theta),
|
|
|
|
np.sin(theta),
|
2022-06-02 09:05:38 +02:00
|
|
|
theta_dot,
|
|
|
|
cup_goal_diff_final,
|
|
|
|
cup_goal_diff_top,
|
2022-07-13 13:28:39 +02:00
|
|
|
self.model.body("cup_table").pos[:2].copy(),
|
2022-07-05 13:15:43 +02:00
|
|
|
# [self._steps], # Use TimeAwareObservation Wrapper instead ....
|
2022-06-30 14:08:54 +02:00
|
|
|
])
|
2022-06-28 16:05:09 +02:00
|
|
|
|
2022-05-29 11:59:02 +02:00
|
|
|
@property
|
2022-05-29 12:15:04 +02:00
|
|
|
def dt(self):
|
2022-07-04 11:29:51 +02:00
|
|
|
return super(BeerPongEnv, self).dt * self.repeat_action
|
2022-06-28 16:05:09 +02:00
|
|
|
|
2022-07-05 13:15:43 +02:00
|
|
|
def _get_reward(self, action):
|
2022-07-13 13:28:39 +02:00
|
|
|
goal_pos = self.data.site("cup_goal_table").xpos
|
|
|
|
goal_final_pos = self.data.site("cup_goal_final_table").xpos
|
|
|
|
ball_pos = self.data.qpos.flat[7:].copy()
|
|
|
|
ball_vel = self.data.qvel.flat[7:].copy()
|
2022-07-05 13:15:43 +02:00
|
|
|
|
|
|
|
self._check_contacts()
|
|
|
|
self.dists.append(np.linalg.norm(goal_pos - ball_pos))
|
|
|
|
self.dists_final.append(np.linalg.norm(goal_final_pos - ball_pos))
|
|
|
|
self.dist_ground_cup = np.linalg.norm(ball_pos - goal_pos) \
|
|
|
|
if self.ball_ground_contact_first and self.dist_ground_cup == -1 else self.dist_ground_cup
|
|
|
|
action_cost = np.sum(np.square(action))
|
|
|
|
self.action_costs.append(np.copy(action_cost))
|
|
|
|
# # ##################### Reward function which does not force to bounce once on the table (quad dist) #########
|
|
|
|
|
|
|
|
# Is this needed?
|
|
|
|
# self._is_collided = self._check_collision_with_itself([self.geom_id(name) for name in CUP_COLLISION_OBJ])
|
|
|
|
|
2022-07-06 11:29:04 +02:00
|
|
|
if self._steps == self.ep_length - 1: # or self._is_collided:
|
2022-07-05 13:15:43 +02:00
|
|
|
min_dist = np.min(self.dists)
|
|
|
|
final_dist = self.dists_final[-1]
|
|
|
|
if self.ball_ground_contact_first:
|
|
|
|
min_dist_coeff, final_dist_coeff, ground_contact_dist_coeff, rew_offset = 1, 0.5, 2, -4
|
|
|
|
else:
|
|
|
|
if not self.ball_in_cup:
|
|
|
|
if not self.ball_table_contact and not self.ball_cup_contact and not self.ball_wall_contact:
|
|
|
|
min_dist_coeff, final_dist_coeff, ground_contact_dist_coeff, rew_offset = 1, 0.5, 0, -4
|
|
|
|
else:
|
|
|
|
min_dist_coeff, final_dist_coeff, ground_contact_dist_coeff, rew_offset = 1, 0.5, 0, -2
|
|
|
|
else:
|
|
|
|
min_dist_coeff, final_dist_coeff, ground_contact_dist_coeff, rew_offset = 0, 1, 0, 0
|
|
|
|
action_cost = 1e-4 * np.mean(action_cost)
|
|
|
|
reward = rew_offset - min_dist_coeff * min_dist ** 2 - final_dist_coeff * final_dist ** 2 - \
|
|
|
|
action_cost - ground_contact_dist_coeff * self.dist_ground_cup ** 2
|
|
|
|
# release step punishment
|
|
|
|
min_time_bound = 0.1
|
|
|
|
max_time_bound = 1.0
|
|
|
|
release_time = self.release_step * self.dt
|
|
|
|
release_time_rew = int(release_time < min_time_bound) * (-30 - 10 * (release_time - min_time_bound) ** 2) + \
|
|
|
|
int(release_time > max_time_bound) * (-30 - 10 * (release_time - max_time_bound) ** 2)
|
|
|
|
reward += release_time_rew
|
|
|
|
success = self.ball_in_cup
|
|
|
|
else:
|
|
|
|
action_cost = 1e-2 * action_cost
|
|
|
|
reward = - action_cost
|
|
|
|
success = False
|
|
|
|
# ##############################################################################################################
|
|
|
|
infos = {"success": success, "ball_pos": ball_pos.copy(),
|
|
|
|
"ball_vel": ball_vel.copy(), "action_cost": action_cost, "task_reward": reward,
|
|
|
|
"table_contact_first": int(not self.ball_ground_contact_first),
|
|
|
|
"is_collided": False} # TODO: Check if is collided is needed
|
|
|
|
return reward, infos
|
|
|
|
|
|
|
|
def _check_contacts(self):
|
|
|
|
if not self.ball_table_contact:
|
|
|
|
self.ball_table_contact = self._check_collision({self.geom_id("ball_geom")},
|
|
|
|
{self.geom_id("table_contact_geom")})
|
|
|
|
if not self.ball_cup_contact:
|
|
|
|
self.ball_cup_contact = self._check_collision({self.geom_id("ball_geom")},
|
|
|
|
{self.geom_id(name) for name in CUP_COLLISION_OBJ})
|
|
|
|
if not self.ball_wall_contact:
|
|
|
|
self.ball_wall_contact = self._check_collision({self.geom_id("ball_geom")},
|
|
|
|
{self.geom_id("wall")})
|
|
|
|
if not self.ball_in_cup:
|
|
|
|
self.ball_in_cup = self._check_collision({self.geom_id("ball_geom")},
|
|
|
|
{self.geom_id("cup_base_table_contact")})
|
|
|
|
if not self.ball_ground_contact_first:
|
|
|
|
if not self.ball_table_contact and not self.ball_cup_contact and not self.ball_wall_contact \
|
|
|
|
and not self.ball_in_cup:
|
|
|
|
self.ball_ground_contact_first = self._check_collision({self.geom_id("ball_geom")},
|
|
|
|
{self.geom_id("ground")})
|
|
|
|
|
|
|
|
# Checks if id_set1 has a collision with id_set2
|
|
|
|
def _check_collision(self, id_set_1, id_set_2):
|
|
|
|
"""
|
|
|
|
If id_set_2 is set to None, it will check for a collision with itself (id_set_1).
|
|
|
|
"""
|
|
|
|
collision_id_set = id_set_2 - id_set_1 if id_set_2 is not None else id_set_1
|
2022-07-06 11:29:04 +02:00
|
|
|
for coni in range(self.data.ncon):
|
|
|
|
con = self.data.contact[coni]
|
2022-07-05 13:15:43 +02:00
|
|
|
if ((con.geom1 in id_set_1 and con.geom2 in collision_id_set) or
|
|
|
|
(con.geom2 in id_set_1 and con.geom1 in collision_id_set)):
|
|
|
|
return True
|
|
|
|
return False
|
|
|
|
|
2021-02-24 15:37:54 +01:00
|
|
|
|
2022-07-04 11:29:51 +02:00
|
|
|
class BeerPongEnvFixedReleaseStep(BeerPongEnv):
|
2022-07-04 19:14:31 +02:00
|
|
|
def __init__(self, frame_skip=2):
|
|
|
|
super().__init__(frame_skip)
|
2022-06-21 17:15:01 +02:00
|
|
|
self.release_step = 62 # empirically evaluated for frame_skip=2!
|
2022-06-02 09:05:38 +02:00
|
|
|
|
2022-06-28 16:05:09 +02:00
|
|
|
|
2022-07-04 11:29:51 +02:00
|
|
|
class BeerPongEnvStepBasedEpisodicReward(BeerPongEnv):
|
2022-07-04 19:14:31 +02:00
|
|
|
def __init__(self, frame_skip=2):
|
|
|
|
super().__init__(frame_skip)
|
2022-06-04 17:43:35 +02:00
|
|
|
self.release_step = 62 # empirically evaluated for frame_skip=2!
|
|
|
|
|
|
|
|
def step(self, a):
|
|
|
|
if self._steps < self.release_step:
|
2022-07-04 11:29:51 +02:00
|
|
|
return super(BeerPongEnvStepBasedEpisodicReward, self).step(a)
|
2022-06-04 17:43:35 +02:00
|
|
|
else:
|
|
|
|
reward = 0
|
|
|
|
done = False
|
|
|
|
while not done:
|
2022-07-04 11:29:51 +02:00
|
|
|
sub_ob, sub_reward, done, sub_infos = super(BeerPongEnvStepBasedEpisodicReward, self).step(
|
2022-06-28 16:05:09 +02:00
|
|
|
np.zeros(a.shape))
|
2022-06-04 17:43:35 +02:00
|
|
|
reward += sub_reward
|
|
|
|
infos = sub_infos
|
|
|
|
ob = sub_ob
|
2022-06-28 16:05:09 +02:00
|
|
|
ob[-1] = self.release_step + 1 # Since we simulate until the end of the episode, PPO does not see the
|
|
|
|
# internal steps and thus, the observation also needs to be set correctly
|
2022-06-04 17:43:35 +02:00
|
|
|
return ob, reward, done, infos
|
|
|
|
|
2022-06-21 17:15:01 +02:00
|
|
|
|
2022-06-28 20:33:19 +02:00
|
|
|
# class ALRBeerBongEnvStepBased(ALRBeerBongEnv):
|
|
|
|
# def __init__(self, frame_skip=1, apply_gravity_comp=True, noisy=False, rndm_goal=False, cup_goal_pos=None):
|
|
|
|
# super().__init__(frame_skip, apply_gravity_comp, noisy, rndm_goal, cup_goal_pos)
|
|
|
|
# self.release_step = 62 # empirically evaluated for frame_skip=2!
|
|
|
|
#
|
|
|
|
# def step(self, a):
|
|
|
|
# if self._steps < self.release_step:
|
|
|
|
# return super(ALRBeerBongEnvStepBased, self).step(a)
|
|
|
|
# else:
|
|
|
|
# reward = 0
|
|
|
|
# done = False
|
|
|
|
# while not done:
|
|
|
|
# sub_ob, sub_reward, done, sub_infos = super(ALRBeerBongEnvStepBased, self).step(np.zeros(a.shape))
|
|
|
|
# if not done or sub_infos['sim_crash']:
|
|
|
|
# reward += sub_reward
|
|
|
|
# else:
|
|
|
|
# ball_pos = self.sim.data.body_xpos[self.sim.model._body_name2id["ball"]].copy()
|
|
|
|
# cup_goal_dist_final = np.linalg.norm(ball_pos - self.sim.data.site_xpos[
|
|
|
|
# self.sim.model._site_name2id["cup_goal_final_table"]].copy())
|
|
|
|
# cup_goal_dist_top = np.linalg.norm(ball_pos - self.sim.data.site_xpos[
|
|
|
|
# self.sim.model._site_name2id["cup_goal_table"]].copy())
|
|
|
|
# if sub_infos['success']:
|
|
|
|
# dist_rew = -cup_goal_dist_final ** 2
|
|
|
|
# else:
|
|
|
|
# dist_rew = -0.5 * cup_goal_dist_final ** 2 - cup_goal_dist_top ** 2
|
|
|
|
# reward = reward - sub_infos['action_cost'] + dist_rew
|
|
|
|
# infos = sub_infos
|
|
|
|
# ob = sub_ob
|
|
|
|
# ob[-1] = self.release_step + 1 # Since we simulate until the end of the episode, PPO does not see the
|
|
|
|
# # internal steps and thus, the observation also needs to be set correctly
|
|
|
|
# return ob, reward, done, infos
|
2022-06-04 15:27:20 +02:00
|
|
|
|
2022-06-02 09:05:38 +02:00
|
|
|
|
2021-02-24 15:37:54 +01:00
|
|
|
if __name__ == "__main__":
|
2022-07-04 11:29:51 +02:00
|
|
|
env = BeerPongEnv(frame_skip=2)
|
2022-07-05 13:15:43 +02:00
|
|
|
env.seed(0)
|
2022-06-30 17:55:00 +02:00
|
|
|
# env = ALRBeerBongEnvStepBased(frame_skip=2)
|
|
|
|
# env = ALRBeerBongEnvStepBasedEpisodicReward(frame_skip=2)
|
|
|
|
# env = ALRBeerBongEnvFixedReleaseStep(frame_skip=2)
|
2022-01-28 19:24:34 +01:00
|
|
|
import time
|
2022-06-28 16:05:09 +02:00
|
|
|
|
2021-02-24 15:37:54 +01:00
|
|
|
env.reset()
|
2021-11-05 11:04:04 +01:00
|
|
|
env.render("human")
|
2022-07-05 13:15:43 +02:00
|
|
|
for i in range(600):
|
|
|
|
# ac = 10 * env.action_space.sample()
|
|
|
|
ac = 0.05 * np.ones(7)
|
2021-02-24 15:37:54 +01:00
|
|
|
obs, rew, d, info = env.step(ac)
|
2021-11-05 11:04:04 +01:00
|
|
|
env.render("human")
|
2021-02-24 15:37:54 +01:00
|
|
|
|
|
|
|
if d:
|
2022-07-05 13:15:43 +02:00
|
|
|
print('reward:', rew)
|
2022-01-28 19:24:34 +01:00
|
|
|
print('RESETTING')
|
|
|
|
env.reset()
|
|
|
|
time.sleep(1)
|
2021-02-24 15:37:54 +01:00
|
|
|
env.close()
|