Skip to content

Commit dbdd1b5

Browse files
committed
[#1332] Add module rst documentation
1 parent d486ee8 commit dbdd1b5

1 file changed

Lines changed: 198 additions & 0 deletions

File tree

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
Executive Summary
2+
-----------------
3+
The faceted spacecraft solar radiation pressure (SRP) module computes the aggregate force and torque acting on the
4+
spacecraft due to impinging photons from the Sun. The inertial Sun state information must be subscribed
5+
to the module ``SpicePlanetStateMsgPayload`` input message. The module assumes the spacecraft is modeled as a
6+
collection of facets, where the facet geometry information is passed as a vector of ``FacetElementBodyMsgPayload``
7+
input messages to the module. The facet geometry information is required to be provided in the spacecraft body frame.
8+
This SRP module does not make any assumptions regarding whether the facets are rigid or articulate.
9+
The ``facetedSpacecraftModel`` module can be connected upstream and used to transform the facet geometry data from the
10+
facet frames to the spacecraft body frame. This upstream module can also be used to configure articulating facets.
11+
Finally, this SRP module also requires the sunlit area of all facets to be pre-computed and connected to the module
12+
vector of ``ProjectedAreaMsgPayload`` input messages. This information can be passed to the SRP module by connecting
13+
the facet geometry information to the ``facetedSpacecraftProjectedArea`` module upstream.
14+
15+
.. important::
16+
The total number of facets must be set using ``setNumFacets()`` before connecting the facet input message vectors.
17+
18+
.. important::
19+
All facet geometry and projected area input message vectors must have lengths equal to ``numFacets``.
20+
21+
22+
Message Connection Descriptions
23+
-------------------------------
24+
The following table lists all module input messages.
25+
The module msg connections are set by the user from Python.
26+
The msg type contains a link to the message structure definition, while the description
27+
provides information on what each message is used for.
28+
29+
.. list-table:: Module I/O Messages
30+
:widths: 30 25 45
31+
:header-rows: 1
32+
33+
* - Msg Variable Name
34+
- Msg Type
35+
- Description
36+
* - sunStateInMsg
37+
- :ref:`SpicePlanetStateMsgPayload`
38+
- Input message containing the Sun inertial state
39+
* - facetElementBodyInMsgs
40+
- :ref:`FacetElementBodyMsgPayload`
41+
- Input message vector containing facet element data expressed in body-frame components
42+
* - facetProjectedAreaInMsgs
43+
- :ref:`ProjectedAreaMsgPayload`
44+
- Input message vector containing pre-computed per-facet projected areas
45+
46+
47+
Module Functions
48+
----------------
49+
Below is a list of functions this simulation module performs:
50+
51+
- Reads the Sun inertial position and computes the Sun direction vector in spacecraft body-frame components
52+
- Reads facet body-frame geometry and optical coefficients for each facet
53+
- Reads per-facet projected areas for each facet
54+
- Computes SRP pressure scaled by spacecraft heliocentric distance
55+
- Computes and sums per-facet SRP force and torque contributions
56+
- Writes total SRP force and torque to the dynamic effector base-class outputs ``forceExternal_B`` and ``torqueExternalPntB_B``
57+
58+
59+
Module Assumptions and Limitations
60+
----------------------------------
61+
- The user must call ``setNumFacets()`` before connecting message vectors
62+
- This module assumes facet normals and center-of-pressure vectors are already expressed in the spacecraft body frame
63+
- This module expects projected areas to be provided externally; it does not compute projected area internally
64+
- This module does not read articulation-angle messages directly
65+
- Facets with non-positive projected area contribute zero SRP force and torque
66+
67+
68+
Test Description and Success Criteria
69+
-------------------------------------
70+
The unit test for this module is located in :ref:`test_facetedSRPEffector`. The test verifies that the module
71+
correctly computes the aggregate SRP force and torque acting on the spacecraft due to impinging photons
72+
from the Sun. The test sets up a simulation with a faceted spacecraft modeled as a cubic hub with two attached
73+
circular solar arrays. Six square facets represent the cubic hub and four circular facets represent the two solar
74+
arrays. The test varies the initial state information of both the spacecraft and the Sun. Specifically, the test
75+
parameterizes:
76+
77+
- Spacecraft initial inertial position
78+
- Sun inertial position
79+
- Spacecraft initial attitude
80+
- Spacecraft initial angular velocity
81+
82+
The test checks that the computed SRP forces and torques at each timestep match the values output from the module.
83+
84+
User Guide
85+
----------
86+
The following steps are required to set up the ``facetedSRPEffector`` module in Python.
87+
88+
.. note::
89+
A common setup is to connect ``facetedSpacecraftModel`` upstream to provide body-frame facet geometry and connect
90+
``facetedSpacecraftProjectedArea`` upstream to provide per-facet projected areas.
91+
92+
#. Import the required BSK modules::
93+
94+
from Basilisk.simulation import facetedSRPEffector
95+
from Basilisk.simulation import facetedSpacecraftProjectedArea
96+
from Basilisk.simulation import spacecraft
97+
98+
#. Create the spacecraft object and set its initial states::
99+
100+
sc_object = spacecraft.Spacecraft()
101+
sc_object.ModelTag = "scObject"
102+
sc_object.hub.mHub = 750.0 # [kg]
103+
sc_object.hub.r_BcB_B = [[0.0], [0.0], [1.0]] # [m]
104+
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]
105+
sc_object.hub.r_CN_NInit = [[-4020338.690396649], [7490566.741852513], [5248299.211589362]] # [m]
106+
sc_object.hub.v_CN_NInit = [[-5199.77710904224], [-3436.681645356935], [1041.576797498721]] # [m/s]
107+
sc_object.hub.sigma_BNInit = [0.0, 0.0, 0.0] # [-]
108+
sc_object.hub.omega_BN_BInit = [0.0, 0.0, 0.0] # [rad/s]
109+
110+
#. Create the SRP module and set the number of facets::
111+
112+
faceted_srp_effector = facetedSRPEffector.FacetedSRPEffector()
113+
faceted_srp_effector.ModelTag = "facetedSRPEffector"
114+
faceted_srp_effector.setNumFacets(2)
115+
116+
#. Create the sun and connect the Sun inertial state message::
117+
118+
sun_state_message_data = messaging.SpicePlanetStateMsgPayload()
119+
sun_state_message_data.PositionVector = [0.0, 0.0, 0.0] # [m]
120+
sun_state_message_data.VelocityVector = [0.0, 0.0, 0.0] # [m/s]
121+
sun_state_message = messaging.SpicePlanetStateMsg().write(sun_state_message_data)
122+
123+
grav_factory = simIncludeGravBody.gravBodyFactory()
124+
sun = grav_factory.createSun()
125+
sun.isCentralBody = True
126+
grav_factory.gravBodies['sun'].planetBodyInMsg.subscribeTo(sun_state_message)
127+
faceted_srp_effector.sunStateInMsg.subscribeTo(sun_state_message)
128+
129+
#. Create a :ref:`FacetElementBodyMsgPayload` facet geometry input message for each facet::
130+
131+
facet_area_list = [0.5, 1.0] # [m^2]
132+
facet_r_CopB_B_list = [np.array([-0.1, 0.1, -0.1]),
133+
np.array([0.1, -0.1, -0.1])] # [m]
134+
facet_nHat_B_list = [np.array([1.0, 0.0, 0.0]),
135+
np.array([0.0, 1.0, 0.0])]
136+
facet_rotHat_B_list = [np.array([0.0, 1.0, 0.0]),
137+
np.array([1.0, 0.0, 0.0])]
138+
facet_diffuse_coeff_list = [0.1, 0.1]
139+
facet_specular_coeff_list = [0.9, 0.9]
140+
141+
facet_1_message_data = messaging.FacetElementBodyMsgPayload(
142+
area = facet_area_list[0],
143+
r_CopB_B = facet_r_CopB_B_list[0],
144+
nHat_B = facet_nHat_B_list[0],
145+
rotHat_B = facet_rotHat_B_list[0],
146+
c_diffuse = facet_diffuse_coeff_list[0],
147+
c_specular = facet_specular_coeff_list[0],
148+
)
149+
facet_2_message_data = messaging.FacetElementBodyMsgPayload(
150+
area = facet_area_list[1],
151+
r_CopB_B = facet_r_CopB_B_list[1],
152+
nHat_B = facet_nHat_B_list[1],
153+
rotHat_B = facet_rotHat_B_list[1],
154+
c_diffuse = facet_diffuse_coeff_list[1],
155+
c_specular = facet_specular_coeff_list[1],
156+
)
157+
facet_1_message = messaging.FacetElementBodyMsg().write(facet_1_message_data)
158+
facet_2_message = messaging.FacetElementBodyMsg().write(facet_2_message_data)
159+
160+
#. Subscribe the facet geometry input messages to the SRP module ``facetElementBodyInMsgs`` input message vector::
161+
162+
faceted_srp_effector.facetElementBodyInMsgs[0].subscribeTo(facet_1_message)
163+
faceted_srp_effector.facetElementBodyInMsgs[1].subscribeTo(facet_2_message)
164+
165+
#. Create the faceted spacecraft projected area module and set the total number of facets::
166+
167+
faceted_sc_projected_area = facetedSpacecraftProjectedArea.FacetedSpacecraftProjectedArea()
168+
faceted_sc_projected_area.ModelTag = "facetedSpacecraftProjectedArea"
169+
faceted_sc_projected_area.setNumFacets(2)
170+
171+
#. Subscribe the facet geometry input messages to the projected area module ``facetElementBodyInMsgs`` input message vector::
172+
173+
faceted_sc_projected_area.facetElementBodyInMsgs[0].subscribeTo(facet_1_message)
174+
faceted_sc_projected_area.facetElementBodyInMsgs[1].subscribeTo(facet_2_message)
175+
176+
#. Subscribe the projected area module ``facetProjectedAreaOutMsgs`` output message vector to the SRP module ``facetProjectedAreaInMsgs`` input message vector::
177+
178+
faceted_srp_effector.facetProjectedAreaInMsgs[0].subscribeTo(faceted_sc_projected_area.facetProjectedAreaOutMsgs[0])
179+
faceted_srp_effector.facetProjectedAreaInMsgs[1].subscribeTo(faceted_sc_projected_area.facetProjectedAreaOutMsgs[1])
180+
181+
#. Subscribe other required messages to the projected area module::
182+
183+
faceted_sc_projected_area.sunStateInMsg.subscribeTo(sun_state_message)
184+
faceted_sc_projected_area.spacecraftStateInMsg.subscribeTo(sc_object.scStateOutMsg)
185+
186+
#. Add the SRP effector to the spacecraft::
187+
188+
sc_object.addDynamicEffector(faceted_srp_effector)
189+
190+
#. Add each module to a task::
191+
192+
test_sim.AddModelToTask(task_name, faceted_sc_projected_area)
193+
test_sim.AddModelToTask(task_name, sc_object)
194+
test_sim.AddModelToTask(task_name, faceted_srp_effector)
195+
196+
.. note::
197+
Add the spacecraft object to the task after the projected area module to ensure the SRP effector has valid input
198+
message data at the first integration timestep.

0 commit comments

Comments
 (0)