@@ -248,17 +248,14 @@ def test_dumbbell(showPlots, initialAngularRate):
248248 scene .setIntegrator (integ )
249249 scSim .AddModelToTask ("test" , scene )
250250
251- # Create gravity model and add it to the scene dynamics task
252- gravity = NBodyGravity .NBodyGravity ()
253- gravity .ModelTag = "gravity"
254- scene .AddModelToDynamicsTask (gravity )
255-
256- # Set a point mass gravity source
257- gravityModel = pointMassGravityModel .PointMassGravityModel ()
258- gravityModel .muBody = mu
259- gravity .addGravitySource ("earth" , gravityModel , True )
251+ # Use a custom factory body to preserve the gravitational parameter defined
252+ # by this test. The factory applies gravity to every body in the scene.
253+ gravFactory = simIncludeGravBody .gravBodyFactory ()
254+ earth = gravFactory .createCustomGravObject ("earth" , mu )
255+ earth .isCentralBody = True
256+ gravity = gravFactory .addBodiesTo (scene )
260257
261- # Add a gravity target for each of the bodies of the spacecraft
258+ # Retrieve the gravity target that the factory created for each body.
262259 # Note that because 'center' has zero mass, no force should be
263260 # produced on this body.
264261 # Also, create recorders for the state of each body and for the
@@ -268,7 +265,7 @@ def test_dumbbell(showPlots, initialAngularRate):
268265 bodyStateRecorders = {}
269266 for bodyName in bodies :
270267 body : mujoco .MJBody = scene .getBody (bodyName )
271- target = gravity .addGravityTarget (bodyName , body )
268+ target = gravity .getGravityTarget (bodyName )
272269
273270 forceRecorders [bodyName ] = target .massFixedForceOutMsg .recorder ()
274271 scSim .AddModelToTask ("test" , forceRecorders [bodyName ])
@@ -626,17 +623,24 @@ def test_mujocoVsSpacecraft(
626623
627624 rN , vN = orbitalMotion .elem2rv (mu , oe )
628625
629- # Create GravBodies, which will be used for the spacecraft
630- # and also the mujoco sim
626+ # Configure the body names shared by the two simulation paths. Each path
627+ # receives its own factory so that models and ephemeris modules are not
628+ # shared across sequential simulations.
631629 bodies = ["earth" ]
632630 if useThirdBodies :
633631 bodies .extend (["sun" , "moon" ])
634- gravFactory = simIncludeGravBody .gravBodyFactory ()
635- gravBodies = gravFactory .createBodies (bodies )
636- gravBodies ["earth" ].isCentralBody = True
637- if useSphericalHarmonics :
638- ggm03s_path = get_path (DataFile .LocalGravData .GGM03S )
639- gravBodies ["earth" ].useSphericalHarmonicsGravityModel (str (ggm03s_path ), 4 )
632+
633+ def createGravityFactory ():
634+ """Create an independent factory with the requested gravity models."""
635+ factory = simIncludeGravBody .gravBodyFactory ()
636+ gravBodies = factory .createBodies (bodies )
637+ gravBodies ["earth" ].isCentralBody = True
638+ if useSphericalHarmonics :
639+ ggm03s_path = get_path (DataFile .LocalGravData .GGM03S )
640+ gravBodies ["earth" ].useSphericalHarmonicsGravityModel (
641+ str (ggm03s_path ), 4
642+ )
643+ return factory
640644
641645 # A decorator that times how long the function takes and
642646 # prints it to the console
@@ -659,6 +663,8 @@ def wrap():
659663
660664 @timed
661665 def spacecraftSim ():
666+ gravFactory = createGravityFactory ()
667+
662668 # Create sim, process, and task
663669 scSim = SimulationBaseClass .SimBaseClass ()
664670 dynProcess = scSim .CreateNewProcess ("test" )
@@ -677,9 +683,7 @@ def spacecraftSim():
677683 scObject .setIntegrator (integSc )
678684 scSim .AddModelToTask ("test" , scObject , 9 )
679685
680- scObject .gravField .gravBodies = spacecraft .GravBodyVector (
681- list (gravFactory .gravBodies .values ())
682- )
686+ gravFactory .addBodiesTo (scObject )
683687
684688 # initialize spacecraft parameters
685689 scObject .hub .mHub = 100 # kg
@@ -705,42 +709,31 @@ def spacecraftSim():
705709
706710 @timed
707711 def mujocoSim ():
712+ gravFactory = createGravityFactory ()
713+
708714 # Create sim, process, and task
709715 scSim = SimulationBaseClass .SimBaseClass ()
710716 dynProcess = scSim .CreateNewProcess ("test" )
711717 dynProcess .addTask (scSim .CreateNewTask ("test" , macros .sec2nano (dt )))
712718
713- # Create the spice interface module, which reports the state of
714- # planetary bodies
715- spice = spiceInterface .SpiceInterface ()
716- spice .ModelTag = "SpiceInterface"
717- spice .addPlanetNames (["earth" , "sun" , "moon" ])
718- spice .UTCCalInit = utcCalInit
719- # spice.zeroBase = 'Earth' # Not actually needed for NBodyGravity
720- scSim .AddModelToTask ("test" , spice )
721-
722719 # Create mujoco scene
723720 scene = mujoco .MJScene .fromFile (XML_PATH_BALL )
724721 scene .ModelTag = "mujocoScene"
725722 integScene = svIntegrators .svIntegratorEuler (scene ) # MUST BE EULER!
726723 scene .setIntegrator (integScene )
727724 scSim .AddModelToTask ("test" , scene )
728725
729- # Create N-Body Gravity
730- gravity = NBodyGravity .NBodyGravity ()
731- scene .AddModelToDynamicsTask (gravity )
726+ # MuJoCo evaluates gravity at integrator substeps, so its SPICE model
727+ # belongs in the scene dynamics task ahead of the factory-created
728+ # NBodyGravity model.
729+ if useSpice :
730+ gravFactory .createSpiceInterface (time = utcCalInit )
731+ gravFactory .spiceObject .zeroBase = "Earth"
732+ scene .AddModelToDynamicsTask (gravFactory .spiceObject , 75 )
732733
733- for (name , gravBody ), stateOuMsg in zip (
734- gravBodies .items (), spice .planetStateOutMsgs
735- ):
736- source = gravity .addGravitySource (
737- name , gravBody .gravityModel , isCentralBody = (name == "earth" )
738- )
739- if useSpice :
740- source .stateInMsg .subscribeTo (stateOuMsg )
734+ gravFactory .addBodiesTo (scene )
741735
742736 body : mujoco .MJBody = scene .getBody ("ball" )
743- gravity .addGravityTarget ("ball" , body )
744737
745738 bodyStateRecorder = body .getCenterOfMass ().stateOutMsg .recorder ()
746739 scSim .AddModelToTask ("test" , bodyStateRecorder )
0 commit comments