Replies: 2 comments 1 reply
|
You're correct that PhysX joints don't currently expose a native backlash or dead-zone parameter. Your approach of using an intermediate near-massless link with a limited passive joint is a physically reasonable workaround for modeling this type of mechanical play. Here are some key considerations:
Notes:
Native backlash support would be a valuable feature request for the PhysX team, we will discussion this with them to see if this can be natively supported. |
|
You're absolutely right that backlash is fundamentally a history-dependent nonlinearity, and modeling it at the command/observation level is a much more practical approach than adding extra bodies for many use cases.
def __init__(self, cfg, ...):
super().__init__(cfg, ...)
# State tracking
self._last_direction = torch.zeros(...)
self._backlash_offset = torch.zeros(...)
self._backlash_range = cfg.backlash_range # e.g., ±0.02 rad
def compute(self, control_action, joint_pos, joint_vel, ...):
# Detect direction reversals
direction = torch.sign(control_action - joint_pos)
direction_changed = (direction != self._last_direction)
# Apply hysteresis: when direction reverses, command "sticks"
# until the play range is taken up
effective_command = control_action.clone()
effective_command[direction_changed] -= (
self._backlash_offset[direction_changed]
)
# Update state
self._last_direction = direction
# Pass to underlying actuator model
return super().compute(effective_command, joint_pos, joint_vel, ...)
from omni.isaac.lab.utils.noise import NoiseCfg, NoiseModel
class BacklashNoiseCfg(NoiseCfg):
"""Backlash as observation noise."""
class_type: type = BacklashNoiseModel
backlash_range: float = 0.02
class BacklashNoiseModel(NoiseModel):
"""History-dependent position offset in observations."""
# Similar state tracking as actuator version
# Applied to joint_pos observations |
Uh oh!
There was an error while loading. Please reload this page.
We're developing a small biped robot using CubeMars AK-series geared actuators
(~10:1 reduction) and are trying to model realistic mechanical play in the
joints for Sim-to-Real RL training. We're interested in two related but
distinct sources of play:
horn connection with a small amount of slop) — in our own hardware testing,
this turned out to be the dominant source, larger than the gearbox backlash
itself
Both show up as the same kind of behavior: a small dead-zone where the driven
side can move slightly without the output side responding.
We found an older unanswered forum thread on the same topic (Simulating joint
/ servo backlash,
2024) and wanted to ask again with more specifics here, since this seems like
a common need for anyone working with geared actuators or bolted/keyed
mechanical joints in general.
We went through the available joint APIs and couldn't find a play / dead-zone
parameter anywhere:
PxFixedJoint/PxSphericalJoint/PxRevoluteJoint/PxPrismaticJoint/PxDistanceJoint/PxD6Jointexpose anything like itPxGearJoint/PxRackAndPinionJoint(the gear-mesh-specific joints) don'thave one either
PxArticulationJointReducedCoordinate(used by Isaac Lab's Articulation-based robots) doesn't have one either — checked the full member list (limit
params, drive params, armature, friction coefficient, etc.)
Since PhysX/USD Physics joints always connect exactly two rigid bodies (or a
body and world), our current plan is to add an explicit, near-massless
intermediate link between the driven (actuated) joint and a limited, undriven
"play" joint, to represent this as a small extra DOF — regardless of whether
the play originates in the gearbox or in a mechanical coupling further down
the chain.
Questions:
(gearbox backlash or mechanical coupling slop) in Isaac Sim / PhysX that
we're missing?
workaround, or is there a known issue with it (e.g. solver stability with a
very low-mass link)?
Environment: Isaac Sim 5.1.0, Ubuntu 24.04, RTX 5080
Happy to share more details about our setup if useful. Thanks in advance!
All reactions