C++ Module: facetedSRPEffector
Executive Summary
The faceted spacecraft solar radiation pressure (SRP) module computes the aggregate force and torque acting on the spacecraft due to impinging photons from the Sun. The inertial Sun state information must be subscribed to the module SpicePlanetStateMsgPayload input message. The module assumes the spacecraft is modeled as a collection of facets, where the facet geometry information is passed as a vector of FacetElementBodyMsgPayload input messages to the module. The facet geometry information is required to be provided in the spacecraft body frame. This SRP module does not make any assumptions regarding whether the facets are rigid or articulate. The C++ Module: facetedSpacecraftModel module can be connected upstream and used to transform the facet geometry data from the facet frames to the spacecraft body frame. This upstream module can also be used to configure articulating facets. Finally, this SRP module also requires the sunlit area of all facets to be pre-computed and connected to the module vector of ProjectedAreaMsgPayload input messages. This information can be passed to the SRP module by connecting the facet geometry information to the C++ Module: facetedSpacecraftProjectedArea module upstream.
Important
The total number of facets must be set using setNumFacets() before connecting the facet input message vectors.
Important
All facet geometry and projected area input message vectors must have lengths equal to numFacets.
Note
Unlike the C++ Module: facetSRPDynamicEffector module, this module does not internally compute the facet projected areas or manipulate facet information. The facets are general in this module. Articulating facets can be configured upstream using the C++ Module: facetedSpacecraftModel module. The C++ Module: facetSRPDynamicEffector module can be used to quickly set up a simulation where all facet information is computed internally.
Message Connection Descriptions
The following table lists all module input messages. The module msg connections are set by the user from Python. The msg type contains a link to the message structure definition, while the description provides information on what each message is used for.
Msg Variable Name |
Msg Type |
Description |
|---|---|---|
sunStateInMsg |
Input message containing the Sun inertial state. |
|
facetElementBodyInMsgs |
Input message vector containing facet element data expressed in body-frame components. |
|
facetProjectedAreaInMsgs |
Input message vector containing pre-computed per-facet projected areas. |
|
sunEclipseInMsg |
(Optional) Input msg for the Sun eclipse data. If connected, the SRP force and torque are scaled by the illumination factor (0 = full shadow, 1 = full sunlight). |
Module Functions
Below is a list of functions this simulation module performs:
Reads the Sun inertial position and computes the Sun direction vector in spacecraft body-frame components
Reads facet body-frame geometry and optical coefficients for each facet
Reads per-facet projected areas for each facet
Computes SRP pressure scaled by spacecraft heliocentric distance
Computes and sums per-facet SRP force and torque contributions
Writes total SRP force and torque to the dynamic effector base-class outputs
forceExternal_BandtorqueExternalPntB_B
Module Assumptions and Limitations
The user must call
setNumFacets()before connecting message vectorsThis module assumes facet normals and center-of-pressure vectors are already expressed in the spacecraft body frame
This module expects projected areas to be provided externally; it does not compute projected area internally
This module does not read articulation-angle messages directly
Facets with non-positive projected area contribute zero SRP force and torque
Test Description and Success Criteria
The unit test for this module is located in test_facetedSRPEffector. The test verifies that the module correctly computes the aggregate SRP force and torque acting on the spacecraft due to impinging photons from the Sun. The test sets up a simulation with a faceted spacecraft modeled as a cubic hub with two attached circular solar arrays. Six square facets represent the cubic hub and four circular facets represent the two solar arrays. The test varies the initial state information of the spacecraft, the initial state information of the Sun, and the Sun illumination factor. Specifically, the test parameterizes:
Spacecraft initial inertial position
Sun inertial position
Spacecraft initial attitude
Spacecraft initial angular velocity
Sun visibility (illumination) factor
The test checks that the computed SRP forces and torques at each timestep match the values output from the module.
User Guide
The following steps are required to set up the facetedSRPEffector module in Python.
Note
A common setup is to connect facetedSpacecraftModel upstream to provide body-frame facet geometry and connect
facetedSpacecraftProjectedArea upstream to provide per-facet projected areas.
Import the required BSK modules:
import numpy as np from Basilisk.utilities import SimulationBaseClass from Basilisk.utilities import simIncludeGravBody from Basilisk.simulation import facetedSpacecraftProjectedArea from Basilisk.simulation import facetedSRPEffector from Basilisk.simulation import spacecraft from Basilisk.architecture import messaging
Create the spacecraft object and set its initial states:
sc_object = spacecraft.Spacecraft() sc_object.ModelTag = "scObject" sc_object.hub.mHub = 750.0 # [kg] sc_object.hub.r_BcB_B = [[0.0], [0.0], [1.0]] # [m] sc_object.hub.IHubPntBc_B = [[900.0, 0.0, 0.0], [0.0, 800.0, 0.0], [0.0, 0.0, 600.0]] # [kg m^2] sc_object.hub.r_CN_NInit = [[-4020338.690396649], [7490566.741852513], [5248299.211589362]] # [m] sc_object.hub.v_CN_NInit = [[-5199.77710904224], [-3436.681645356935], [1041.576797498721]] # [m/s] sc_object.hub.sigma_BNInit = [0.0, 0.0, 0.0] # [-] sc_object.hub.omega_BN_BInit = [0.0, 0.0, 0.0] # [rad/s]
Create the SRP module and set the number of facets:
faceted_srp_effector = facetedSRPEffector.FacetedSRPEffector() faceted_srp_effector.ModelTag = "facetedSRPEffector" faceted_srp_effector.setNumFacets(2)
Create the sun and connect the Sun inertial state message:
sun_state_message_data = messaging.SpicePlanetStateMsgPayload() sun_state_message_data.PositionVector = [0.0, 0.0, 0.0] # [m] sun_state_message_data.VelocityVector = [0.0, 0.0, 0.0] # [m/s] sun_state_message = messaging.SpicePlanetStateMsg().write(sun_state_message_data) grav_factory = simIncludeGravBody.gravBodyFactory() sun = grav_factory.createSun() sun.isCentralBody = True grav_factory.gravBodies['sun'].planetBodyInMsg.subscribeTo(sun_state_message) faceted_srp_effector.sunStateInMsg.subscribeTo(sun_state_message)
Create a FacetElementBodyMsgPayload facet geometry input message for each facet:
facet_area_list = [0.5, 1.0] # [m^2] facet_r_CopB_B_list = [np.array([-0.1, 0.1, -0.1]), np.array([0.1, -0.1, -0.1])] # [m] facet_nHat_B_list = [np.array([1.0, 0.0, 0.0]), np.array([0.0, 1.0, 0.0])] facet_rotHat_B_list = [np.array([0.0, 1.0, 0.0]), np.array([1.0, 0.0, 0.0])] facet_diffuse_coeff_list = [0.1, 0.1] facet_specular_coeff_list = [0.9, 0.9] facet_1_message_data = messaging.FacetElementBodyMsgPayload( area = facet_area_list[0], r_CopB_B = facet_r_CopB_B_list[0], nHat_B = facet_nHat_B_list[0], rotHat_B = facet_rotHat_B_list[0], c_diffuse = facet_diffuse_coeff_list[0], c_specular = facet_specular_coeff_list[0], ) facet_2_message_data = messaging.FacetElementBodyMsgPayload( area = facet_area_list[1], r_CopB_B = facet_r_CopB_B_list[1], nHat_B = facet_nHat_B_list[1], rotHat_B = facet_rotHat_B_list[1], c_diffuse = facet_diffuse_coeff_list[1], c_specular = facet_specular_coeff_list[1], ) facet_1_message = messaging.FacetElementBodyMsg().write(facet_1_message_data) facet_2_message = messaging.FacetElementBodyMsg().write(facet_2_message_data)
Subscribe the facet geometry input messages to the SRP module
facetElementBodyInMsgsinput message vector:faceted_srp_effector.facetElementBodyInMsgs[0].subscribeTo(facet_1_message) faceted_srp_effector.facetElementBodyInMsgs[1].subscribeTo(facet_2_message)
Create the faceted spacecraft projected area module and set the total number of facets:
faceted_sc_projected_area = facetedSpacecraftProjectedArea.FacetedSpacecraftProjectedArea() faceted_sc_projected_area.ModelTag = "facetedSpacecraftProjectedArea" faceted_sc_projected_area.setNumFacets(2)
Subscribe the facet geometry input messages to the projected area module
facetElementBodyInMsgsinput message vector:faceted_sc_projected_area.facetElementBodyInMsgs[0].subscribeTo(facet_1_message) faceted_sc_projected_area.facetElementBodyInMsgs[1].subscribeTo(facet_2_message)
Subscribe the projected area module
facetProjectedAreaOutMsgsoutput message vector to the SRP modulefacetProjectedAreaInMsgsinput message vector:faceted_srp_effector.facetProjectedAreaInMsgs[0].subscribeTo(faceted_sc_projected_area.facetProjectedAreaOutMsgs[0]) faceted_srp_effector.facetProjectedAreaInMsgs[1].subscribeTo(faceted_sc_projected_area.facetProjectedAreaOutMsgs[1])
Subscribe other required messages to the projected area module:
faceted_sc_projected_area.sunStateInMsg.subscribeTo(sun_state_message) faceted_sc_projected_area.spacecraftStateInMsg.subscribeTo(sc_object.scStateOutMsg)
Optionally, connect an eclipse message to account for shadow conditions. If connected, the computed SRP force and torque are scaled by the illumination factor (0.0 = full shadow, 1.0 = full sunlight):
faceted_srp_effector.sunEclipseInMsg.subscribeTo(eclipse_msg)
Add the SRP effector to the spacecraft:
sc_object.addDynamicEffector(faceted_srp_effector)
Add each module to a task:
test_sim.AddModelToTask(task_name, faceted_sc_projected_area) test_sim.AddModelToTask(task_name, sc_object) test_sim.AddModelToTask(task_name, faceted_srp_effector)
Note
Add the spacecraft object to the task after the projected area module to ensure the SRP effector has valid input message data at the first integration timestep.
-
class FacetedSRPEffector : public SysModel, public DynamicEffector
- #include <facetedSRPEffector.h>
Faceted solar radiation pressure dynamic effector.
Public Functions
-
FacetedSRPEffector() = default
Constructor.
-
~FacetedSRPEffector() = default
Destructor.
-
void linkInStates(DynParamManager &states) override
Method for giving the effector access to the hub states.
This method gives the module access to the hub inertial attitude and position.
- Parameters:
states – Dynamic parameter states
-
void computeForceTorque(double callTime, double timeStep) override
Method for computing the total SRP force and torque about point B.
This method computes the srp force and torque acting about the hub point B in B frame components.
- Parameters:
callTime – [s] Time the method is called
timeStep – [s] Simulation time step
-
void Reset(uint64_t currentSimNanos) override
Reset method.
This method resets required module variables and checks the input messages to ensure they are linked.
- Parameters:
currentSimNanos – [ns] Time the method is called
-
void setNumFacets(const uint64_t numFacets)
Setter method for total number of spacecraft facets.
Setter method for the total number of spacecraft facets.
- Parameters:
numFacets – [-]
-
const uint64_t getNumFacets() const
Getter method for total number of spacecraft facets.
Getter method for the total number of spacecraft facets.
- Returns:
const uint64_t
Public Members
-
std::vector<ReadFunctor<FacetElementBodyMsgPayload>> facetElementBodyInMsgs
List of facet geometry input data (Expressed in hub B frame).
-
std::vector<ReadFunctor<ProjectedAreaMsgPayload>> facetProjectedAreaInMsgs
List of facet projected area input messages.
-
ReadFunctor<SpicePlanetStateMsgPayload> sunStateInMsg
Sun spice ephemeris input message.
-
ReadFunctor<EclipseMsgPayload> sunEclipseInMsg
(optional) Sun eclipse input message
Private Members
-
std::vector<double> facetAreaList
[m^2] List of facet areas
-
std::vector<double> facetProjectedAreaList
[m^2] List of facet projected areas
-
std::vector<Eigen::Vector3d> facetR_CopB_BList
[m] List of facet center of pressure locations wrt point B expressed in B frame components
-
std::vector<Eigen::Vector3d> facetNHat_BList
[-] List of facet normal vectors expressed in hub B frame components
-
std::vector<double> facetDiffuseCoeffList
[-] List of facet diffuse reflection optical coefficient list
-
std::vector<double> facetSpecularCoeffList
[-] List of facet specular reflection optical coefficient list
-
uint64_t numFacets = {}
Number of spacecraft facets.
-
double sunVisibilityFactor = 1.0
Sun visibility factor (0 = full shadow, 1 = full sunlight).
-
FacetedSRPEffector() = default