Skip to content

[RFC] Introducing transform primatives for sim2real #4422

Description

@theap06

##Summary:

  • Six transforms for sim-to-real + Compose recipes over existing mechanics.
  • DomainRandomization needs a small protocol on EnvBase.
  • these are the primatives i think we need to introduce:
    ObservationDelay, ActionDelay,
    ObservationNoise, ActuatorModel, SymmetryAugmentation, DomainRandomization.
    DomainRandomization
    ##RFC decision for domainrandomization interaction with sim
    • A. EnvBase.physics_param_spec + set_physics_params(td); transform samples in _reset.
    • B. Config field on MujocoEnvBase. Not composable, not loggable, no Isaac Lab path.
    • C. Transform mutates env.unwrapped directly. No spec, breaks under ParallelEnv.

Activity

  1. sattyamjjain commented on Sep 18, 2026

    @sattyamjjain

    A data point for ActuatorModel and ActionDelay defaults, from a public recording: in lerobot/svla_so101_pickplace (SO-101 arm, Feetech STS3215 servos, 30 Hz loop) the measured joint position trails the commanded target by 4 frames (133 ms) on the most-moving joint, with a steady mean offset of −0.98 units (action − state) on the gravity-loaded shoulder_lift, in dataset units (−100..100); reproducible from episode 0's action and observation.state columns (303 frames, best lag by cross-correlation over 0–14 frames). A one-parameter first-order servo fit gives k ≈ 0.25 per tick on every arm joint, which is the same as 133 ms.

    On the design question: option A maps cleanly onto MuJoCo's mjModel arrays (body_mass, dof_damping, geom_friction, actuator_gainprm). Would physics_param_spec be a Composite so that sampled values are loggable per reset?

  2. theap06 commented on Sep 18, 2026

    @theap06
    CollaboratorAuthor

    @sattyamjjain I think that physics param will be a composite in my view so far. for now, i am just looking at sampled values per reset as a property just of DomainRandomization. I don't see the point in having it for EnvBase reset right now

  3. vmoens commented on Sep 19, 2026

    @vmoens
    Contributor

    This might be related to the streaming TensorDict tutorial: https://docs.pytorch.org/tensordict/stable/tutorials/streamed_tensordict.html

    There we use LazyStackedTensorDict to represent asynchronous streams sampled at different frequencies, bucketize them over time, and optionally densify them afterwards.

    I think this could be relevant in particular for ObservationDelay. On real systems, delay often comes together with observations arriving asynchronously / at different frequencies, rather than being purely an N-env-steps FIFO. It may be useful to make sure the abstraction we choose for delayed observations can eventually accommodate that case too.

    Potentially the buffering/stream representation and the transform deciding what constitutes the current observation could remain separate concerns.

  4. sattyamjjain commented on Sep 19, 2026

    @sattyamjjain

    Agree, and my data point has exactly that limitation, so worth saying it out loud.

    In lerobot/svla_so101_pickplace the meta/info.json carries one timestamp and one frame_index shared by action, observation.state, and both camera streams, all at 30 fps. So the 4-frame lag I measured is a lag inside an already resampled uniform grid. That recording cannot show the async case at all; it was densified before it was stored. Most public LeRobot datasets are shaped the same way, which means a pure N-step FIFO will look correct against every one of them and still be wrong on hardware.

    The split you are describing also matches what the number actually is. The 4 frames is a property of the servo bus, constant and estimable from a recording. Camera arrival jitter is a property of the stream. A single global N conflates the two, and then neither can be
    calibrated. If ObservationDelay took per-key delays instead of one N, the measured value drops straight in as observation.state: 4 at 30 Hz, and the image keys keep their own.

  5. arthurlw commented on Sep 23, 2026

    @arthurlw

    /assign

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions