diff --git a/examples/BskSim/scenarios/scenario_AttEclipse.py b/examples/BskSim/scenarios/scenario_AttEclipse.py index 9f24947d24..106c93e663 100755 --- a/examples/BskSim/scenarios/scenario_AttEclipse.py +++ b/examples/BskSim/scenarios/scenario_AttEclipse.py @@ -98,7 +98,7 @@ This plot illustrates the shadow fraction calculated by the CSS as the spacecraft orbits Earth and passes through the Earth's shadow. 0.0 corresponds with total eclipse and 1.0 corresponds with direct sunlight. -.. image:: /_images/Scenarios/scenario_AttEclipse_shadowFraction.svg +.. image:: /_images/Scenarios/scenario_AttEclipse_illuminationFraction.svg :align: center The :ref:`CSSWlsEst` module calculates the position of the sun based on input from the CSS. @@ -217,7 +217,7 @@ def pull_outputs(self, showPlots): num_RW = 4 # number of wheels used in the scenario # Dynamics process outputs: pull log messages below if any - shadowFactor = np.delete(self.shadowRec.shadowFactor, 0, 0) + illuminationFactor = np.delete(self.shadowRec.illuminationFactor, 0, 0) # FSW process outputs dataUsReq = np.delete(self.rwMotorRec.motorTorque[:, range(num_RW)], 0, 0) @@ -235,7 +235,7 @@ def pull_outputs(self, showPlots): BSK_plt.plot_rate_error(timeData, omega_BR_B) BSK_plt.plot_rw_speeds(timeData, RW_speeds, num_RW) - BSK_plt.plot_shadow_fraction(timeData, shadowFactor) + BSK_plt.plot_shadow_fraction(timeData, illuminationFactor) BSK_plt.plot_sun_point(timeData, sunPoint) figureList = {} @@ -243,7 +243,7 @@ def pull_outputs(self, showPlots): BSK_plt.show_all_plots() else: fileName = os.path.basename(os.path.splitext(__file__)[0]) - figureNames = ["attitudeErrorNorm", "rwMotorTorque", "rateError", "rwSpeed", "shadowFraction", "sunDirectionVector"] + figureNames = ["attitudeErrorNorm", "rwMotorTorque", "rateError", "rwSpeed", "illuminationFraction", "sunDirectionVector"] figureList = BSK_plt.save_all_plots(fileName, figureNames) return figureList diff --git a/examples/scenarioCSS.py b/examples/scenarioCSS.py index bee1fa0234..0d1910fe0d 100755 --- a/examples/scenarioCSS.py +++ b/examples/scenarioCSS.py @@ -246,7 +246,7 @@ def run(show_plots, useCSSConstellation, usePlatform, useEclipse, useKelly): sunPositionMsg = messaging.SpicePlanetStateMsg().write(sunPositionMsgData) if useEclipse: - eclipseMsgData = messaging.EclipseMsgPayload(shadowFactor=0.5) + eclipseMsgData = messaging.EclipseMsgPayload(illuminationFactor=0.5) eclipseMsg = messaging.EclipseMsg().write(eclipseMsgData) def setupCSS(CSS): @@ -418,6 +418,6 @@ def setupCSS(CSS): True, # show_plots False, # useCSSConstellation False, # usePlatform - False, # useEclipse + True, # useEclipse False # useKelly ) diff --git a/src/architecture/messaging/msgAutoSource/msgInterfacePy.i.in b/src/architecture/messaging/msgAutoSource/msgInterfacePy.i.in index e7be810f2a..cc1d37b5a1 100644 --- a/src/architecture/messaging/msgAutoSource/msgInterfacePy.i.in +++ b/src/architecture/messaging/msgAutoSource/msgInterfacePy.i.in @@ -54,3 +54,50 @@ INSTANTIATE_TEMPLATES({type}, {type}Payload, {baseDir}) %template({type}OutMsgsVector) std::vector, std::allocator> >; %template({type}OutMsgsPtrVector) std::vector*, std::allocator*> >; %template({type}InMsgsVector) std::vector, std::allocator> >; +%pythoncode %{{ +if "{type}" == "EclipseMsg": + from . import _{type}Payload as _m + from Basilisk.utilities import deprecated + + # ----- Payload aliasing ----- + def _get_illum(self): + return _m.{type}Payload_shadowFactor_get(self) + + def _set_illum(self, v): + _m.{type}Payload_shadowFactor_set(self, v) + + {type}Payload.illuminationFactor = property(_get_illum, _set_illum) + + # Deprecate the old shadowFactor name + def _warn_get_shadow(self): + deprecated.deprecationWarn( + "EclipseMsgPayload.shadowFactor", + "2026/12/31", + "Use EclipseMsgPayload.illuminationFactor instead (0=fully eclipsed, 1=fully sunlit)." + ) + return _m.{type}Payload_shadowFactor_get(self) + + def _warn_set_shadow(self, v): + deprecated.deprecationWarn( + "EclipseMsgPayload.shadowFactor", + "2026/12/31", + "Use EclipseMsgPayload.illuminationFactor instead (0=fully eclipsed, 1=fully sunlit)." + ) + _m.{type}Payload_shadowFactor_set(self, v) + + {type}Payload.shadowFactor = property(_warn_get_shadow, _warn_set_shadow) + + # ----- Recorder aliasing so logs can use illuminationFactor ----- + try: + _orig_rec_getattr = EclipseMsgRecorder.__getattr__ + + def _rec_getattr_with_alias(self, name): + if name == "illuminationFactor": + # Delegate to the original implementation but ask for shadowFactor + return _orig_rec_getattr(self, "shadowFactor") + return _orig_rec_getattr(self, name) + + EclipseMsgRecorder.__getattr__ = _rec_getattr_with_alias + except Exception: + pass +%}} diff --git a/src/architecture/msgPayloadDefC/EclipseMsgPayload.h b/src/architecture/msgPayloadDefC/EclipseMsgPayload.h index 63ea633406..4b85718a52 100644 --- a/src/architecture/msgPayloadDefC/EclipseMsgPayload.h +++ b/src/architecture/msgPayloadDefC/EclipseMsgPayload.h @@ -21,10 +21,15 @@ #define eclipseSimMsg_h -//!@brief Eclipse shadow factor message definition. +//! @brief Eclipse illumination message definition. typedef struct { - double shadowFactor; //!< Proportion of illumination due to eclipse. 0 = fully shadowed, 1 = fully illuminated. -}EclipseMsgPayload; - + //! Fraction of illumination due to eclipse. 0 = fully shadowed, 1 = fully illuminated. + double shadowFactor; +} EclipseMsgPayload; + +//! illuminationFactor alias to be used instead of shadowFactor. shadowFactor will be deprecarted by +#ifndef BSK_DISABLE_ILLUMINATIONFACTOR_ALIAS +#define illuminationFactor shadowFactor +#endif #endif /* eclipseSimMsg_h */ diff --git a/src/simulation/dynamics/RadiationPressure/_Documentation/secUserGuide.tex b/src/simulation/dynamics/RadiationPressure/_Documentation/secUserGuide.tex index 32fe225c11..54f3fbde19 100644 --- a/src/simulation/dynamics/RadiationPressure/_Documentation/secUserGuide.tex +++ b/src/simulation/dynamics/RadiationPressure/_Documentation/secUserGuide.tex @@ -12,13 +12,13 @@ \subsection{Variable Definition and Code Description} \begin{table}[H] \caption{Definition and Explanation of Variables Used.} \centering \fontsize{10}{10}\selectfont - \begin{tabular}{ | m{5cm}| m{2cm} | m{1.5cm} | m{6cm} |} % Column formatting, + \begin{tabular}{ | m{5cm}| m{2cm} | m{1.5cm} | m{6cm} |} % Column formatting, \hline \textbf{Variable} & \textbf{LaTeX Equivalent} & \textbf{Variable Type} & \textbf{Notes} \\ \hline area & $A_{\odot}$ & double & [m2] Default setting: 0.0f. Required input for cannonball method to get any real output. This is the area to use when approximating the surface area of the spacecraft.\\ \hline coefficientReflection & $c_{R}$ & double & Default setting: 1.2. This is a factor applied to the radiation pressure based on spacecraft surface properties.\\ \hline sunEclipseMsgData & N/A & string & No default. If creating a "fake" eclipse message, set to radiation\_pressure.EclipseSimMsg() \\ \hline - sunEclipseMsgData.shadowFactor & $F_{\mathrm{s}}$& double & Default setting: 1.0. i.e. there is no shadow by default. \\ \hline + sunEclipseMsgData.illuminationFactor & $F_{\mathrm{s}}$& double & Default setting: 1.0. i.e. there is no shadow by default. \\ \hline \end{tabular} \label{tabular:vars} \end{table} @@ -36,4 +36,4 @@ \subsection{Code Diagram} After the inputs are given, radiation\_pressure.cpp calculates the effects of radiation pressure via one of the two methods. At the end, the eclipse factor scales the output forces and torques. -The spacecraft position and orientation states are obtained through the `spacecraft` state engine variables {\tt hubPosition} and {\tt hubSigma}. There is no longer a need to provide spacecraft states through an input message. \ No newline at end of file +The spacecraft position and orientation states are obtained through the `spacecraft` state engine variables {\tt hubPosition} and {\tt hubSigma}. There is no longer a need to provide spacecraft states through an input message. diff --git a/src/simulation/dynamics/RadiationPressure/_UnitTest/test_radiationPressure.py b/src/simulation/dynamics/RadiationPressure/_UnitTest/test_radiationPressure.py index 26abe46850..fe17f61e1c 100644 --- a/src/simulation/dynamics/RadiationPressure/_UnitTest/test_radiationPressure.py +++ b/src/simulation/dynamics/RadiationPressure/_UnitTest/test_radiationPressure.py @@ -125,7 +125,7 @@ def unitRadiationPressure(show_plots, modelType, eclipseOn): if eclipseOn: sunEclipseMsgData = messaging.EclipseMsgPayload() - sunEclipseMsgData.shadowFactor = 0.5 + sunEclipseMsgData.illuminationFactor = 0.5 sunEclMsg = messaging.EclipseMsg().write(sunEclipseMsgData) srpDynEffector.sunEclipseInMsg.subscribeTo(sunEclMsg) srpDynEffector2.sunEclipseInMsg.subscribeTo(sunEclMsg) @@ -196,8 +196,8 @@ def unitRadiationPressure(show_plots, modelType, eclipseOn): truthForceExternal_N = [0, 0, 0] truthTorqueExternalPntB_B = [-0.80492463017846114E-12, 0.50888380426172319E-12, 0.10249431804585393E-11] if eclipseOn: - truthForceExternal_B = sunEclipseMsgData.shadowFactor*np.array(truthForceExternal_B) - truthTorqueExternalPntB_B = sunEclipseMsgData.shadowFactor * np.array(truthTorqueExternalPntB_B) + truthForceExternal_B = sunEclipseMsgData.illuminationFactor * np.array(truthForceExternal_B) + truthTorqueExternalPntB_B = sunEclipseMsgData.illuminationFactor * np.array(truthTorqueExternalPntB_B) testFailCount, testMessages = unitTestSupport.compareVector(truthForceExternal_B, srpDataForce_B[1, 1:], errTol, diff --git a/src/simulation/dynamics/RadiationPressure/radiationPressure.cpp b/src/simulation/dynamics/RadiationPressure/radiationPressure.cpp index 3366919a8d..feebaedaf3 100755 --- a/src/simulation/dynamics/RadiationPressure/radiationPressure.cpp +++ b/src/simulation/dynamics/RadiationPressure/radiationPressure.cpp @@ -31,7 +31,7 @@ RadiationPressure::RadiationPressure() ,srpModel(SRP_CANNONBALL_MODEL) ,stateRead(false) { - this->sunVisibilityFactor.shadowFactor = 1.0; + this->sunVisibilityFactor.illuminationFactor = 1.0; this->forceExternal_N.setZero(); this->forceExternal_B.setZero(); this->torqueExternalPntB_B.setZero(); @@ -106,7 +106,7 @@ void RadiationPressure::computeForceTorque(double integTime, double timeStep) if (this->srpModel == SRP_CANNONBALL_MODEL) { this->computeCannonballModel(s_N); - this->forceExternal_N = this->forceExternal_N * this->sunVisibilityFactor.shadowFactor; + this->forceExternal_N = this->forceExternal_N * this->sunVisibilityFactor.illuminationFactor; } else if (this->srpModel == SRP_FACETED_CPU_MODEL) { Eigen::MRPd sigmaLocal_NB; @@ -114,8 +114,8 @@ void RadiationPressure::computeForceTorque(double integTime, double timeStep) Eigen::Matrix3d dcmLocal_BN = sigmaLocal_NB.toRotationMatrix().transpose(); Eigen::Vector3d s_B = dcmLocal_BN*(sun_r_N - r_N); this->computeLookupModel(s_B); - this->forceExternal_B = this->forceExternal_B * this->sunVisibilityFactor.shadowFactor; - this->torqueExternalPntB_B = this->torqueExternalPntB_B * this->sunVisibilityFactor.shadowFactor; + this->forceExternal_B = this->forceExternal_B * this->sunVisibilityFactor.illuminationFactor; + this->torqueExternalPntB_B = this->torqueExternalPntB_B * this->sunVisibilityFactor.illuminationFactor; } else { bskLogger.bskLog(BSK_ERROR,"Requested SRF Model not implemented.\n"); } diff --git a/src/simulation/environment/albedo/albedo.cpp b/src/simulation/environment/albedo/albedo.cpp index 83f8351982..c92e611091 100644 --- a/src/simulation/environment/albedo/albedo.cpp +++ b/src/simulation/environment/albedo/albedo.cpp @@ -55,7 +55,7 @@ Albedo::Albedo() this->nHat_B_default = { 1.0, 0.0, 0.0 }; this->fov_default = 90. * D2R; this->eclipseCase = false; - this->shadowFactorAtdA = 1.0; + this->illuminationFactorAtdA = 1.0; this->altitudeRateLimit = -1.0; return; } @@ -527,7 +527,7 @@ void Albedo::computeAlbedo(int idx, int instIdx, SpicePlanetStateMsgPayload plan this->rHat_PI_N = -r_IP_N / r_IP_N.norm(); //! - [-] direction vector from instrument to planet (inertial) auto r_SI_N = r_SP_N - r_IP_N; //! - [m] sun's position wrt instrument (inertial) //! - Calculate the authalic radius, if the polar radius available - double t[3], t_aut[3], e, RA_planet, shadowFactorAtdA; + double t[3], t_aut[3], e, RA_planet, illuminationFactorAtdA; if (this->RP_planets.at(idx) > 0.0) { e = sqrt(1 - pow(this->RP_planets.at(idx), 2) / pow(this->REQ_planets.at(idx), 2)); t[0] = pow(this->REQ_planets.at(idx), 2) * 0.5; @@ -595,9 +595,9 @@ void Albedo::computeAlbedo(int idx, int instIdx, SpicePlanetStateMsgPayload plan //! - Detect the sunlit region of the planet seen by the instrument if (f1 > 0 && f2 > 0) { //! - Sunlit portion of the planet seen by the instrument's position (max) - //! - Shadow factor at dA (optional) - shadowFactorAtdA = this->shadowFactorAtdA; - if (this->eclipseCase) { shadowFactorAtdA = computeEclipseAtdA(RA_planet, r_dAP_N, r_SP_N); } + //! - illumination factor at dA (optional) + illuminationFactorAtdA = this->illuminationFactorAtdA; + if (this->eclipseCase) { illuminationFactorAtdA = computeEclipseAtdA(RA_planet, r_dAP_N, r_SP_N); } //! - Area of the incremental area dArea = (fabs(lon1 - lon2) * fabs(sin(lat1) - sin(lat2)) * pow(r_dAP_N.norm(), 2)); //! - Maximum albedo flux ratio at instrument's position [-] @@ -609,7 +609,7 @@ void Albedo::computeAlbedo(int idx, int instIdx, SpicePlanetStateMsgPayload plan else { tempmax = this->ALB[idx][ilat][ilon] * tempmax; } - alb_Imax = alb_Imax + tempmax * shadowFactorAtdA; + alb_Imax = alb_Imax + tempmax * illuminationFactorAtdA; if (f3 >= cos(fov)) { //! - Sunlit portion of the planet seen by the instrument (fov) @@ -621,7 +621,7 @@ void Albedo::computeAlbedo(int idx, int instIdx, SpicePlanetStateMsgPayload plan else { tempfov = this->ALB[idx][ilat][ilon] * tempfov; } - alb_I = alb_I + tempfov * shadowFactorAtdA; + alb_I = alb_I + tempfov * illuminationFactorAtdA; albLon1.push_back(this->gdlon[idx][ilon] * 180 / M_PI); albLat1.push_back(this->gdlat[idx][ilat] * 180 / M_PI); IIdx++; @@ -659,8 +659,8 @@ void Albedo::computeAlbedo(int idx, int instIdx, SpicePlanetStateMsgPayload plan */ double Albedo::computeEclipseAtdA(double Rplanet, Eigen::Vector3d r_dAP_N, Eigen::Vector3d r_SP_N) { - //! - Compute the shadow factor at incremental area - //! - Note that the eclipse module computes the shadow factor at the spacecraft position + //! - Compute the illumination factor at incremental area + //! - Note that the eclipse module computes the illumination factor at the spacecraft position auto r_SdA_N = r_SP_N - r_dAP_N; //! - [m] position vector from dA to Sun (inertial) auto s = r_dAP_N.norm(); auto f_1 = safeAsin((REQ_SUN * 1000 + Rplanet) / r_SP_N.norm()); @@ -672,7 +672,7 @@ double Albedo::computeEclipseAtdA(double Rplanet, Eigen::Vector3d r_dAP_N, Eigen auto l_1 = c_1 * tan(f_1); auto l_2 = c_2 * tan(f_2); double area = 0.0; - double shadowFactorAtdA = 1.0; //! - Initialise the value for no eclipse + double illuminationFactorAtdA = 1.0; //! - Initialise the value for no eclipse double a = safeAsin(REQ_SUN * 1000 / r_SdA_N.norm()); //! - Apparent radius of sun double b = safeAsin(Rplanet / r_dAP_N.norm()); //! - Apparent radius of occulting body double c = safeAcos((-r_dAP_N.dot(r_SdA_N)) / (r_dAP_N.norm() * r_SdA_N.norm())); @@ -682,26 +682,26 @@ double Albedo::computeEclipseAtdA(double Rplanet, Eigen::Vector3d r_dAP_N, Eigen // In particular (c < a + b) must check last to avoid testing // with implausible a, b and c values if (c < b - a) { // total eclipse, implying a < b - shadowFactorAtdA = 0.0; + illuminationFactorAtdA = 0.0; } else if (c < a - b) { // partial maximum eclipse, implying a > b double areaSun = M_PI * a * a; double areaBody = M_PI * b * b; area = areaSun - areaBody; - shadowFactorAtdA = 1 - area / (M_PI * a * a); + illuminationFactorAtdA = 1 - area / (M_PI * a * a); } else if (c < a + b) { // partial eclipse double x = (c * c + a * a - b * b) / (2 * c); double y = sqrt(a * a - x * x); area = a * a * safeAcos(x / a) + b * b * safeAcos((c - x) / b) - c * y; - shadowFactorAtdA = 1 - area / (M_PI * a * a); + illuminationFactorAtdA = 1 - area / (M_PI * a * a); } } - if (shadowFactorAtdA < 0.0) { - shadowFactorAtdA = 0.0; + if (illuminationFactorAtdA < 0.0) { + illuminationFactorAtdA = 0.0; } - else if (shadowFactorAtdA > 1.0) { - shadowFactorAtdA = 1.0; + else if (illuminationFactorAtdA > 1.0) { + illuminationFactorAtdA = 1.0; } - return shadowFactorAtdA; + return illuminationFactorAtdA; } diff --git a/src/simulation/environment/albedo/albedo.h b/src/simulation/environment/albedo/albedo.h index 4b083a3f41..99a461527e 100644 --- a/src/simulation/environment/albedo/albedo.h +++ b/src/simulation/environment/albedo/albedo.h @@ -76,7 +76,7 @@ class Albedo : public SysModel { void getPlanetRadius(std::string planetSpiceName); //!< gets the planet's radius void evaluateAlbedoModel(int idx); //!< evaluates the ALB model void computeAlbedo(int idx, int instIdx, SpicePlanetStateMsgPayload planetMsg, bool AlbArray, double outData[]); //!< computes the albedo at instrument's location - double computeEclipseAtdA(double Rplanet, Eigen::Vector3d r_dAP_N, Eigen::Vector3d r_SP_N); //!< computes the shadow factor at dA + double computeEclipseAtdA(double Rplanet, Eigen::Vector3d r_dAP_N, Eigen::Vector3d r_SP_N); //!< computes the illumination factor at dA public: std::vector*> albOutMsgs; //!< vector of output messages for albedo data @@ -84,13 +84,13 @@ class Albedo : public SysModel { ReadFunctor spacecraftStateInMsg; //!< input message name for spacecraft data std::vector> planetInMsgs; //!< vector of planet data input data - BSKLogger bskLogger; //!< BSK Logging + BSKLogger bskLogger; //!< BSK Logging int defaultNumLat; //!< [-] default number of latitude grid points int defaultNumLon; //!< [-] default number of longitude grid points Eigen::Vector3d nHat_B_default; //!< [-] default value for unit normal of the instrument (spacecraft body) double fov_default; //!< [rad] default value for instrument's field of view half angle bool eclipseCase; //!< consider eclipse at dA, if true - double shadowFactorAtdA; //!< [-] shadow factor at incremental area + double illuminationFactorAtdA; //!< [-] illumination factor at incremental area double altitudeRateLimit; //!< [-] rate limit of the instrument's altitude to the planet's radius for albedo calculations private: diff --git a/src/simulation/environment/albedo/albedo.rst b/src/simulation/environment/albedo/albedo.rst index 9faef88af0..513b421d14 100644 --- a/src/simulation/environment/albedo/albedo.rst +++ b/src/simulation/environment/albedo/albedo.rst @@ -126,9 +126,9 @@ conditions. The Mars' albedo data is obtained from `TES instrument `__ as VICAR format and converted to .csv format for consistency with 1x1, 5x5, and 10x10 degree resolutions. -``shadowFactorAtdA`` is optional to be calculated with eclipseCase being True or can be assigned +``illuminationFactorAtdA`` is optional to be calculated with eclipseCase being True or can be assigned directly by the user with eclipseCase False. It is used as a multiplication term in Eq. :eq:`eq:albedo:10`, if defined. -Therefore, when using albedo output on an instrument, it should be used after the shadow factor multiplication of the +Therefore, when using albedo output on an instrument, it should be used after the illumination factor multiplication of the instrument, if exists. A limit can be set in order not to compute the albedo for planets too far by :math:`altitudeRateLimit` which is the @@ -202,3 +202,8 @@ The model can be added to a task like other simModels. .. code-block:: python unitTestSim.AddModelToTask(simTaskName, albModule) + +.. warning:: + ``shadowFactor`` is **deprecated** in favor of ``illuminationFactor``. + In C/C++ both names work until **Dec 31, 2026**. After that date, code must + use ``illuminationFactor`` exclusively. diff --git a/src/simulation/environment/eclipse/_UnitTest/test_eclipse.py b/src/simulation/environment/eclipse/_UnitTest/test_eclipse.py index 047aa4d340..de46523742 100755 --- a/src/simulation/environment/eclipse/_UnitTest/test_eclipse.py +++ b/src/simulation/environment/eclipse/_UnitTest/test_eclipse.py @@ -19,7 +19,7 @@ # Eclipse Condition Unit Test # # Purpose: Test the proper function of the Eclipse environment module. -# This is done by comparing computed expected shadow factors in +# This is done by comparing computed expected illumination factors in # particular eclipse conditions to what is simulated # Author: Patrick Kenneally # Creation Date: May. 31, 2017 @@ -29,6 +29,7 @@ import numpy as np import pytest +import datetime from Basilisk import __path__ from Basilisk.simulation import eclipse from Basilisk.simulation import spacecraft @@ -39,6 +40,7 @@ from Basilisk.utilities import simIncludeGravBody from Basilisk.utilities import unitTestSupport from Basilisk.architecture import messaging +from Basilisk.architecture.messaging import EclipseMsgPayload bskPath = __path__[0] @@ -54,7 +56,7 @@ def test_unitEclipse(show_plots, eclipseCondition, planet): **Test Description and Success Criteria** The unit test validates the internal aspects of the Basilisk eclipse module by comparing simulated output with \ -expected output. It validates the computation of a shadow factor for total eclipse, partial eclipse,annular eclipse, \ +expected output. It validates the computation of a illumination factor for total eclipse, partial eclipse,annular eclipse, \ and no eclipse scenarios. The test is designed to analyze one type at a time for both Earth and Mars and is then \ repeated for all three. @@ -72,9 +74,9 @@ def test_unitEclipse(show_plots, eclipseCondition, planet): step process, the velocity is not necessarily needed as an input, so only a position vector is provided \ for these cases. -The shadow factor obtained through the module is compared to the expected result, which is either trivial or \ -calculated, depending on the eclipse type. Full eclipse and no eclipse shadow factors are compared without the \ -need for computation, since they are just 0.0 and 1.0, respectively. The partial and annular eclipse shadow \ +The illumination factor obtained through the module is compared to the expected result, which is either trivial or \ +calculated, depending on the eclipse type. Full eclipse and no eclipse illumination factors are compared without the \ +need for computation, since they are just 0.0 and 1.0, respectively. The partial and annular eclipse illumination \ factors, however, vary between 0.0 and 1.0, based on the cone dimensions, and are calculated using \ MATLAB and Spice data. @@ -89,9 +91,9 @@ def test_unitEclipse(show_plots, eclipseCondition, planet): **Description of Variables Being Tested** -In each test scenario the shadow eclipse variable +In each test scenario the illumination eclipse variable - ``shadowFactor`` + ``illuminationFactor`` is pulled from the log data and compared to expected truth values. @@ -105,19 +107,19 @@ def test_unitEclipseCustom(show_plots): **Test Description and Success Criteria** The unit test validates the internal aspects of the Basilisk eclipse module by comparing simulated output with \ -expected output. It validates the computation of a shadow factor for total eclipse using a custom gravity body. +expected output. It validates the computation of a illumination factor for total eclipse using a custom gravity body. This unit test sets up a custom gravity body, the asteroid Bennu, using the planetEphemeris module (i.e. Spice \ is not used for this test.) An empty spice planet message is created for the sun. The spacecraft is set 500 m \ on the side of the asteroid opposite of the sun. -The shadow factor obtained through the module is compared to the expected result, which is trivial to compute. +The illumination factor obtained through the module is compared to the expected result, which is trivial to compute. **Description of Variables Being Tested** -In this test scenario the shadow eclipse variable +In this test scenario the illumination eclipse variable - ``shadowFactor`` + ``illuminationFactor`` is pulled from the log data and compared to the expected truth value. @@ -251,55 +253,55 @@ def unitEclipse(show_plots, eclipseCondition, planet): # Execute the simulation for one time step unitTestSim.TotalSim.SingleStepProcesses() - eclipseData_0 = dataLog.shadowFactor + eclipseData_0 = dataLog.illuminationFactor # Obtain body position vectors to check with MATLAB errTol = 1E-12 if planet == "earth": if eclipseCondition == "partial": - truthShadowFactor = 0.62310760206735027 - if not unitTestSupport.isDoubleEqual(eclipseData_0[-1], truthShadowFactor, errTol): + truthilluminationFactor = 0.62310760206735027 + if not unitTestSupport.isDoubleEqual(eclipseData_0[-1], truthilluminationFactor, errTol): testFailCount += 1 - testMessages.append("Shadow Factor failed for Earth partial eclipse condition") + testMessages.append("Illumination Factor failed for Earth partial eclipse condition") elif eclipseCondition == "full": - truthShadowFactor = 0.0 - if not unitTestSupport.isDoubleEqual(eclipseData_0[-1], truthShadowFactor, errTol): + truthilluminationFactor = 0.0 + if not unitTestSupport.isDoubleEqual(eclipseData_0[-1], truthilluminationFactor, errTol): testFailCount += 1 - testMessages.append("Shadow Factor failed for Earth full eclipse condition") + testMessages.append("Illumination Factor failed for Earth full eclipse condition") elif eclipseCondition == "none": - truthShadowFactor = 1.0 - if not unitTestSupport.isDoubleEqual(eclipseData_0[-1], truthShadowFactor, errTol): + truthilluminationFactor = 1.0 + if not unitTestSupport.isDoubleEqual(eclipseData_0[-1], truthilluminationFactor, errTol): testFailCount += 1 - testMessages.append("Shadow Factor failed for Earth none eclipse condition") + testMessages.append("Illumination Factor failed for Earth none eclipse condition") elif eclipseCondition == "annular": - truthShadowFactor = 1.497253388113018e-04 - if not unitTestSupport.isDoubleEqual(eclipseData_0[-1], truthShadowFactor, errTol): + truthilluminationFactor = 1.497253388113018e-04 + if not unitTestSupport.isDoubleEqual(eclipseData_0[-1], truthilluminationFactor, errTol): testFailCount += 1 - testMessages.append("Shadow Factor failed for Earth annular eclipse condition") + testMessages.append("Illumination Factor failed for Earth annular eclipse condition") elif planet == "mars": if eclipseCondition == "partial": - truthShadowFactor = 0.18745025055615416 - if not unitTestSupport.isDoubleEqual(eclipseData_0[-1], truthShadowFactor, errTol): + truthilluminationFactor = 0.18745025055615416 + if not unitTestSupport.isDoubleEqual(eclipseData_0[-1], truthilluminationFactor, errTol): testFailCount += 1 - testMessages.append("Shadow Factor failed for Mars partial eclipse condition") + testMessages.append("Illumination Factor failed for Mars partial eclipse condition") elif eclipseCondition == "full": - truthShadowFactor = 0.0 - if not unitTestSupport.isDoubleEqual(eclipseData_0[-1], truthShadowFactor, errTol): + truthilluminationFactor = 0.0 + if not unitTestSupport.isDoubleEqual(eclipseData_0[-1], truthilluminationFactor, errTol): testFailCount += 1 - testMessages.append("Shadow Factor failed for Mars full eclipse condition") + testMessages.append("Illumination Factor failed for Mars full eclipse condition") elif eclipseCondition == "none": - truthShadowFactor = 1.0 - if not unitTestSupport.isDoubleEqual(eclipseData_0[-1], truthShadowFactor, errTol): + truthilluminationFactor = 1.0 + if not unitTestSupport.isDoubleEqual(eclipseData_0[-1], truthilluminationFactor, errTol): testFailCount += 1 - testMessages.append("Shadow Factor failed for Mars none eclipse condition") + testMessages.append("Illumination Factor failed for Mars none eclipse condition") elif eclipseCondition == "annular": - truthShadowFactor = 4.245137380531894e-05 - if not unitTestSupport.isDoubleEqual(eclipseData_0[-1], truthShadowFactor, errTol): + truthilluminationFactor = 4.245137380531894e-05 + if not unitTestSupport.isDoubleEqual(eclipseData_0[-1], truthilluminationFactor, errTol): testFailCount += 1 - testMessages.append("Shadow Factor failed for Mars annular eclipse condition") + testMessages.append("Illumination Factor failed for Mars annular eclipse condition") if testFailCount == 0: print("PASSED: " + planet + "-" + eclipseCondition) @@ -388,14 +390,14 @@ def unitEclipseCustom(show_plots): # Execute the simulation for one time step unitTestSim.TotalSim.SingleStepProcesses() - eclipseData_0 = dataLog.shadowFactor + eclipseData_0 = dataLog.illuminationFactor # Obtain body position vectors to check with MATLAB errTol = 1E-12 - truthShadowFactor = 0.0 - if not unitTestSupport.isDoubleEqual(eclipseData_0[-1], truthShadowFactor, errTol): + truthilluminationFactor = 0.0 + if not unitTestSupport.isDoubleEqual(eclipseData_0[-1], truthilluminationFactor, errTol): testFailCount += 1 - testMessages.append("Shadow Factor failed for custom full eclipse condition") + testMessages.append("Illumination Factor failed for custom full eclipse condition") if testFailCount == 0: print("PASSED: custom-full") @@ -408,6 +410,38 @@ def unitEclipseCustom(show_plots): return [testFailCount, ''.join(testMessages)] +def test_shadow_vs_illumination_alias_and_deprecation_behavior(): + """Check aliasing and deprecation behavior for EclipseMsgPayload.""" + p = EclipseMsgPayload() + + # Forward direction: setting illuminationFactor updates shadowFactor + p.illuminationFactor = 0.8 + assert p.illuminationFactor == pytest.approx(0.8) + assert p.shadowFactor == pytest.approx(0.8) + + cutoff = datetime.date(2026, 12, 31) + today = datetime.date.today() + + if today <= cutoff: + # Using the deprecated name should emit a warning, but must not error. + with pytest.warns(Warning, match=r".*illuminationFactor.*"): + p.shadowFactor = 0.5 + with pytest.warns(Warning, match=r".*illuminationFactor.*"): + _ = p.shadowFactor + + # Values remain interchangeable + assert p.illuminationFactor == pytest.approx(0.5) + + else: + # After cutoff, shadowFactor should be gone/raise + with pytest.raises((AttributeError, RuntimeError, TypeError, NameError)): + p.shadowFactor = 0.5 + + # Preferred name continues to work + p.illuminationFactor = 0.4 + assert p.illuminationFactor == pytest.approx(0.4) + if __name__ == "__main__": unitEclipse(False, "annular", "mars") unitEclipseCustom(False) + test_shadow_vs_illumination_alias_and_deprecation_behavior() diff --git a/src/simulation/environment/eclipse/eclipse.cpp b/src/simulation/environment/eclipse/eclipse.cpp index fc2dd921e0..c7763d1d60 100755 --- a/src/simulation/environment/eclipse/eclipse.cpp +++ b/src/simulation/environment/eclipse/eclipse.cpp @@ -74,7 +74,7 @@ void Eclipse::readInputMessages() } } -/*! This method takes the computed shadow factors and outputs them to the +/*! This method takes the computed illumination factors and outputs them to the messaging system. @param CurrentClock The current simulation time (used for time stamping) @@ -83,7 +83,7 @@ void Eclipse::writeOutputMessages(uint64_t CurrentClock) { for (long unsigned int c = 0; c < this->eclipseOutMsgs.size(); c++) { EclipseMsgPayload tmpEclipseMsg = {}; - tmpEclipseMsg.shadowFactor = this->eclipseShadowFactors.at(c); + tmpEclipseMsg.illuminationFactor = this->eclipseIlluminationFactors.at(c); this->eclipseOutMsgs.at(c)->write(&tmpEclipseMsg, this->moduleID, CurrentClock); } } @@ -112,13 +112,13 @@ void Eclipse::UpdateState(uint64_t CurrentSimNanos) std::vector::iterator planetIt; - // Index to assign the shadowFactor for each body position (S/C) + // Index to assign the illuminationFactor for each body position (S/C) // being tracked int scIdx = 0; for(scIt = this->scStateBuffer.begin(); scIt != this->scStateBuffer.end(); scIt++) { - double tmpShadowFactor = 1.0; // 1.0 means 100% illumination (no eclipse) + double tmpIlluminationFactor = 1.0; // 1.0 means 100% illumination (no eclipse) double eclipsePlanetDistance = 0.0; int64_t eclipsePlanetKey = -1; r_BN_N = cArray2EigenVector3d(scIt->r_BN_N); @@ -170,15 +170,15 @@ void Eclipse::UpdateState(uint64_t CurrentSimNanos) if (fabs(l) < fabs(l_2)) { if (c_2 < 0) { // total eclipse - tmpShadowFactor = this->computePercentShadow(planetRadius, r_HB_N, s_BP_N); + tmpIlluminationFactor = this->computePercentIllumination(planetRadius, r_HB_N, s_BP_N); } else { //c_2 > 0 // annular - tmpShadowFactor = this->computePercentShadow(planetRadius, r_HB_N, s_BP_N); + tmpIlluminationFactor = this->computePercentIllumination(planetRadius, r_HB_N, s_BP_N); } } else if (fabs(l) < fabs(l_1)) { // partial - tmpShadowFactor = this->computePercentShadow(planetRadius, r_HB_N, s_BP_N); + tmpIlluminationFactor = this->computePercentIllumination(planetRadius, r_HB_N, s_BP_N); } } - this->eclipseShadowFactors.at(scIdx) = tmpShadowFactor; + this->eclipseIlluminationFactors.at(scIdx) = tmpIlluminationFactor; scIdx++; } this->writeOutputMessages(CurrentSimNanos); @@ -188,12 +188,12 @@ void Eclipse::UpdateState(uint64_t CurrentSimNanos) @param planetRadius @param r_HB_N @param s_BP_N - @return double fractionShadow The eclipse shadow fraction. + @return double fractionIllumination The eclipse illumination fraction. */ -double Eclipse::computePercentShadow(double planetRadius, Eigen::Vector3d r_HB_N, Eigen::Vector3d s_BP_N) +double Eclipse::computePercentIllumination(double planetRadius, Eigen::Vector3d r_HB_N, Eigen::Vector3d s_BP_N) { double area = 0.0; - double shadowFraction = 1.0; // Initialise to value for no eclipse + double illuminationFraction = 1.0; // Initialise to value for no eclipse double normR_HB_N = r_HB_N.norm(); double normS_BP_N = s_BP_N.norm(); double a = safeAsin(REQ_SUN*1000/normR_HB_N); // apparent radius of sun @@ -204,19 +204,19 @@ double Eclipse::computePercentShadow(double planetRadius, Eigen::Vector3d r_HB_N // In particular (c < a + b) must check last to avoid testing // with implausible a, b and c values if (c < b - a) { // total eclipse, implying a < b - shadowFraction = 0.0; + illuminationFraction = 0.0; } else if (c < a - b) { // partial maximum eclipse, implying a > b double areaSun = M_PI*a*a; double areaBody = M_PI*b*b; area = areaSun - areaBody; - shadowFraction = 1 - area/(M_PI*a*a); + illuminationFraction = 1 - area/(M_PI*a*a); } else if (c < a + b) { // partial eclipse double x = (c*c + a*a - b*b)/(2*c); double y = sqrt(a*a - x*x); area = a*a*safeAcos(x/a) + b*b*safeAcos((c-x)/b) - c*y; - shadowFraction = 1 - area/(M_PI*a*a); + illuminationFraction = 1 - area/(M_PI*a*a); } - return shadowFraction; + return illuminationFraction; } /*! @@ -240,7 +240,7 @@ void Eclipse::addSpacecraftToModel(Message *tmpScMsg) // Now that we know the number of output messages we can size and zero // the eclipse data vector - this->eclipseShadowFactors.resize(this->eclipseOutMsgs.size()); + this->eclipseIlluminationFactors.resize(this->eclipseOutMsgs.size()); } diff --git a/src/simulation/environment/eclipse/eclipse.h b/src/simulation/environment/eclipse/eclipse.h index f436baccb1..493d7a7e8f 100755 --- a/src/simulation/environment/eclipse/eclipse.h +++ b/src/simulation/environment/eclipse/eclipse.h @@ -38,13 +38,13 @@ class Eclipse: public SysModel { public: Eclipse(); ~Eclipse(); - + void Reset(uint64_t CurrenSimNanos); void UpdateState(uint64_t CurrentSimNanos); void writeOutputMessages(uint64_t CurrentClock); void addSpacecraftToModel(Message *tmpScMsg); void addPlanetToModel(Message *tmpSpMsg); - + public: ReadFunctor sunInMsg; //!< sun ephemeris input message name std::vector> planetInMsgs; //!< A vector of planet incoming state message names ordered by the sequence in which planet are added to the module @@ -58,11 +58,11 @@ class Eclipse: public SysModel { std::vector scStateBuffer; //!< buffer of the spacecraft state input messages std::vector planetBuffer; //!< buffer of the spacecraft state input messages SpicePlanetStateMsgPayload sunInMsgState; //!< copy of sun input msg - std::vector eclipseShadowFactors; //!< vector of shadow factor output values + std::vector eclipseIlluminationFactors; //!< vector of illumination factor output values private: void readInputMessages(); - double computePercentShadow(double planetRadius, Eigen::Vector3d r_HB_N, Eigen::Vector3d s_BP_N); + double computePercentIllumination(double planetRadius, Eigen::Vector3d r_HB_N, Eigen::Vector3d s_BP_N); double getPlanetEquatorialRadius(std::string planetSpiceName); }; diff --git a/src/simulation/environment/solarFlux/_UnitTest/test_solarFlux.py b/src/simulation/environment/solarFlux/_UnitTest/test_solarFlux.py index 1795657b7e..e96d0ec2d8 100755 --- a/src/simulation/environment/solarFlux/_UnitTest/test_solarFlux.py +++ b/src/simulation/environment/solarFlux/_UnitTest/test_solarFlux.py @@ -25,8 +25,8 @@ from Basilisk.utilities import orbitalMotion as om -@pytest.mark.parametrize("positionFactor, shadowFactor, eclipseMsgName, relTol", [(np.sqrt(2), 0.5, "eclipse_data_0", 1e-8), (np.sqrt(2), 0.5, "", 1e-8)]) -def test_solarFlux(show_plots, positionFactor, shadowFactor, eclipseMsgName, relTol): +@pytest.mark.parametrize("positionFactor, illuminationFactor, eclipseMsgName, relTol", [(np.sqrt(2), 0.5, "eclipse_data_0", 1e-8), (np.sqrt(2), 0.5, "", 1e-8)]) +def test_solarFlux(show_plots, positionFactor, illuminationFactor, eclipseMsgName, relTol): """ **Test Description** @@ -34,12 +34,12 @@ def test_solarFlux(show_plots, positionFactor, shadowFactor, eclipseMsgName, rel To test this, the module is asked to write the solar flux at 1 AU. Then it is asked to write the flux at ``positionFactor*AU`` and the flux is checked to be ``positionFactor**2`` of that at 1 AU to within a relative tolerance of relTol. - The application of the shadowFactor is also checked as a multiple of the un-shadowed flux. + The application of the illuminationFactor is also checked as a multiple of the un-shadowed flux. Args: positionFactor (float): positive, a factor by which to multiply the original s/c position to check flux at a new position - shadowFactor (float): between 0 and 1, + illuminationFactor (float): between 0 and 1, the eclipse factor by which to multiple the solar flux at a position relTol (float): positive, the relative tolerance to which the result is checked. """ @@ -58,7 +58,7 @@ def test_solarFlux(show_plots, positionFactor, shadowFactor, eclipseMsgName, rel scMsg = messaging.SCStatesMsg().write(scPositionMessage) eclipseMessage = messaging.EclipseMsgPayload() - eclipseMessage.shadowFactor = shadowFactor + eclipseMessage.illuminationFactor = illuminationFactor eclMsg = messaging.EclipseMsg().write(eclipseMessage) sf = solarFlux.SolarFlux() @@ -80,7 +80,7 @@ def test_solarFlux(show_plots, positionFactor, shadowFactor, eclipseMsgName, rel sim.TotalSim.SingleStepProcesses() fluxOutFurther = dataLog.flux - assert fluxOutFurther[1] == pytest.approx(fluxOutEarth[0] / shadowFactor / (positionFactor**2) * shadowFactor, rel=relTol) + assert fluxOutFurther[1] == pytest.approx(fluxOutEarth[0] / illuminationFactor / (positionFactor**2) * illuminationFactor, rel=relTol) if __name__ == "__main__": diff --git a/src/simulation/environment/solarFlux/solarFlux.cpp b/src/simulation/environment/solarFlux/solarFlux.cpp index 6aba95a80d..ed54b748d9 100755 --- a/src/simulation/environment/solarFlux/solarFlux.cpp +++ b/src/simulation/environment/solarFlux/solarFlux.cpp @@ -75,7 +75,7 @@ void SolarFlux::readMessages() if (this->eclipseInMsg.isLinked()) { EclipseMsgPayload eclipseInMsgData; eclipseInMsgData = this->eclipseInMsg(); - this->eclipseFactor = eclipseInMsgData.shadowFactor; + this->eclipseFactor = eclipseInMsgData.illuminationFactor; } } diff --git a/src/simulation/environment/solarFlux/solarFlux.rst b/src/simulation/environment/solarFlux/solarFlux.rst index 02355db686..331c5d028d 100644 --- a/src/simulation/environment/solarFlux/solarFlux.rst +++ b/src/simulation/environment/solarFlux/solarFlux.rst @@ -48,13 +48,13 @@ Overall, this module was created because many other modules need this informatio Equations ^^^^^^^^^ -The flux is calculated by scaling the flux at 1 AU and applying the :ref:`EclipseMsgPayload` ``shadowFactor``: +The flux is calculated by scaling the flux at 1 AU and applying the :ref:`EclipseMsgPayload` ``illuminationFactor``: .. math:: F_{\mathrm{out}} = F_{\mathrm{Earth}} * \frac{\mathrm{AU}^2}{r_{\mathrm{Sun}}^2} * f_s -where :math:`r_{\mathrm{Sun}}` is the distance between the spacecraft and the sun and :math:`f_s` is the shadow factor. +where :math:`r_{\mathrm{Sun}}` is the distance between the spacecraft and the sun and :math:`f_s` is the illumination factor. User Guide @@ -80,3 +80,8 @@ The names below are only special in that they are useful defaults and are actual dataLog = sf.solarFluxOutMsg.recorder() +.. warning:: + + ``shadowFactor`` is **deprecated** in favor of ``illuminationFactor``. + In C/C++ both names work until **Dec 31, 2026**. After that date, code must + use ``illuminationFactor`` exclusively. diff --git a/src/simulation/environment/spacecraftLocation/spacecraftLocation.cpp b/src/simulation/environment/spacecraftLocation/spacecraftLocation.cpp index c906b9f1d8..cc5d783b93 100644 --- a/src/simulation/environment/spacecraftLocation/spacecraftLocation.cpp +++ b/src/simulation/environment/spacecraftLocation/spacecraftLocation.cpp @@ -36,7 +36,7 @@ SpacecraftLocation::SpacecraftLocation() this->aHat_B.fill(0.0); this->theta = -1.0; this->theta_solar = -1.0; - this->min_shadow_factor = -1.0; + this->min_illumination_factor = -1.0; this->planetState = this->planetInMsg.zeroMsgPayload; this->planetState.J20002Pfix[0][0] = 1; @@ -283,8 +283,8 @@ SpacecraftLocation::computeAccess() } // Check if eclipse is valid - if (this->eclipseInMsg.isLinked() && this->min_shadow_factor > 0.0) { - if (eclipseInMsgData.shadowFactor < this->min_shadow_factor) { + if (this->eclipseInMsg.isLinked() && this->min_illumination_factor > 0.0) { + if (eclipseInMsgData.illuminationFactor < this->min_illumination_factor) { this->accessMsgBuffer.at(c).hasAccess = 0; this->accessMsgBuffer.at(c).hasIllumination = 0; } diff --git a/src/simulation/environment/spacecraftLocation/spacecraftLocation.h b/src/simulation/environment/spacecraftLocation/spacecraftLocation.h index e4ac6907f1..baa585ef95 100644 --- a/src/simulation/environment/spacecraftLocation/spacecraftLocation.h +++ b/src/simulation/environment/spacecraftLocation/spacecraftLocation.h @@ -56,7 +56,7 @@ class SpacecraftLocation : public SysModel Eigen::Vector3d aHat_B; //!< [] (optional) unit direction vector of the sensor/communication boresight axis double theta; //!< [r] (optional) sensor/communication half-cone angle, must be set if shat_B is specified double theta_solar; //!< [r] (optional) illumination half-cone angle, treating aHat_B as the surface normal - double min_shadow_factor; //!< [] (optional) minimum amount of illumination due to eclipse necessary to observe + double min_illumination_factor; //!< [] (optional) minimum amount of illumination due to eclipse necessary to observe ReadFunctor primaryScStateInMsg; //!< primary spacecraft input message ReadFunctor planetInMsg; //!< (optional) planet state input message diff --git a/src/simulation/environment/spacecraftLocation/spacecraftLocation.rst b/src/simulation/environment/spacecraftLocation/spacecraftLocation.rst index 372fc20644..f2038ca965 100644 --- a/src/simulation/environment/spacecraftLocation/spacecraftLocation.rst +++ b/src/simulation/environment/spacecraftLocation/spacecraftLocation.rst @@ -41,7 +41,7 @@ provides information on what this message is used for. - (optional) sun state input message. Used for illumination checking if the message is connected and ``theta_solar`` is set. * - eclipseInMsg - :ref:`EclipseMsgPayload` - - (optional) eclipse input message. Used for illumination checking if the message is connected and ``min_shadow_factor`` is set. + - (optional) eclipse input message. Used for illumination checking if the message is connected and ``min_illumination_factor`` is set. * - accessOutMsgs - :ref:`AccessMsgPayload` - output vector of ground location access messages @@ -123,7 +123,7 @@ If the ``sunInMsg`` is connected and :math:`\theta_{\text{solar,max}}` is set, t .. math:: \arccos \left( \hat{\bf a} \cdot \hat{\bf s} \right) = \theta_{\text{solar}} \le \theta_{\text{solar,max}} -If an eclipse message is connected and ``min_shadow_factor`` is set, the module will also check that the shadow factor is above this threshold. +If an eclipse message is connected and ``min_illumination_factor`` is set, the module will also check that the shadow factor is above this threshold. User Guide ---------- @@ -164,3 +164,9 @@ The access output messages can be logged through:: dataRec0 = location.accessOutMsgs[0].recorder() dataRec1 = location.accessOutMsgs[1].recorder() + +.. warning:: + + ``min_shadow_factor`` is **deprecated** in favor of ``min_illumination_factor``. + In C/C++ both names work until **Dec 31, 2026**. After that date, code must + use ``min_illumination_factor`` exclusively. diff --git a/src/simulation/power/simpleSolarPanel/_UnitTest/test_unitSimpleSolarPanel.py b/src/simulation/power/simpleSolarPanel/_UnitTest/test_unitSimpleSolarPanel.py index 707291d2db..3a59c741df 100644 --- a/src/simulation/power/simpleSolarPanel/_UnitTest/test_unitSimpleSolarPanel.py +++ b/src/simulation/power/simpleSolarPanel/_UnitTest/test_unitSimpleSolarPanel.py @@ -99,7 +99,7 @@ def run(showPlots, orbitDistance, eclipseValue, scAttitude): # Input message set-up eclipseMessage = messaging.EclipseMsgPayload() - eclipseMessage.shadowFactor = eclipseValue # Set it to be totally in shadow + eclipseMessage.illuminationFactor = eclipseValue # Set it to be totally in shadow eclipseMsg = messaging.EclipseMsg().write(eclipseMessage) diff --git a/src/simulation/power/simpleSolarPanel/simpleSolarPanel.cpp b/src/simulation/power/simpleSolarPanel/simpleSolarPanel.cpp index 7e03c9aaeb..f11101bbc5 100644 --- a/src/simulation/power/simpleSolarPanel/simpleSolarPanel.cpp +++ b/src/simulation/power/simpleSolarPanel/simpleSolarPanel.cpp @@ -16,7 +16,7 @@ SimpleSolarPanel::SimpleSolarPanel(){ this->panelEfficiency = -1; this->nHat_B.setZero(); - this->shadowFactor = 1; + this->illuminationFactor = 1; return; @@ -32,7 +32,7 @@ SimpleSolarPanel::~SimpleSolarPanel(){ */ void SimpleSolarPanel::customReset(uint64_t CurrentClock) { - this->shadowFactor = 1.0; + this->illuminationFactor = 1.0; if (this->panelArea < 0.0) { bskLogger.bskLog(BSK_ERROR, "The panelArea must be a positive value"); @@ -76,7 +76,7 @@ bool SimpleSolarPanel::customReadMessages() if(this->sunEclipseInMsg.isLinked()) { EclipseMsgPayload sunVisibilityFactor; // sun visiblity input message sunVisibilityFactor = this->sunEclipseInMsg(); - this->shadowFactor = sunVisibilityFactor.shadowFactor; + this->illuminationFactor = sunVisibilityFactor.illuminationFactor; } return(true); } @@ -143,7 +143,7 @@ void SimpleSolarPanel::computeSunData() void SimpleSolarPanel::evaluatePowerModel(PowerNodeUsageMsgPayload *powerUsageSimMsg) { this->computeSunData(); - double sunPowerFactor = SOLAR_FLUX_EARTH * this->sunDistanceFactor * this->shadowFactor; + double sunPowerFactor = SOLAR_FLUX_EARTH * this->sunDistanceFactor * this->illuminationFactor; powerUsageSimMsg->netPower = sunPowerFactor * this->projectedArea * this->panelEfficiency; return; diff --git a/src/simulation/power/simpleSolarPanel/simpleSolarPanel.h b/src/simulation/power/simpleSolarPanel/simpleSolarPanel.h index 223adb8431..34be3309ef 100644 --- a/src/simulation/power/simpleSolarPanel/simpleSolarPanel.h +++ b/src/simulation/power/simpleSolarPanel/simpleSolarPanel.h @@ -60,7 +60,7 @@ class SimpleSolarPanel: public PowerNodeBase { double sunDistanceFactor; //!< [-] Scale factor on the base solar power computed using the true s/c-sun distance. SpicePlanetStateMsgPayload sunData; //!< [-] Unused for now, but including it for future SCStatesMsgPayload stateCurrent; //!< [-] Current SSBI-relative state - double shadowFactor; //!< [-] solar eclipse shadow factor from 0 (fully obscured) to 1 (fully visible) + double illuminationFactor; //!< [-] solar eclipse illumination factor from 0 (fully obscured) to 1 (fully visible) }; diff --git a/src/simulation/sensors/coarseSunSensor/_UnitTest/test_coarseSunSensor.py b/src/simulation/sensors/coarseSunSensor/_UnitTest/test_coarseSunSensor.py index 7966f6acb2..d7e47e79ac 100644 --- a/src/simulation/sensors/coarseSunSensor/_UnitTest/test_coarseSunSensor.py +++ b/src/simulation/sensors/coarseSunSensor/_UnitTest/test_coarseSunSensor.py @@ -118,7 +118,7 @@ def run(show_plots, useConstellation, visibilityFactor, fov, kelly, scaleFactor, # create dummy eclipse message eclipseMsg = messaging.EclipseMsgPayload() - eclipseMsg.shadowFactor = visibilityFactor + eclipseMsg.illuminationFactor = visibilityFactor ecMsg = messaging.EclipseMsg().write(eclipseMsg) def setupCSS(CSS): diff --git a/src/simulation/sensors/coarseSunSensor/coarseSunSensor.cpp b/src/simulation/sensors/coarseSunSensor/coarseSunSensor.cpp index 88ed79f864..5e9c4805f3 100755 --- a/src/simulation/sensors/coarseSunSensor/coarseSunSensor.cpp +++ b/src/simulation/sensors/coarseSunSensor/coarseSunSensor.cpp @@ -58,7 +58,7 @@ CoarseSunSensor::CoarseSunSensor() this->setBodyToPlatformDCM(B2P321Angles[0], B2P321Angles[1], B2P321Angles[2]); this->setUnitDirectionVectorWithPerturbation(0, 0); this->sunVisibilityFactor = this->sunEclipseInMsg.zeroMsgPayload; - this->sunVisibilityFactor.shadowFactor = 1.0; + this->sunVisibilityFactor.illuminationFactor = 1.0; this->sunDistanceFactor = 1.0; this->dcm_PB.setIdentity(3,3); this->propagationMatrix.resize(1); @@ -264,7 +264,7 @@ void CoarseSunSensor::computeTrueOutput() this->trueValue *= this->sunDistanceFactor; // Also apply shadow factor. Basically, correct the intensity of the light. - this->trueValue *= this->sunVisibilityFactor.shadowFactor; + this->trueValue *= this->sunVisibilityFactor.illuminationFactor; // Adding albedo value (if defined by the user) if (this->albedoValue > 0.0){ diff --git a/src/simulation/thermal/sensorThermal/sensorThermal.cpp b/src/simulation/thermal/sensorThermal/sensorThermal.cpp index 30a1546887..f5c444fcc5 100644 --- a/src/simulation/thermal/sensorThermal/sensorThermal.cpp +++ b/src/simulation/thermal/sensorThermal/sensorThermal.cpp @@ -7,7 +7,7 @@ SensorThermal::SensorThermal(){ - this->shadowFactor = 1; + this->illuminationFactor = 1; // Set the required parameters from the constructor this->nHat_B.setZero(); @@ -37,7 +37,7 @@ SensorThermal::~SensorThermal(){ */ void SensorThermal::Reset(uint64_t CurrentClock) { - this->shadowFactor = 1.0; + this->illuminationFactor = 1.0; if (this->sensorArea <= 0.0) { bskLogger.bskLog(BSK_ERROR, "The sensorArea must be a positive value"); @@ -88,7 +88,7 @@ void SensorThermal::readMessages() if(this->sunEclipseInMsg.isLinked()) { EclipseMsgPayload sunVisibilityFactor; // sun visiblity input message sunVisibilityFactor = this->sunEclipseInMsg(); - this->shadowFactor = sunVisibilityFactor.shadowFactor; + this->illuminationFactor = sunVisibilityFactor.illuminationFactor; } //! if the device status msg is connected, read in and update sensor power status @@ -176,7 +176,7 @@ void SensorThermal::evaluateThermalModel(uint64_t CurrentSimSeconds) { this->computeSunData(); //! - Compute Q_in - this->Q_in = this->shadowFactor * this->S * this->projectedArea * this->sensorAbsorptivity + this->sensorPowerDraw * this->sensorPowerStatus; + this->Q_in = this->illuminationFactor * this->S * this->projectedArea * this->sensorAbsorptivity + this->sensorPowerDraw * this->sensorPowerStatus; //! - Compute Q_out this->Q_out = this->sensorArea * this->sensorEmissivity * this->boltzmannConst * pow((this->sensorTemp + 273.15), 4); diff --git a/src/simulation/thermal/sensorThermal/sensorThermal.h b/src/simulation/thermal/sensorThermal/sensorThermal.h index 00dcb5b06a..03dfbf44c0 100644 --- a/src/simulation/thermal/sensorThermal/sensorThermal.h +++ b/src/simulation/thermal/sensorThermal/sensorThermal.h @@ -74,7 +74,7 @@ class SensorThermal: public SysModel { double projectedArea; //!< [m^2] Area of the sensor projected along the sun vector. SpicePlanetStateMsgPayload sunData; //!< [-] sun message input buffer SCStatesMsgPayload stateCurrent; //!< [-] Current spacecraft state - double shadowFactor; //!< [-] solar eclipse shadow factor from 0 (fully obscured) to 1 (fully visible) + double illuminationFactor; //!< [-] solar eclipse illumination factor from 0 (fully obscured) to 1 (fully visible) double sensorTemp; //!< [C] Current temperature double Q_in; //!< [W] Current power in double Q_out; //!< [W] Current power out diff --git a/src/simulation/thermal/sensorThermal/sensorThermal.rst b/src/simulation/thermal/sensorThermal/sensorThermal.rst index 675bb7f531..c7796a46bf 100644 --- a/src/simulation/thermal/sensorThermal/sensorThermal.rst +++ b/src/simulation/thermal/sensorThermal/sensorThermal.rst @@ -51,10 +51,10 @@ radiative surface area, and :math:`T` is the current temperature of the sensor. The radiative thermal absorption, which comes only from the sun in this module, is given by: .. math:: - \dot{Q}_{\text{absorb}} = shadowFactor \cdot \alpha \cdot S \cdot A_{\text{proj}} + \dot{Q}_{\text{absorb}} = illuminationFactor \cdot \alpha \cdot S \cdot A_{\text{proj}} -The :math:`shadowFactor` is an indication of whether or not the sensor is in eclipse. A shadowFactor of 0 indicates the sensor -is in eclipse. Likewise, a shadowFactor of 1 indicates the sensor is not in eclipse. The :math:`\alpha` parameter +The :math:`illuminationFactor` is an indication of whether or not the sensor is in eclipse. An illuminationFactor of 0 indicates the sensor +is in eclipse. Likewise, an illuminationFactor of 1 indicates the sensor is not in eclipse. The :math:`\alpha` parameter is the absorptivity constant of the sensor. :math:`S` is the solar constant, and :math:`A_{\text{proj}}` is the projected area of the sensor with respect to incoming solar flux. @@ -160,4 +160,10 @@ The relevant messages are then connected to the module: sensorThermalModel.sunInMsg.subscribeTo(sunMsg) sensorThermalModel.stateInMsg.subscribeTo(scStateMsg) sensorThermalModel.sensorStatusInMsg.subscribeTo(sensorStatusMsg) - unitTestSim.AddModelToTask(unitTaskName, sensorThermalModel) \ No newline at end of file + unitTestSim.AddModelToTask(unitTaskName, sensorThermalModel) + +.. warning:: + + ``shadowFactor`` is **deprecated** in favor of ``illuminationFactor``. + In C/C++ both names work until **Dec 31, 2026**. After that date, code must + use ``illuminationFactor`` exclusively.