2022-02-23 19:08:12 +01:00
|
|
|
#ifndef MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_
|
|
|
|
#define MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_
|
|
|
|
|
2022-10-12 17:23:54 +02:00
|
|
|
#include <fsfw/globalfunctions/PeriodicOperationDivider.h>
|
2023-03-26 16:42:00 +02:00
|
|
|
#include <mission/utility/trace.h>
|
2022-10-13 15:09:47 +02:00
|
|
|
|
2022-10-12 14:24:45 +02:00
|
|
|
#include <unordered_map>
|
|
|
|
|
2022-10-12 14:09:07 +02:00
|
|
|
#include "devices/powerSwitcherList.h"
|
2022-10-12 17:18:57 +02:00
|
|
|
#include "eive/definitions.h"
|
2022-10-12 14:24:45 +02:00
|
|
|
#include "events/subsystemIdRanges.h"
|
2022-10-12 14:09:07 +02:00
|
|
|
#include "fsfw/action/HasActionsIF.h"
|
|
|
|
#include "fsfw/devicehandlers/CookieIF.h"
|
|
|
|
#include "fsfw/devicehandlers/DeviceHandlerIF.h"
|
|
|
|
#include "fsfw/objectmanager/SystemObject.h"
|
|
|
|
#include "fsfw/power/PowerSwitchIF.h"
|
|
|
|
#include "fsfw/returnvalues/returnvalue.h"
|
2022-10-13 15:09:47 +02:00
|
|
|
#include "fsfw/serialize/SerialLinkedListAdapter.h"
|
2022-10-12 14:09:07 +02:00
|
|
|
#include "fsfw/tasks/ExecutableObjectIF.h"
|
|
|
|
#include "fsfw/timemanager/Countdown.h"
|
|
|
|
#include "fsfw_hal/common/gpio/GpioIF.h"
|
|
|
|
#include "mission/memory/SdCardMountedIF.h"
|
2022-09-14 13:44:43 +02:00
|
|
|
#include "returnvalues/classIds.h"
|
|
|
|
|
2022-10-13 15:09:47 +02:00
|
|
|
enum DeploymentChannels : uint8_t { SA_1 = 1, SA_2 = 2 };
|
|
|
|
|
2022-10-13 15:13:19 +02:00
|
|
|
class ManualDeploymentCommand : public SerialLinkedListAdapter<SerializeIF> {
|
2022-10-13 15:09:47 +02:00
|
|
|
public:
|
2022-10-14 11:55:21 +02:00
|
|
|
ManualDeploymentCommand() { setLinks(); }
|
2022-10-13 15:09:47 +02:00
|
|
|
|
|
|
|
void setLinks() {
|
2023-01-20 11:51:29 +01:00
|
|
|
setStart(&burnTimeSecs);
|
|
|
|
burnTimeSecs.setNext(&switchIntervalMs);
|
2023-01-20 12:24:19 +01:00
|
|
|
switchIntervalMs.setNext(&initChannel);
|
|
|
|
initChannel.setNext(&dryRun);
|
2022-10-13 15:09:47 +02:00
|
|
|
}
|
|
|
|
|
2023-01-20 11:51:29 +01:00
|
|
|
uint32_t getBurnTimeSecs() const { return burnTimeSecs.entry; }
|
|
|
|
|
|
|
|
uint32_t getSwitchIntervalMs() const { return switchIntervalMs.entry; };
|
2022-10-13 15:59:56 +02:00
|
|
|
|
2023-01-20 12:24:19 +01:00
|
|
|
uint8_t getInitChannel() const { return initChannel.entry; };
|
|
|
|
|
2022-10-13 17:34:33 +02:00
|
|
|
bool isDryRun() const { return dryRun.entry; }
|
|
|
|
|
2022-10-13 15:09:47 +02:00
|
|
|
private:
|
2023-01-20 11:51:29 +01:00
|
|
|
SerializeElement<uint32_t> burnTimeSecs;
|
|
|
|
SerializeElement<uint32_t> switchIntervalMs;
|
2023-01-20 12:24:19 +01:00
|
|
|
SerializeElement<uint8_t> initChannel;
|
2022-10-13 17:34:33 +02:00
|
|
|
SerializeElement<uint8_t> dryRun;
|
2022-10-13 15:09:47 +02:00
|
|
|
};
|
|
|
|
|
2022-02-23 19:08:12 +01:00
|
|
|
/**
|
|
|
|
* @brief This class is used to control the solar array deployment.
|
|
|
|
*
|
|
|
|
* @author J. Meier
|
|
|
|
*/
|
|
|
|
class SolarArrayDeploymentHandler : public ExecutableObjectIF,
|
|
|
|
public SystemObject,
|
|
|
|
public HasActionsIF {
|
|
|
|
public:
|
2023-01-20 12:31:42 +01:00
|
|
|
//! Manual deployment of the solar arrays. Burn time, channel switch interval, initial
|
|
|
|
//! burn channel and dry run flag are supplied as parameters. There are following cases to
|
|
|
|
//! consider.
|
2023-01-20 11:51:29 +01:00
|
|
|
//!
|
2023-01-20 12:31:42 +01:00
|
|
|
//! - Channel switch interval greater or equal to burn time: Only burn one channel. The init
|
|
|
|
//! burn channel parameter can be used to select which channel is burned.
|
2023-01-20 11:51:29 +01:00
|
|
|
//! - Channel switch interval half of burn time: Burn each channel for half of the burn time.
|
|
|
|
//!
|
|
|
|
//! The dry run flag can be used to avoid actually toggling IO pins and only test the
|
|
|
|
//! application logic.
|
2022-10-12 17:21:10 +02:00
|
|
|
static constexpr DeviceCommandId_t DEPLOY_SOLAR_ARRAYS_MANUALLY = 0x05;
|
2022-10-13 15:59:56 +02:00
|
|
|
static constexpr DeviceCommandId_t SWITCH_OFF_DEPLOYMENT = 0x06;
|
2022-10-12 15:19:21 +02:00
|
|
|
|
2022-10-13 17:34:33 +02:00
|
|
|
static constexpr uint32_t FIRST_BURN_START_TIME = config::SA_DEPL_INIT_BUFFER_SECS;
|
2022-10-12 17:18:57 +02:00
|
|
|
static constexpr uint32_t FIRST_BURN_END_TIME =
|
|
|
|
FIRST_BURN_START_TIME + config::SA_DEPL_BURN_TIME_SECS;
|
|
|
|
static constexpr uint32_t WAIT_START_TIME = FIRST_BURN_END_TIME;
|
|
|
|
static constexpr uint32_t WAIT_END_TIME = WAIT_START_TIME + config::SA_DEPL_WAIT_TIME_SECS;
|
|
|
|
static constexpr uint32_t SECOND_BURN_START_TIME = WAIT_END_TIME;
|
|
|
|
static constexpr uint32_t SECOND_BURN_END_TIME =
|
|
|
|
SECOND_BURN_START_TIME + config::SA_DEPL_WAIT_TIME_SECS;
|
2022-10-12 15:19:21 +02:00
|
|
|
|
|
|
|
static constexpr char SD_0_DEPL_FILE[] = "/mnt/sd0/conf/deployment";
|
|
|
|
static constexpr char SD_1_DEPL_FILE[] = "/mnt/sd1/conf/deployment";
|
|
|
|
static constexpr char SD_0_DEPLY_INFO[] = "/mnt/sd0/conf/deployment_info.txt";
|
|
|
|
static constexpr char SD_1_DEPLY_INFO[] = "/mnt/sd1/conf/deployment_info.txt";
|
|
|
|
|
|
|
|
static constexpr char PHASE_INIT_STR[] = "init";
|
|
|
|
static constexpr char PHASE_FIRST_BURN_STR[] = "first_burn";
|
|
|
|
static constexpr char PHASE_WAIT_STR[] = "wait";
|
|
|
|
static constexpr char PHASE_SECOND_BURN_STR[] = "second_burn";
|
|
|
|
static constexpr char PHASE_DONE[] = "done";
|
2022-02-23 19:08:12 +01:00
|
|
|
/**
|
|
|
|
* @brief constructor
|
|
|
|
*
|
|
|
|
* @param setObjectId The object id of the SolarArrayDeploymentHandler.
|
|
|
|
* @param gpioDriverId The id of the gpio com if.
|
|
|
|
* @param gpioCookie GpioCookie holding information about the gpios used to switch the
|
|
|
|
* transistors.
|
|
|
|
* @param mainLineSwitcherObjectId The object id of the object responsible for switching
|
|
|
|
* the 8V power source. This is normally the PCDU.
|
|
|
|
* @param mainLineSwitch The id of the main line switch. This is defined in
|
|
|
|
* powerSwitcherList.h.
|
|
|
|
* @param deplSA1 gpioId of the GPIO controlling the deployment 1 transistor.
|
|
|
|
* @param deplSA2 gpioId of the GPIO controlling the deployment 2 transistor.
|
|
|
|
* @param burnTimeMs Time duration the power will be applied to the burn wires.
|
|
|
|
*/
|
2022-10-12 13:56:25 +02:00
|
|
|
SolarArrayDeploymentHandler(object_id_t setObjectId, GpioIF& gpio,
|
2023-03-16 18:47:51 +01:00
|
|
|
PowerSwitchIF& mainLineSwitcher, power::Switches mainLineSwitch,
|
2022-10-12 14:24:45 +02:00
|
|
|
gpioId_t deplSA1, gpioId_t deplSA2, SdCardMountedIF& sdcMountedIF);
|
2022-02-23 19:08:12 +01:00
|
|
|
|
|
|
|
virtual ~SolarArrayDeploymentHandler();
|
|
|
|
|
|
|
|
virtual ReturnValue_t performOperation(uint8_t operationCode = 0) override;
|
|
|
|
|
|
|
|
virtual MessageQueueId_t getCommandQueue() const override;
|
|
|
|
virtual ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
|
|
|
const uint8_t* data, size_t size) override;
|
|
|
|
virtual ReturnValue_t initialize() override;
|
|
|
|
|
|
|
|
private:
|
2022-10-13 16:04:34 +02:00
|
|
|
enum AutonomousDeplState { INIT, FIRST_BURN, WAIT, SECOND_BURN, DONE };
|
|
|
|
|
|
|
|
enum StateMachine {
|
|
|
|
IDLE,
|
|
|
|
MAIN_POWER_ON,
|
|
|
|
MAIN_POWER_OFF,
|
|
|
|
WAIT_MAIN_POWER_ON,
|
|
|
|
WAIT_MAIN_POWER_OFF,
|
|
|
|
SWITCH_DEPL_GPIOS,
|
2022-10-13 17:34:33 +02:00
|
|
|
BURNING
|
2022-10-13 16:04:34 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
struct FsmInfo {
|
2022-10-13 17:34:33 +02:00
|
|
|
// Not required anymore
|
|
|
|
// DeploymentChannels channel;
|
2022-10-13 16:04:34 +02:00
|
|
|
bool dryRun;
|
2022-10-13 17:34:33 +02:00
|
|
|
bool alternationDummy = false;
|
2023-01-20 12:24:19 +01:00
|
|
|
uint8_t initChannel = 0;
|
2022-10-13 18:42:47 +02:00
|
|
|
uint32_t burnCountdownMs = config::SA_DEPL_MAX_BURN_TIME;
|
2022-10-13 16:04:34 +02:00
|
|
|
};
|
|
|
|
|
2022-02-23 19:08:12 +01:00
|
|
|
static const uint8_t INTERFACE_ID = CLASS_ID::SA_DEPL_HANDLER;
|
|
|
|
static const ReturnValue_t COMMAND_NOT_SUPPORTED = MAKE_RETURN_CODE(0xA0);
|
|
|
|
static const ReturnValue_t DEPLOYMENT_ALREADY_EXECUTING = MAKE_RETURN_CODE(0xA1);
|
|
|
|
static const ReturnValue_t MAIN_SWITCH_TIMEOUT_FAILURE = MAKE_RETURN_CODE(0xA2);
|
|
|
|
static const ReturnValue_t SWITCHING_DEPL_SA1_FAILED = MAKE_RETURN_CODE(0xA3);
|
|
|
|
static const ReturnValue_t SWITCHING_DEPL_SA2_FAILED = MAKE_RETURN_CODE(0xA4);
|
|
|
|
|
|
|
|
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SA_DEPL_HANDLER;
|
2022-10-14 11:55:21 +02:00
|
|
|
|
|
|
|
//! [EXPORT] : [COMMENT] P1: Burn duration in milliseconds, P2: Dry run flag
|
|
|
|
static constexpr Event BURN_PHASE_START = event::makeEvent(SUBSYSTEM_ID, 0, severity::INFO);
|
|
|
|
//! [EXPORT] : [COMMENT] P1: Burn duration in milliseconds, P2: Dry run flag
|
|
|
|
static constexpr Event BURN_PHASE_DONE = event::makeEvent(SUBSYSTEM_ID, 1, severity::INFO);
|
|
|
|
static constexpr Event MAIN_SWITCH_ON_TIMEOUT = event::makeEvent(SUBSYSTEM_ID, 2, severity::LOW);
|
|
|
|
static constexpr Event MAIN_SWITCH_OFF_TIMEOUT = event::makeEvent(SUBSYSTEM_ID, 3, severity::LOW);
|
|
|
|
static constexpr Event DEPL_SA1_GPIO_SWTICH_ON_FAILED =
|
|
|
|
event::makeEvent(SUBSYSTEM_ID, 4, severity::HIGH);
|
|
|
|
static constexpr Event DEPL_SA2_GPIO_SWTICH_ON_FAILED =
|
|
|
|
event::makeEvent(SUBSYSTEM_ID, 5, severity::HIGH);
|
|
|
|
static constexpr Event DEPL_SA1_GPIO_SWTICH_OFF_FAILED =
|
|
|
|
event::makeEvent(SUBSYSTEM_ID, 6, severity::HIGH);
|
|
|
|
static constexpr Event DEPL_SA2_GPIO_SWTICH_OFF_FAILED =
|
|
|
|
event::makeEvent(SUBSYSTEM_ID, 7, severity::HIGH);
|
2022-10-14 14:55:37 +02:00
|
|
|
static constexpr Event AUTONOMOUS_DEPLOYMENT_COMPLETED =
|
|
|
|
event::makeEvent(SUBSYSTEM_ID, 8, severity::INFO);
|
2022-02-23 19:08:12 +01:00
|
|
|
|
2022-10-13 16:04:34 +02:00
|
|
|
FsmInfo fsmInfo;
|
2022-10-12 17:18:57 +02:00
|
|
|
StateMachine stateMachine = IDLE;
|
|
|
|
bool actionActive = false;
|
2022-10-14 15:05:44 +02:00
|
|
|
bool firstAutonomousCycle = true;
|
2022-10-12 17:18:57 +02:00
|
|
|
ActionId_t activeCmd = HasActionsIF::INVALID_ACTION_ID;
|
|
|
|
std::optional<uint64_t> initUptime;
|
2023-02-14 10:59:35 +01:00
|
|
|
#if OBSW_THREAD_TRACING == 1
|
2023-02-14 11:10:18 +01:00
|
|
|
uint32_t opCounter = 0;
|
2023-02-14 10:59:35 +01:00
|
|
|
#endif
|
2022-10-12 17:23:54 +02:00
|
|
|
PeriodicOperationDivider opDivider = PeriodicOperationDivider(5);
|
2022-10-12 17:18:57 +02:00
|
|
|
uint8_t retryCounter = 3;
|
2022-10-13 15:59:56 +02:00
|
|
|
|
2023-01-20 12:24:19 +01:00
|
|
|
bool startFsmOn(uint32_t burnCountdownSecs, uint32_t channelAlternationIntervalMs,
|
|
|
|
uint8_t initChannel, bool dryRun);
|
2022-10-13 15:59:56 +02:00
|
|
|
void startFsmOff();
|
|
|
|
|
2022-10-12 17:18:57 +02:00
|
|
|
void finishFsm(ReturnValue_t resultForActionHelper);
|
2022-10-12 14:24:45 +02:00
|
|
|
|
2022-10-13 17:34:33 +02:00
|
|
|
ReturnValue_t performAutonomousDepl(sd::SdCard sdCard, bool dryRun);
|
|
|
|
bool dryRunStringInFile(const char* filename);
|
2022-10-14 14:55:37 +02:00
|
|
|
bool autonomousDeplForFile(sd::SdCard sdCard, const char* filename, bool dryRun);
|
2022-02-23 19:08:12 +01:00
|
|
|
/**
|
|
|
|
* This countdown is used to check if the PCDU sets the 8V line on in the intended time.
|
|
|
|
*/
|
|
|
|
Countdown mainSwitchCountdown;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This countdown is used to wait for the burn wire being successful cut.
|
|
|
|
*/
|
2022-10-13 15:59:56 +02:00
|
|
|
Countdown burnCountdown;
|
2022-02-23 19:08:12 +01:00
|
|
|
|
2023-01-20 11:51:29 +01:00
|
|
|
// Only initial value, new approach is to burn each channel half of the total burn time.
|
2022-10-14 13:30:35 +02:00
|
|
|
Countdown channelAlternationCd =
|
2023-01-20 11:51:29 +01:00
|
|
|
Countdown(config::LEGACY_SA_DEPL_CHANNEL_ALTERNATION_INTERVAL_SECS * 1000);
|
2022-10-13 17:34:33 +02:00
|
|
|
|
2022-02-23 19:08:12 +01:00
|
|
|
/**
|
|
|
|
* The message queue id of the component commanding an action will be stored in this variable.
|
|
|
|
* This is necessary to send later the action finish replies.
|
|
|
|
*/
|
|
|
|
MessageQueueId_t rememberCommanderId = 0;
|
|
|
|
|
|
|
|
/** Size of command queue */
|
|
|
|
size_t cmdQueueSize = 20;
|
2022-10-12 13:56:25 +02:00
|
|
|
GpioIF& gpioInterface;
|
2022-02-23 19:08:12 +01:00
|
|
|
gpioId_t deplSA1;
|
|
|
|
gpioId_t deplSA2;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* After initialization this pointer will hold the reference to the main line switcher object.
|
|
|
|
*/
|
2022-10-12 13:21:58 +02:00
|
|
|
PowerSwitchIF& mainLineSwitcher;
|
|
|
|
|
|
|
|
/** Switch number of the 8V power switch */
|
|
|
|
uint8_t mainLineSwitch;
|
2022-02-23 19:08:12 +01:00
|
|
|
|
2022-10-12 14:24:45 +02:00
|
|
|
SdCardMountedIF& sdcMan;
|
|
|
|
|
2022-02-23 19:08:12 +01:00
|
|
|
ActionHelper actionHelper;
|
|
|
|
|
2022-10-12 14:24:45 +02:00
|
|
|
/** Queue to receive messages from other objects. */
|
|
|
|
MessageQueueIF* commandQueue = nullptr;
|
|
|
|
|
2022-02-23 19:08:12 +01:00
|
|
|
void readCommandQueue();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief This function performs actions dependent on the current state.
|
|
|
|
*/
|
|
|
|
void handleStateMachine();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief This function polls the 8V switch state and changes the state machine when the
|
|
|
|
* switch has been enabled.
|
|
|
|
*/
|
2022-10-12 17:18:57 +02:00
|
|
|
bool checkMainPowerOn();
|
|
|
|
bool checkMainPowerOff();
|
|
|
|
bool checkMainPower(bool onOff);
|
2022-02-23 19:08:12 +01:00
|
|
|
|
2022-10-13 15:59:56 +02:00
|
|
|
void allOff();
|
|
|
|
|
2022-10-13 17:34:33 +02:00
|
|
|
ReturnValue_t deploymentTransistorsOff();
|
|
|
|
ReturnValue_t saGpioAlternation();
|
|
|
|
ReturnValue_t sa1On();
|
|
|
|
ReturnValue_t sa1Off();
|
|
|
|
ReturnValue_t sa2On();
|
|
|
|
ReturnValue_t sa2Off();
|
2022-02-23 19:08:12 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif /* MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_ */
|