Creating the bodies#
The usual workflow to create bodies in Tudat (both natural and artificial bodies!) is composed of three subsequent steps, described separately:
Warning
Body settings are not used in the propagation: they are only used to define the settings of the body objects, and are used to create Body
objects, which are used during the propagation and contain the actual objects/functions performing the relevant calculations. This procedure is
described in the separate page Modifying the bodies.
Creating body settings#
In Tudat, the settings of a single body are stored as a BodySettings
object. Together, these objects are stored in a BodyListSettings
object.
Typically, the settings for a body are created by retrieving the default settings, and then modifying these as needed. In some cases, the default settings are not available, and the settings have to be created from scratch (“empty” settings).
Note
In order to create empty settings for a body, the user must first create a BodyListSettings
object as described in the default settings section.
From default settings#
In most cases, the starting point for the creation of body settings will be the retrieval of default settings. This
prevents a user from having to manually define a variety of ‘typical’ models for solar-system bodies. The full list of
default body settings is given at Default environment models, and can be retrieved using the
get_default_body_settings()
function:
Required
# import statements required
from tudatpy.numerical_simulation import environment_setup
from tudatpy.interface import spice
# load spice kernels
spice.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)
where the global_frame_origin
and global_frame_orientation
define the reference frame in which state vectors
stored in the environment during the propagation are represented. In general, it is recommended to choose this as the most ‘intuitive’ frame origin for your propagation
(e.g. SSB or Sun for solar system scale propagations, Earth for an Earth orbiter, Mars for a Martian mission, etc.). The above function creates an object of type BodyListSettings
, which stores the settings for all bodies.
Note
The global frame origin definition is distinct from the
center of propagation that you can define for the propagation of translational dynamics (see translational()
function, and the Translational Dynamics page). For more information about this distinction, and the use of these reference frames in general, see Frames in the Environment.
In addition to the above method of creating default bodies, we offer an alternative which is more computationally efficient, at the expense of higher RAM usage and a more limited time interval in which the environment is valid. Such an approach is typically only used when computational speed is very important, and is described in more detail here.
Finally, in case you want to initialize body settings without any default settings, body_settings
can also be created manually as:
Required
# import statements required
from tudatpy.numerical_simulation import environment_setup
from tudatpy.interface import spice
# load spice kernels
spice.load_standard_kernels()
# Manually create (empty) settings for a list of bodies, with origin/orientation Earth/J2000
body_settings = environment_setup.BodyListSettings( frame_origin = "Earth", frame_orientation = "J2000" )
where the frame origin and orientation have been defined manually as “Earth” and “J2000”, respectively.
From empty settings#
Some bodies do not have any default settings, and in some cases all default settings may be different from what a user desired. In such cases, manually creating the settings can also be done.
Required
# import statements required
from tudatpy.numerical_simulation import environment_setup
from tudatpy.interface import spice
# load spice kernels
spice.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)
# Add empty body settings for body Oumuamua, and add to existing list of settings
body_settings.add_empty_settings( "Oumuamua" )
# Manually create and assign environment model settings to new body settings
body_settings.get( "Oumuamua" ).ephemeris_settings = ...
body_settings.get( "Oumuamua" ).gravity_field_settings = ...
body_settings.get( "Oumuamua" ).rotation_model_settings = ...
In this example, empty body settings for a body ‘Oumuamua’ are first added to the body_settings
created previously. When adding such settings, no properties whatsoever are assigned to the body, the body is only given a name. Each environment model setting has to be manually added.
The above setup is also one that is typically used for artificial bodies, for which no default settings are currently implemented. Even though the type and settings of a vehicle’s constituent environment (and system) models are typically very different from a natural body, the manner in which such a body is set up is not fundamentally different in Tudat. See below for a representative example:
Required
# import statements required
from tudatpy.numerical_simulation import environment_setup
from tudatpy.interface import spice
# load spice kernels
spice.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)
# Add empty body settings for body Oumuamua, and add to existing list of settings
body_settings.add_empty_settings( "Spacecraft" )
# Manually create and assign environment model settings to new body settings
body_settings.get( "Spacecraft" ).radiation_pressure_target_settings = ...
body_settings.get( "Spacecraft" ).aerodynamic_coefficient_settings = ...
body_settings.get( "Spacecraft" ).constant_mass = 500.0;
In the above code snippet, you may notice that the body mass is set directly as a value (here 500 kg) in the BodySettings
. This is used as a ‘shortcut’ for the use of the constant_rigid_body_properties()
and assigning this to the rigid_body_settings
.
Customizing body settings#
Although the default body settings are often very useful, there are various cases where a user will want to override these default settings, or where such default settings are not available. These cases can be divided into three categories:
Modifying the type of the model that is used. Example: using a spherical harmonic gravity field instead of a point-mass gravity field
Modifying the specific parameters inside a given default model setting. Example: modifying the value of the gravitational parameter used for the given default model
Creating body settings from scratch, without any use of the default settings.
Below we show each manner to modify the settings with a representative example.
See also
A comprehensive list of all environment models, and how their settings can be defined and overridden as above, is given in the page about Environment Models.
Overriding existing settings objects#
Default settings may be overridden as follows:
Required
# import statements required
from tudatpy.numerical_simulation import environment_setup
from tudatpy.interface import spice
# load spice kernels
spice.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.central( 1.32712440042E20 )
The above works equally well if the existing environment model settings are empty or the default model is not suitable for the users simulation. The new settings define a central gravity field with a gravitational parameter of \(1.32712440042 \cdot 10^{20}\) m 3 / s 2 for the Sun.
Modifying parameters in existing settings objects#
Parameters of default models may be overridden as follows:
Required
# import statements required
from tudatpy.numerical_simulation import environment_setup
from tudatpy.interface import spice
# load spice kernels
spice.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.gravitational_parameter = 1.32712440042E20
Functionally, this example is identical to the previous one, but it permits different kinds of modifications to be made. It allows only a single property of the environment model to be modified, while in the previous example, it is required that all properties are redefined by the user. The present example therefor allows for more ‘fine-grained’ control of the settings, but limits the user to a modifying the properties of the settings.
Below is a slightly more involved example, which does not use a property of the GravityFieldSettings
base class, but rather the SphericalHarmonicsGravityFieldSettings
derived class. Therefore, the example below will only work if the current gravity field settings for the Earth already define a spherical harmonic gravity field:
Required
# import statements required
from tudatpy.numerical_simulation import environment_setup
from tudatpy.interface import spice
# load spice kernels
spice.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)
# Get the current cosine coefficients of the Earth
cosine_coefficients = body_settings.get('Earth').gravity_field_settings.normalized_cosine_coefficients
# Modify the C_{2,0} coefficient of the Earth
cosine_coefficients[ 2, 0 ] = cosine_coefficients[ 2, 0 ] + 1.0E-12
# Reset the coefficients of the Earth
body_settings.get('Earth').gravity_field_settings.normalized_cosine_coefficients = cosine_coefficients
Here, we extracted, modified, and then reset the normalized_cosine_coefficients
property of the SphericalHarmonicsGravityFieldSettings
.
Provided that the body settings of the Sun and Earth have any gravity field settings, the above will work. If it does not, you should first create such settings (see Overriding existing settings objects). For an overview of the relevant attributes, functions and classes for other environment models, see Environment Models.
Creating system of bodies from settings#
The SystemOfBodies
class is at the heart of many Tudat simulations. It contains all properties of your celestial and artificial bodies, and is used to retrieve properties of your accelerations, state derivative models, output variables, etc.
See the Environment - Overall Architecture page for a more detailed discussion of the architecture of the Body
and SystemOfBodies
classes and the interdependencies between environment models.
The example below shows how to create a set of bodies from previously defined body settings, using the create_system_of_bodies()
function:
Required
# import statements required
from tudatpy.numerical_simulation import environment_setup
from tudatpy.interface import spice
# load spice kernels
spice.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)
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 they 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 chosen to not require a manual definition of its contents by the user, although such an approach is possible.