Conversation
Persist generic versioned action contracts in locomotion configurations and resolve them through the current ActionManager implementation registry. Migrate legacy pretrained bundles, update locomotion bindings and documentation, and validate all default and Newton policy examples.
|
| def resolved_contract_id(self) -> str | None: | ||
| """Return the configured contract or the implementation's stable ID.""" | ||
| return self.cfg.contract or self.contract_id |
There was a problem hiding this comment.
[P2] Validate configured contracts against the action implementation
With ActionTermCfg(func=JointVelocityAction, contract="joint_position.absolute@1", ...), the manager instantiates JointVelocityAction and writes qvel, but this method labels it as an absolute-position action. The built-in descriptor copies the same overridden ID, so the new descriptor mismatch check accepts it, and get_term_by_contract() returns the velocity action for the position contract. A CPU probe confirmed the incorrect metadata and the call to set_qvel().
The same fields passed through config_to_cfg() instead select JointPositionAction, so Python and YAML configurations disagree on which command to execute. Please resolve or validate func and contract consistently at the shared initialization boundary, and add a regression test that checks the declared contract against the actual command written to the robot.
| if term_contract is None and isinstance(term_class_name, str): | ||
| term_contract = _LEGACY_ACTION_CONTRACTS.get(term_class_name) |
There was a problem hiding this comment.
[P2] Preserve legacy clipping semantics when migrating saved actions
All 12 published locomotion snapshots inspected here contain DefaultJointPositionTerm with params: {}. The legacy implementation treated an omitted or null clip as unbounded, whereas DefaultJointPositionAction defaults to clip=1.0. This migration changes the implementation without translating that default.
A CPU comparison with action 2.0, offset 0.2, and scale 0.5 produces a joint target of 1.2 before migration and 0.7 afterward; the stored action also changes from 2.0 to 1.0. Thus, outputs outside [-1, 1] change both control targets and action-history observations. An explicit legacy clip: null instead fails at float(None). Please preserve the legacy omitted/null behavior during migration and test numerical outputs and history buffers; the added test currently checks only the resolved class and contract ID.
| action_term = self.action_manager.get_term_by_contract( | ||
| "joint_position.default_offset@1" | ||
| ) |
There was a problem hiding this comment.
[P2] Preserve binding for existing custom locomotion actions
An existing configuration can provide a custom ActionTerm named joint_position with the required raw_actions, previous_raw_actions, and position_bias buffers, without declaring a contract ID. Such a term still passes ActionManager initialization because contract IDs remain optional, but this lookup now raises KeyError and prevents environment construction. A CPU probe using the same custom term confirmed that the previous name-based binding succeeds and the new binding fails.
The constructor still locates joint_position by name to inject joint order, offset, and scale. Please retain a validated compatibility path for that existing named term, or provide an explicit migration mechanism for custom implementations, and add a regression test covering initialization without a contract ID.
Description
This PR decouples persisted policy action semantics from concrete ActionManager Python class names and migrates the official locomotion configurations to generic versioned action contracts.
It adds the generic
joint_position.default_offset@1contract and the built-in action contract registry, records contract IDs in action descriptors, binds locomotion state through the contract, and keeps legacy pretrained bundles containingDefaultJointPositionTermloadable. The six velocity locomotion tasks now use the stable contract in both Default and Newton deployments. Documentation and project context describe the new configuration and migration behavior.Issue: no issue number was provided.
Dependencies: none.
Type of change
Screenshots
Not applicable. Viewer smoke tests were run for all 12 official pretrained velocity policy bundles.
Validation
207 passedtargeted gym/action/config tests.--sim-device gpu; Newton ContactSensor is not supported on CPU.python docs/scripts/check_api_docs.py—2295/2295exports documented.black .andgit diff --checkpassed.context.py checkpassed.Checklist
black .command to format the code base.