Skip to main content
This tutorial walks through scenarioBasicOrbit.py, the most minimal complete Basilisk scenario. You will set up a spacecraft, attach a gravity model, configure an orbit, run the simulation, and retrieve position and velocity data.
This scenario is the recommended starting point before exploring more advanced examples. It demonstrates only translational (orbital) motion — rotational dynamics are present but use default values and are not tracked.

What this scenario demonstrates

  • Creating a SimBaseClass simulation container with a single dynamics process and task
  • Instantiating a spacecraft.Spacecraft() module
  • Adding a planetary gravity body (Earth or Mars) via simIncludeGravBody
  • Optionally enabling spherical harmonics for higher-fidelity gravity
  • Converting classical orbital elements to inertial position and velocity vectors
  • Recording spacecraft state output messages and plotting results

Key modules used

ModulePackageRole
spacecraft.SpacecraftBasilisk.simulationIntegrates translational and rotational equations of motion
gravBodyFactoryBasilisk.utilities.simIncludeGravBodyCreates and attaches planetary gravity effectors
SimBaseClassBasilisk.utilities.SimulationBaseClassTop-level simulation container
orbitalMotionBasilisk.utilitiesConverts between orbital elements and state vectors
macrosBasilisk.utilitiesUnit conversion helpers (e.g. sec2nano, D2R)

Running the scenario

python3 scenarioBasicOrbit.py
The run() function accepts four parameters:
run(
    True,    # show_plots
    "LEO",   # orbitCase: 'LEO', 'GTO', or 'GEO'
    False,   # useSphericalHarmonics
    "Earth", # planetCase: 'Earth' or 'Mars'
)

Step-by-step walkthrough

1

Create the simulation container and process

Every Basilisk simulation starts with a SimBaseClass instance. You then create a named process and add a task with a fixed integration time step.
from Basilisk.utilities import SimulationBaseClass, macros

simTaskName = "simTask"
simProcessName = "simProcess"

scSim = SimulationBaseClass.SimBaseClass()
scSim.SetProgressBar(True)  # optional terminal progress bar

dynProcess = scSim.CreateNewProcess(simProcessName)

simulationTimeStep = macros.sec2nano(10.0)  # [ns] - 10-second integration step
dynProcess.addTask(scSim.CreateNewTask(simTaskName, simulationTimeStep))
macros.sec2nano() converts seconds to nanoseconds — Basilisk’s internal time unit throughout.
2

Instantiate and add the spacecraft

Create a Spacecraft object, assign it a tag, and register it with the task.
from Basilisk.simulation import spacecraft

scObject = spacecraft.Spacecraft()
scObject.ModelTag = "bsk-Sat"

scSim.AddModelToTask(simTaskName, scObject)
At this stage the spacecraft has no mass properties set — that is fine for a pure orbital simulation because gravity-only dynamics do not depend on mass.
3

Add a gravity body

Use gravBodyFactory to create Earth or Mars and attach it to the spacecraft.
from Basilisk.utilities import simIncludeGravBody

gravFactory = simIncludeGravBody.gravBodyFactory()

# Earth (default case)
planet = gravFactory.createEarth()
planet.isCentralBody = True

# Optionally enable J2 spherical harmonics
if useSphericalHarmonics:
    from Basilisk.utilities.supportDataTools.dataFetcher import get_path, DataFile
    ggm03s_path = get_path(DataFile.LocalGravData.GGM03S_J2_only)
    planet.useSphericalHarmonicsGravityModel(str(ggm03s_path), 2)

mu = planet.mu

# Connect all gravity bodies to the spacecraft
gravFactory.addBodiesTo(scObject)
For Mars, replace createEarth() with createMarsBarycenter() and use DataFile.LocalGravData.GGM2BData for the harmonics file.
Calling gravFactory.addBodiesTo(scObject) wires up the complete gravity effector list to the spacecraft in a single call, regardless of how many bodies are in the factory.
4

Configure the orbit and set initial conditions

Basilisk’s orbitalMotion utilities let you define an orbit in classical elements and convert to inertial Cartesian vectors.
import numpy as np
from Basilisk.utilities import orbitalMotion, macros

oe = orbitalMotion.ClassicElements()
rLEO = 7000.0 * 1000  # [m] - LEO radius

# Low Earth Orbit example
oe.a = rLEO        # [m]   - semi-major axis
oe.e = 0.0001      #       - eccentricity
oe.i = 33.3 * macros.D2R   # [rad] - inclination
oe.Omega = 48.2 * macros.D2R  # [rad] - RAAN
oe.omega = 347.8 * macros.D2R # [rad] - argument of perigee
oe.f = 85.3 * macros.D2R     # [rad] - true anomaly

rN, vN = orbitalMotion.elem2rv(mu, oe)

scObject.hub.r_CN_NInit = rN  # [m]   - inertial position
scObject.hub.v_CN_NInit = vN  # [m/s] - inertial velocity
The GEO and GTO cases follow the same pattern with different semi-major axis and eccentricity values.
5

Set the simulation duration and configure data recording

Compute the simulation time from the orbital period and attach a message recorder to the spacecraft state output.
from Basilisk.utilities import unitTestSupport

n = np.sqrt(mu / oe.a**3)  # [rad/s] - mean motion
P = 2.0 * np.pi / n        # [s]     - orbital period
simulationTime = macros.sec2nano(0.75 * P)  # [ns]

numDataPoints = 100
samplingTime = unitTestSupport.samplingTime(
    simulationTime, simulationTimeStep, numDataPoints
)

# Attach a recorder to the spacecraft state output message
dataRec = scObject.scStateOutMsg.recorder(samplingTime)
scSim.AddModelToTask(simTaskName, dataRec)
6

Initialize and run the simulation

scSim.InitializeSimulation()
scSim.ConfigureStopTime(simulationTime)
scSim.ExecuteSimulation()
InitializeSimulation() calls self_init() and reset() on every module. ConfigureStopTime() followed by ExecuteSimulation() advances the simulation forward.
7

Retrieve and plot the recorded data

After the run completes, read data arrays directly from the recorder object.
posData = dataRec.r_BN_N   # shape (N, 3) - inertial position [m]
velData = dataRec.v_BN_N   # shape (N, 3) - inertial velocity [m/s]
timeAxis = dataRec.times() # shape (N,)   - time in nanoseconds
The scenario plots inertial position components and either a perifocal orbit view (without harmonics) or semi-major axis history (with harmonics).

Orbit case comparison

orbitCaseSemi-major axisEccentricityNotes
'LEO'7000 km0.000133.3° inclination
'GTO'(rLEO + rGEO) / 21 - rLEO/aZero inclination
'GEO'42000 km0.00001Zero inclination

Vizard visualization

To stream the simulation to the Vizard application, uncomment the enableUnityVisualization call:
from Basilisk.utilities import vizSupport

if vizSupport.vizFound:
    viz = vizSupport.enableUnityVisualization(scSim, simTaskName, scObject
                                              # , saveFile=__file__
                                              )
Vizard reads the stored binary file or live stream and renders the orbit in 3D with correct planet textures.

Build docs developers (and LLMs) love