src/wuji_rl_libs/rsl_rl/.
The Reorient Task
The reorient task is full SO(3) in-hand reorientation of a cube held by a downward-facing dexterous hand. The policy receives a target orientation in the palm’s tag frame and rotates the cube in place until its orientation matches the goal within a hold window, without dropping it. The task design — MDP terms, reward shaping, and domain randomization — lives in the task package, separate from the robot binding. This split keeps the task reusable and the Wuji Hand binding thin.
The
mdp/ package holds the runtime task terms consumed by the mjlab manager system, including the SO(3) goal state machine (commands.py), the palm-relative cage geometry and reward escalation (cage.py), and the standard term modules for actions, observations, rewards, terminations, and curricula.
Domain Randomization
The contact-parameter domain randomization splits the hand into two anatomical groups: the palm and thumb compliance zone versus fingers 2 through 5. Randomizing these groups separately, rather than uniformly, is what lets the sim-trained policy transfer to the physical hand’s uneven contact behavior. The full randomization spec sits inreorient_terms.py.
Deploy Reuse
The deploy bridge reuses the sim env verbatim.RealHandEnv subclasses mjlab’s ManagerBasedRlEnv, so the same observation and action managers apply on real hardware — no parallel pipelines to drift out of sync. See Sim-to-real Deployment for the runtime pipeline.
Architecture Invariants
- The event implementation split under
mdp/event_impl/is internal. Outside callers consume events only through themdp.eventsfacade. ReorientEventStateis the single owner of every event-side runtime cache. Access it throughget_reorient_event_state(env)rather than stashing fields onenvdirectly.tooling/is the importable core of script logic.scripts/own only argparse, env-var setup, and the__main__glue, so anything intooling/can be called from Python for sweeps, tests, or notebooks.- The public API surface (
make_reorient_env_cfg,wuji_hand_reorient_env_cfg, themdpre-exports, registered task IDs, and the eval core) stays stable. Internal modules may move, but names external callers consume don’t.
Add a New Task
- Create
src/wuji_mjlab/tasks/<your_task>/with an env-cfg factory. - Put all MDP design (events, rewards, terminations) in
<your_task>_terms.py. Keep theconfig/<robot>/layer a thin binding. - Register the task with
register_mjlab_task()inconfig/<robot>/__init__.py. - Run a quick
pixi run train --task <your_task_id>smoke test before committing. The canonical training entrypoint isscripts/train/train_rsl_rl.py, exposed through thetrainpixi task.