Robot control should be defined through actuators
Proposal
Applying drive targets to a robot, either in the modular or the direct workflow, should be done through the actuators defined in the robot config, in order to maintain consistency within the API.
Presently, if a user wants to apply actions to a robot manually, it is done through the set_joint_positions_target member of the Articulation class defined in Isaac Lab
scene["MyRobot"].set_joint_position_target(action)
I propose that we modify the articulation class to directly support actuators. If a user has a configured articulation object, they should be able to interact with the actuators they configured in two ways
first, by accessing a dictionary of actuators
scene["MyRobot"].Actuators["joint_act_1"].set_target(joint_target)
but also through the tensor API
scene["MyRobot].set_actuator_targets(target_tensor)
Motivation
Consider the following configuration for the Dofbot
DOFBOT_CONFIG = ArticulationCfg(
spawn=sim_utils.UsdFileCfg(
usd_path=f"{ISAAC_NUCLEUS_DIR}/Robots/Dofbot/dofbot.usd",
rigid_props=sim_utils.RigidBodyPropertiesCfg(
disable_gravity=False,
max_depenetration_velocity=5.0,
),
articulation_props=sim_utils.ArticulationRootPropertiesCfg(
enabled_self_collisions=True, solver_position_iteration_count=8, solver_velocity_iteration_count=0
),
),
init_state=ArticulationCfg.InitialStateCfg(
joint_pos={
"joint1":0.0,
"joint2":0.0,
"joint3":0.0,
"joint4":0.0,
},
pos=(0.25, -0.25, 0.0)
),
actuators={
"joint1_act": ImplicitActuatorCfg(
joint_names_expr=["joint1"],
effort_limit=100.0,
velocity_limit=100.0,
stiffness=10000.0,
damping=100.0,
),
"joint2_act": ImplicitActuatorCfg(
joint_names_expr=["joint2"],
effort_limit=100.0,
velocity_limit=100.0,
stiffness=10000.0,
damping=100.0,
),
"joint3_act": ImplicitActuatorCfg(
joint_names_expr=["joint3"],
effort_limit=100.0,
velocity_limit=100.0,
stiffness=10000.0,
damping=100.0,
),
"joint4_act": ImplicitActuatorCfg(
joint_names_expr=["joint4"],
effort_limit=100.0,
velocity_limit=100.0,
stiffness=10000.0,
damping=100.0,
),
}
)
This is a "legal" config for the Dofbot, and it loads and runs fine even though we define only 4 of the 11 available joints as actuators. As a user, I don't care about those other joints, only the first 4.
Now, in the direct workflow, I can define an InteractiveSceneCfg in the usual way
class NewRobotsSceneCfg(InteractiveSceneCfg):
"""Designs the scene."""
# Ground-plane
ground = AssetBaseCfg(prim_path="/World/defaultGroundPlane", spawn=sim_utils.GroundPlaneCfg())
# lights
dome_light = AssetBaseCfg(
prim_path="/World/Light", spawn=sim_utils.DomeLightCfg(intensity=3000.0, color=(0.75, 0.75, 0.75))
)
# robot
Dofbot = DOFBOT_CONFIG.replace(prim_path="{ENV_REGEX_NS}/Dofbot")
and I can make the Dofbot wave
def run_simulator(sim: sim_utils.SimulationContext, scene: InteractiveScene):
sim_dt = sim.get_physics_dt()
sim_time = 0.0
count = 0
while simulation_app.is_running():
#wave
wave_action = scene["Dofbot"].data.default_joint_pos
wave_action[:, 0:4] = 0.25*np.sin(2 * np.pi * 0.5 * sim_time)
scene["Dofbot"].set_joint_position_target(wave_action)
scene.write_data_to_sim()
sim.step()
sim_time += sim_dt
count += 1
scene.update(sim_dt)
and everything runs beautifully, except the size of wave action is [NUM_ENVS, 11]... As a user, I expect there to be 4 actuators that I'm interacting with, not 11. I configured them!
Checklist
- [X] I have checked that there is no similar issue in the repo (required)
Thank you for posting this. The team will review.
Hi, How is this enhancement going? This enhancement also will improve the user experience for robot with caster wheels. And for robot with used passive joints, this enhancement will also reduce the input size for observation meaning save computation resource. For my robot I with 9 passive joints, I wasted 18 inputs for the joint positions and joint velocities.