Add gravity factory support for MuJoCo scenes#1490
Merged
Conversation
schaubh
added a commit
that referenced
this pull request
Jul 20, 2026
Extend gravBodyFactory.addBodiesTo() to configure MJScene objects in addition to conventional GravityEffector owners. For each MuJoCo scene, create an NBodyGravity model, register every factory body as a gravity source, and apply gravity independently at every MuJoCo body's center of mass. Retain the model and Vizard gravity metadata on the scene and reject duplicate gravity attachment. Allow NBodyGravity sources to retain a shared GravBodyData descriptor. Resolve the gravity model, central-body flag, and ephemeris input from the descriptor so the same configuration can be shared by conventional spacecraft and MuJoCo dynamics. Initialize descriptor-backed gravity models during Reset and warn when an orientation-dependent model has no ephemeris input. Expose descriptor-backed sources to Python as addGravitySourceFromBody(). Keep the existing manual addGravitySource(..., isCentralBody=...) interface unchanged, including support for its keyword argument. This enables gravity models and SPICE connections created by simIncludeGravBody to be reused directly by MuJoCo scenes without duplicating their configuration.
schaubh
added a commit
that referenced
this pull request
Jul 20, 2026
schaubh
added a commit
that referenced
this pull request
Jul 20, 2026
Add an optional zeroBase setting to PlanetEphemeris so generated planet states can be expressed relative to another body propagated by the same module instance. Preserve the existing heliocentric behavior when zeroBase is left empty. Resolve the selected body during Reset using case-insensitive name matching and report an initialization error when the requested body is not configured in the module. Compute all heliocentric states before subtracting the selected body's position and velocity, ensuring the translation is independent of body ordering. Leave planet names, timestamps, attitudes, attitude rates, and orientation flags unchanged. Expand the PlanetEphemeris unit tests to verify: - the default empty zeroBase value - position and velocity translation at multiple simulation times - zero position and velocity for the selected base body - preservation of attitude and message metadata - case-insensitive body-name matching - rejection of bodies from outside the module instance Document zeroBase configuration, default behavior, and the requirement that the reference body be propagated by the same PlanetEphemeris instance. Clarify that changing the output origin does not introduce hierarchical or mutually coupled orbital propagation. Update scenarioCustomGravBody to use Itokawa as the output origin, placing the planet and spacecraft states in a common asteroid-centered translational frame.
schaubh
force-pushed
the
feature/grav_factory_mujoco
branch
from
July 20, 2026 21:01
2bbbd8c to
b0a9b37
Compare
schaubh
added a commit
that referenced
this pull request
Jul 20, 2026
Example uses both Spice and planetEphemeris message states.
schaubh
added a commit
that referenced
this pull request
Jul 20, 2026
schaubh
added a commit
that referenced
this pull request
Jul 20, 2026
schaubh
added a commit
that referenced
this pull request
Jul 20, 2026
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2bbbd8c1fb
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
schaubh
added a commit
that referenced
this pull request
Jul 20, 2026
Add an optional zeroBase setting to PlanetEphemeris so generated planet states can be expressed relative to another body propagated by the same module instance. Preserve the existing heliocentric behavior when zeroBase is left empty. Resolve the selected body during Reset using case-insensitive name matching and report an initialization error when the requested body is not configured in the module. Compute all heliocentric states before subtracting the selected body's position and velocity, ensuring the translation is independent of body ordering. Leave planet names, timestamps, attitudes, attitude rates, and orientation flags unchanged. Expand the PlanetEphemeris unit tests to verify: - the default empty zeroBase value - position and velocity translation at multiple simulation times - zero position and velocity for the selected base body - preservation of attitude and message metadata - case-insensitive body-name matching - rejection of bodies from outside the module instance Document zeroBase configuration, default behavior, and the requirement that the reference body be propagated by the same PlanetEphemeris instance. Clarify that changing the output origin does not introduce hierarchical or mutually coupled orbital propagation. Update scenarioCustomGravBody to use Itokawa as the output origin, placing the planet and spacecraft states in a common asteroid-centered translational frame.
schaubh
added a commit
that referenced
this pull request
Jul 20, 2026
Example uses both Spice and planetEphemeris message states.
schaubh
added a commit
that referenced
this pull request
Jul 20, 2026
schaubh
added a commit
that referenced
this pull request
Jul 20, 2026
schaubh
force-pushed
the
feature/grav_factory_mujoco
branch
from
July 20, 2026 23:59
b0a9b37 to
f209d89
Compare
schaubh
added a commit
that referenced
this pull request
Jul 20, 2026
schaubh
added a commit
that referenced
this pull request
Jul 20, 2026
Treat an all-zero J20002Pfix matrix from a linked gravity-source ephemeris message as an identity transformation. Position-only ephemeris messages leave J20002Pfix at its default zero value. Applying that matrix previously collapsed transformed target positions to zero, which could produce a singular gravity calculation and NaN forces. The new fallback matches the existing GravityEffector behavior and interprets an unspecified source attitude as inertially aligned. Add a MuJoCo regression test using a factory-created central gravity body connected to a position-only ephemeris message. Verify that the computed force remains finite and agrees with the analytical point-mass gravity result. Verification: - NBodyGravity unit tests: 11 passed - MuJoCo dynamics tests: 68 passed - pre-commit checks passed - git diff --check passed
juan-g-bonilla
approved these changes
Jul 22, 2026
juan-g-bonilla
left a comment
Contributor
There was a problem hiding this comment.
Focused mostly on the NBodyGravity changes and usage. Left two nitpick-y comments and suggested a fix for what I think gets you stale recorded data. Otherwise the scenarios look much nicer with the factory!
Extend gravBodyFactory.addBodiesTo() to configure MJScene objects in addition to conventional GravityEffector owners. For each MuJoCo scene, create an NBodyGravity model, register every factory body as a gravity source, and apply gravity independently at every MuJoCo body's center of mass. Retain the model and Vizard gravity metadata on the scene and reject duplicate gravity attachment. Allow NBodyGravity sources to retain a shared GravBodyData descriptor. Resolve the gravity model, central-body flag, and ephemeris input from the descriptor so the same configuration can be shared by conventional spacecraft and MuJoCo dynamics. Initialize descriptor-backed gravity models during Reset and warn when an orientation-dependent model has no ephemeris input. Expose descriptor-backed sources to Python as addGravitySourceFromBody(). Keep the existing manual addGravitySource(..., isCentralBody=...) interface unchanged, including support for its keyword argument. This enables gravity models and SPICE connections created by simIncludeGravBody to be reused directly by MuJoCo scenes without duplicating their configuration.
Add an optional zeroBase setting to PlanetEphemeris so generated planet states can be expressed relative to another body propagated by the same module instance. Preserve the existing heliocentric behavior when zeroBase is left empty. Resolve the selected body during Reset using case-insensitive name matching and report an initialization error when the requested body is not configured in the module. Compute all heliocentric states before subtracting the selected body's position and velocity, ensuring the translation is independent of body ordering. Leave planet names, timestamps, attitudes, attitude rates, and orientation flags unchanged. Expand the PlanetEphemeris unit tests to verify: - the default empty zeroBase value - position and velocity translation at multiple simulation times - zero position and velocity for the selected base body - preservation of attitude and message metadata - case-insensitive body-name matching - rejection of bodies from outside the module instance Document zeroBase configuration, default behavior, and the requirement that the reference body be propagated by the same PlanetEphemeris instance. Clarify that changing the output origin does not introduce hierarchical or mutually coupled orbital propagation. Update scenarioCustomGravBody to use Itokawa as the output origin, placing the planet and spacecraft states in a common asteroid-centered translational frame.
Example uses both Spice and planetEphemeris message states.
Treat an all-zero J20002Pfix matrix from a linked gravity-source ephemeris message as an identity transformation. Position-only ephemeris messages leave J20002Pfix at its default zero value. Applying that matrix previously collapsed transformed target positions to zero, which could produce a singular gravity calculation and NaN forces. The new fallback matches the existing GravityEffector behavior and interprets an unspecified source attitude as inertially aligned. Add a MuJoCo regression test using a factory-created central gravity body connected to a position-only ephemeris message. Verify that the computed force remains finite and agrees with the analytical point-mass gravity result. Verification: - NBodyGravity unit tests: 11 passed - MuJoCo dynamics tests: 68 passed - pre-commit checks passed - git diff --check passed
schaubh
force-pushed
the
feature/grav_factory_mujoco
branch
from
July 22, 2026 01:23
f209d89 to
c0fd86a
Compare
schaubh
added a commit
that referenced
this pull request
Jul 22, 2026
Extend gravBodyFactory.addBodiesTo() to configure MJScene objects in addition to conventional GravityEffector owners. For each MuJoCo scene, create an NBodyGravity model, register every factory body as a gravity source, and apply gravity independently at every MuJoCo body's center of mass. Retain the model and Vizard gravity metadata on the scene and reject duplicate gravity attachment. Allow NBodyGravity sources to retain a shared GravBodyData descriptor. Resolve the gravity model, central-body flag, and ephemeris input from the descriptor so the same configuration can be shared by conventional spacecraft and MuJoCo dynamics. Initialize descriptor-backed gravity models during Reset and warn when an orientation-dependent model has no ephemeris input. Expose descriptor-backed sources to Python as addGravitySourceFromBody(). Keep the existing manual addGravitySource(..., isCentralBody=...) interface unchanged, including support for its keyword argument. This enables gravity models and SPICE connections created by simIncludeGravBody to be reused directly by MuJoCo scenes without duplicating their configuration.
schaubh
added a commit
that referenced
this pull request
Jul 22, 2026
schaubh
added a commit
that referenced
this pull request
Jul 22, 2026
Add an optional zeroBase setting to PlanetEphemeris so generated planet states can be expressed relative to another body propagated by the same module instance. Preserve the existing heliocentric behavior when zeroBase is left empty. Resolve the selected body during Reset using case-insensitive name matching and report an initialization error when the requested body is not configured in the module. Compute all heliocentric states before subtracting the selected body's position and velocity, ensuring the translation is independent of body ordering. Leave planet names, timestamps, attitudes, attitude rates, and orientation flags unchanged. Expand the PlanetEphemeris unit tests to verify: - the default empty zeroBase value - position and velocity translation at multiple simulation times - zero position and velocity for the selected base body - preservation of attitude and message metadata - case-insensitive body-name matching - rejection of bodies from outside the module instance Document zeroBase configuration, default behavior, and the requirement that the reference body be propagated by the same PlanetEphemeris instance. Clarify that changing the output origin does not introduce hierarchical or mutually coupled orbital propagation. Update scenarioCustomGravBody to use Itokawa as the output origin, placing the planet and spacecraft states in a common asteroid-centered translational frame.
schaubh
added a commit
that referenced
this pull request
Jul 22, 2026
Example uses both Spice and planetEphemeris message states.
schaubh
added a commit
that referenced
this pull request
Jul 22, 2026
schaubh
added a commit
that referenced
this pull request
Jul 22, 2026
schaubh
added a commit
that referenced
this pull request
Jul 22, 2026
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.
Description
This PR extends
simIncludeGravBody.gravBodyFactoryso the same gravity-body configuration can be attached to conventional Basilisk spacecraft dynamics or a MuJoCoMJScene.MuJoCo users can now configure gravity with the standard factory workflow:
For a MuJoCo scene,
addBodiesTo()creates and retains anNBodyGravitymodel, adds the factory bodies as gravity sources, and registers every MuJoCo body as a gravity target at its center of mass. The gravity-body configuration is also exposed to Vizard. Duplicate attachment to a scene is rejected.NBodyGravitynow accepts sharedGravBodyDatadescriptors. This preserves each body’s gravity model, central-body designation, and ephemeris input without duplicating configuration between conventional and MuJoCo dynamics. The existing manualNBodyGravityAPIs remain available.This PR also adds
PlanetEphemeris.zeroBase. When set to a body propagated by the module, all output positions and velocities are translated relative to that body while retaining J2000-aligned axes. LeavingzeroBaseempty preserves the existing heliocentric behavior. Body-name matching is case-insensitive, and invalid selections stop initialization with an error.A new
scenarioMJEarthMoonGravitytutorial demonstrates Earth and Moon gravity using either SPICE orPlanetEphemeris. It includes correct ephemeris scheduling, safe low-Earth-orbit initial conditions, Vizard binary-saving support, and illustrative plots.Existing MuJoCo examples and appropriate MuJoCo-backed tests were migrated to the factory helper. Tests that intentionally exercise the low-level
NBodyGravityconfiguration APIs remain explicit.The commits are organized as follows:
GravBodyDataand MuJoCo-scene support toNBodyGravityandgravBodyFactory.PlanetEphemeris.zeroBase.Verification
The following validation was performed:
planetEphemerisC++ and SWIG target.PlanetEphemerisunit tests.src/simulation/mujocoDynamics.PlanetEphemeris.No test baselines were re-generated or relaxed.
Documentation
The following documentation was added or updated:
simIncludeGravBodymodule documentation and inline comments.PlanetEphemeris.zeroBase, including default behavior, usage, and limitations.zeroBaseonly works with bodies propagated by the samePlanetEphemerisinstance.scenarioMJEarthMoonGravityand linked it from the example index.scenarioCustomGravBodyto use an asteroid-centered ephemeris origin.zeroBase, and tutorial.Reviewers should pay particular attention to the
GravBodyDataownership and ephemeris connections inNBodyGravity, the automatic MuJoCo target registration ingravBodyFactory.addBodiesTo(), and the two-pass state translation inPlanetEphemeris.Future work
No required follow-up is currently identified.
Cross-instance
PlanetEphemeris.zeroBasesupport remains intentionally out of scope because separate module instances do not exchange propagated body states.