Skip to content

Commit

Permalink
feat(agents): support Doggo agent (#51)
Browse files Browse the repository at this point in the history
  • Loading branch information
muchvo authored May 10, 2023
1 parent 2e3c510 commit 7c32d25
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 81 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ Here is a list of all the environments we support for now; some are being tested
<tr>
<td rowspan="4">Safe Navigation</td>
<td>Goal[012]</td>
<td rowspan="4">Point, Car, Racecar, Ant</td>
<td rowspan="4">Point, Car, Doggo, Racecar, Ant</td>
<td rowspan="4">SafetyPointGoal1-v0</td>
</tr>
<tr>
Expand All @@ -95,6 +95,9 @@ Here is a list of all the environments we support for now; some are being tested
</tbody>
</table>

**Note**: We newly support `Doggo` agent in `v0.4.0`, the corresponding `benchmarks`, `pictures`, and `documentation` will be updated soon. And `PRs` are welcome.


Here are some screenshots of the Safe Navigation tasks.

#### Agents
Expand Down
1 change: 1 addition & 0 deletions docs/spelling_wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -394,3 +394,4 @@ mjData
mjModel
SomeWrapperN
fixme
Doggo
2 changes: 1 addition & 1 deletion safety_gymnasium/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
]

VERSION = 'v0'
ROBOT_NAMES = ('Point', 'Car', 'Racecar', 'Ant')
ROBOT_NAMES = ('Point', 'Car', 'Doggo', 'Racecar', 'Ant')
MAKE_VISION_ENVIRONMENTS = True
MAKE_DEBUG_ENVIRONMENTS = True

Expand Down
2 changes: 2 additions & 0 deletions safety_gymnasium/agents/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

from safety_gymnasium.agents.ant import Ant
from safety_gymnasium.agents.car import Car
from safety_gymnasium.agents.doggo import Doggo
from safety_gymnasium.agents.point import Point
from safety_gymnasium.agents.racecar import Racecar

Expand All @@ -25,4 +26,5 @@
'car': Car,
'point': Point,
'racecar': Racecar,
'doggo': Doggo,
}
64 changes: 64 additions & 0 deletions safety_gymnasium/agents/doggo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Copyright 2022-2023 OmniSafe AI Team. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Doggo."""


from safety_gymnasium.bases.base_agent import BaseAgent
from safety_gymnasium.utils.random_generator import RandomGenerator


class Doggo(BaseAgent):
"""A quadrupedal robot with bilateral symmetry.
Each of the four legs has two controls at the hip,
for azimuth and elevation relative to the torso,
and one in the knee controlling angle.
It is designed such that a uniform random policy should keep
the robot from falling over and generate some travel.
"""

def __init__( # pylint: disable=too-many-arguments
self,
random_generator: RandomGenerator,
placements: list = None,
locations: list = None,
keepout: float = 0.4,
rot: float = None,
) -> None:
super().__init__(
self.__class__.__name__,
random_generator,
placements,
locations,
keepout,
rot,
)
self.sensor_conf.sensors += (
'touch_ankle_1a',
'touch_ankle_2a',
'touch_ankle_3a',
'touch_ankle_4a',
'touch_ankle_1b',
'touch_ankle_2b',
'touch_ankle_3b',
'touch_ankle_4b',
)

def is_alive(self):
"""Doggo runs until timeout."""
return True

def reset(self):
"""No need to reset anything."""
76 changes: 38 additions & 38 deletions safety_gymnasium/assets/xmls/doggo.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,76 +19,76 @@
<size njmax="3000" nconmax="1000"/>
<default>
<joint limited="true" stiffness="0.01"/>
<geom condim="6" size="0.032" rgba="1 0 0 1" type="capsule" density="5"/>
<geom condim="6" size="0.032" rgba="0.8 0.6 0.4 1" type="capsule" density="5"/>
<motor ctrllimited="true" ctrlrange="-1.0 1.0" gear=".0125"/>
<site size="0.036" type="sphere" rgba="1 0 0 0"/>
</default>
<worldbody>
<geom name="floor" size="5 5 0.1" type="plane" condim="6"/>
<body name="robot" pos="0 0 0.22">
<body name="agent" pos="0 0 0.22">
<camera name="vision" pos=".125 0 .2" xyaxes="0 -1 0 .4 0 1" fovy="100"/>
<!-- <geom name="cam" pos=".15 0 .2" type="sphere" size="0.005"/> -->
<site name="robot" pos="0 0 0"/>
<geom name="robot" pos="0 0 0" size="0.075" fromto="0 0 0 .2 0 0" type="cylinder" density="0.5"/>
<freejoint name="robot"/>
<site name="agent" pos="0 0 0"/>
<geom name="agent" pos="0 0 0" size="0.075" fromto="0 0 0 .2 0 0" type="cylinder" density="0.5"/>
<freejoint name="agent"/>

<body name="leg_1" pos="0 0 0">
<geom fromto=".1 0.0 0.0 0.2 0.1 0.0" name="aux_1"/>
<geom fromto=".1 0.0 0.0 0.2 0.1 0.0" name="aux_1" rgba="0.0039 0.1529 0.3961 1"/>
<body name="aux_1" pos="0.2 0.1 0">
<joint axis="0 0 1" name="hip_1_z" pos="0.0 0.0 0.0" range="-10 30" type="hinge" springref="0"/>
<joint axis="0 1 0" name="hip_1_y" pos="0.0 0.0 0.0" range="-75 15" type="hinge" springref="-10"/>
<geom fromto="0.0 0.0 0.0 0.098 0.0566 -.05" name="hip_1"/>
<joint axis="0 0 1" name="hip_1_z" pos="0.0 0.0 0.0" range="-0.174533 0.523599" type="hinge" springref="0"/>
<joint axis="0 1 0" name="hip_1_y" pos="0.0 0.0 0.0" range="-1.308998 0.2618" type="hinge" springref="-0.174533"/>
<geom fromto="0.0 0.0 0.0 0.098 0.0566 -.05" name="hip_1" rgba="0.0039 0.1529 0.3961 1"/>
<body pos="0.098 0.0566 -.05">
<joint axis="-.5 .866 0" name="ankle_1" pos="0.0 0.0 0.0" range="-75 0" type="hinge" springref="-20"/>
<geom fromto="0.0 0.0 0.0 -0.1176 -0.0679 -.1" name="ankle_1" rgba="0 0 1 1"/>
<joint axis="-.5 .866 0" name="ankle_1" pos="0.0 0.0 0.0" range="-1.308998 0" type="hinge" springref="-0.349066"/>
<geom fromto="0.0 0.0 0.0 -0.1176 -0.0679 -.1" name="ankle_1"/>
<site name="ankle_1a" pos="0 0 0"/>
<site name="ankle_1b" pos="-0.1176 -0.0679 -.1"/>
</body>
</body>
</body>
<body name="leg_4" pos="0 0 0">
<geom fromto=".1 0.0 0.0 0.2 -0.1 0.0" name="aux_4"/>
<geom fromto=".1 0.0 0.0 0.2 -0.1 0.0" name="aux_4" rgba="0.0039 0.1529 0.3961 1"/>
<body name="aux_4" pos="0.2 -0.1 0">
<joint axis="0 0 -1" name="hip_4_z" pos="0.0 0.0 0.0" range="-10 30" type="hinge" springref="0"/>
<joint axis="0 1 0" name="hip_4_y" pos="0.0 0.0 0.0" range="-75 15" type="hinge" springref="-10"/>
<geom fromto="0.0 0.0 0.0 0.098 -0.0566 -.05" name="hip_4"/>
<joint axis="0 0 -1" name="hip_4_z" pos="0.0 0.0 0.0" range="-0.174533 0.523599" type="hinge" springref="0"/>
<joint axis="0 1 0" name="hip_4_y" pos="0.0 0.0 0.0" range="-1.308998 0.2618" type="hinge" springref="-0.174533"/>
<geom fromto="0.0 0.0 0.0 0.098 -0.0566 -.05" name="hip_4" rgba="0.0039 0.1529 0.3961 1"/>
<body pos="0.098 -0.0566 -.05">
<joint axis=".5 .866 0" name="ankle_4" pos="0.0 0.0 0.0" range="-75 0" type="hinge" springref="-20"/>
<geom fromto="0.0 0.0 0.0 -0.1176 0.0679 -.1" name="ankle_4" rgba="0 0 1 1"/>
<joint axis=".5 .866 0" name="ankle_4" pos="0.0 0.0 0.0" range="-1.308998 0" type="hinge" springref="-0.349066"/>
<geom fromto="0.0 0.0 0.0 -0.1176 0.0679 -.1" name="ankle_4"/>
<site name="ankle_4a" pos="0 0 0"/>
<site name="ankle_4b" pos="-0.1176 0.0679 -.1"/>
</body>
</body>
</body>

<body name="rear" pos="0 0 0">
<geom name="robot2" pos="0 0 0" size="0.075" fromto="-.2 0 0 0 0 0" type="cylinder" density="0.5"/>
<joint axis="1 0 0" name="waist_x" pos="0 0 0" range="-30 30" type="hinge" springref="0"/>
<geom name="agent2" pos="0 0 0" size="0.075" fromto="-.2 0 0 0 0 0" type="cylinder" density="0.5"/>
<joint axis="1 0 0" name="waist_x" pos="0 0 0" range="-0.523599 0.523599" type="hinge" springref="0"/>
<body name="leg_2" pos="0 0 0">
<geom fromto="-.1 0.0 0.0 -0.2 0.1 0.0" name="aux_2"/>
<geom fromto="-.1 0.0 0.0 -0.2 0.1 0.0" name="aux_2" rgba="0.7412 0.0431 0.1843 1"/>
<body name="aux_2" pos="-0.2 0.1 0">
<joint axis="0 0 1" name="hip_2_z" pos="0.0 0.0 0.0" range="-10 30" type="hinge" springref="0"/>
<joint axis="0 1 0" name="hip_2_y" pos="0.0 0.0 0.0" range="0 135" type="hinge" springref="0"/>
<geom fromto="0.0 0.0 0.0 0.098 0.0566 -.05" name="hip_2"/>
<joint axis="0 0 1" name="hip_2_z" pos="0.0 0.0 0.0" range="-0.174533 0.523599" type="hinge" springref="0"/>
<joint axis="0 1 0" name="hip_2_y" pos="0.0 0.0 0.0" range="0 2.356196" type="hinge" springref="0"/>
<geom fromto="0.0 0.0 0.0 0.098 0.0566 -.05" name="hip_2" rgba="0.7412 0.0431 0.1843 1"/>
<body pos="0.098 0.0566 -.05">
<!-- <joint axis="-.5 .866 0" name="ankle_2" pos="0.0 0.0 0.0" range="-80 -30" type="hinge"/> -->
<joint axis="-.5 .866 0" name="ankle_2" pos="0.0 0.0 0.0" range="-75 0" type="hinge" springref="-20"/>
<geom fromto="0.0 0.0 0.0 -0.1176 -0.0679 -.1" name="ankle_2" rgba="0 1 0 1"/>
<joint axis="-.5 .866 0" name="ankle_2" pos="0.0 0.0 0.0" range="-1.308998 0" type="hinge" springref="-0.349066"/>
<geom fromto="0.0 0.0 0.0 -0.1176 -0.0679 -.1" name="ankle_2"/>
<site name="ankle_2a" pos="0 0 0"/>
<site name="ankle_2b" pos="-0.1176 -0.0679 -.1"/>
</body>
</body>
</body>
<body name="leg_3" pos="0 0 0">
<geom fromto="-.1 0.0 0.0 -0.2 -0.1 0.0" name="aux_3"/>
<geom fromto="-.1 0.0 0.0 -0.2 -0.1 0.0" name="aux_3" rgba="0.7412 0.0431 0.1843 1"/>
<body name="aux_3" pos="-0.2 -0.1 0">
<joint axis="0 0 -1" name="hip_3_z" pos="0.0 0.0 0.0" range="-10 30" type="hinge" springref="0"/>
<joint axis="0 1 0" name="hip_3_y" pos="0.0 0.0 0.0" range="0 135" type="hinge" springref="0"/>
<geom fromto="0.0 0.0 0.0 0.098 -0.0566 -.05" name="hip_3"/>
<joint axis="0 0 -1" name="hip_3_z" pos="0.0 0.0 0.0" range="-0.174533 0.523599" type="hinge" springref="0"/>
<joint axis="0 1 0" name="hip_3_y" pos="0.0 0.0 0.0" range="0 2.356196" type="hinge" springref="0"/>
<geom fromto="0.0 0.0 0.0 0.098 -0.0566 -.05" name="hip_3" rgba="0.7412 0.0431 0.1843 1"/>
<body pos="0.098 -0.0566 -.05">
<!-- <joint axis=".5 .866 0" name="ankle_3" pos="0.0 0.0 0.0" range="-80 -30" type="hinge"/> -->
<joint axis=".5 .866 0" name="ankle_3" pos="0.0 0.0 0.0" range="-75 0" type="hinge" springref="-20"/>
<geom fromto="0.0 0.0 0.0 -0.1176 0.0679 -.1" name="ankle_3" rgba="0 1 0 1"/>
<joint axis=".5 .866 0" name="ankle_3" pos="0.0 0.0 0.0" range="-1.308998 0" type="hinge" springref="-0.349066"/>
<geom fromto="0.0 0.0 0.0 -0.1176 0.0679 -.1" name="ankle_3"/>
<site name="ankle_3a" pos="0 0 0"/>
<site name="ankle_3b" pos="-0.1176 0.0679 -.1"/>
</body>
Expand Down Expand Up @@ -166,15 +166,15 @@
<actuatorfrc actuator="ankle_4"/> -->

<!-- Used for observation -->
<accelerometer site="robot" name="accelerometer"/>
<velocimeter site="robot" name="velocimeter"/>
<gyro site="robot" name="gyro"/>
<magnetometer site="robot" name="magnetometer"/>
<accelerometer site="agent" name="accelerometer"/>
<velocimeter site="agent" name="velocimeter"/>
<gyro site="agent" name="gyro"/>
<magnetometer site="agent" name="magnetometer"/>

<!-- Used for intrinsic constraints -->
<subtreecom body="robot" name="subtreecom"/>
<subtreelinvel body="robot" name="subtreelinvel"/>
<subtreeangmom body="robot" name="subtreeangmom"/>
<subtreecom body="agent" name="subtreecom"/>
<subtreelinvel body="agent" name="subtreelinvel"/>
<subtreeangmom body="agent" name="subtreeangmom"/>
</sensor>
<actuator>
<motor name="hip_1_z" joint="hip_1_z"/>
Expand Down
2 changes: 1 addition & 1 deletion safety_gymnasium/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# ==============================================================================
"""Safety-Gymnasium."""

__version__ = '0.3.0'
__version__ = '0.4.0'
__license__ = 'Apache License, Version 2.0'
__author__ = 'Safety-Gymnasium Contributors'
__release__ = False
Expand Down
46 changes: 6 additions & 40 deletions tests/test_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@


@helpers.parametrize(
agent_id=['Point', 'Car', 'Racecar', 'Ant'],
agent_id=['Point', 'Car', 'Racecar', 'Ant', 'Doggo'],
env_id=['Goal', 'Push', 'Button', 'Circle'],
level=['0', '1', '2'],
render_mode=['rgb_array', 'depth_array'],
Expand Down Expand Up @@ -50,7 +50,7 @@ def test_env_render(agent_id, env_id, level, render_mode):


@helpers.parametrize(
agent_id=['Point', 'Car', 'Racecar', 'Ant'],
agent_id=['Point', 'Car', 'Racecar', 'Ant', 'Doggo'],
env_id=['Run'],
level=['0'],
render_mode=['rgb_array', 'depth_array'],
Expand Down Expand Up @@ -118,47 +118,13 @@ def test_velocity_env_render(agent_id, env_id, render_mode, version):


@helpers.parametrize(
agent_id=['Point', 'Car', 'Racecar', 'Ant'],
env_id=['Goal', 'Push', 'Button', 'Circle'],
level=['0', '1', '2'],
render_mode=['rgb_array_list', 'depth_array_list'],
)
# pylint: disable-next=too-many-locals
def test_env_render_list(agent_id, env_id, level, render_mode):
"""Test env."""
env_name = 'Safety' + agent_id + env_id + level + '-v0'
env = safety_gymnasium.make(env_name, render_mode=render_mode)
obs, _ = env.reset()
terminated, truncated = False, False
ep_ret, ep_cost = 0, 0
for step in range(4):
if step == 2:
print(f'Episode Return: {ep_ret} \t Episode Cost: {ep_cost}')
ep_ret, ep_cost = 0, 0
obs, _ = env.reset()
assert env.observation_space.contains(obs)
act = env.action_space.sample()
assert env.action_space.contains(act)

# Use the environment's built_in max_episode_steps
if hasattr(env, '_max_episode_steps'): # pylint: disable=protected-access
pass # pylint: disable=unused-variable,protected-access
# pylint: disable-next=unused-variable
obs, reward, cost, terminated, truncated, info = env.step(act)
ep_ret += reward
ep_cost += cost

assert isinstance(env.render(), list)


@helpers.parametrize(
agent_id=['Point', 'Car', 'Racecar', 'Ant'],
env_id=['Run'],
agent_id=['Point'],
env_id=['Goal'],
level=['0'],
render_mode=['rgb_array_list', 'depth_array_list'],
)
# pylint: disable-next=too-many-locals
def test_run_env_render_list(agent_id, env_id, level, render_mode):
def test_env_render_list(agent_id, env_id, level, render_mode):
"""Test env."""
env_name = 'Safety' + agent_id + env_id + level + '-v0'
env = safety_gymnasium.make(env_name, render_mode=render_mode)
Expand Down Expand Up @@ -186,7 +152,7 @@ def test_run_env_render_list(agent_id, env_id, level, render_mode):


@helpers.parametrize(
agent_id=['Humanoid', 'Ant', 'Hopper', 'HalfCheetah', 'Swimmer', 'Walker2d'],
agent_id=['Humanoid'],
env_id=['Velocity'],
render_mode=['rgb_array_list', 'depth_array_list'],
version=['v0', 'v1'],
Expand Down

0 comments on commit 7c32d25

Please sign in to comment.