Add Go1 evaluation and keyboard control
This commit is contained in:
BIN
resources/models/go1/policy.pt
Normal file
BIN
resources/models/go1/policy.pt
Normal file
Binary file not shown.
BIN
resources/models/go1/policy_10k.pt
Normal file
BIN
resources/models/go1/policy_10k.pt
Normal file
Binary file not shown.
BIN
resources/robots/go1/assets/calf.stl
Normal file
BIN
resources/robots/go1/assets/calf.stl
Normal file
Binary file not shown.
BIN
resources/robots/go1/assets/hip.stl
Normal file
BIN
resources/robots/go1/assets/hip.stl
Normal file
Binary file not shown.
BIN
resources/robots/go1/assets/thigh.stl
Normal file
BIN
resources/robots/go1/assets/thigh.stl
Normal file
Binary file not shown.
BIN
resources/robots/go1/assets/thigh_mirror.stl
Normal file
BIN
resources/robots/go1/assets/thigh_mirror.stl
Normal file
Binary file not shown.
BIN
resources/robots/go1/assets/trunk.stl
Normal file
BIN
resources/robots/go1/assets/trunk.stl
Normal file
Binary file not shown.
197
resources/robots/go1/go1.xml
Normal file
197
resources/robots/go1/go1.xml
Normal file
@@ -0,0 +1,197 @@
|
||||
<mujoco model="go1">
|
||||
<compiler angle="radian" meshdir="assets" />
|
||||
<size njmax="500" nconmax="100" />
|
||||
<option gravity='0 0 -9.806' iterations='50' solver='Newton' timestep='0.002'/>
|
||||
|
||||
<default>
|
||||
<geom contype="1" conaffinity="1" friction="0.6 0.3 0.3" rgba="0.5 0.6 0.7 1" margin="0.001" group="0"/>
|
||||
|
||||
<light castshadow="false" diffuse="1 1 1"/>
|
||||
<motor ctrlrange="-33.5 33.5" ctrllimited="true"/>
|
||||
<camera fovy="60"/>
|
||||
<joint damping="0.01" armature="0.01" frictionloss="0.2" />
|
||||
|
||||
</default>
|
||||
<asset>
|
||||
<mesh name="trunk" file="trunk.stl" />
|
||||
<mesh name="hip" file="hip.stl" />
|
||||
<mesh name="thigh_mirror" file="thigh_mirror.stl" />
|
||||
<mesh name="calf" file="calf.stl" />
|
||||
<mesh name="thigh" file="thigh.stl" />
|
||||
</asset>
|
||||
|
||||
<worldbody>
|
||||
<body name="base_link" pos="0 0 0.35">
|
||||
<inertial pos="0.0116053 0.00442221 0.000106692" quat="0.0111438 0.707126 -0.00935374 0.706938" mass="4.801" diaginertia="0.0447997 0.0366257 0.0162187" />
|
||||
<geom type="mesh" contype="0" conaffinity="0" group="1" rgba="0.913725 0.913725 0.847059 1" mesh="trunk" />
|
||||
<geom size="0.13 0.04675 0.057" type="box" rgba="0.913725 0.913725 0.847059 1" />
|
||||
<geom size="0.0005 0.0005 0.0005" pos="-0.01592 -0.06659 -0.00617" type="box" contype="0" conaffinity="0" group="1" rgba="0.8 0 0 0" />
|
||||
<geom size="0.0005 0.0005 0.0005" pos="-0.01592 -0.06659 -0.00617" type="box" rgba="0.8 0 0 0" />
|
||||
<site name="imu" pos="0 0 0"/>
|
||||
|
||||
<body name="FR_hip" pos="0.1881 -0.04675 0">
|
||||
<inertial pos="-0.00406411 -0.0193463 4.50733e-06" quat="0.467526 0.531662 -0.466259 0.530431" mass="0.679292" diaginertia="0.00131334 0.00122648 0.000728484" />
|
||||
<joint name="FR_hip_joint" pos="0 0 0" axis="1 0 0" limited="true" range="-0.802851 0.802851" />
|
||||
<geom quat="0 1 0 0" type="mesh" contype="0" conaffinity="0" group="1" rgba="0.913725 0.913725 0.847059 1" mesh="hip" />
|
||||
<geom size="0.046 0.02" pos="0 -0.045 0" quat="0.707107 0.707107 0 0" type="cylinder" rgba="0.913725 0.913725 0.847059 0" />
|
||||
<geom size="0.031 0.02" pos="0 -0.07 0" quat="0.707107 0.707107 0 0" type="cylinder" rgba="0.913725 0.913725 0.847059 0" />
|
||||
|
||||
<body name="FR_thigh" pos="0 -0.08 0">
|
||||
<inertial pos="-0.003468 0.018947 -0.032736" quat="0.999266 0.00067676 -0.0382978 0.000639813" mass="0.898919" diaginertia="0.00542178 0.00514246 0.000998869" />
|
||||
<joint name="FR_thigh_joint" pos="0 0 0" axis="0 1 0" limited="true" range="-1.0472 4.18879" />
|
||||
<geom type="mesh" contype="0" conaffinity="0" group="1" rgba="0.913725 0.913725 0.847059 1" mesh="thigh_mirror" />
|
||||
<geom size="0.1065 0.01225 0.017" pos="0 0 -0.1065" quat="0.707107 0 0.707107 0" type="box" rgba="0.913725 0.913725 0.847059 0" />
|
||||
<body name="FR_calf" pos="0 0 -0.213">
|
||||
<inertial pos="0.00455603 0.0009473 -0.147239" quat="0.762045 0.00970173 0.0180098 0.647201" mass="0.218015" diaginertia="0.00399678 0.00398122 3.99428e-05" />
|
||||
<joint name="FR_calf_joint" pos="0 0 0" axis="0 1 0" limited="true" range="-2.69653 -0.916298" />
|
||||
<geom type="mesh" contype="0" conaffinity="0" group="1" rgba="0 0 0 1" mesh="calf" />
|
||||
<geom size="0.1065 0.008 0.008" pos="0 0 -0.1065" quat="0.707107 0 0.707107 0" type="box" rgba="0 0 0 0" />
|
||||
<geom size="0.01" pos="0 0 -0.213" contype="0" conaffinity="0" group="1" rgba="0 0 0 1" />
|
||||
<geom name="FR" size="0.02" pos="0 0 -0.213" rgba="0 0 0 1" />
|
||||
<body name="FR_foot" pos="0 0 -0.213" />
|
||||
</body>
|
||||
</body>
|
||||
</body>
|
||||
<body name="FL_hip" pos="0.1881 0.04675 0">
|
||||
<inertial pos="-0.00406411 0.0193463 4.50733e-06" quat="0.531662 0.467526 -0.530431 0.466259" mass="0.679292" diaginertia="0.00131334 0.00122648 0.000728484" />
|
||||
<joint name="FL_hip_joint" pos="0 0 0" axis="1 0 0" limited="true" range="-0.802851 0.802851" />
|
||||
<geom type="mesh" contype="0" conaffinity="0" group="1" rgba="0.913725 0.913725 0.847059 1" mesh="hip" />
|
||||
<geom size="0.046 0.02" pos="0 0.045 0" quat="0.707107 0.707107 0 0" type="cylinder" rgba="0.913725 0.913725 0.847059 0" />
|
||||
<geom size="0.031 0.02" pos="0 0.07 0" quat="0.707107 0.707107 0 0" type="cylinder" rgba="0.913725 0.913725 0.847059 0" />
|
||||
|
||||
<body name="FL_thigh" pos="0 0.08 0">
|
||||
<inertial pos="-0.003468 -0.018947 -0.032736" quat="0.999266 -0.00067676 -0.0382978 -0.000639813" mass="0.898919" diaginertia="0.00542178 0.00514246 0.000998869" />
|
||||
<joint name="FL_thigh_joint" pos="0 0 0" axis="0 1 0" limited="true" range="-1.0472 4.18879" />
|
||||
<geom type="mesh" contype="0" conaffinity="0" group="1" rgba="0.913725 0.913725 0.847059 1" mesh="thigh" />
|
||||
<geom size="0.1065 0.01225 0.017" pos="0 0 -0.1065" quat="0.707107 0 0.707107 0" type="box" rgba="0.913725 0.913725 0.847059 0" />
|
||||
<body name="FL_calf" pos="0 0 -0.213">
|
||||
<inertial pos="0.00455603 0.0009473 -0.147239" quat="0.762045 0.00970173 0.0180098 0.647201" mass="0.218015" diaginertia="0.00399678 0.00398122 3.99428e-05" />
|
||||
<joint name="FL_calf_joint" pos="0 0 0" axis="0 1 0" limited="true" range="-2.69653 -0.916298" />
|
||||
<geom type="mesh" contype="0" conaffinity="0" group="1" rgba="0 0 0 1" mesh="calf" />
|
||||
<geom size="0.1065 0.008 0.008" pos="0 0 -0.1065" quat="0.707107 0 0.707107 0" type="box" rgba="0.913725 0.913725 0.847059 0" />
|
||||
<geom size="0.01" pos="0 0 -0.213" contype="0" conaffinity="0" group="1" rgba="0 0 0 1" />
|
||||
<geom name="FL" size="0.02" pos="0 0 -0.213" rgba="0 0 0 1" />
|
||||
<body name="FL_foot" pos="0 0 -0.213" />
|
||||
</body>
|
||||
</body>
|
||||
</body>
|
||||
<body name="RR_hip" pos="-0.1881 -0.04675 0">
|
||||
<inertial pos="0.00406411 -0.0193463 4.50733e-06" quat="0.530431 0.466259 -0.531662 0.467526" mass="0.679292" diaginertia="0.00131334 0.00122648 0.000728484" />
|
||||
<joint name="RR_hip_joint" pos="0 0 0" axis="1 0 0" limited="true" range="-0.802851 0.802851" />
|
||||
<geom quat="0 0 0 -1" type="mesh" contype="0" conaffinity="0" group="1" rgba="0.913725 0.913725 0.847059 1" mesh="hip" />
|
||||
<geom size="0.046 0.02" quat="0.707107 0.707107 0 0" type="cylinder" rgba="0.913725 0.913725 0.847059 1" />
|
||||
<geom size="0.046 0.02" pos="0 -0.045 0" quat="0.707107 0.707107 0 0" type="cylinder" rgba="0.913725 0.913725 0.847059 0" />
|
||||
<geom size="0.031 0.02" pos="0 -0.07 0" quat="0.707107 0.707107 0 0" type="cylinder" rgba="0.913725 0.913725 0.847059 0" />
|
||||
|
||||
<body name="RR_thigh" pos="0 -0.08 0">
|
||||
<inertial pos="-0.003468 0.018947 -0.032736" quat="0.999266 0.00067676 -0.0382978 0.000639813" mass="0.898919" diaginertia="0.00542178 0.00514246 0.000998869" />
|
||||
<joint name="RR_thigh_joint" pos="0 0 0" axis="0 1 0" limited="true" range="-1.0472 4.18879" />
|
||||
<geom type="mesh" contype="0" conaffinity="0" group="1" rgba="0.913725 0.913725 0.847059 1" mesh="thigh_mirror" />
|
||||
<geom size="0.1065 0.01225 0.017" pos="0 0 -0.1065" quat="0.707107 0 0.707107 0" type="box" rgba="0.913725 0.913725 0.847059 0" />
|
||||
<body name="RR_calf" pos="0 0 -0.213">
|
||||
<inertial pos="0.00455603 0.0009473 -0.147239" quat="0.762045 0.00970173 0.0180098 0.647201" mass="0.218015" diaginertia="0.00399678 0.00398122 3.99428e-05" />
|
||||
<joint name="RR_calf_joint" pos="0 0 0" axis="0 1 0" limited="true" range="-2.69653 -0.916298" />
|
||||
<geom type="mesh" contype="0" conaffinity="0" group="1" rgba="0 0 0 1" mesh="calf" />
|
||||
<geom size="0.1065 0.008 0.008" pos="0 0 -0.1065" quat="0.707107 0 0.707107 0" type="box" rgba="0 0 0 0" />
|
||||
<geom size="0.01" pos="0 0 -0.213" contype="0" conaffinity="0" group="1" rgba="0 0 0 1" />
|
||||
<geom name="RR" size="0.02" pos="0 0 -0.213" rgba="0 0 0 1" />
|
||||
<body name="RR_foot" pos="0 0 -0.213" />
|
||||
</body>
|
||||
</body>
|
||||
</body>
|
||||
<body name="RL_hip" pos="-0.1881 0.04675 0">
|
||||
<inertial pos="0.00406411 0.0193463 4.50733e-06" quat="0.466259 0.530431 -0.467526 0.531662" mass="0.679292" diaginertia="0.00131334 0.00122648 0.000728484" />
|
||||
<joint name="RL_hip_joint" pos="0 0 0" axis="1 0 0" limited="true" range="-0.802851 0.802851" />
|
||||
<geom quat="0 0 1 0" type="mesh" contype="0" conaffinity="0" group="1" rgba="0.913725 0.913725 0.847059 1" mesh="hip" />
|
||||
<geom size="0.046 0.02" quat="0.707107 0.707107 0 0" type="cylinder" rgba="0.913725 0.913725 0.847059 1" />
|
||||
<geom size="0.046 0.02" pos="0 0.045 0" quat="0.707107 0.707107 0 0" type="cylinder" rgba="0.913725 0.913725 0.847059 0" />
|
||||
<geom size="0.031 0.02" pos="0 0.07 0" quat="0.707107 0.707107 0 0" type="cylinder" rgba="0.913725 0.913725 0.847059 0" />
|
||||
|
||||
<body name="RL_thigh" pos="0 0.08 0">
|
||||
<inertial pos="-0.003468 -0.018947 -0.032736" quat="0.999266 -0.00067676 -0.0382978 -0.000639813" mass="0.898919" diaginertia="0.00542178 0.00514246 0.000998869" />
|
||||
<joint name="RL_thigh_joint" pos="0 0 0" axis="0 1 0" limited="true" range="-1.0472 4.18879" />
|
||||
<geom type="mesh" contype="0" conaffinity="0" group="1" rgba="0.913725 0.913725 0.847059 1" mesh="thigh" />
|
||||
<geom size="0.1065 0.01225 0.017" pos="0 0 -0.1065" quat="0.707107 0 0.707107 0" type="box" rgba="0.913725 0.913725 0.847059 0" />
|
||||
<body name="RL_calf" pos="0 0 -0.213">
|
||||
<inertial pos="0.00455603 0.0009473 -0.147239" quat="0.762045 0.00970173 0.0180098 0.647201" mass="0.218015" diaginertia="0.00399678 0.00398122 3.99428e-05" />
|
||||
<joint name="RL_calf_joint" pos="0 0 0" axis="0 1 0" limited="true" range="-2.69653 -0.916298" />
|
||||
<geom type="mesh" contype="0" conaffinity="0" group="1" rgba="0 0 0 1" mesh="calf" />
|
||||
<geom size="0.1065 0.008 0.008" pos="0 0 -0.1065" quat="0.707107 0 0.707107 0" type="box" rgba="0 0 0 0" />
|
||||
<geom size="0.01" pos="0 0 -0.213" contype="0" conaffinity="0" group="1" rgba="0 0 0 1" />
|
||||
<geom name="RL" size="0.02" pos="0 0 -0.213" rgba="0 0 0 1" />
|
||||
<body name="RL_foot" pos="0 0 -0.213" />
|
||||
</body>
|
||||
</body>
|
||||
</body>
|
||||
</body>
|
||||
</worldbody>
|
||||
<actuator>
|
||||
|
||||
<motor name="FR_hip" gear="1" joint="FR_hip_joint"/>
|
||||
<motor name="FR_thigh" gear="1" joint="FR_thigh_joint"/>
|
||||
<motor name="FR_calf" gear="1" joint="FR_calf_joint"/>
|
||||
<motor name="FL_hip" gear="1" joint="FL_hip_joint"/>
|
||||
<motor name="FL_thigh" gear="1" joint="FL_thigh_joint"/>
|
||||
<motor name="FL_calf" gear="1" joint="FL_calf_joint"/>
|
||||
<motor name="RR_hip" gear="1" joint="RR_hip_joint"/>
|
||||
<motor name="RR_thigh" gear="1" joint="RR_thigh_joint"/>
|
||||
<motor name="RR_calf" gear="1" joint="RR_calf_joint" />
|
||||
<motor name="RL_hip" gear="1" joint="RL_hip_joint"/>
|
||||
<motor name="RL_thigh" gear="1" joint="RL_thigh_joint"/>
|
||||
<motor name="RL_calf" gear="1" joint="RL_calf_joint"/>
|
||||
</actuator>
|
||||
|
||||
<sensor>
|
||||
|
||||
<jointpos name="FR_hip_pos" joint="FR_hip_joint"/>
|
||||
<jointpos name="FR_thigh_pos" joint="FR_thigh_joint"/>
|
||||
<jointpos name="FR_calf_pos" joint="FR_calf_joint"/>
|
||||
<jointpos name="FL_hip_pos" joint="FL_hip_joint"/>
|
||||
<jointpos name="FL_thigh_pos" joint="FL_thigh_joint"/>
|
||||
<jointpos name="FL_calf_pos" joint="FL_calf_joint"/>
|
||||
<jointpos name="RR_hip_pos" joint="RR_hip_joint"/>
|
||||
<jointpos name="RR_thigh_pos" joint="RR_thigh_joint"/>
|
||||
<jointpos name="RR_calf_pos" joint="RR_calf_joint" />
|
||||
<jointpos name="RL_hip_pos" joint="RL_hip_joint"/>
|
||||
<jointpos name="RL_thigh_pos" joint="RL_thigh_joint"/>
|
||||
<jointpos name="RL_calf_pos" joint="RL_calf_joint"/>
|
||||
|
||||
<jointvel name="FR_hip_vel" joint="FR_hip_joint"/>
|
||||
<jointvel name="FR_thigh_vel" joint="FR_thigh_joint"/>
|
||||
<jointvel name="FR_calf_vel" joint="FR_calf_joint"/>
|
||||
<jointvel name="FL_hip_vel" joint="FL_hip_joint"/>
|
||||
<jointvel name="FL_thigh_vel" joint="FL_thigh_joint"/>
|
||||
<jointvel name="FL_calf_vel" joint="FL_calf_joint"/>
|
||||
<jointvel name="RR_hip_vel" joint="RR_hip_joint"/>
|
||||
<jointvel name="RR_thigh_vel" joint="RR_thigh_joint"/>
|
||||
<jointvel name="RR_calf_vel" joint="RR_calf_joint" />
|
||||
<jointvel name="RL_hip_vel" joint="RL_hip_joint"/>
|
||||
<jointvel name="RL_thigh_vel" joint="RL_thigh_joint"/>
|
||||
<jointvel name="RL_calf_vel" joint="RL_calf_joint"/>
|
||||
|
||||
<jointactuatorfrc name="FR_hip_torque" joint="FR_hip_joint" />
|
||||
<jointactuatorfrc name="FR_thigh_torque" joint="FR_thigh_joint" />
|
||||
<jointactuatorfrc name="FR_calf_torque" joint="FR_calf_joint" />
|
||||
<jointactuatorfrc name="FL_hip_torque" joint="FL_hip_joint" />
|
||||
<jointactuatorfrc name="FL_thigh_torque" joint="FL_thigh_joint" />
|
||||
<jointactuatorfrc name="FL_calf_torque" joint="FL_calf_joint" />
|
||||
<jointactuatorfrc name="RR_hip_torque" joint="RR_hip_joint" />
|
||||
<jointactuatorfrc name="RR_thigh_torque" joint="RR_thigh_joint" />
|
||||
<jointactuatorfrc name="RR_calf_torque" joint="RR_calf_joint" />
|
||||
<jointactuatorfrc name="RL_hip_torque" joint="RL_hip_joint" />
|
||||
<jointactuatorfrc name="RL_thigh_torque" joint="RL_thigh_joint" />
|
||||
<jointactuatorfrc name="RL_calf_torque" joint="RL_calf_joint" />
|
||||
|
||||
<accelerometer name="Body_Acc" site="imu"/>
|
||||
|
||||
<gyro name="Body_Gyro" site="imu"/>
|
||||
|
||||
<framepos name="Body_Pos" objtype="site" objname="imu"/>
|
||||
|
||||
<framelinvel name="Body_LinVel" objtype="site" objname="imu"/>
|
||||
|
||||
<framequat name="Body_Quat" objtype="site" objname="imu"/>
|
||||
|
||||
|
||||
</sensor>
|
||||
</mujoco>
|
||||
@@ -8,6 +8,8 @@ from robogauge.tasks.robots import (
|
||||
Go2TerrainConfig,
|
||||
Go2LabTerrainConfig,
|
||||
Go2MoETerrainConfig,
|
||||
Go1MoEConfig,
|
||||
Go1MoETerrainConfig,
|
||||
)
|
||||
from robogauge.tasks.pipeline import BasePipeline
|
||||
from robogauge.tasks.gauge import BaseGaugeConfig
|
||||
@@ -35,6 +37,15 @@ task_register.register('go2_moe.stairs_fd', BasePipeline, MujocoConfig, Go2Stair
|
||||
task_register.register('go2_moe.stairs_bd', BasePipeline, MujocoConfig, Go2StairsBackwardGaugeConfig, Go2MoETerrainConfig)
|
||||
task_register.register('go2_moe.obstacle', BasePipeline, MujocoConfig, Go2ObstacleGaugeConfig, Go2MoETerrainConfig)
|
||||
|
||||
# Go1 MoE (the policy is evaluated in the Go1 MuJoCo dynamics model)
|
||||
task_register.register('go1_moe.flat', BasePipeline, MujocoConfig, Go2FlatGaugeConfig, Go1MoEConfig)
|
||||
task_register.register('go1_moe.slope_fd', BasePipeline, MujocoConfig, Go2SlopeForwardGaugeConfig, Go1MoETerrainConfig)
|
||||
task_register.register('go1_moe.slope_bd', BasePipeline, MujocoConfig, Go2SlopeBackwardGaugeConfig, Go1MoETerrainConfig)
|
||||
task_register.register('go1_moe.wave', BasePipeline, MujocoConfig, Go2WaveGaugeConfig, Go1MoETerrainConfig)
|
||||
task_register.register('go1_moe.stairs_fd', BasePipeline, MujocoConfig, Go2StairsForwardGaugeConfig, Go1MoETerrainConfig)
|
||||
task_register.register('go1_moe.stairs_bd', BasePipeline, MujocoConfig, Go2StairsBackwardGaugeConfig, Go1MoETerrainConfig)
|
||||
task_register.register('go1_moe.obstacle', BasePipeline, MujocoConfig, Go2ObstacleGaugeConfig, Go1MoETerrainConfig)
|
||||
|
||||
# Go2 Lab
|
||||
task_register.register('go2_lab.flat', BasePipeline, MujocoConfig, Go2FlatGaugeConfig, Go2LabConfig)
|
||||
task_register.register('go2_lab.slope_fd', BasePipeline, MujocoConfig, Go2SlopeForwardGaugeConfig, Go2LabTerrainConfig)
|
||||
|
||||
@@ -58,6 +58,9 @@ class BaseGauge:
|
||||
elif name == 'joystick':
|
||||
self.goals.append(JoystickGoal(robot_cfg.commands, **kwargs))
|
||||
log_str += f" - Joystick Goal: {kwargs}\n"
|
||||
elif name == 'keyboard':
|
||||
self.goals.append(KeyboardGoal(robot_cfg.commands, **kwargs))
|
||||
log_str += f" - Keyboard Goal: {kwargs}\n"
|
||||
else:
|
||||
raise NotImplementedError(f"Goal '{name}' is not implemented in BaseGauge.")
|
||||
self.info['goal'].append(name)
|
||||
|
||||
@@ -55,6 +55,10 @@ class BaseGaugeConfig(Config):
|
||||
goal_type = 'velocity' # 'velocity'
|
||||
dead_zone = 0.1 # joystick dead zone
|
||||
|
||||
class keyboard: # goal controlled by a keyboard listener independent of MuJoCo
|
||||
enabled = False
|
||||
goal_type = 'velocity'
|
||||
|
||||
class metrics:
|
||||
metric_dt = 0.1 # [s] frequency to compute metrics
|
||||
class dof_limits:
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from robogauge.tasks.gauge.goals.base_goal import BaseGoal
|
||||
from robogauge.tasks.gauge.goals.joystick_goal import JoystickGoal
|
||||
from robogauge.tasks.gauge.goals.keyboard_goal import KeyboardGoal
|
||||
from robogauge.tasks.gauge.goals.velocity_goals import MaxVelocityGoal, DiagonalVelocityGoal, TargetPosVelocityGoal
|
||||
|
||||
149
robogauge/tasks/gauge/goals/keyboard_goal.py
Normal file
149
robogauge/tasks/gauge/goals/keyboard_goal.py
Normal file
@@ -0,0 +1,149 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Keyboard teleoperation goal using an input listener separate from MuJoCo."""
|
||||
|
||||
import atexit
|
||||
import queue
|
||||
import threading
|
||||
|
||||
from robogauge.tasks.gauge.goal_data import GoalData, VelocityGoal
|
||||
from robogauge.tasks.gauge.goals.base_goal import BaseGoal
|
||||
from robogauge.tasks.simulator.sim_data import SimData
|
||||
from robogauge.utils.helpers import class_to_dict
|
||||
from robogauge.utils.logger import logger
|
||||
|
||||
|
||||
class _KeyboardState:
|
||||
"""Track held keys without replacing MuJoCo viewer shortcuts."""
|
||||
|
||||
def __init__(self):
|
||||
self.events = queue.Queue()
|
||||
self.running = False
|
||||
self.held = set()
|
||||
self.lock = threading.Lock()
|
||||
self.thread = None
|
||||
self.listener = None
|
||||
|
||||
@staticmethod
|
||||
def _name(key):
|
||||
try:
|
||||
if hasattr(key, 'char') and key.char:
|
||||
return key.char.lower()
|
||||
except Exception:
|
||||
pass
|
||||
return str(key).lower()
|
||||
|
||||
def _worker(self):
|
||||
while self.running:
|
||||
try:
|
||||
event_type, key = self.events.get(timeout=0.05)
|
||||
except queue.Empty:
|
||||
continue
|
||||
name = self._name(key)
|
||||
with self.lock:
|
||||
if event_type == 'press':
|
||||
self.held.add(name)
|
||||
else:
|
||||
self.held.discard(name)
|
||||
|
||||
def start(self):
|
||||
try:
|
||||
from pynput import keyboard
|
||||
except ImportError as exc:
|
||||
raise ImportError(
|
||||
"Keyboard control requires 'pynput'. Install it with "
|
||||
"'python -m pip install pynput'."
|
||||
) from exc
|
||||
|
||||
self.running = True
|
||||
self.listener = keyboard.Listener(
|
||||
on_press=lambda key: self.events.put(('press', key)),
|
||||
on_release=lambda key: self.events.put(('release', key)),
|
||||
)
|
||||
self.listener.start()
|
||||
self.thread = threading.Thread(target=self._worker, daemon=True)
|
||||
self.thread.start()
|
||||
|
||||
def snapshot(self):
|
||||
with self.lock:
|
||||
return set(self.held)
|
||||
|
||||
def clear(self):
|
||||
with self.lock:
|
||||
self.held.clear()
|
||||
|
||||
def stop(self):
|
||||
self.running = False
|
||||
if self.listener is not None:
|
||||
self.listener.stop()
|
||||
self.listener = None
|
||||
|
||||
|
||||
class KeyboardGoal(BaseGoal):
|
||||
"""Produce velocity commands while the configured teleoperation keys are held."""
|
||||
|
||||
name = 'keyboard'
|
||||
|
||||
def __init__(self, max_velocity, goal_type='velocity', **kwargs):
|
||||
super().__init__()
|
||||
if goal_type != 'velocity':
|
||||
raise NotImplementedError("Only 'velocity' goal type is implemented for KeyboardGoal.")
|
||||
|
||||
kwargs.pop('enabled', None)
|
||||
if kwargs:
|
||||
logger.warning(f"Unused kwargs in KeyboardGoal: {kwargs}")
|
||||
|
||||
self.max_velocity = class_to_dict(max_velocity)
|
||||
self.total = 1
|
||||
self.current_command = (0.0, 0.0, 0.0)
|
||||
self.keyboard = _KeyboardState()
|
||||
self.keyboard.start()
|
||||
atexit.register(self.keyboard.stop)
|
||||
logger.info(
|
||||
"Keyboard control: Up/Down=forward/back, Left/Right=yaw, "
|
||||
"','=left strafe, '.'=right strafe, K=stop. "
|
||||
"MuJoCo viewer shortcuts remain independent."
|
||||
)
|
||||
|
||||
def is_reset(self, sim_data: SimData) -> bool:
|
||||
return False
|
||||
|
||||
def pre_get_goal(self, sim_data: SimData) -> bool:
|
||||
return False
|
||||
|
||||
def reset_goal(self):
|
||||
self.keyboard.clear()
|
||||
self.current_command = (0.0, 0.0, 0.0)
|
||||
|
||||
@staticmethod
|
||||
def _axis_command(held, positive_key, negative_key, limits):
|
||||
positive = positive_key in held
|
||||
negative = negative_key in held
|
||||
if positive == negative:
|
||||
return 0.0
|
||||
return float(limits[1] if positive else limits[0])
|
||||
|
||||
def command_from_keys(self, held):
|
||||
if 'k' in held:
|
||||
return 0.0, 0.0, 0.0
|
||||
return (
|
||||
self._axis_command(held, 'key.up', 'key.down', self.max_velocity['lin_vel_x']),
|
||||
self._axis_command(held, ',', '.', self.max_velocity['lin_vel_y']),
|
||||
self._axis_command(held, 'key.left', 'key.right', self.max_velocity['ang_vel_yaw']),
|
||||
)
|
||||
|
||||
def get_goal(self, sim_data: SimData) -> GoalData:
|
||||
command = self.command_from_keys(self.keyboard.snapshot())
|
||||
if command != self.current_command:
|
||||
self.current_command = command
|
||||
logger.info(
|
||||
"Keyboard command: vx=%.2f, vy=%.2f, yaw=%.2f",
|
||||
*command,
|
||||
)
|
||||
return GoalData(
|
||||
goal_type='velocity',
|
||||
velocity_goal=VelocityGoal(
|
||||
lin_vel_x=command[0],
|
||||
lin_vel_y=command[1],
|
||||
ang_vel_yaw=command[2],
|
||||
),
|
||||
)
|
||||
@@ -17,7 +17,7 @@ from copy import deepcopy
|
||||
from robogauge.utils.logger import logger
|
||||
from robogauge.tasks.simulator import MujocoSimulator, MujocoConfig, SimData
|
||||
from robogauge.tasks.robots import (
|
||||
BaseRobot, RobotConfig, Go2Config, Go2, Go2MoEConfig, Go2MoE
|
||||
BaseRobot, RobotConfig, Go2Config, Go2, Go2MoEConfig, Go2MoE, Go1MoE
|
||||
)
|
||||
from robogauge.tasks.gauge import BaseGauge, BaseGaugeConfig
|
||||
from robogauge.tasks.gauge.goal_data import GoalData, VelocityGoal, PositionGoal
|
||||
|
||||
@@ -5,3 +5,4 @@ from .go2.go2_lab_config import Go2LabConfig, Go2LabTerrainConfig
|
||||
from .go2.go2 import Go2
|
||||
from .go2.go2_moe_config import Go2MoEConfig, Go2MoETerrainConfig
|
||||
from .go2.go2_moe import Go2MoE
|
||||
from .go1 import Go1Config, Go1TerrainConfig, Go1, Go1MoEConfig, Go1MoETerrainConfig, Go1MoE
|
||||
|
||||
4
robogauge/tasks/robots/go1/__init__.py
Normal file
4
robogauge/tasks/robots/go1/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
||||
from .go1_config import Go1Config, Go1TerrainConfig
|
||||
from .go1 import Go1
|
||||
from .go1_moe_config import Go1MoEConfig, Go1MoETerrainConfig
|
||||
from .go1_moe import Go1MoE
|
||||
13
robogauge/tasks/robots/go1/go1.py
Normal file
13
robogauge/tasks/robots/go1/go1.py
Normal file
@@ -0,0 +1,13 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Go1 policy adapter.
|
||||
|
||||
The trained policy and the Go1 MuJoCo asset both use FR, FL, RR, RL joint
|
||||
groups. Isaac Gym exposed the training asset as FL, FR, RL, RR, but Go1Robot
|
||||
permuted its observations and actions during training.
|
||||
"""
|
||||
|
||||
from robogauge.tasks.robots.go2.go2 import Go2
|
||||
|
||||
|
||||
class Go1(Go2):
|
||||
pass
|
||||
38
robogauge/tasks/robots/go1/go1_config.py
Normal file
38
robogauge/tasks/robots/go1/go1_config.py
Normal file
@@ -0,0 +1,38 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Go1 configuration for the RoboGauge MuJoCo evaluator."""
|
||||
|
||||
from robogauge.tasks.robots.go2.go2_config import Go2Config
|
||||
|
||||
|
||||
class Go1Config(Go2Config):
|
||||
robot_name = 'go1'
|
||||
robot_class = 'Go1'
|
||||
|
||||
class assets(Go2Config.assets):
|
||||
robot_xml = "{ROBOGAUGE_ROOT_DIR}/resources/robots/go1/go1.xml"
|
||||
foot_geom_names = ['FR', 'FL', 'RR', 'RL']
|
||||
|
||||
class control(Go2Config.control):
|
||||
model_path = "{ROBOGAUGE_ROOT_DIR}/resources/models/go1/policy.pt"
|
||||
control_dt = 0.02
|
||||
p_gains = [28.0] * 12
|
||||
d_gains = [0.7] * 12
|
||||
|
||||
# Both this MuJoCo model and the trained policy use FR, FL, RR, RL.
|
||||
# Go1Robot permuted Isaac Gym's FL, FR, RL, RR asset state into this
|
||||
# order during training, so applying that permutation again here
|
||||
# would swap every left/right leg pair.
|
||||
default_dof_pos = [
|
||||
-0.1, 0.8, -1.5,
|
||||
0.1, 0.8, -1.5,
|
||||
-0.1, 1.0, -1.5,
|
||||
0.1, 1.0, -1.5,
|
||||
]
|
||||
mj2model_dof_indices = list(range(12))
|
||||
|
||||
|
||||
class Go1TerrainConfig(Go1Config):
|
||||
class commands(Go1Config.commands):
|
||||
lin_vel_x = [-1.0, 1.0]
|
||||
lin_vel_y = [-1.0, 1.0]
|
||||
ang_vel_yaw = [-1.5, 1.5]
|
||||
8
robogauge/tasks/robots/go1/go1_moe.py
Normal file
8
robogauge/tasks/robots/go1/go1_moe.py
Normal file
@@ -0,0 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""MoE Go1 policy adapter."""
|
||||
|
||||
from robogauge.tasks.robots.go2.go2_moe import Go2MoE
|
||||
|
||||
|
||||
class Go1MoE(Go2MoE):
|
||||
pass
|
||||
12
robogauge/tasks/robots/go1/go1_moe_config.py
Normal file
12
robogauge/tasks/robots/go1/go1_moe_config.py
Normal file
@@ -0,0 +1,12 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""MoE policy configuration for the trained Go1 checkpoint."""
|
||||
|
||||
from robogauge.tasks.robots.go1.go1_config import Go1Config, Go1TerrainConfig
|
||||
|
||||
|
||||
class Go1MoEConfig(Go1Config):
|
||||
robot_class = 'Go1MoE'
|
||||
|
||||
|
||||
class Go1MoETerrainConfig(Go1TerrainConfig, Go1MoEConfig):
|
||||
robot_class = 'Go1MoE'
|
||||
Reference in New Issue
Block a user