Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Analysis/120 momentum management #121

Closed
wants to merge 13 commits into from
18 changes: 10 additions & 8 deletions docs/source/Support/bskReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Basilisk Release Notes
- landing dynamics force/torque effector that computes the interaction between a CAD spacecraft model and a
CAD asteroid or lunar surface terrain.
- spacecraft charging related modules
- ability to integrate dynamics of multiple spacecraft simultaneously
- support a way to do thread-safe messaging
- ability to integrate Python Basilisk modules in the same task and process as C/C++ modules
- automated documentation build system when code is pushed to the repo
Expand All @@ -47,6 +48,14 @@ Version |release|
To convert prior script to use the new syntax, see :ref:`bskPrinciples-2` for the simple new
syntaxt to add C-modules.
- Modified :ref:`mrpFeedback` to enable the use of a modified control law, and added the integral control torque feedback output message.
- Created :ref:`lambertSolver` module to solve Lambert's problem
- Created :ref:`lambertPlanner` module to write the :ref:`lambertProblemMsgPayload` Lambert problem setup message
- Created :ref:`lambertValidator` module to check if the solution from the :ref:`lambertSolver` module violates any
constraints before a Delta-V is commanded.
- Added :ref:`scenarioLambertSolver` scenario to illustrate the Lambert solver module package
- Created :ref:`flybyPoint` to provide hill point reference during a flyby, and a related :ref:`scenarioFlybyPoint`.
- Created :ref:`thrusterPlatformState` to map the thruster configuration information to body frame given the time-varying platform states.
- Created :ref:`thrustCMEstimation` to perform online estimation of the CM using gimbaled thruster torque measurements.


Version 2.2.0 (June 28, 2023)
Expand All @@ -66,12 +75,6 @@ Version 2.2.0 (June 28, 2023)
- Updated :ref:`SmallBodyNavEKF` with several bug fixes. Removed spacecraft attitude estimation component.
- Bug fix made to :ref:`eclipse`: Saturn, Jupiter, Uranus, and Neptune radii were incorrectly being assigned the
radius of Mars.
- Created :ref:`lambertSolver` module to solve Lambert's problem
- Created :ref:`lambertPlanner` module to write the :ref:`lambertProblemMsgPayload` Lambert problem setup message
- Created :ref:`lambertValidator` module to check if the solution from the :ref:`lambertSolver` module violates any
constraints before a Delta-V is commanded.
- Added :ref:`scenarioLambertSolver` scenario to illustrate the Lambert solver module package
- Created :ref:`flybyPoint` to provide hill point reference during a flyby, and a related :ref:`scenarioFlybyPoint`.
- Added custom planet name to :ref:`eclipse` in case the user wants to use a body not contained within the module.
- Removed all instances of using ``unitTestSupport.np2EigenVectorXd()``, as this function is now unneeded.
- Created a :ref:`facetSRPDynamicEffector` dynamics module to calculate the B frame SRP force and torque acting on a
Expand Down Expand Up @@ -103,8 +106,7 @@ Version 2.2.0 (June 28, 2023)
- Reworked how integrators are implemented. New Runge-Kutta integrators may
now be added simply by specifying the relevant coefficients.
- Added a scenario that showcases differences between integrators. See :ref:`scenarioIntegratorsComparison`
- Created :ref:`thrusterPlatformState` to map the thruster configuration information to body frame given the
time-varying platform states.


Version 2.1.7 (March 24, 2023)
------------------------------
Expand Down
155 changes: 155 additions & 0 deletions examples/BskSim/BSK_SEPMasters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
#
# ISC License
#
# Copyright (c) 2016, Autonomous Vehicle Systems Lab, University of Colorado at Boulder
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#

# Import architectural modules
from Basilisk.utilities import SimulationBaseClass, macros as mc

from Basilisk import __path__
from Basilisk.fswAlgorithms import formationBarycenter

# Get current file path
import sys, os, inspect

filename = inspect.getframeinfo(inspect.currentframe()).filename
path = os.path.dirname(os.path.abspath(filename))
bskPath = __path__[0]

# Import Dynamics and FSW models
sys.path.append(path + '/models')


class BSKSim(SimulationBaseClass.SimBaseClass):
"""
Main bskSim simulation class

Args:
numberSpacecraft (int): number of spacecraft
relativeNavigation (bool): whether the chief is the barycenter of the spacecraft formation
fswRate (float): [s] FSW update rate
dynRate (float): [s] dynamics update rate
envRate (float): [s] environment update rate
relNavRate (float): [s] relative navigation update rate

"""

def __init__(self, numberSpacecraft, relativeNavigation=False, fswRate=0.1, platRefRate=0.1, dynRate=0.1, envRate=0.1, relNavRate=0.1):
self.dynRate = dynRate
self.fswRate = fswRate
self.platRefRate = platRefRate
self.envRate = envRate
self.relNavRate = relNavRate
self.numberSpacecraft = numberSpacecraft

# Create a sim module as an empty container
SimulationBaseClass.SimBaseClass.__init__(self)
self.SetProgressBar(True)

self.EnvModel = []
self.DynModels = []
self.FSWModels = []
self.EnvProcessName = None
self.DynamicsProcessName = []
self.FSWProcessName = []
self.envProc = None
self.dynProc = []
self.fswProc = []

self.environment_added = False
self.dynamics_added = False
self.fsw_added = False

# Set the formationBarycenter module if the flag is set to True
if relativeNavigation:
self.relNavProc = None
self.relativeNavigationModule = None
self.relativeNavigationTaskName = None
self.add_relativeNavigation()

def get_EnvModel(self):
assert (self.environment_added is True), "It is mandatory to use an environment model as an argument"
return self.EnvModel

def set_EnvModel(self, envModel):
self.environment_added = True
self.EnvProcessName = "EnvironmentProcess"
self.envProc = self.CreateNewProcess(self.EnvProcessName, 300)

# Add the environment class
self.EnvModel = envModel.BSKEnvironmentModel(self, self.envRate)

def get_DynModel(self):
assert (self.dynamics_added is True), "It is mandatory to use a dynamics model as an argument"
return self.DynModels

def set_DynModel(self, dynModel):
self.dynamics_added = True

# Add the dynamics classes
for spacecraftIndex in range(self.numberSpacecraft):
self.DynamicsProcessName.append("DynamicsProcess" + str(spacecraftIndex)) # Create simulation process name
self.dynProc.append(self.CreateNewProcess(self.DynamicsProcessName[spacecraftIndex], 200)) # Create process
self.DynModels.append(dynModel[spacecraftIndex].BSKDynamicModels(self, self.dynRate, spacecraftIndex))

def get_FswModel(self):
assert (self.fsw_added is True), "A flight software model has not been added yet"
return self.FSWModels

def set_FswModel(self, fswModel):
self.fsw_added = True

# Add the FSW classes
for spacecraftIndex in range(self.numberSpacecraft):
self.FSWProcessName.append("FSWProcess" + str(spacecraftIndex)) # Create simulation process name
self.fswProc.append(self.CreateNewProcess(self.FSWProcessName[spacecraftIndex], 100)) # Create process
self.FSWModels.append(fswModel[spacecraftIndex].BSKFswModels(self, self.fswRate, self.platRefRate, spacecraftIndex))

def add_relativeNavigation(self):
processName = "RelativeNavigation"
processTasksTimeStep = mc.sec2nano(self.relNavRate)
self.relativeNavigationTaskName = "relativeNavigationTask"

# Create an independt process for barycenter calculation
self.relNavProc = self.CreateNewProcess(processName, 150)
self.relNavProc.addTask(self.CreateNewTask(self.relativeNavigationTaskName, processTasksTimeStep), 20)

# Add the formationBarycenter module
self.relativeNavigationModule = formationBarycenter.FormationBarycenter()
self.relativeNavigationModule.ModelTag = "RelativeNavigation"
self.AddModelToTask(self.relativeNavigationTaskName, self.relativeNavigationModule, None, 0)

class BSKScenario(object):
def __init__(self):
self.name = "scenario"

def configure_initial_conditions(self):
"""
Developer must override this method in their BSK_Scenario derived subclass.
"""
pass

def log_outputs(self):
"""
Developer must override this method in their BSK_Scenario derived subclass.
"""
pass

def pull_outputs(self, showPlots, spacecraftIndex):
"""
Developer must override this method in their BSK_Scenario derived subclass.
"""
pass
98 changes: 98 additions & 0 deletions examples/BskSim/models/BSK_EnvironmentEarth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#
# ISC License
#
# Copyright (c) 2022, Autonomous Vehicle Systems Lab, University of Colorado at Boulder
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#

import numpy as np

from Basilisk.utilities import macros as mc, simIncludeGravBody
from Basilisk.simulation import ephemerisConverter, groundLocation, eclipse
from Basilisk.topLevelModules import pyswice

from Basilisk import __path__

bskPath = __path__[0]


class BSKEnvironmentModel:
"""Defines the Earth Environment."""
def __init__(self, SimBase, envRate):
# Define empty class variables
self.mu = None
self.planetRadius = None
self.sun = None
self.earth = None

# Define process name, task name and task time-step
self.envTaskName = "EnvironmentTask"
processTasksTimeStep = mc.sec2nano(envRate)

# Create task
SimBase.envProc.addTask(SimBase.CreateNewTask(self.envTaskName, processTasksTimeStep))

# Instantiate Env modules as objects
self.gravFactory = simIncludeGravBody.gravBodyFactory()
self.ephemObject = ephemerisConverter.EphemerisConverter()

# Initialize all modules and write init one-time messages
self.InitAllEnvObjects()

# Add modules to environment task
SimBase.AddModelToTask(self.envTaskName, self.gravFactory.spiceObject, None, 200)
SimBase.AddModelToTask(self.envTaskName, self.ephemObject, None, 200)

# ------------------------------------------------------------------------------------------- #
# These are module-initialization methods

def SetGravityBodies(self):
"""
Specify what gravitational bodies to include in the simulation.
"""
# Create gravity bodies
gravBodies = self.gravFactory.createBodies(['sun', 'earth'])
gravBodies['sun'].isCentralBody = True
self.mu = self.gravFactory.gravBodies['sun'].mu
self.planetRadius = self.gravFactory.gravBodies['sun'].radEquator
self.sun = 0
self.earth = 1

# Override information with SPICE
timeInitString = "2021 MAY 04 07:47:48.965 (UTC)"
self.gravFactory.createSpiceInterface(bskPath + '/supportData/EphemerisData/',
timeInitString,
epochInMsg=True)
self.gravFactory.spiceObject.zeroBase = 'Earth'

# Add pyswice instances
pyswice.furnsh_c(self.gravFactory.spiceObject.SPICEDataPath + 'de430.bsp') # solar system bodies
pyswice.furnsh_c(self.gravFactory.spiceObject.SPICEDataPath + 'naif0012.tls') # leap second file
pyswice.furnsh_c(self.gravFactory.spiceObject.SPICEDataPath + 'de-403-masses.tpc') # solar system masses
pyswice.furnsh_c(self.gravFactory.spiceObject.SPICEDataPath + 'pck00010.tpc') # generic Planetary Constants

def SetEpochObject(self):
"""
Add the ephemeris object to use with the SPICE library.
"""

# self.epochMsg = self.gravFactory.epochMsg
self.ephemObject.ModelTag = 'EphemData'
self.ephemObject.addSpiceInputMsg(self.gravFactory.spiceObject.planetStateOutMsgs[self.sun])
self.ephemObject.addSpiceInputMsg(self.gravFactory.spiceObject.planetStateOutMsgs[self.earth])

# Global call to initialize every module
def InitAllEnvObjects(self):
self.SetGravityBodies()
self.SetEpochObject()
Loading
Loading