feat(pace): integrate PACE actuator system identification#117
feat(pace): integrate PACE actuator system identification#117fan-ziqi wants to merge 12 commits into
Conversation
It is an offline visualisation tool, so importing robot_lab.utils.paths (which pulls in the full robot_lab.tasks registry and requires launching the Isaac Sim app) was overkill. Resolve the project root directly from the script's __file__ location instead.
How to collect data on real hardwareWhile exploring this integration I noticed the upstream PACE docs don't actually cover real-robot data collection —
For anyone wondering "okay, but how?", here's what What
|
Summary
Integrate the upstream
leggedrobotics/pace-sim2realintorobot_labas first-class modules, and register a demo taskIsaac-Pace-Anymal-D-v0that mirrors the PACE ANYmal-D example.PACE (Precise Adaptation through Continuous Evolution) estimates physical actuator and joint parameters (armature, viscous friction, static/dynamic friction, encoder bias, command delay) from chirp-excitation data using CMA-ES, then lets you apply those parameters back into your simulation for higher-fidelity sim-to-real transfer. See the PACE documentation and paper.
What's added
robot_lab.actuators.PaceDCMotor/PaceDCMotorCfg— DCMotor with encoder bias and torque delay buffer (port of upstream).robot_lab.utils.paths.project_root()— repo-root helper used by the PACE scripts that go through the IsaacLab launcher.robot_lab.tasks.manager_based.pace/— base env_cfg,mdp/,optim/CMAESOptimizer,agents/placeholder.robot_lab.tasks.manager_based.pace.config.anymal_d/—AnymalDPaceEnvCfgand registration ofIsaac-Pace-Anymal-D-v0.scripts/pace/{data_collection,fit,plot_trajectory}.py— three user-facing entry points mirroring upstream.plot_trajectory.pyresolves the project root from__file__so it can run offline without launching Isaac Sim.setup.py: addcmaesruntime dependency..gitignore: ignore root-level/data/for chirp recordings.Usage
Outputs:
data/anymal_d_sim/chirp_data.pt,logs/pace/anymal_d_sim/<timestamp>/{config.pt, mean_xxx.pt, best_trajectory.pt}.Notes
fix_root_link=True,static < dynamic frictionwrite order, 49-dim parameter layout, ANYmal-D 12-joint order).Isaac-Velocity-Flat-Anymal-D-v0) are not affected.Test Plan (verified locally on RTX 4090, Isaac Sim 5.x)
pip install -e source/robot_labsucceeds and pulls incmaes(cmaes-0.13.0)Isaac-Pace-Anymal-D-v0discovered viarobot_lab.tasksandparse_env_cfgsucceeds (verified end-to-end viadata_collection.pyandfit.py)python scripts/pace/data_collection.py --headless --task=Isaac-Pace-Anymal-D-v0 --num_envs=1 --duration=1producesdata/anymal_d_sim/chirp_data.ptwith{time:[400], dof_pos:[400,12], des_dof_pos:[400,12]}python scripts/pace/fit.py --headless --task=Isaac-Pace-Anymal-D-v0 --num_envs=256runs all 200 CMA-ES generations and writesmean_000.pt … mean_199.pt,best_trajectory.pt, TensorBoard events; score decreases monotonically (e.g. min 0.124 → 0.059 over the first 7 generations)MPLBACKEND=Agg python scripts/pace/plot_trajectory.py --plot_trajectory --robot_name=anymal_d_simruns offline (no Isaac Sim launch) and recovers parameters close to ground truth: armature ≈ 0.100 (truth 0.1), viscous friction ≈ 4.45 (truth 4.5), encoder bias ≈ 0.05 (truth 0.05), delay ≈ 5.67 (truth 5)Isaac-Velocity-Flat-Anymal-D-v0and other existing tasks remain registered (no regression)pre-commit run --all-filespasses