Gym mecanum kinematics matching to Webots roller-hinge proto
Mecanum proto rewrite in b3cf990 made the wheels truly omnidirectional
in Webots, but with asymmetric slip: forward command produces ~89% of
textbook speed while strafe produces only ~38% plus a consistent
~28% backward bleed-through. v1 BC/RL trained on perfect mecanum
gym kinematics could not herd the new dynamics. To unblock that:
* `mecanum_kinematics_step` gains two parameters that scale the
realised motion to match a deployed-platform calibration:
- strafe_efficiency ∈ (0, 1] default 1.0
- strafe_to_forward_bleed default 0.0
Forward motion is untouched (textbook X-pattern continues to apply
to vx_body); only the lateral channel is scaled and bleed is added.
* `RobotConfig` exposes both as drive-config fields with the same
pass-through defaults so existing diff-drive code and existing
mecanum training pipelines see no behaviour change.
* `HERDING_MEC_WEBOTS` preset bakes in the values measured against the
current Webots mecanum proto (strafe_efficiency=0.4,
strafe_to_forward_bleed=-0.28). Training mecanum BC/RL with this
preset produces policies that compensate for the imperfect
physical mecanum at deploy.
* `HerdingEnv` plumbs `RobotConfig.strafe_*` through to
`mecanum_kinematics_step` so the preset takes effect.
* tools/gen_mecanum_wheels.py is added so the proto's 32 roller
hinges can be regenerated by editing a single set of constants
rather than hand-editing 1500+ lines of VRML.
Tests:
* 4 new mecanum_kinematics_step tests (default pass-through, strafe
scaling, backward bleed, forward unaffected by strafe params).
* 3 new RobotConfig tests (defaults, validation, preset shape).
* Sanity check: gym strafe with HERDING_MEC_WEBOTS over 100 steps
reproduces the Webots calibration to 2 decimal places.
126 unit tests pass (was 120).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -252,11 +252,32 @@ class RobotConfig:
|
||||
sees at deployment.
|
||||
"""
|
||||
|
||||
strafe_efficiency: float = 1.0
|
||||
"""Mecanum strafe magnitude as a fraction of textbook X-pattern.
|
||||
|
||||
``1.0`` (default) = perfect mecanum kinematics. ``0.4`` matches the
|
||||
Webots roller-hinge mecanum proto calibration (62% slip on strafe,
|
||||
11% on forward). Used by ``mecanum_kinematics_step`` only — has no
|
||||
effect on differential drive.
|
||||
"""
|
||||
|
||||
strafe_to_forward_bleed: float = 0.0
|
||||
"""Fraction of ideal strafe magnitude that bleeds into body-frame x.
|
||||
|
||||
``0.0`` (default) = no bleed. ``-0.28`` matches the Webots proto's
|
||||
consistent backward push under strafe commands. Used by
|
||||
``mecanum_kinematics_step`` only.
|
||||
"""
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
if not (0.0 <= self.action_smooth < 1.0):
|
||||
raise ValueError(
|
||||
f"action_smooth must be in [0, 1), got {self.action_smooth}"
|
||||
)
|
||||
if not (0.0 < self.strafe_efficiency <= 1.0):
|
||||
raise ValueError(
|
||||
f"strafe_efficiency must be in (0, 1], got {self.strafe_efficiency}"
|
||||
)
|
||||
|
||||
@property
|
||||
def max_linear(self) -> float:
|
||||
@@ -360,6 +381,39 @@ HERDING_WEBOTS = HerdingConfig(
|
||||
),
|
||||
robot=RobotConfig(action_smooth=0.55),
|
||||
)
|
||||
|
||||
HERDING_MEC_WEBOTS = HerdingConfig(
|
||||
lidar=LIDAR_WEBOTS,
|
||||
detection=DetectionConfig(wall_reject=0.5, static_reject=1.2),
|
||||
tracker=TrackerConfig(
|
||||
forget_steps=300,
|
||||
max_new_tracks_per_step=1,
|
||||
pen_latch_depth=2.0,
|
||||
predict_steps=180,
|
||||
consensus_k=3,
|
||||
consensus_radius_m=0.3,
|
||||
consensus_max_age=20,
|
||||
),
|
||||
robot=RobotConfig(
|
||||
action_smooth=0.55,
|
||||
strafe_efficiency=0.4,
|
||||
strafe_to_forward_bleed=-0.28,
|
||||
),
|
||||
)
|
||||
"""Webots-mecanum-matched training preset.
|
||||
|
||||
Same as HERDING_WEBOTS but with the gym mecanum kinematics scaled to
|
||||
match the Webots roller-hinge mecanum proto:
|
||||
* ``strafe_efficiency=0.4`` — strafing produces ~40% of textbook
|
||||
X-pattern lateral velocity in Webots; this matches the bias.
|
||||
* ``strafe_to_forward_bleed=-0.28`` — strafe commands bleed ~28% of
|
||||
their magnitude into backward body motion in Webots.
|
||||
|
||||
Use this preset when training BC/RL for the mecanum drive so the
|
||||
policy learns to compensate for the imperfect physical mecanum.
|
||||
Differential drive ignores both parameters and behaves identically
|
||||
to HERDING_WEBOTS.
|
||||
"""
|
||||
"""Webots-matched training preset.
|
||||
|
||||
Changes vs HERDING_DEFAULT:
|
||||
|
||||
Reference in New Issue
Block a user