#
# 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.
#
"""
Overview
--------
This script sets up a 6-DOF spacecraft on a hyperbolic trajectory. The goal of this tutorial is to demonstrate how to
configure a velocity pointing FSW in the new BSK_Sim architecture.
The script is found in the folder ``basilisk/examples/BskSim/scenarios`` and executed by using::
python3 scenario_AttGuidHyperbolic.py
The simulation mimics the basic simulation simulation in the earlier tutorial in
:ref:`scenarioAttGuideHyperbolic`.
The simulation layout is shown in the following illustration.
.. image:: /_images/static/test_scenario_AttGuidHyperbolic.svg
:align: center
Custom Dynamics Configurations Instructions
-------------------------------------------
The modules required for this scenario are identical to those used in :ref:`scenario_AttGuidance`.
Custom FSW Configurations Instructions
--------------------------------------
The only new module required to configure the "velocityPoint" FSW mode is ``velocityPoint`` itself.
Unlike hill pointing, this module provides a pointing model relative to the velocity vector.
The advantage of the BSK_Sim architecture becomes apparent here. All modules and setup required for the MRP Feedback task
were already defined from an earlier scenario. The user simply adds the preconfigured task to the event without
having to manually reconfigure the messages. Now there is an additional FSW mode available for all current and
future :ref:`Folder_BskSim` files.
Illustration of Simulation Results
----------------------------------
::
showPlots = True
.. image:: /_images/Scenarios/scenario_AttGuidHyperbolic_attitudeErrorNorm.svg
:align: center
.. image:: /_images/Scenarios/scenario_AttGuidHyperbolic_rwMotorTorque.svg
:align: center
.. image:: /_images/Scenarios/scenario_AttGuidHyperbolic_rateError.svg
:align: center
.. image:: /_images/Scenarios/scenario_AttGuidHyperbolic_orbit.svg
:align: center
"""
# Get current file path
import inspect
import os
import sys
import numpy as np
# Import utilities
from Basilisk.utilities import orbitalMotion, macros, vizSupport
filename = inspect.getframeinfo(inspect.currentframe()).filename
path = os.path.dirname(os.path.abspath(filename))
# Import master classes: simulation base class and scenario base class
sys.path.append(path + '/..')
from BSK_masters import BSKSim, BSKScenario
# Import plotting files for your scenario
sys.path.append(path + '/../plotting')
import BSK_Plotting as BSK_plt
import BSK_Dynamics, BSK_Fsw
sys.path.append(path + '/../../')
import scenarioAttGuideHyperbolic as scene_plt
# Create your own scenario child class
[docs]
class scenario_VelocityPointing(BSKSim, BSKScenario):
def __init__(self):
super(scenario_VelocityPointing, self).__init__()
self.name = 'scenario_VelocityPointing'
self.attNavRec = None
self.transNavRec = None
self.attErrRec = None
self.LrRec = None
self.set_DynModel(BSK_Dynamics)
self.set_FswModel(BSK_Fsw)
self.configure_initial_conditions()
self.log_outputs()
# if this scenario is to interface with the BSK Viz, uncomment the following line
DynModels = self.get_DynModel()
vizSupport.enableUnityVisualization(self, DynModels.taskName, DynModels.scObject
# , saveFile=__file__
, rwEffectorList=DynModels.rwStateEffector
)
[docs]
def log_outputs(self):
# Dynamics process outputs
samplingTime = self.get_FswModel().processTasksTimeStep
self.attNavRec = self.get_DynModel().simpleNavObject.attOutMsg.recorder(samplingTime)
self.transNavRec = self.get_DynModel().simpleNavObject.transOutMsg.recorder(samplingTime)
# FSW process outputs
self.attErrRec = self.get_FswModel().attGuidMsg.recorder(samplingTime)
self.LrRec = self.get_FswModel().cmdTorqueMsg.recorder(samplingTime)
self.AddModelToTask(self.get_DynModel().taskName, self.attNavRec)
self.AddModelToTask(self.get_DynModel().taskName, self.transNavRec)
self.AddModelToTask(self.get_DynModel().taskName, self.attErrRec)
self.AddModelToTask(self.get_DynModel().taskName, self.LrRec)
[docs]
def pull_outputs(self, showPlots):
# Dynamics process outputs
r_BN_N = np.delete(self.transNavRec.r_BN_N, 0, 0)
v_BN_N = np.delete(self.transNavRec.v_BN_N, 0, 0)
# FSW process outputs
sigma_BR = np.delete(self.attErrRec.sigma_BR, 0, 0)
omega_BR_B = np.delete(self.attErrRec.omega_BR_B, 0, 0)
Lr = np.delete(self.LrRec.torqueRequestBody, 0, 0)
# Plot results
BSK_plt.clear_all_plots()
timeLineSet = np.delete(self.transNavRec.times(), 0, 0) * macros.NANO2MIN
scene_plt.plot_track_error_norm(timeLineSet, sigma_BR)
scene_plt.plot_control_torque(timeLineSet, Lr)
scene_plt.plot_rate_error(timeLineSet, omega_BR_B)
scene_plt.plot_orbit(self.oe,
self.get_DynModel().gravFactory.gravBodies['earth'].mu,
self.get_DynModel().gravFactory.gravBodies['earth'].radEquator,
r_BN_N, v_BN_N)
figureList = {}
if showPlots:
BSK_plt.show_all_plots()
else:
fileName = os.path.basename(os.path.splitext(__file__)[0])
figureNames = ["attitudeErrorNorm", "rwMotorTorque", "rateError", "orbit"]
figureList = BSK_plt.save_all_plots(fileName, figureNames)
return figureList
def runScenario(TheScenario):
# Initialize simulation
TheScenario.InitializeSimulation()
# Configure FSW mode
TheScenario.modeRequest = 'velocityPoint'
# Configure run time and execute simulation
simulationTime = macros.min2nano(10.)
TheScenario.ConfigureStopTime(simulationTime)
TheScenario.ExecuteSimulation()
[docs]
def run(showPlots):
"""
The scenarios can be run with the followings setups parameters:
Args:
showPlots (bool): Determines if the script should display plots
"""
# Instantiate base simulation
# Configure a scenario in the base simulation
TheScenario = scenario_VelocityPointing()
runScenario(TheScenario)
figureList = TheScenario.pull_outputs(showPlots)
return figureList
if __name__ == "__main__":
run(True)