feat(dr): generic interval term dispatch in DomainRandomizationManager - #1504
Merged
Conversation
Migrate interval DR to the unisim-core 1.1.0 descriptor contract: the manager no longer enumerates term fields or per-term capability branches; it validates plan.iter_ops() against supported_interval_terms and fails closed with backend type + term names. Locomotion push and Sharpa body-force providers now emit IntervalTermOp entries; legacy plan fields keep working through iter_ops() (deprecated, removal in the next unisim-core major). Entity/EventManager interval paths are unchanged via the legacy adapter. Adds interval-side manager tests: custom-term extensibility without manager changes, capability-negative errors, legacy compat, mixed plans, empty plans, and pickle protocol-4 round-trip. Updates DR contract and provider docs (en + zh_CN). Bumps unisim-core floor to >=1.1.0. Refs #1502
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
UniLab half of #1502 (approved approach A: descriptor/operation registry). Consumes the unisim-core contract PR unilabsim/unisim#21.
DomainRandomizationManager.apply_interval_randomization_if_dueis now fully generic (src/unilab/dr/manager.py:91): no interval term names, no per-field capabilityifbranches. It validatesplan.iter_ops()againstcapabilities.get_unsupported_interval_terms(...)and fails closed with backend type + sorted term names, then dispatches once.src/unilab/dr/dr_utils.py) and Sharpa body force (src/unilab/tasks/manipulation/sharpa_inhand/rotation.py) now emitIntervalTermOpentries with identical payloads/timing; validation usessupports_interval_term.IntervalRandomizationPlanfields keep working throughiter_ops()(deprecated in the provider docstring; removal in the next unisim-core major) — existing task owners and the Entity/EventManager interval path (src/unilab/base/entity.py,src/unilab/envs/mdp/events.py) are untouched and run through the compatibility adapter.unilab.drre-exportsIntervalTermOp+INTERVAL_TERM_*.pyproject.toml:unisim-core>=0.1.14→>=1.1.0.Tests
tests/dr/test_manager.py: custom-term extensibility without touching the manager (acceptance proof), capability-negative errors (term + backend in message), legacy-fields compat, mixed legacy+ops, empty/None plans, multi-op single dispatch, pickle protocol-4 round-trip.body_torque/body_angular_velocity_delta; they now fail closed. No UniLab test relied on the silent behavior; three backend tests were updated for the new unified error messages/validation order (test_genesis_backend.py,test_isaacgym_backend.py,test_sim_backend_smoke.py).Benchmark (interval hot path, 20k calls, min of 5 repeats, this machine)
apply_interval_randomization(body-force plan)The generic dispatch adds ≤0.9 µs per interval application; interval terms fire on multi-step cadence (e.g. push interval) against ~ms physics steps, so there is no measurable hot-path regression and no extra backend round-trip (still one
apply_interval_randomizationcall per due step). An ops-only fast path initer_ops()avoids per-call tuple re-allocation (unisim b49e8b5).Validation
UV_NO_SYNC=1 make test-all: ruff format/check clean, mypy clean (148 files), pyright 0 errors, pytestnot slow1578 passed / 20 skipped / 1 xfailed, benchmark smoke 36/37 pass (1 platform-optional mlx skip).tests/base/test_backend_imports.py::test_unisim_dependency_is_installed_from_package_index— by design it rejects non-index unisim-core installs; local verification used an editable install of feat(dr): declarative interval term descriptors with generic backend dispatch unilabsim/unisim#21. It passes once unisim-core 1.1.0 is published and installed from PyPI.Dependency / merge order
git tag v1.1.0, trusted publishing per unisim docs/release.md).uv.lockhere (uv lock) — deliberately not done yet since 1.1.0 is not on PyPI; remote CI on this PR will be red until then. I will push the lock update and confirm CI green after the release.