Creating and modifying the bodies

Once all settings for the bodies are defined as described in Creation of celestial body settings, the bodies are created and linked together, so that all required interdependencies are automatically satisfied.

Creation of system of bodies from settings

The example below shows how to create a set of bodies, using the create_system_of_bodies() function:

Required Show/Hide

# import statements required
from tudatpy.kernel.numerical_simulation import environment_setup
from tudatpy.kernel.interface import spice

# load spice kernels
spice_interface.load_standard_kernels()
# define bodies in simulation
bodies_to_create = ["Sun", "Earth", "Moon", "Mars", "Jupiter"]

# create body settings dictionary
global_frame_origin = "SSB"
global_frame_orientation = "J2000"
body_settings = environment_setup.get_default_body_settings(
        bodies_to_create, global_frame_origin, global_frame_orientation)
# Modify the gravity field of the Sun
body_settings.get( "Sun" ).gravity_field_settings = 
    environment_setup.gravity_field.point_mass( 1.32712440042E20 )
# Create system of bodies from the body settings
bodies = environment_setup.create_system_of_bodies(body_settings)

The SystemOfBodies class (the type of the bodies variable in the above simulation) is at the heart of many Tudat simulations. It contains all properties of your celestial and manmade bodies, and is used to retieve properties of your accelerations, state derivative models, output variables, etc. A more detailed discussion of the architecture of the Body and SystemOfBodies classes, as well as their constituent environment models and possible interdependencies, are discussed here

It is crucial to understand the distinction between body_settings (of type BodyListSettings) and bodies (of type SystemOfBodies). The former is merely a list of settings for the models in the environment and is the main input to the body creation. It does not provide any functionality to perform any specific calculations: it describes what the models should do when rhet are created. The latter (bodies) is the object which is actually used during the propagation, and performs all required calculations (updating an ephemeris to the current time, calculating body orientations, determining atmospheric properties at a given location, etc). Since the creation of the bodies requires many steps, links with other packages, links between bodies, links between environment objects, frame transformations, etc., we have chose to not require a manual definition of its contents by the user, although such an apporoach is possible.

Adding bodies to an existing SystemOfBodies

After creating a SystemOfBodies from body settings, any number of additional custom bodies may be added to the simulation. Such an approach can be useful when:

  • Wanting to add bodies to an existing system of bodies (for instance: first running a simulation with N bodies, and then one with N+1 bodies)

  • Wanting to create a body that has a custom environment model that depends on the other bodies (such as aerodynamic guidance, thrust guidance, etc.), see Custom models for a detailed set of options.

One crucial downside of adding bodies to an existing SystemOfBodies is that the dependencies between the bodies can only go in ‘one direction’: the newly added body may depend on the existing bodies, but the existing bodies can typically not be updated to depend on the newly added body.

Warning

The (semi-)manual creation of bodies, or the modification of environment models of existing bodies, is not the recommended approach to take. Unless you have a good reason to take this approach (such as those listed above), we recommend the creation of bodies using creation of body settings

The first step is to add an empty Body object to the existing SystemOfBodies object through its create_empty_body() method:

Required Show/Hide

# import statements required
from tudatpy.kernel.numerical_simulation import environment_setup
from tudatpy.kernel.interface import spice

# load spice kernels
spice_interface.load_standard_kernels()
# define bodies in simulation
bodies_to_create = ["Sun", "Earth", "Moon", "Mars", "Jupiter"]

# create body settings dictionary
global_frame_origin = "SSB"
global_frame_orientation = "J2000"
body_settings = environment_setup.get_default_body_settings(
        bodies_to_create, global_frame_origin, global_frame_orientation)
# Create system of bodies from the body settings
bodies = environment_setup.create_system_of_bodies(body_settings)
# Add empty body to simulation
body_system.create_empty_body( "Vehicle" )

which adds a body with no properties to the system.

Addition of properties to a body

Properties can be added to an existing body after the body’s creation (with the limitations mentioned above). For an artificial body, typical properties are:

  • Mass

  • Aerodynamic coefficients

  • Radiation pressure properties

  • Engine model

  • Required Show/Hide

    # import statements required
    from tudatpy.kernel.numerical_simulation import environment_setup
    from tudatpy.kernel.interface import spice
    
    # load spice kernels
    spice_interface.load_standard_kernels()
    
    # define bodies in simulation
    bodies_to_create = ["Sun", "Earth", "Moon", "Mars", "Jupiter"]
    
    # create body settings dictionary
    global_frame_origin = "SSB"
    global_frame_orientation = "J2000"
    body_settings = environment_setup.get_default_body_settings(
            bodies_to_create, global_frame_origin, global_frame_orientation)
    
    # Create system of bodies from the body settings
    bodies = environment_setup.create_system_of_bodies(body_settings)
    
    # Add empty body to simulation
    body_system.create_empty_body( "Vehicle" )
    
    # Set mass of vehicle
    bodies.get( "Vehicle").mass = 5000.0
    
    # Create aerodynamic coefficient interface settings, and add to vehicle
    aero_coefficient_settings = environment_setup.aerodynamic_coefficients.constant(
        reference_area = 50.0,
        constant_force_coefficient = [drag_coefficient,0,0]
    )
    environment_setup.add_aerodynamic_coefficient_interface(
                bodies, "Vehicle", aero_coefficient_settings );
    
    # Create radiation pressure settings, and add to vehicle
    radiation_pressure_settings = environment_setup.radiation_pressure.cannonball(
        source_body = "Sun", 
        reference_area = 50.0, 
        radiation_pressure_coefficient = 1.5, 
        occulting_bodies = ["Earth"]
    )
    environment_setup.add_radiation_pressure_interface(
                bodies, "Vehicle", radiation_pressure_settings );
    

In this example, the settings for the aerodynamic coefficients and radiation pressure are defined as the most simple models available (constant drag-only aerodynamic coefficients, and cannonball radiation pressure). The above approach uses the settings for environment models, just as the creation of bodies from settings<creation_celestial_body_settings> (which is the preferred and recommended approach in most cases). However, instead of storing these environment settings in a larger object defining the settings for the full bodies, and for all bodies together, here we use the environment model settings one at a time. For each supported environment model, an add.... function is provided in the environment_setup module.

Note that a similar approach is typically taken to add ground stations to a body (see Ground stations)

See also

A comprehensive list of settings for both types of models can be found in Available Model Types.