#ifndef MISSION_CONTROLLER_ACSCONTROLLER_H_ #define MISSION_CONTROLLER_ACSCONTROLLER_H_ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class AcsController : public ExtendedControllerBase, public ReceivesParameterMessagesIF { public: static constexpr dur_millis_t INIT_DELAY = 500; AcsController(object_id_t objectId, bool enableHkSets, SdCardMountedIF& sdcMan); MessageQueueId_t getCommandQueue() const; ReturnValue_t getParameter(uint8_t domainId, uint8_t parameterId, ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues, uint16_t startAtIndex) override; protected: private: static constexpr int16_t ZERO_VEC3_INT16[3] = {0, 0, 0}; static constexpr double ZERO_VEC3[3] = {0, 0, 0}; static constexpr double ZERO_VEC4[4] = {0, 0, 0, 0}; static constexpr double RW_OFF_TORQUE[4] = {0, 0, 0, 0}; static constexpr int32_t RW_OFF_SPEED[4] = {0, 0, 0, 0}; bool enableHkSets = false; SdCardMountedIF& sdcMan; timeval timeAbsolute; timeval timeRelative; double timeDelta = 0.0; timeval oldTimeRelative; AcsParameters acsParameters; SensorProcessing sensorProcessing; AttitudeEstimation attitudeEstimation; FusedRotationEstimation fusedRotationEstimation; Navigation navigation; ActuatorCmd actuatorCmd; Guidance guidance; SafeCtrl safeCtrl; Detumble detumble; PtgCtrl ptgCtrl; ParameterHelper parameterHelper; bool tleTooOldFlag = false; uint8_t detumbleCounter = 0; uint8_t multipleRwUnavailableCounter = 0; bool mekfInvalidFlag = false; uint16_t ptgCtrlLostCounter = 0; bool safeCtrlFailureFlag = false; uint8_t safeCtrlFailureCounter = 0; uint8_t resetMekfCount = 0; bool mekfLost = false; int32_t cmdSpeedRws[4] = {0, 0, 0, 0}; int16_t cmdDipoleMtqs[3] = {0, 0, 0}; acsctrl::RwAvail rwAvail; #if OBSW_THREAD_TRACING == 1 uint32_t opCounter = 0; #endif enum class InternalState { STARTUP, INITIAL_DELAY, READY }; InternalState internalState = InternalState::STARTUP; enum class DetumbleState { NO_DETUMBLE, DETUMBLE_FROM_PTG, PTG_TO_SAFE_TRANSITION, DETUMBLE_FROM_SAFE, IN_DETUMBLE }; DetumbleState detumbleState = DetumbleState::NO_DETUMBLE; /** Device command IDs */ static const DeviceCommandId_t SOLAR_ARRAY_DEPLOYMENT_SUCCESSFUL = 0x0; static const DeviceCommandId_t RESET_MEKF = 0x1; static const DeviceCommandId_t RESTORE_MEKF_NONFINITE_RECOVERY = 0x2; static const DeviceCommandId_t UPDATE_TLE = 0x3; static const DeviceCommandId_t READ_TLE = 0x4; static const DeviceCommandId_t UPDATE_MEKF_STANDARD_DEVIATIONS = 0x5; ReturnValue_t initialize() override; ReturnValue_t handleCommandMessage(CommandMessage* message) override; void performControlOperation() override; /* HasActionsIF overrides */ ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t* data, size_t size) override; ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, LocalDataPoolManager& poolManager) override; LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override; // Mode abstract functions ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, uint32_t* msToReachTheMode) override; void modeChanged(Mode_t mode, Submode_t submode); void announceMode(bool recursive); void performAttitudeControl(); void performSafe(); void performDetumble(); void performPointingCtrl(); void handleDetumbling(); void safeCtrlFailure(uint8_t mgmFailure, uint8_t sensorFailure); ReturnValue_t commandActuators(int16_t xDipole, int16_t yDipole, int16_t zDipole, uint16_t dipoleTorqueDuration); ReturnValue_t commandActuators(int16_t xDipole, int16_t yDipole, int16_t zDipole, uint16_t dipoleTorqueDuration, int32_t rw1Speed, int32_t rw2Speed, int32_t rw3Speed, int32_t rw4Speed, uint16_t rampTime); void updateActuatorCmdData(const int16_t* mtqTargetDipole); void updateActuatorCmdData(const double* rwTargetTorque, const int32_t* rwTargetSpeed, const int16_t* mtqTargetDipole); void updateCtrlValData(acs::ControlModeStrategy ctrlStrat); void updateCtrlValData(double errAng, acs::ControlModeStrategy ctrlStrat); void updateCtrlValData(const double* tgtQuat, const double* errQuat, double errAng, const double* tgtRotRate, acs::ControlModeStrategy cStrat); ReturnValue_t updateTle(const uint8_t* line1, const uint8_t* line2, bool fromFile); ReturnValue_t writeTleToFs(const uint8_t* tle); ReturnValue_t readTleFromFs(uint8_t* line1, uint8_t* line2); const std::string TLE_FILE = "/conf/tle.txt"; /* ACS Sensor Values */ ACS::SensorValues sensorValues; /* ACS Actuation Datasets */ imtq::DipoleActuationSet dipoleSet = imtq::DipoleActuationSet(objects::IMTQ_HANDLER); rws::RwSpeedActuationSet rw1SpeedSet = rws::RwSpeedActuationSet(objects::RW1); rws::RwSpeedActuationSet rw2SpeedSet = rws::RwSpeedActuationSet(objects::RW2); rws::RwSpeedActuationSet rw3SpeedSet = rws::RwSpeedActuationSet(objects::RW3); rws::RwSpeedActuationSet rw4SpeedSet = rws::RwSpeedActuationSet(objects::RW4); /* ACS Datasets */ // MGMs acsctrl::MgmDataRaw mgmDataRaw; PoolEntry mgm0VecRaw = PoolEntry(3); PoolEntry mgm1VecRaw = PoolEntry(3); PoolEntry mgm2VecRaw = PoolEntry(3); PoolEntry mgm3VecRaw = PoolEntry(3); PoolEntry imtqMgmVecRaw = PoolEntry(3); PoolEntry imtqCalActStatus = PoolEntry(); void copyMgmData(); acsctrl::MgmDataProcessed mgmDataProcessed; PoolEntry mgm0VecProc = PoolEntry(3); PoolEntry mgm1VecProc = PoolEntry(3); PoolEntry mgm2VecProc = PoolEntry(3); PoolEntry mgm3VecProc = PoolEntry(3); PoolEntry mgm4VecProc = PoolEntry(3); PoolEntry mgmVecTot = PoolEntry(3); PoolEntry mgmVecTotDer = PoolEntry(3); PoolEntry magIgrf = PoolEntry(3); // SUSs acsctrl::SusDataRaw susDataRaw; PoolEntry sus0ValRaw = PoolEntry(6); PoolEntry sus1ValRaw = PoolEntry(6); PoolEntry sus2ValRaw = PoolEntry(6); PoolEntry sus3ValRaw = PoolEntry(6); PoolEntry sus4ValRaw = PoolEntry(6); PoolEntry sus5ValRaw = PoolEntry(6); PoolEntry sus6ValRaw = PoolEntry(6); PoolEntry sus7ValRaw = PoolEntry(6); PoolEntry sus8ValRaw = PoolEntry(6); PoolEntry sus9ValRaw = PoolEntry(6); PoolEntry sus10ValRaw = PoolEntry(6); PoolEntry sus11ValRaw = PoolEntry(6); void copySusData(); acsctrl::SusDataProcessed susDataProcessed; PoolEntry sus0VecProc = PoolEntry(3); PoolEntry sus1VecProc = PoolEntry(3); PoolEntry sus2VecProc = PoolEntry(3); PoolEntry sus3VecProc = PoolEntry(3); PoolEntry sus4VecProc = PoolEntry(3); PoolEntry sus5VecProc = PoolEntry(3); PoolEntry sus6VecProc = PoolEntry(3); PoolEntry sus7VecProc = PoolEntry(3); PoolEntry sus8VecProc = PoolEntry(3); PoolEntry sus9VecProc = PoolEntry(3); PoolEntry sus10VecProc = PoolEntry(3); PoolEntry sus11VecProc = PoolEntry(3); PoolEntry susVecTot = PoolEntry(3); PoolEntry susVecTotDer = PoolEntry(3); PoolEntry sunIjk = PoolEntry(3); // GYRs acsctrl::GyrDataRaw gyrDataRaw; PoolEntry gyr0VecRaw = PoolEntry(3); PoolEntry gyr1VecRaw = PoolEntry(3); PoolEntry gyr2VecRaw = PoolEntry(3); PoolEntry gyr3VecRaw = PoolEntry(3); void copyGyrData(); acsctrl::GyrDataProcessed gyrDataProcessed; PoolEntry gyr0VecProc = PoolEntry(3); PoolEntry gyr1VecProc = PoolEntry(3); PoolEntry gyr2VecProc = PoolEntry(3); PoolEntry gyr3VecProc = PoolEntry(3); PoolEntry gyrVecTot = PoolEntry(3); // GPS acsctrl::GpsDataProcessed gpsDataProcessed; PoolEntry gcLatitude = PoolEntry(); PoolEntry gdLongitude = PoolEntry(); PoolEntry altitude = PoolEntry(); PoolEntry gpsPosition = PoolEntry(3); PoolEntry gpsVelocity = PoolEntry(3); PoolEntry gpsSource = PoolEntry(); // Attitude Estimation acsctrl::AttitudeEstimationData attitudeEstimationData; PoolEntry quatMekf = PoolEntry(4); PoolEntry satRotRateMekf = PoolEntry(3); PoolEntry mekfStatus = PoolEntry(); PoolEntry quatQuest = PoolEntry(4); // Ctrl Values acsctrl::CtrlValData ctrlValData; PoolEntry safeStrat = PoolEntry(); PoolEntry tgtQuat = PoolEntry(4); PoolEntry errQuat = PoolEntry(4); PoolEntry errAng = PoolEntry(); PoolEntry tgtRotRate = PoolEntry(3); // Actuator CMD acsctrl::ActuatorCmdData actuatorCmdData; PoolEntry rwTargetTorque = PoolEntry(4); PoolEntry rwTargetSpeed = PoolEntry(4); PoolEntry mtqTargetDipole = PoolEntry(3); // Fused Rot Rate acsctrl::FusedRotRateData fusedRotRateData; PoolEntry rotRateOrthogonal = PoolEntry(3); PoolEntry rotRateParallel = PoolEntry(3); PoolEntry rotRateTotal = PoolEntry(3); PoolEntry rotRateSource = PoolEntry(); // Fused Rot Rate Sources acsctrl::FusedRotRateSourcesData fusedRotRateSourcesData; PoolEntry rotRateOrthogonalSusMgm = PoolEntry(3); PoolEntry rotRateParallelSusMgm = PoolEntry(3); PoolEntry rotRateTotalSusMgm = PoolEntry(3); PoolEntry rotRateTotalQuest = PoolEntry(3); PoolEntry rotRateTotalStr = PoolEntry(3); // Initial delay to make sure all pool variables have been initialized their owners Countdown initialCountdown = Countdown(INIT_DELAY); // Countdown after which the detumbling mode change should have been finished static constexpr dur_millis_t MAX_DURATION = 60 * 1e3; Countdown detumbleTransitionCountdow = Countdown(MAX_DURATION); }; #endif /* MISSION_CONTROLLER_ACSCONTROLLER_H_ */