Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: (safe vision) update building and formula_one tasks #69

Merged
merged 15 commits into from
Aug 20, 2023
Merged
  •  
  •  
  •  
Next Next commit
upload new envs
  • Loading branch information
muchvo committed Aug 11, 2023
commit fd89b82e0344ecee1a41e8b1948924133142f202
2 changes: 1 addition & 1 deletion examples/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,6 @@ def run_random(env_name):

if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--env', default='SafetyAntVelocity-v0')
parser.add_argument('--env', default='SafetyRacecarFormulaOne2Debug-v0')
args = parser.parse_args()
run_random(args.env)
40 changes: 40 additions & 0 deletions safety_gymnasium/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,36 @@ def __combine(tasks, agents, max_episode_steps):
# Safety Vision
# ----------------------------------------

# Building Button Environments
# ----------------------------------------
building_button_tasks = {
'BuildingButton0': {'floor_conf.type': 'mud'},
'BuildingButton1': {'floor_conf.type': 'mud'},
'BuildingButton2': {'floor_conf.type': 'mud'},
}
__combine(building_button_tasks, robots, max_episode_steps=1000)


# Building Push Environments
# ----------------------------------------
building_push_tasks = {
'BuildingPush0': {'floor_conf.type': 'mud'},
'BuildingPush1': {'floor_conf.type': 'mud'},
'BuildingPush2': {'floor_conf.type': 'mud'},
}
__combine(building_push_tasks, robots, max_episode_steps=1000)


# Building Goal Environments
# ----------------------------------------
building_goal_tasks = {
'BuildingGoal0': {'floor_conf.type': 'mud'},
'BuildingGoal1': {'floor_conf.type': 'mud'},
'BuildingGoal2': {'floor_conf.type': 'mud'},
}
__combine(building_goal_tasks, robots, max_episode_steps=1000)


# Race Environments
# ----------------------------------------
race_tasks = {
Expand All @@ -158,6 +188,16 @@ def __combine(tasks, agents, max_episode_steps):
__combine(race_tasks, robots, max_episode_steps=500)


# Racing Environments
# ----------------------------------------
race_tasks = {
'FormulaOne0': {'floor_conf.type': 'none'},
'FormulaOne1': {'floor_conf.type': 'none'},
'FormulaOne2': {'floor_conf.type': 'none'},
}
__combine(race_tasks, robots, max_episode_steps=50000000000000)


# Fading Environments
# ----------------------------------------
fading_tasks = {'FadingEasy0': {}, 'FadingEasy1': {}, 'FadingEasy2': {}}
Expand Down
2 changes: 1 addition & 1 deletion safety_gymnasium/assets/color.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
'button': np.array([1, 0.5, 0, 1]),
'goal': np.array([0, 1, 0, 1]),
'vase': np.array([0, 1, 1, 1]),
'hazard': np.array([0, 0, 1, 0.25]),
'hazard': np.array([0, 0, 1, 1]),
'pillar': np.array([0.5, 0.5, 1, 1]),
'wall': np.array([0.5, 0.5, 0.5, 1]),
'gremlin': np.array([0.5, 0, 1, 1]),
Expand Down
40 changes: 32 additions & 8 deletions safety_gymnasium/assets/free_geoms/push_box.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,47 @@ class PushBox(FreeGeom): # pylint: disable=too-many-instance-attributes
reward_box_goal: float = 1.0 # Reward for moving the box towards the goal

color: np.array = COLOR['push_box']
alpha: float = 0.25
group: np.array = GROUP['push_box']
is_lidar_observed: bool = True
is_comp_observed: bool = False
is_constrained: bool = False
is_meshed: bool = False
mesh_name: str = name

def get_config(self, xy_pos, rot):
"""To facilitate get specific config for this object."""
return {
'name': 'push_box',
'type': 'box',
'size': np.ones(3) * self.size,
body = {
'name': self.name,
'pos': np.r_[xy_pos, self.size],
'rot': rot,
'density': self.density,
'group': self.group,
'rgba': self.color,
'geoms': [
{
'name': self.name,
'type': 'box',
'size': np.ones(3) * self.size,
'density': self.density,
'group': self.group,
'rgba': self.color * np.array([1, 1, 1, self.alpha]),
},
],
}
if self.is_meshed:
body['geoms'].append(
{
'name': 'push_box_visual',
'pos': [0, 0, -0.2],
'contype': 0,
'conaffinity': 0,
'density': 0,
'group': self.group,
'type': 'mesh',
'mesh': self.mesh_name,
'material': self.mesh_name,
'euler': [np.pi / 2, 0, 0],
},
)
return body

def _specific_agent_config(self):
"""Modify the push_box property according to specific agent."""
Expand All @@ -67,4 +91,4 @@ def _specific_agent_config(self):
@property
def pos(self):
"""Helper to get the box position."""
return self.engine.data.body('push_box').xpos.copy()
return self.engine.data.body(self.name).xpos.copy()
31 changes: 24 additions & 7 deletions safety_gymnasium/assets/free_geoms/vases.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,36 @@ class Vases(FreeGeom): # pylint: disable=too-many-instance-attributes
group: np.array = GROUP['vase']
is_lidar_observed: bool = True
is_constrained: bool = True
is_meshed: bool = False
mesh_name: str = name[:-1]

def get_config(self, xy_pos, rot):
"""To facilitate get specific config for this object."""
return {
body = {
'name': self.name,
'size': np.ones(3) * self.size,
'type': 'box',
'density': self.density,
'pos': np.r_[xy_pos, self.size - self.sink],
'rot': rot,
'group': self.group,
'rgba': self.color,
'geoms': [
{
'size': np.ones(3) * self.size,
'type': 'box',
'density': self.density,
'group': self.group,
'rgba': self.color,
},
],
}
if self.is_meshed:
body['geoms'][0].update(
{
'type': 'mesh',
'mesh': self.mesh_name,
'material': self.mesh_name,
'euler': [np.pi / 2, 0, 0],
},
)
body['geoms'][0]['rgba'] = np.array([1.0, 1.0, 1.0, 1.0])
return body

def cal_cost(self):
"""Contacts processing."""
Expand Down Expand Up @@ -116,4 +133,4 @@ def cal_cost(self):
def pos(self):
"""Helper to get the list of vase positions."""
# pylint: disable-next=no-member
return [self.engine.data.body(f'vase{p}').xpos.copy() for p in range(self.num)]
return [self.engine.data.body(f'{self.name[:-1]}{p}').xpos.copy() for p in range(self.num)]
14 changes: 13 additions & 1 deletion safety_gymnasium/assets/geoms/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,19 @@
from safety_gymnasium.assets.geoms.oranges import Oranges
from safety_gymnasium.assets.geoms.pillars import Pillars
from safety_gymnasium.assets.geoms.sigwalls import Sigwalls
from safety_gymnasium.assets.geoms.staged_goal import StagedGoal
from safety_gymnasium.assets.geoms.walls import Walls


GEOMS_REGISTER = [Apples, Buttons, Circle, Goal, Hazards, Oranges, Pillars, Walls, Sigwalls]
GEOMS_REGISTER = [
Apples,
Buttons,
Circle,
Goal,
StagedGoal,
Hazards,
Oranges,
Pillars,
Walls,
Sigwalls,
]
31 changes: 19 additions & 12 deletions safety_gymnasium/assets/geoms/apples.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,37 +45,44 @@ class Apples(Geom): # pylint: disable=too-many-instance-attributes
reward_distance: float = 1.0 # Dense reward multiplied by the distance moved to the goal

color: np.array = COLOR['apple']
alpha: float = 0.25
group: np.array = GROUP['apple']
is_lidar_observed: bool = True
is_constrained: bool = False
is_meshed: bool = False
mesh_name: str = name[:-1]

def get_config(self, xy_pos, rot):
"""To facilitate get specific config for this object."""
geom = {
body = {
'name': self.name,
'size': [self.size, self.size / 2],
'pos': np.r_[xy_pos, self.size / 2 + 1e-2],
'rot': rot,
'type': 'cylinder',
'contype': 0,
'conaffinity': 0,
'group': self.group,
'rgba': self.color * [1, 1, 1, 0.25], # transparent
'geoms': [
{
'name': self.name,
'size': [self.size, self.size / 2],
'type': 'cylinder',
'contype': 0,
'conaffinity': 0,
'group': self.group,
'rgba': self.color * np.array([1, 1, 1, self.alpha]),
},
],
}
if self.is_meshed:
geom.update(
body['geoms'][0].update(
{
'pos': np.r_[xy_pos, 0.3],
'type': 'mesh',
'mesh': 'apple',
'material': 'apple',
'mesh': self.mesh_name,
'material': self.mesh_name,
'euler': [np.pi / 2, 0, 0],
},
)
return geom
return body

@property
def pos(self):
"""Helper to get goal position from layout"""
return [self.engine.data.body(f'apple{i}').xpos.copy() for i in range(self.num)]
return [self.engine.data.body(f'{self.name[:-1]}{i}').xpos.copy() for i in range(self.num)]
29 changes: 23 additions & 6 deletions safety_gymnasium/assets/geoms/buttons.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,35 @@ class Buttons(Geom): # pylint: disable=too-many-instance-attributes
group: np.array = GROUP['button']
is_lidar_observed: bool = True
is_constrained: bool = True
is_meshed: bool = False
mesh_name: str = name[:-1]

def get_config(self, xy_pos, rot):
"""To facilitate get specific config for this object."""
return {
body = {
'name': self.name,
'size': np.ones(3) * self.size,
'pos': np.r_[xy_pos, self.size],
'rot': rot,
'type': 'sphere',
'group': self.group,
'rgba': self.color,
'geoms': [
{
'name': self.name,
'size': self.size,
'type': 'sphere',
'group': self.group,
'rgba': self.color,
},
],
}
if self.is_meshed:
body['geoms'][0].update(
{
'type': 'mesh',
'mesh': self.mesh_name,
'material': self.mesh_name,
'euler': [np.pi / 2, 0, 0],
},
)
return body

def cal_cost(self):
"""Contacts processing."""
Expand Down Expand Up @@ -97,4 +114,4 @@ def reset_timer(self):
def pos(self):
"""Helper to get the list of button positions."""
# pylint: disable-next=no-member
return [self.engine.data.body(f'button{i}').xpos.copy() for i in range(self.num)]
return [self.engine.data.body(f'{self.name[:-1]}{i}').xpos.copy() for i in range(self.num)]
34 changes: 26 additions & 8 deletions safety_gymnasium/assets/geoms/circle.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,23 +34,41 @@ class Circle(Geom): # pylint: disable=too-many-instance-attributes
keepout: float = 0.0

color: np.array = COLOR['circle']
alpha: float = 0.1
group: np.array = GROUP['circle']
is_lidar_observed: bool = True
is_constrained: bool = False
is_meshed: bool = False
mesh_name: str = name

def get_config(self, xy_pos, rot): # pylint: disable=unused-argument
"""To facilitate get specific config for this object."""
return {
'name': 'circle',
'size': np.array([self.radius, 1e-2]),
body = {
'name': self.name,
'pos': np.r_[xy_pos, 1e-2],
'rot': 0,
'type': 'cylinder',
'contype': 0,
'conaffinity': 0,
'group': GROUP['circle'],
'rgba': COLOR['circle'] * [1, 1, 1, 0.1], # transparent
'geoms': [
{
'name': self.name,
'size': np.array([self.radius, 1e-2]),
'type': 'cylinder',
'contype': 0,
'conaffinity': 0,
'group': self.group,
'rgba': self.color * np.array([1, 1, 1, self.alpha]),
},
],
}
if self.is_meshed:
body['geoms'][0].update(
{
'type': 'mesh',
'mesh': self.mesh_name,
'material': self.mesh_name,
'euler': [0, 0, 0],
},
)
return body

@property
def pos(self):
Expand Down
Loading