From b6b258d82ce23e4ad44d29656607dcb5721d4fc0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 12 Oct 2022 13:21:58 +0200 Subject: [PATCH 01/35] remove gpio pst --- bsp_q7s/core/InitMission.cpp | 37 +-- bsp_q7s/core/ObjectFactory.cpp | 6 +- bsp_q7s/core/ObjectFactory.h | 2 +- bsp_q7s/fmObjectFactory.cpp | 2 +- .../pollingSequenceFactory.cpp | 16 -- .../pollingsequence/pollingSequenceFactory.h | 3 - .../devices/SolarArrayDeploymentHandler.cpp | 225 +++++++++--------- mission/devices/SolarArrayDeploymentHandler.h | 47 ++-- 8 files changed, 152 insertions(+), 186 deletions(-) diff --git a/bsp_q7s/core/InitMission.cpp b/bsp_q7s/core/InitMission.cpp index a5cc3df9..d74581c7 100644 --- a/bsp_q7s/core/InitMission.cpp +++ b/bsp_q7s/core/InitMission.cpp @@ -211,13 +211,27 @@ void initmission::initTasks() { tcsTask->addComponent(rtd, DeviceHandlerIF::SEND_READ); tcsTask->addComponent(rtd, DeviceHandlerIF::GET_READ); } - tcsTask->addComponent(objects::TCS_BOARD_ASS); -#endif /* OBSW_ADD_RTD_DEVICES */ - -#if OBSW_ADD_TCS_CTRL == 1 - tcsTask->addComponent(objects::THERMAL_CONTROLLER); #endif + PeriodicTaskIF* tcsSystemTask = factory->createPeriodicTask( + "TCS_TASK", 45, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.5, missedDeadlineFunc); +#if OBSW_ADD_RTD_DEVICES == 1 + result = tcsSystemTask->addComponent(objects::TCS_BOARD_ASS); + if (result != returnvalue::OK) { + initmission::printAddObjectError("TCS_BOARD_ASS", objects::TCS_BOARD_ASS); + } +#endif /* OBSW_ADD_RTD_DEVICES */ +#if OBSW_ADD_TCS_CTRL == 1 + result = tcsSystemTask->addComponent(objects::THERMAL_CONTROLLER); + if (result != returnvalue::OK) { + initmission::printAddObjectError("THERMAL_CONTROLLER", objects::THERMAL_CONTROLLER); + } +#endif + result = tcsSystemTask->addComponent(objects::HEATER_HANDLER); + if (result != returnvalue::OK) { + initmission::printAddObjectError("HEATER_HANDLER", objects::HEATER_HANDLER); + } + #if OBSW_ADD_STAR_TRACKER == 1 PeriodicTaskIF* strHelperTask = factory->createPeriodicTask( "STR_HELPER", 20, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); @@ -319,6 +333,7 @@ void initmission::initTasks() { tcsPollingTask->startTask(); tcsTask->startTask(); #endif /* OBSW_ADD_RTD_DEVICES == 1 */ + tcsSystemTask->startTask(); #if OBSW_ADD_PLOC_SUPERVISOR == 1 supvHelperTask->startTask(); #endif /* OBSW_ADD_PLOC_SUPERVISOR == 1 */ @@ -378,18 +393,6 @@ void initmission::createPstTasks(TaskFactory& factory, taskVec.push_back(uartPst); } - FixedTimeslotTaskIF* gpioPst = factory.createFixedTimeslotTask( - "GPIO_PST", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 0.2, missedDeadlineFunc); - result = pst::pstGpio(gpioPst); - if (result != returnvalue::OK) { - if (result == FixedTimeslotTaskIF::SLOT_LIST_EMPTY) { - sif::warning << "InitMission::initTasks: GPIO PST is empty" << std::endl; - } else { - sif::error << "InitMission::initTasks: Creating GPIO PST failed!" << std::endl; - } - } else { - taskVec.push_back(gpioPst); - } #if OBSW_ADD_I2C_TEST_CODE == 0 FixedTimeslotTaskIF* i2cPst = factory.createFixedTimeslotTask( "I2C_PST", 65, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.2, missedDeadlineFunc); diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 80dcb55e..db2779bd 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -539,7 +539,7 @@ void ObjectFactory::createHeaterComponents(GpioIF* gpioIF, PowerSwitchIF* pwrSwi pcdu::Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V); } -void ObjectFactory::createSolarArrayDeploymentComponents() { +void ObjectFactory::createSolarArrayDeploymentComponents(PowerSwitchIF& pwrSwitcher) { using namespace gpio; GpioCookie* solarArrayDeplCookie = new GpioCookie; GpiodRegularByLineName* gpio = nullptr; @@ -555,9 +555,9 @@ void ObjectFactory::createSolarArrayDeploymentComponents() { // TODO: Find out burn time. For now set to 1000 ms. new SolarArrayDeploymentHandler(objects::SOLAR_ARRAY_DEPL_HANDLER, objects::GPIO_IF, - solarArrayDeplCookie, objects::PCDU_HANDLER, + solarArrayDeplCookie, pwrSwitcher, pcdu::Switches::PDU2_CH5_DEPLOYMENT_MECHANISM_8V, - gpioIds::DEPLSA1, gpioIds::DEPLSA2, 1000); + gpioIds::DEPLSA1, gpioIds::DEPLSA2); } void ObjectFactory::createSyrlinksComponents(PowerSwitchIF* pwrSwitcher) { diff --git a/bsp_q7s/core/ObjectFactory.h b/bsp_q7s/core/ObjectFactory.h index 0b81c235..37cdc70e 100644 --- a/bsp_q7s/core/ObjectFactory.h +++ b/bsp_q7s/core/ObjectFactory.h @@ -33,7 +33,7 @@ void createHeaterComponents(GpioIF* gpioIF, PowerSwitchIF* pwrSwitcher, HealthTa void createImtqComponents(PowerSwitchIF* pwrSwitcher); void createBpxBatteryComponent(); void createStrComponents(PowerSwitchIF* pwrSwitcher); -void createSolarArrayDeploymentComponents(); +void createSolarArrayDeploymentComponents(PowerSwitchIF& pwrSwitcher); void createSyrlinksComponents(PowerSwitchIF* pwrSwitcher); void createPayloadComponents(LinuxLibgpioIF* gpioComIF); void createReactionWheelComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF* pwrSwitcher); diff --git a/bsp_q7s/fmObjectFactory.cpp b/bsp_q7s/fmObjectFactory.cpp index 1746c048..413223d8 100644 --- a/bsp_q7s/fmObjectFactory.cpp +++ b/bsp_q7s/fmObjectFactory.cpp @@ -35,7 +35,7 @@ void ObjectFactory::produce(void* args) { createAcsBoardComponents(gpioComIF, uartComIF, pwrSwitcher); #endif createHeaterComponents(gpioComIF, pwrSwitcher, healthTable); - createSolarArrayDeploymentComponents(); + createSolarArrayDeploymentComponents(*pwrSwitcher); createPlPcduComponents(gpioComIF, spiMainComIF, pwrSwitcher); #if OBSW_ADD_SYRLINKS == 1 createSyrlinksComponents(pwrSwitcher); diff --git a/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp b/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp index e11632c8..0d75588f 100644 --- a/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp +++ b/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp @@ -15,22 +15,6 @@ #define RPI_TEST_GPS_HANDLER 0 #endif -ReturnValue_t pst::pstGpio(FixedTimeslotTaskIF *thisSequence) { - // Length of a communication cycle - uint32_t length = thisSequence->getPeriodMs(); - - thisSequence->addSlot(objects::HEATER_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::SOLAR_ARRAY_DEPL_HANDLER, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - - if (thisSequence->checkSequence() == returnvalue::OK) { - return returnvalue::OK; - } - - sif::error << "PollingSequence::initialize has errors!" << std::endl; - return returnvalue::FAILED; -} - ReturnValue_t pst::pstSpiRw(FixedTimeslotTaskIF *thisSequence) { uint32_t length = thisSequence->getPeriodMs(); static_cast(length); diff --git a/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.h b/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.h index 960820b5..1b585d81 100644 --- a/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.h +++ b/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.h @@ -31,9 +31,6 @@ class FixedTimeslotTaskIF; */ namespace pst { -/* 0.4 second period init*/ -ReturnValue_t pstGpio(FixedTimeslotTaskIF* thisSequence); - /** * @brief This function creates the PST for all gomspace devices. * @details diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index c4e9a43b..63425615 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -7,16 +7,15 @@ SolarArrayDeploymentHandler::SolarArrayDeploymentHandler( object_id_t setObjectId_, object_id_t gpioDriverId_, CookieIF* gpioCookie_, - object_id_t mainLineSwitcherObjectId_, pcdu::Switches mainLineSwitch_, gpioId_t deplSA1, - gpioId_t deplSA2, uint32_t burnTimeMs) + PowerSwitchIF& mainLineSwitcher_, pcdu::Switches mainLineSwitch_, gpioId_t deplSA1, + gpioId_t deplSA2) : SystemObject(setObjectId_), gpioDriverId(gpioDriverId_), gpioCookie(gpioCookie_), - mainLineSwitcherObjectId(mainLineSwitcherObjectId_), - mainLineSwitch(mainLineSwitch_), deplSA1(deplSA1), deplSA2(deplSA2), - burnTimeMs(burnTimeMs), + mainLineSwitcher(mainLineSwitcher_), + mainLineSwitch(mainLineSwitch_), actionHelper(this, nullptr) { auto mqArgs = MqArgs(setObjectId_, static_cast(this)); commandQueue = QueueFactory::instance()->createMessageQueue( @@ -52,16 +51,6 @@ ReturnValue_t SolarArrayDeploymentHandler::initialize() { return ObjectManagerIF::CHILD_INIT_FAILED; } - if (mainLineSwitcherObjectId != objects::NO_OBJECT) { - mainLineSwitcher = ObjectManager::instance()->get(mainLineSwitcherObjectId); - if (mainLineSwitcher == nullptr) { - sif::error - << "SolarArrayDeploymentHandler::initialize: Main line switcher failed to fetch object" - << "from object ID." << std::endl; - return ObjectManagerIF::CHILD_INIT_FAILED; - } - } - result = actionHelper.initialize(commandQueue); if (result != returnvalue::OK) { return ObjectManagerIF::CHILD_INIT_FAILED; @@ -71,102 +60,102 @@ ReturnValue_t SolarArrayDeploymentHandler::initialize() { } void SolarArrayDeploymentHandler::handleStateMachine() { - switch (stateMachine) { - case WAIT_ON_DELOYMENT_COMMAND: - readCommandQueue(); - break; - case SWITCH_8V_ON: - mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_ON); - mainSwitchCountdown.setTimeout(mainLineSwitcher->getSwitchDelayMs()); - stateMachine = WAIT_ON_8V_SWITCH; - break; - case WAIT_ON_8V_SWITCH: - performWaitOn8VActions(); - break; - case SWITCH_DEPL_GPIOS: - switchDeploymentTransistors(); - break; - case WAIT_ON_DEPLOYMENT_FINISH: - handleDeploymentFinish(); - break; - case WAIT_FOR_MAIN_SWITCH_OFF: - if (mainLineSwitcher->getSwitchState(mainLineSwitch) == PowerSwitchIF::SWITCH_OFF) { - stateMachine = WAIT_ON_DELOYMENT_COMMAND; - } else if (mainSwitchCountdown.hasTimedOut()) { - triggerEvent(MAIN_SWITCH_OFF_TIMEOUT); - sif::error << "SolarArrayDeploymentHandler::handleStateMachine: Failed to switch main" - << " switch off" << std::endl; - stateMachine = WAIT_ON_DELOYMENT_COMMAND; - } - break; - default: - sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Invalid state" << std::endl; - break; - } +// switch (stateMachine) { +// case WAIT_ON_DELOYMENT_COMMAND: +// readCommandQueue(); +// break; +// case SWITCH_8V_ON: +// mainLineSwitcher.sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_ON); +// mainSwitchCountdown.setTimeout(mainLineSwitcher.getSwitchDelayMs()); +// stateMachine = WAIT_ON_8V_SWITCH; +// break; +// case WAIT_ON_8V_SWITCH: +// performWaitOn8VActions(); +// break; +// case SWITCH_DEPL_GPIOS: +// deploymentTransistorsOn(); +// break; +//// case WAIT_ON_DEPLOYMENT_FINISH: +//// handleDeploymentFinish(); +//// break; +// case WAIT_FOR_MAIN_SWITCH_OFF: +// if (mainLineSwitcher.getSwitchState(mainLineSwitch) == PowerSwitchIF::SWITCH_OFF) { +// stateMachine = WAIT_ON_DELOYMENT_COMMAND; +// } else if (mainSwitchCountdown.hasTimedOut()) { +// triggerEvent(MAIN_SWITCH_OFF_TIMEOUT); +// sif::error << "SolarArrayDeploymentHandler::handleStateMachine: Failed to switch main" +// << " switch off" << std::endl; +// stateMachine = WAIT_ON_DELOYMENT_COMMAND; +// } +// break; +// default: +// sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Invalid state" << std::endl; +// break; +// } } void SolarArrayDeploymentHandler::performWaitOn8VActions() { - if (mainLineSwitcher->getSwitchState(mainLineSwitch) == PowerSwitchIF::SWITCH_ON) { - stateMachine = SWITCH_DEPL_GPIOS; - } else { - if (mainSwitchCountdown.hasTimedOut()) { - triggerEvent(MAIN_SWITCH_ON_TIMEOUT); - actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, - MAIN_SWITCH_TIMEOUT_FAILURE); - stateMachine = WAIT_ON_DELOYMENT_COMMAND; - } - } +// if (mainLineSwitcher.getSwitchState(mainLineSwitch) == PowerSwitchIF::SWITCH_ON) { +// stateMachine = SWITCH_DEPL_GPIOS; +// } else { +// if (mainSwitchCountdown.hasTimedOut()) { +// triggerEvent(MAIN_SWITCH_ON_TIMEOUT); +// actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, +// MAIN_SWITCH_TIMEOUT_FAILURE); +// stateMachine = WAIT_ON_DELOYMENT_COMMAND; +// } +// } } -void SolarArrayDeploymentHandler::switchDeploymentTransistors() { - ReturnValue_t result = returnvalue::OK; - result = gpioInterface->pullHigh(deplSA1); - if (result != returnvalue::OK) { - sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" - " array deployment switch 1 high " - << std::endl; - /* If gpio switch high failed, state machine is reset to wait for a command reinitiating - * the deployment sequence. */ - stateMachine = WAIT_ON_DELOYMENT_COMMAND; - triggerEvent(DEPL_SA1_GPIO_SWTICH_ON_FAILED); - actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, SWITCHING_DEPL_SA2_FAILED); - mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF); - } - result = gpioInterface->pullHigh(deplSA2); - if (result != returnvalue::OK) { - sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" - " array deployment switch 2 high " - << std::endl; - stateMachine = WAIT_ON_DELOYMENT_COMMAND; - triggerEvent(DEPL_SA2_GPIO_SWTICH_ON_FAILED); - actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, SWITCHING_DEPL_SA2_FAILED); - mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF); - } - deploymentCountdown.setTimeout(burnTimeMs); - stateMachine = WAIT_ON_DEPLOYMENT_FINISH; +void SolarArrayDeploymentHandler::deploymentTransistorsOn() { +// ReturnValue_t result = returnvalue::OK; +// result = gpioInterface->pullHigh(deplSA1); +// if (result != returnvalue::OK) { +// sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" +// " array deployment switch 1 high " +// << std::endl; +// /* If gpio switch high failed, state machine is reset to wait for a command reinitiating +// * the deployment sequence. */ +// stateMachine = WAIT_ON_DELOYMENT_COMMAND; +// triggerEvent(DEPL_SA1_GPIO_SWTICH_ON_FAILED); +// actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, SWITCHING_DEPL_SA2_FAILED); +// mainLineSwitcher.sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF); +// } +// result = gpioInterface->pullHigh(deplSA2); +// if (result != returnvalue::OK) { +// sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" +// " array deployment switch 2 high " +// << std::endl; +// stateMachine = WAIT_ON_DELOYMENT_COMMAND; +// triggerEvent(DEPL_SA2_GPIO_SWTICH_ON_FAILED); +// actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, SWITCHING_DEPL_SA2_FAILED); +// mainLineSwitcher.sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF); +// } + //deploymentCountdown.setTimeout(burnTimeMs); + //stateMachine = WAIT_ON_DEPLOYMENT_FINISH; } -void SolarArrayDeploymentHandler::handleDeploymentFinish() { - ReturnValue_t result = returnvalue::OK; - if (deploymentCountdown.hasTimedOut()) { - actionHelper.finish(true, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, returnvalue::OK); - result = gpioInterface->pullLow(deplSA1); - if (result != returnvalue::OK) { - sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" - " array deployment switch 1 low " - << std::endl; - } - result = gpioInterface->pullLow(deplSA2); - if (result != returnvalue::OK) { - sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" - " array deployment switch 2 low " - << std::endl; - } - mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF); - mainSwitchCountdown.setTimeout(mainLineSwitcher->getSwitchDelayMs()); - stateMachine = WAIT_FOR_MAIN_SWITCH_OFF; - } -} +//void SolarArrayDeploymentHandler::handleDeploymentFinish() { +// ReturnValue_t result = returnvalue::OK; +//// if (deploymentCountdown.hasTimedOut()) { +//// actionHelper.finish(true, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, returnvalue::OK); +//// result = gpioInterface->pullLow(deplSA1); +//// if (result != returnvalue::OK) { +//// sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" +//// " array deployment switch 1 low " +//// << std::endl; +//// } +//// result = gpioInterface->pullLow(deplSA2); +//// if (result != returnvalue::OK) { +//// sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" +//// " array deployment switch 2 low " +//// << std::endl; +//// } +// mainLineSwitcher.sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF); +// mainSwitchCountdown.setTimeout(mainLineSwitcher.getSwitchDelayMs()); +// stateMachine = WAIT_FOR_MAIN_SWITCH_OFF; +// } +//} void SolarArrayDeploymentHandler::readCommandQueue() { CommandMessage command; @@ -185,20 +174,20 @@ ReturnValue_t SolarArrayDeploymentHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t* data, size_t size) { ReturnValue_t result; - if (stateMachine != WAIT_ON_DELOYMENT_COMMAND) { - sif::error << "SolarArrayDeploymentHandler::executeAction: Received command while not in" - << "waiting-on-command-state" << std::endl; - return DEPLOYMENT_ALREADY_EXECUTING; - } - if (actionId != DEPLOY_SOLAR_ARRAYS) { - sif::error << "SolarArrayDeploymentHandler::executeAction: Received invalid command" - << std::endl; - result = COMMAND_NOT_SUPPORTED; - } else { - stateMachine = SWITCH_8V_ON; - rememberCommanderId = commandedBy; - result = returnvalue::OK; - } +// if (stateMachine != WAIT_ON_DELOYMENT_COMMAND) { +// sif::error << "SolarArrayDeploymentHandler::executeAction: Received command while not in" +// << "waiting-on-command-state" << std::endl; +// return DEPLOYMENT_ALREADY_EXECUTING; +// } +// if (actionId != DEPLOY_SOLAR_ARRAYS) { +// sif::error << "SolarArrayDeploymentHandler::executeAction: Received invalid command" +// << std::endl; +// result = COMMAND_NOT_SUPPORTED; +// } else { +// stateMachine = SWITCH_8V_ON; +// rememberCommanderId = commandedBy; +// result = returnvalue::OK; +// } return result; } diff --git a/mission/devices/SolarArrayDeploymentHandler.h b/mission/devices/SolarArrayDeploymentHandler.h index 89be12a6..05fb7fb4 100644 --- a/mission/devices/SolarArrayDeploymentHandler.h +++ b/mission/devices/SolarArrayDeploymentHandler.h @@ -26,7 +26,7 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, public SystemObject, public HasActionsIF { public: - static const DeviceCommandId_t DEPLOY_SOLAR_ARRAYS = 0x5; + static constexpr DeviceCommandId_t DEPLOY_SOLAR_ARRAYS_MANUALLY = 0x5; /** * @brief constructor @@ -44,9 +44,8 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, * @param burnTimeMs Time duration the power will be applied to the burn wires. */ SolarArrayDeploymentHandler(object_id_t setObjectId, object_id_t gpioDriverId, - CookieIF* gpioCookie, object_id_t mainLineSwitcherObjectId, - pcdu::Switches mainLineSwitch, gpioId_t deplSA1, gpioId_t deplSA2, - uint32_t burnTimeMs); + CookieIF* gpioCookie, PowerSwitchIF& mainLineSwitcher, + pcdu::Switches mainLineSwitch, gpioId_t deplSA1, gpioId_t deplSA2); virtual ~SolarArrayDeploymentHandler(); @@ -72,16 +71,16 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, static const Event DEPL_SA1_GPIO_SWTICH_ON_FAILED = MAKE_EVENT(3, severity::HIGH); static const Event DEPL_SA2_GPIO_SWTICH_ON_FAILED = MAKE_EVENT(4, severity::HIGH); - enum StateMachine { - WAIT_ON_DELOYMENT_COMMAND, - SWITCH_8V_ON, - WAIT_ON_8V_SWITCH, - SWITCH_DEPL_GPIOS, - WAIT_ON_DEPLOYMENT_FINISH, - WAIT_FOR_MAIN_SWITCH_OFF - }; - - StateMachine stateMachine = WAIT_ON_DELOYMENT_COMMAND; +// enum StateMachine { +// WAIT_ON_DELOYMENT_COMMAND, +// SWITCH_8V_ON, +// WAIT_ON_8V_SWITCH, +// SWITCH_DEPL_GPIOS, +// WAIT_ON_DEPLOYMENT_FINISH, +// WAIT_FOR_MAIN_SWITCH_OFF +// }; +// +// StateMachine stateMachine = WAIT_ON_DELOYMENT_COMMAND; /** * This countdown is used to check if the PCDU sets the 8V line on in the intended time. @@ -91,7 +90,7 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, /** * This countdown is used to wait for the burn wire being successful cut. */ - Countdown deploymentCountdown; + //Countdown deploymentCountdown; /** * The message queue id of the component commanding an action will be stored in this variable. @@ -107,27 +106,21 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, CookieIF* gpioCookie; - /** Object id of the object responsible to switch the 8V power input. Typically the PCDU. */ - object_id_t mainLineSwitcherObjectId; - - /** Switch number of the 8V power switch */ - uint8_t mainLineSwitch; - gpioId_t deplSA1; gpioId_t deplSA2; GpioIF* gpioInterface = nullptr; - /** Time duration switches are active to cut the burn wire */ - uint32_t burnTimeMs; - /** Queue to receive messages from other objects. */ MessageQueueIF* commandQueue = nullptr; /** * After initialization this pointer will hold the reference to the main line switcher object. */ - PowerSwitchIF* mainLineSwitcher = nullptr; + PowerSwitchIF& mainLineSwitcher; + + /** Switch number of the 8V power switch */ + uint8_t mainLineSwitch; ActionHelper actionHelper; @@ -147,13 +140,13 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, /** * @brief This functions handles the switching of the solar array deployment transistors. */ - void switchDeploymentTransistors(); + void deploymentTransistorsOn(); /** * @brief This function performs actions to finish the deployment. Essentially switches * are turned of after the burn time has expired. */ - void handleDeploymentFinish(); + //void handleDeploymentFinish(); }; #endif /* MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_ */ -- 2.34.1 From ea82748496984aabb43b89239665ee94e2fe90fc Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 12 Oct 2022 13:29:38 +0200 Subject: [PATCH 02/35] new solar array deployment task --- bsp_q7s/core/InitMission.cpp | 50 ++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/bsp_q7s/core/InitMission.cpp b/bsp_q7s/core/InitMission.cpp index d74581c7..8872fc1f 100644 --- a/bsp_q7s/core/InitMission.cpp +++ b/bsp_q7s/core/InitMission.cpp @@ -67,16 +67,30 @@ void initmission::initTasks() { void (*missedDeadlineFunc)(void) = nullptr; #endif - PeriodicTaskIF* coreController = factory->createPeriodicTask( + PeriodicTaskIF* sysCtrlTask = factory->createPeriodicTask( "CORE_CTRL", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.4, missedDeadlineFunc); - result = coreController->addComponent(objects::CORE_CONTROLLER); + result = sysCtrlTask->addComponent(objects::CORE_CONTROLLER); if (result != returnvalue::OK) { initmission::printAddObjectError("CORE_CTRL", objects::CORE_CONTROLLER); } + // Could add this to the core controller but the core controller does so many thing that I would + // prefer to have the solar array deployment in a seprate task. + PeriodicTaskIF* solarArrayDeplTask = factory->createPeriodicTask( + "SOLAR_ARRAY_DEPL", 65, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.4, missedDeadlineFunc); + result = solarArrayDeplTask->addComponent(objects::SOLAR_ARRAY_DEPL_HANDLER); + if (result != returnvalue::OK) { + initmission::printAddObjectError("SOLAR_ARRAY_DEPL", objects::SOLAR_ARRAY_DEPL_HANDLER); + } /* TMTC Distribution */ PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask( - "DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); + "DIST", 45, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); +#if OBSW_ADD_TCPIP_BRIDGE == 1 + result = tmTcDistributor->addComponent(objects::TMTC_BRIDGE); + if (result != returnvalue::OK) { + initmission::printAddObjectError("TMTC_BRIDGE", objects::TMTC_BRIDGE); + } +#endif result = tmTcDistributor->addComponent(objects::CCSDS_PACKET_DISTRIBUTOR); if (result != returnvalue::OK) { initmission::printAddObjectError("CCSDS_DISTRIB", objects::CCSDS_PACKET_DISTRIBUTOR); @@ -95,13 +109,6 @@ void initmission::initTasks() { } #if OBSW_ADD_TCPIP_BRIDGE == 1 - // TMTC bridge - PeriodicTaskIF* tmtcBridgeTask = factory->createPeriodicTask( - "TCPIP_TMTC_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); - result = tmtcBridgeTask->addComponent(objects::TMTC_BRIDGE); - if (result != returnvalue::OK) { - initmission::printAddObjectError("TMTC_BRIDGE", objects::TMTC_BRIDGE); - } PeriodicTaskIF* tmtcPollingTask = factory->createPeriodicTask( "TMTC_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); result = tmtcPollingTask->addComponent(objects::TMTC_POLLING_TASK); @@ -138,39 +145,39 @@ void initmission::initTasks() { } #endif - PeriodicTaskIF* acsTask = factory->createPeriodicTask( + PeriodicTaskIF* acsCtrlTask = factory->createPeriodicTask( "ACS_TASK", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 0.4, missedDeadlineFunc); #if OBSW_ADD_GPS_CTRL == 1 - result = acsTask->addComponent(objects::GPS_CONTROLLER); + result = acsCtrlTask->addComponent(objects::GPS_CONTROLLER); if (result != returnvalue::OK) { initmission::printAddObjectError("GPS_CTRL", objects::GPS_CONTROLLER); } #endif /* OBSW_ADD_GPS_CTRL */ #if OBSW_ADD_ACS_CTRL == 1 - acsTask->addComponent(objects::ACS_CONTROLLER); + acsCtrlTask->addComponent(objects::ACS_CONTROLLER); if (result != returnvalue::OK) { initmission::printAddObjectError("ACS_CTRL", objects::ACS_CONTROLLER); } #endif - PeriodicTaskIF* sysTask = factory->createPeriodicTask( + PeriodicTaskIF* acsSysTask = factory->createPeriodicTask( "SYS_TASK", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 0.4, missedDeadlineFunc); - static_cast(sysTask); + static_cast(acsSysTask); #if OBSW_ADD_ACS_BOARD == 1 - result = sysTask->addComponent(objects::ACS_BOARD_ASS); + result = acsSysTask->addComponent(objects::ACS_BOARD_ASS); if (result != returnvalue::OK) { initmission::printAddObjectError("ACS_BOARD_ASS", objects::ACS_BOARD_ASS); } #endif /* OBSW_ADD_ACS_HANDLERS */ #if OBSW_ADD_RW == 1 - result = sysTask->addComponent(objects::RW_ASS); + result = acsSysTask->addComponent(objects::RW_ASS); if (result != returnvalue::OK) { initmission::printAddObjectError("RW_ASS", objects::RW_ASS); } #endif #if OBSW_ADD_SUS_BOARD_ASS == 1 - result = sysTask->addComponent(objects::SUS_BOARD_ASS); + result = acsSysTask->addComponent(objects::SUS_BOARD_ASS); if (result != returnvalue::OK) { initmission::printAddObjectError("SUS_BOARD_ASS", objects::SUS_BOARD_ASS); } @@ -297,7 +304,6 @@ void initmission::initTasks() { tmTcDistributor->startTask(); #if OBSW_ADD_TCPIP_BRIDGE == 1 - tmtcBridgeTask->startTask(); tmtcPollingTask->startTask(); #endif @@ -306,7 +312,7 @@ void initmission::initTasks() { pdecHandlerTask->startTask(); #endif /* OBSW_USE_CCSDS_IP_CORE == 1 */ - coreController->startTask(); + sysCtrlTask->startTask(); taskStarter(pstTasks, "PST task vector"); taskStarter(pusTasks, "PUS task vector"); @@ -327,8 +333,8 @@ void initmission::initTasks() { strHelperTask->startTask(); #endif /* OBSW_ADD_STAR_TRACKER == 1 */ - acsTask->startTask(); - sysTask->startTask(); + acsCtrlTask->startTask(); + acsSysTask->startTask(); #if OBSW_ADD_RTD_DEVICES == 1 tcsPollingTask->startTask(); tcsTask->startTask(); -- 2.34.1 From 09c0afbe7fc14d4be26e389d2836e022b2f6f64d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 12 Oct 2022 13:56:25 +0200 Subject: [PATCH 03/35] simplified SA Depl init --- bsp_q7s/core/ObjectFactory.cpp | 11 +- bsp_q7s/core/ObjectFactory.h | 2 +- bsp_q7s/fmObjectFactory.cpp | 2 +- .../devices/SolarArrayDeploymentHandler.cpp | 193 +++++++++--------- mission/devices/SolarArrayDeploymentHandler.h | 39 ++-- 5 files changed, 116 insertions(+), 131 deletions(-) diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index db2779bd..d4fb01b5 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -539,7 +539,8 @@ void ObjectFactory::createHeaterComponents(GpioIF* gpioIF, PowerSwitchIF* pwrSwi pcdu::Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V); } -void ObjectFactory::createSolarArrayDeploymentComponents(PowerSwitchIF& pwrSwitcher) { +void ObjectFactory::createSolarArrayDeploymentComponents(PowerSwitchIF& pwrSwitcher, + GpioIF& gpioIF) { using namespace gpio; GpioCookie* solarArrayDeplCookie = new GpioCookie; GpiodRegularByLineName* gpio = nullptr; @@ -552,10 +553,12 @@ void ObjectFactory::createSolarArrayDeploymentComponents(PowerSwitchIF& pwrSwitc gpio = new GpiodRegularByLineName(q7s::gpioNames::SA_DPL_PIN_1, consumer.str(), Direction::OUT, Levels::LOW); solarArrayDeplCookie->addGpio(gpioIds::DEPLSA2, gpio); + ReturnValue_t result = gpioIF.addGpios(solarArrayDeplCookie); + if (result != returnvalue::OK) { + sif::error << "Adding Solar Array Deployment GPIO cookie failed" << std::endl; + } - // TODO: Find out burn time. For now set to 1000 ms. - new SolarArrayDeploymentHandler(objects::SOLAR_ARRAY_DEPL_HANDLER, objects::GPIO_IF, - solarArrayDeplCookie, pwrSwitcher, + new SolarArrayDeploymentHandler(objects::SOLAR_ARRAY_DEPL_HANDLER, gpioIF, pwrSwitcher, pcdu::Switches::PDU2_CH5_DEPLOYMENT_MECHANISM_8V, gpioIds::DEPLSA1, gpioIds::DEPLSA2); } diff --git a/bsp_q7s/core/ObjectFactory.h b/bsp_q7s/core/ObjectFactory.h index 37cdc70e..88881090 100644 --- a/bsp_q7s/core/ObjectFactory.h +++ b/bsp_q7s/core/ObjectFactory.h @@ -33,7 +33,7 @@ void createHeaterComponents(GpioIF* gpioIF, PowerSwitchIF* pwrSwitcher, HealthTa void createImtqComponents(PowerSwitchIF* pwrSwitcher); void createBpxBatteryComponent(); void createStrComponents(PowerSwitchIF* pwrSwitcher); -void createSolarArrayDeploymentComponents(PowerSwitchIF& pwrSwitcher); +void createSolarArrayDeploymentComponents(PowerSwitchIF& pwrSwitcher, GpioIF& gpioIF); void createSyrlinksComponents(PowerSwitchIF* pwrSwitcher); void createPayloadComponents(LinuxLibgpioIF* gpioComIF); void createReactionWheelComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF* pwrSwitcher); diff --git a/bsp_q7s/fmObjectFactory.cpp b/bsp_q7s/fmObjectFactory.cpp index 413223d8..d28b7248 100644 --- a/bsp_q7s/fmObjectFactory.cpp +++ b/bsp_q7s/fmObjectFactory.cpp @@ -35,7 +35,7 @@ void ObjectFactory::produce(void* args) { createAcsBoardComponents(gpioComIF, uartComIF, pwrSwitcher); #endif createHeaterComponents(gpioComIF, pwrSwitcher, healthTable); - createSolarArrayDeploymentComponents(*pwrSwitcher); + createSolarArrayDeploymentComponents(*pwrSwitcher, *gpioComIF); createPlPcduComponents(gpioComIF, spiMainComIF, pwrSwitcher); #if OBSW_ADD_SYRLINKS == 1 createSyrlinksComponents(pwrSwitcher); diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index 63425615..30497ed3 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -5,13 +5,13 @@ #include #include -SolarArrayDeploymentHandler::SolarArrayDeploymentHandler( - object_id_t setObjectId_, object_id_t gpioDriverId_, CookieIF* gpioCookie_, - PowerSwitchIF& mainLineSwitcher_, pcdu::Switches mainLineSwitch_, gpioId_t deplSA1, - gpioId_t deplSA2) +SolarArrayDeploymentHandler::SolarArrayDeploymentHandler(object_id_t setObjectId_, + GpioIF& gpioInterface, + PowerSwitchIF& mainLineSwitcher_, + pcdu::Switches mainLineSwitch_, + gpioId_t deplSA1, gpioId_t deplSA2) : SystemObject(setObjectId_), - gpioDriverId(gpioDriverId_), - gpioCookie(gpioCookie_), + gpioInterface(gpioInterface), deplSA1(deplSA1), deplSA2(deplSA2), mainLineSwitcher(mainLineSwitcher_), @@ -38,19 +38,6 @@ ReturnValue_t SolarArrayDeploymentHandler::initialize() { return ObjectManagerIF::CHILD_INIT_FAILED; } - gpioInterface = ObjectManager::instance()->get(gpioDriverId); - if (gpioInterface == nullptr) { - sif::error << "SolarArrayDeploymentHandler::initialize: Invalid Gpio interface." << std::endl; - return ObjectManagerIF::CHILD_INIT_FAILED; - } - - result = gpioInterface->addGpios(dynamic_cast(gpioCookie)); - if (result != returnvalue::OK) { - sif::error << "SolarArrayDeploymentHandler::initialize: Failed to initialize Gpio interface" - << std::endl; - return ObjectManagerIF::CHILD_INIT_FAILED; - } - result = actionHelper.initialize(commandQueue); if (result != returnvalue::OK) { return ObjectManagerIF::CHILD_INIT_FAILED; @@ -60,83 +47,85 @@ ReturnValue_t SolarArrayDeploymentHandler::initialize() { } void SolarArrayDeploymentHandler::handleStateMachine() { -// switch (stateMachine) { -// case WAIT_ON_DELOYMENT_COMMAND: -// readCommandQueue(); -// break; -// case SWITCH_8V_ON: -// mainLineSwitcher.sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_ON); -// mainSwitchCountdown.setTimeout(mainLineSwitcher.getSwitchDelayMs()); -// stateMachine = WAIT_ON_8V_SWITCH; -// break; -// case WAIT_ON_8V_SWITCH: -// performWaitOn8VActions(); -// break; -// case SWITCH_DEPL_GPIOS: -// deploymentTransistorsOn(); -// break; -//// case WAIT_ON_DEPLOYMENT_FINISH: -//// handleDeploymentFinish(); -//// break; -// case WAIT_FOR_MAIN_SWITCH_OFF: -// if (mainLineSwitcher.getSwitchState(mainLineSwitch) == PowerSwitchIF::SWITCH_OFF) { -// stateMachine = WAIT_ON_DELOYMENT_COMMAND; -// } else if (mainSwitchCountdown.hasTimedOut()) { -// triggerEvent(MAIN_SWITCH_OFF_TIMEOUT); -// sif::error << "SolarArrayDeploymentHandler::handleStateMachine: Failed to switch main" -// << " switch off" << std::endl; -// stateMachine = WAIT_ON_DELOYMENT_COMMAND; -// } -// break; -// default: -// sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Invalid state" << std::endl; -// break; -// } + // switch (stateMachine) { + // case WAIT_ON_DELOYMENT_COMMAND: + // readCommandQueue(); + // break; + // case SWITCH_8V_ON: + // mainLineSwitcher.sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_ON); + // mainSwitchCountdown.setTimeout(mainLineSwitcher.getSwitchDelayMs()); + // stateMachine = WAIT_ON_8V_SWITCH; + // break; + // case WAIT_ON_8V_SWITCH: + // performWaitOn8VActions(); + // break; + // case SWITCH_DEPL_GPIOS: + // deploymentTransistorsOn(); + // break; + //// case WAIT_ON_DEPLOYMENT_FINISH: + //// handleDeploymentFinish(); + //// break; + // case WAIT_FOR_MAIN_SWITCH_OFF: + // if (mainLineSwitcher.getSwitchState(mainLineSwitch) == PowerSwitchIF::SWITCH_OFF) { + // stateMachine = WAIT_ON_DELOYMENT_COMMAND; + // } else if (mainSwitchCountdown.hasTimedOut()) { + // triggerEvent(MAIN_SWITCH_OFF_TIMEOUT); + // sif::error << "SolarArrayDeploymentHandler::handleStateMachine: Failed to switch main" + // << " switch off" << std::endl; + // stateMachine = WAIT_ON_DELOYMENT_COMMAND; + // } + // break; + // default: + // sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Invalid state" << + // std::endl; break; + // } } void SolarArrayDeploymentHandler::performWaitOn8VActions() { -// if (mainLineSwitcher.getSwitchState(mainLineSwitch) == PowerSwitchIF::SWITCH_ON) { -// stateMachine = SWITCH_DEPL_GPIOS; -// } else { -// if (mainSwitchCountdown.hasTimedOut()) { -// triggerEvent(MAIN_SWITCH_ON_TIMEOUT); -// actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, -// MAIN_SWITCH_TIMEOUT_FAILURE); -// stateMachine = WAIT_ON_DELOYMENT_COMMAND; -// } -// } + // if (mainLineSwitcher.getSwitchState(mainLineSwitch) == PowerSwitchIF::SWITCH_ON) { + // stateMachine = SWITCH_DEPL_GPIOS; + // } else { + // if (mainSwitchCountdown.hasTimedOut()) { + // triggerEvent(MAIN_SWITCH_ON_TIMEOUT); + // actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, + // MAIN_SWITCH_TIMEOUT_FAILURE); + // stateMachine = WAIT_ON_DELOYMENT_COMMAND; + // } + // } } void SolarArrayDeploymentHandler::deploymentTransistorsOn() { -// ReturnValue_t result = returnvalue::OK; -// result = gpioInterface->pullHigh(deplSA1); -// if (result != returnvalue::OK) { -// sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" -// " array deployment switch 1 high " -// << std::endl; -// /* If gpio switch high failed, state machine is reset to wait for a command reinitiating -// * the deployment sequence. */ -// stateMachine = WAIT_ON_DELOYMENT_COMMAND; -// triggerEvent(DEPL_SA1_GPIO_SWTICH_ON_FAILED); -// actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, SWITCHING_DEPL_SA2_FAILED); -// mainLineSwitcher.sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF); -// } -// result = gpioInterface->pullHigh(deplSA2); -// if (result != returnvalue::OK) { -// sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" -// " array deployment switch 2 high " -// << std::endl; -// stateMachine = WAIT_ON_DELOYMENT_COMMAND; -// triggerEvent(DEPL_SA2_GPIO_SWTICH_ON_FAILED); -// actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, SWITCHING_DEPL_SA2_FAILED); -// mainLineSwitcher.sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF); -// } - //deploymentCountdown.setTimeout(burnTimeMs); - //stateMachine = WAIT_ON_DEPLOYMENT_FINISH; + // ReturnValue_t result = returnvalue::OK; + // result = gpioInterface->pullHigh(deplSA1); + // if (result != returnvalue::OK) { + // sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" + // " array deployment switch 1 high " + // << std::endl; + // /* If gpio switch high failed, state machine is reset to wait for a command reinitiating + // * the deployment sequence. */ + // stateMachine = WAIT_ON_DELOYMENT_COMMAND; + // triggerEvent(DEPL_SA1_GPIO_SWTICH_ON_FAILED); + // actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, + // SWITCHING_DEPL_SA2_FAILED); mainLineSwitcher.sendSwitchCommand(mainLineSwitch, + // PowerSwitchIF::SWITCH_OFF); + // } + // result = gpioInterface->pullHigh(deplSA2); + // if (result != returnvalue::OK) { + // sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" + // " array deployment switch 2 high " + // << std::endl; + // stateMachine = WAIT_ON_DELOYMENT_COMMAND; + // triggerEvent(DEPL_SA2_GPIO_SWTICH_ON_FAILED); + // actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, + // SWITCHING_DEPL_SA2_FAILED); mainLineSwitcher.sendSwitchCommand(mainLineSwitch, + // PowerSwitchIF::SWITCH_OFF); + // } + // deploymentCountdown.setTimeout(burnTimeMs); + // stateMachine = WAIT_ON_DEPLOYMENT_FINISH; } -//void SolarArrayDeploymentHandler::handleDeploymentFinish() { -// ReturnValue_t result = returnvalue::OK; +// void SolarArrayDeploymentHandler::handleDeploymentFinish() { +// ReturnValue_t result = returnvalue::OK; //// if (deploymentCountdown.hasTimedOut()) { //// actionHelper.finish(true, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, returnvalue::OK); //// result = gpioInterface->pullLow(deplSA1); @@ -174,20 +163,20 @@ ReturnValue_t SolarArrayDeploymentHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t* data, size_t size) { ReturnValue_t result; -// if (stateMachine != WAIT_ON_DELOYMENT_COMMAND) { -// sif::error << "SolarArrayDeploymentHandler::executeAction: Received command while not in" -// << "waiting-on-command-state" << std::endl; -// return DEPLOYMENT_ALREADY_EXECUTING; -// } -// if (actionId != DEPLOY_SOLAR_ARRAYS) { -// sif::error << "SolarArrayDeploymentHandler::executeAction: Received invalid command" -// << std::endl; -// result = COMMAND_NOT_SUPPORTED; -// } else { -// stateMachine = SWITCH_8V_ON; -// rememberCommanderId = commandedBy; -// result = returnvalue::OK; -// } + // if (stateMachine != WAIT_ON_DELOYMENT_COMMAND) { + // sif::error << "SolarArrayDeploymentHandler::executeAction: Received command while not in" + // << "waiting-on-command-state" << std::endl; + // return DEPLOYMENT_ALREADY_EXECUTING; + // } + // if (actionId != DEPLOY_SOLAR_ARRAYS) { + // sif::error << "SolarArrayDeploymentHandler::executeAction: Received invalid command" + // << std::endl; + // result = COMMAND_NOT_SUPPORTED; + // } else { + // stateMachine = SWITCH_8V_ON; + // rememberCommanderId = commandedBy; + // result = returnvalue::OK; + // } return result; } diff --git a/mission/devices/SolarArrayDeploymentHandler.h b/mission/devices/SolarArrayDeploymentHandler.h index 05fb7fb4..0f85029f 100644 --- a/mission/devices/SolarArrayDeploymentHandler.h +++ b/mission/devices/SolarArrayDeploymentHandler.h @@ -43,9 +43,9 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, * @param deplSA2 gpioId of the GPIO controlling the deployment 2 transistor. * @param burnTimeMs Time duration the power will be applied to the burn wires. */ - SolarArrayDeploymentHandler(object_id_t setObjectId, object_id_t gpioDriverId, - CookieIF* gpioCookie, PowerSwitchIF& mainLineSwitcher, - pcdu::Switches mainLineSwitch, gpioId_t deplSA1, gpioId_t deplSA2); + SolarArrayDeploymentHandler(object_id_t setObjectId, GpioIF& gpio, + PowerSwitchIF& mainLineSwitcher, pcdu::Switches mainLineSwitch, + gpioId_t deplSA1, gpioId_t deplSA2); virtual ~SolarArrayDeploymentHandler(); @@ -71,16 +71,16 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, static const Event DEPL_SA1_GPIO_SWTICH_ON_FAILED = MAKE_EVENT(3, severity::HIGH); static const Event DEPL_SA2_GPIO_SWTICH_ON_FAILED = MAKE_EVENT(4, severity::HIGH); -// enum StateMachine { -// WAIT_ON_DELOYMENT_COMMAND, -// SWITCH_8V_ON, -// WAIT_ON_8V_SWITCH, -// SWITCH_DEPL_GPIOS, -// WAIT_ON_DEPLOYMENT_FINISH, -// WAIT_FOR_MAIN_SWITCH_OFF -// }; -// -// StateMachine stateMachine = WAIT_ON_DELOYMENT_COMMAND; + // enum StateMachine { + // WAIT_ON_DELOYMENT_COMMAND, + // SWITCH_8V_ON, + // WAIT_ON_8V_SWITCH, + // SWITCH_DEPL_GPIOS, + // WAIT_ON_DEPLOYMENT_FINISH, + // WAIT_FOR_MAIN_SWITCH_OFF + // }; + // + // StateMachine stateMachine = WAIT_ON_DELOYMENT_COMMAND; /** * This countdown is used to check if the PCDU sets the 8V line on in the intended time. @@ -90,7 +90,7 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, /** * This countdown is used to wait for the burn wire being successful cut. */ - //Countdown deploymentCountdown; + // Countdown deploymentCountdown; /** * The message queue id of the component commanding an action will be stored in this variable. @@ -100,17 +100,10 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, /** Size of command queue */ size_t cmdQueueSize = 20; - - /** The object ID of the GPIO driver which switches the deployment transistors */ - object_id_t gpioDriverId; - - CookieIF* gpioCookie; - + GpioIF& gpioInterface; gpioId_t deplSA1; gpioId_t deplSA2; - GpioIF* gpioInterface = nullptr; - /** Queue to receive messages from other objects. */ MessageQueueIF* commandQueue = nullptr; @@ -146,7 +139,7 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, * @brief This function performs actions to finish the deployment. Essentially switches * are turned of after the burn time has expired. */ - //void handleDeploymentFinish(); + // void handleDeploymentFinish(); }; #endif /* MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_ */ -- 2.34.1 From 3289a4032018bbd5383f8a9294ae874546ceaa82 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 12 Oct 2022 13:58:48 +0200 Subject: [PATCH 04/35] update comment block --- .../devices/SolarArrayDeploymentHandler.cpp | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index 30497ed3..9d2d94a3 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -62,9 +62,9 @@ void SolarArrayDeploymentHandler::handleStateMachine() { // case SWITCH_DEPL_GPIOS: // deploymentTransistorsOn(); // break; - //// case WAIT_ON_DEPLOYMENT_FINISH: - //// handleDeploymentFinish(); - //// break; + // case WAIT_ON_DEPLOYMENT_FINISH: + // handleDeploymentFinish(); + // break; // case WAIT_FOR_MAIN_SWITCH_OFF: // if (mainLineSwitcher.getSwitchState(mainLineSwitch) == PowerSwitchIF::SWITCH_OFF) { // stateMachine = WAIT_ON_DELOYMENT_COMMAND; @@ -126,20 +126,20 @@ void SolarArrayDeploymentHandler::deploymentTransistorsOn() { // void SolarArrayDeploymentHandler::handleDeploymentFinish() { // ReturnValue_t result = returnvalue::OK; -//// if (deploymentCountdown.hasTimedOut()) { -//// actionHelper.finish(true, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, returnvalue::OK); -//// result = gpioInterface->pullLow(deplSA1); -//// if (result != returnvalue::OK) { -//// sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" -//// " array deployment switch 1 low " -//// << std::endl; -//// } -//// result = gpioInterface->pullLow(deplSA2); -//// if (result != returnvalue::OK) { -//// sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" -//// " array deployment switch 2 low " -//// << std::endl; -//// } +// if (deploymentCountdown.hasTimedOut()) { +// actionHelper.finish(true, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, returnvalue::OK); +// result = gpioInterface->pullLow(deplSA1); +// if (result != returnvalue::OK) { +// sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" +// " array deployment switch 1 low " +// << std::endl; +// } +// result = gpioInterface->pullLow(deplSA2); +// if (result != returnvalue::OK) { +// sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" +// " array deployment switch 2 low " +// << std::endl; +// } // mainLineSwitcher.sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF); // mainSwitchCountdown.setTimeout(mainLineSwitcher.getSwitchDelayMs()); // stateMachine = WAIT_FOR_MAIN_SWITCH_OFF; -- 2.34.1 From a2e1ed56c91d6b469494fbb3eca25b9cf6639bec Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 12 Oct 2022 14:09:07 +0200 Subject: [PATCH 05/35] pass SDC man to SA DEPL handler --- bsp_q7s/core/ObjectFactory.cpp | 2 +- .../devices/SolarArrayDeploymentHandler.cpp | 18 ++++---------- mission/devices/SolarArrayDeploymentHandler.h | 24 ++++++++++--------- 3 files changed, 19 insertions(+), 25 deletions(-) diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index d4fb01b5..74af9564 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -560,7 +560,7 @@ void ObjectFactory::createSolarArrayDeploymentComponents(PowerSwitchIF& pwrSwitc new SolarArrayDeploymentHandler(objects::SOLAR_ARRAY_DEPL_HANDLER, gpioIF, pwrSwitcher, pcdu::Switches::PDU2_CH5_DEPLOYMENT_MECHANISM_8V, - gpioIds::DEPLSA1, gpioIds::DEPLSA2); + gpioIds::DEPLSA1, gpioIds::DEPLSA2, *SdCardManager::instance()); } void ObjectFactory::createSyrlinksComponents(PowerSwitchIF* pwrSwitcher) { diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index 9d2d94a3..e3357a53 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -9,7 +9,8 @@ SolarArrayDeploymentHandler::SolarArrayDeploymentHandler(object_id_t setObjectId GpioIF& gpioInterface, PowerSwitchIF& mainLineSwitcher_, pcdu::Switches mainLineSwitch_, - gpioId_t deplSA1, gpioId_t deplSA2) + gpioId_t deplSA1, gpioId_t deplSA2, + SdCardMountedIF& sdcMountedIF) : SystemObject(setObjectId_), gpioInterface(gpioInterface), deplSA1(deplSA1), @@ -25,25 +26,16 @@ SolarArrayDeploymentHandler::SolarArrayDeploymentHandler(object_id_t setObjectId SolarArrayDeploymentHandler::~SolarArrayDeploymentHandler() {} ReturnValue_t SolarArrayDeploymentHandler::performOperation(uint8_t operationCode) { - if (operationCode == DeviceHandlerIF::PERFORM_OPERATION) { - handleStateMachine(); - return returnvalue::OK; - } + handleStateMachine(); return returnvalue::OK; } ReturnValue_t SolarArrayDeploymentHandler::initialize() { - ReturnValue_t result = SystemObject::initialize(); + ReturnValue_t result = actionHelper.initialize(commandQueue); if (result != returnvalue::OK) { return ObjectManagerIF::CHILD_INIT_FAILED; } - - result = actionHelper.initialize(commandQueue); - if (result != returnvalue::OK) { - return ObjectManagerIF::CHILD_INIT_FAILED; - } - - return returnvalue::OK; + return SystemObject::initialize(); } void SolarArrayDeploymentHandler::handleStateMachine() { diff --git a/mission/devices/SolarArrayDeploymentHandler.h b/mission/devices/SolarArrayDeploymentHandler.h index 0f85029f..74d207a9 100644 --- a/mission/devices/SolarArrayDeploymentHandler.h +++ b/mission/devices/SolarArrayDeploymentHandler.h @@ -1,16 +1,17 @@ #ifndef MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_ #define MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "devices/powerSwitcherList.h" +#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" +#include "fsfw/tasks/ExecutableObjectIF.h" +#include "fsfw/timemanager/Countdown.h" +#include "fsfw_hal/common/gpio/GpioIF.h" +#include "mission/memory/SdCardMountedIF.h" #include @@ -45,7 +46,8 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, */ SolarArrayDeploymentHandler(object_id_t setObjectId, GpioIF& gpio, PowerSwitchIF& mainLineSwitcher, pcdu::Switches mainLineSwitch, - gpioId_t deplSA1, gpioId_t deplSA2); + gpioId_t deplSA1, gpioId_t deplSA2, + SdCardMountedIF& sdcMountedIF); virtual ~SolarArrayDeploymentHandler(); -- 2.34.1 From 6a900693f3ff5754761c52aec3876bea5834c038 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 12 Oct 2022 14:24:45 +0200 Subject: [PATCH 06/35] continue SA DEPL --- .../devices/SolarArrayDeploymentHandler.cpp | 32 ++++++++++++++++--- mission/devices/SolarArrayDeploymentHandler.h | 25 +++++++++------ 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index e3357a53..fac22115 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -1,9 +1,11 @@ #include "SolarArrayDeploymentHandler.h" -#include -#include -#include -#include +#include "devices/gpioIds.h" +#include "fsfw/ipc/QueueFactory.h" +#include "fsfw/objectmanager/ObjectManager.h" +#include "fsfw_hal/common/gpio/GpioCookie.h" + +#include SolarArrayDeploymentHandler::SolarArrayDeploymentHandler(object_id_t setObjectId_, GpioIF& gpioInterface, @@ -17,16 +19,36 @@ SolarArrayDeploymentHandler::SolarArrayDeploymentHandler(object_id_t setObjectId deplSA2(deplSA2), mainLineSwitcher(mainLineSwitcher_), mainLineSwitch(mainLineSwitch_), + sdcMan(sdcMountedIF), actionHelper(this, nullptr) { auto mqArgs = MqArgs(setObjectId_, static_cast(this)); commandQueue = QueueFactory::instance()->createMessageQueue( cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs); } -SolarArrayDeploymentHandler::~SolarArrayDeploymentHandler() {} +SolarArrayDeploymentHandler::~SolarArrayDeploymentHandler() = default; ReturnValue_t SolarArrayDeploymentHandler::performOperation(uint8_t operationCode) { + using namespace std::filesystem; handleStateMachine(); + auto activeSdc = sdcMan.getActiveSdCard(); + if (activeSdc and activeSdc.value() == sd::SdCard::SLOT_0 and + sdcMan.isSdCardUsable(activeSdc.value())) { + if (exists(SD_0_DEPL_FILE)) { + // perform autonomous deployment handling + performAutonomousDepl(sd::SdCard::SLOT_0); + } + } else if (activeSdc and activeSdc.value() == sd::SdCard::SLOT_1 and + sdcMan.isSdCardUsable(activeSdc.value())) { + if (exists(SD_1_DEPL_FILE)) { + // perform autonomous deployment handling + performAutonomousDepl(sd::SdCard::SLOT_1); + } + } + return returnvalue::OK; +} + +ReturnValue_t SolarArrayDeploymentHandler::performAutonomousDepl(sd::SdCard sdCard) { return returnvalue::OK; } diff --git a/mission/devices/SolarArrayDeploymentHandler.h b/mission/devices/SolarArrayDeploymentHandler.h index 74d207a9..9e0bdfa1 100644 --- a/mission/devices/SolarArrayDeploymentHandler.h +++ b/mission/devices/SolarArrayDeploymentHandler.h @@ -1,7 +1,10 @@ #ifndef MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_ #define MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_ +#include + #include "devices/powerSwitcherList.h" +#include "events/subsystemIdRanges.h" #include "fsfw/action/HasActionsIF.h" #include "fsfw/devicehandlers/CookieIF.h" #include "fsfw/devicehandlers/DeviceHandlerIF.h" @@ -12,10 +15,6 @@ #include "fsfw/timemanager/Countdown.h" #include "fsfw_hal/common/gpio/GpioIF.h" #include "mission/memory/SdCardMountedIF.h" - -#include - -#include "events/subsystemIdRanges.h" #include "returnvalues/classIds.h" /** @@ -28,7 +27,10 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, public HasActionsIF { public: static constexpr DeviceCommandId_t DEPLOY_SOLAR_ARRAYS_MANUALLY = 0x5; - + static const char SD_0_DEPL_FILE[] = "/mnt/sd0/conf/deployment"; + static const char SD_1_DEPL_FILE[] = "/mnt/sd1/conf/deployment"; + static const char SD_0_DEPLY_INFO[] = "/mnt/sd0/conf/deployment_info.txt"; + static const char SD_1_DEPLY_INFO[] = "/mnt/sd1/conf/deployment_info.txt"; /** * @brief constructor * @@ -46,8 +48,7 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, */ SolarArrayDeploymentHandler(object_id_t setObjectId, GpioIF& gpio, PowerSwitchIF& mainLineSwitcher, pcdu::Switches mainLineSwitch, - gpioId_t deplSA1, gpioId_t deplSA2, - SdCardMountedIF& sdcMountedIF); + gpioId_t deplSA1, gpioId_t deplSA2, SdCardMountedIF& sdcMountedIF); virtual ~SolarArrayDeploymentHandler(); @@ -84,6 +85,8 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, // // StateMachine stateMachine = WAIT_ON_DELOYMENT_COMMAND; + ReturnValue_t performAutonomousDepl(sd::SdCard sdCard); + /** * This countdown is used to check if the PCDU sets the 8V line on in the intended time. */ @@ -106,9 +109,6 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, gpioId_t deplSA1; gpioId_t deplSA2; - /** Queue to receive messages from other objects. */ - MessageQueueIF* commandQueue = nullptr; - /** * After initialization this pointer will hold the reference to the main line switcher object. */ @@ -117,8 +117,13 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, /** Switch number of the 8V power switch */ uint8_t mainLineSwitch; + SdCardMountedIF& sdcMan; + ActionHelper actionHelper; + /** Queue to receive messages from other objects. */ + MessageQueueIF* commandQueue = nullptr; + void readCommandQueue(); /** -- 2.34.1 From 2bc7c7b3ae942044b5b4fe69f1bc2c68f5deaef0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 12 Oct 2022 15:19:21 +0200 Subject: [PATCH 07/35] continue autonomous depl handling --- common/config/eive/definitions.h | 4 ++ .../devices/SolarArrayDeploymentHandler.cpp | 71 ++++++++++++++++++- mission/devices/SolarArrayDeploymentHandler.h | 34 +++++++-- 3 files changed, 104 insertions(+), 5 deletions(-) diff --git a/common/config/eive/definitions.h b/common/config/eive/definitions.h index 1e8faad9..fb941edc 100644 --- a/common/config/eive/definitions.h +++ b/common/config/eive/definitions.h @@ -34,6 +34,10 @@ static constexpr uint8_t LIVE_TM = 0; static constexpr uint32_t MAX_PATH_SIZE = 100; static constexpr uint32_t MAX_FILENAME_SIZE = 50; +static constexpr uint32_t SA_DEPL_INIT_BUFFER_SECS = 120; +static constexpr uint32_t SA_DEPL_BURN_TIME_SECS = 90; +static constexpr uint32_t SA_DEPL_WAIT_TIME_SECS = 45 * 60; + } // namespace config #endif /* COMMON_CONFIG_DEFINITIONS_H_ */ diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index fac22115..47d93e09 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -6,6 +6,8 @@ #include "fsfw_hal/common/gpio/GpioCookie.h" #include +#include +#include SolarArrayDeploymentHandler::SolarArrayDeploymentHandler(object_id_t setObjectId_, GpioIF& gpioInterface, @@ -49,6 +51,73 @@ ReturnValue_t SolarArrayDeploymentHandler::performOperation(uint8_t operationCod } ReturnValue_t SolarArrayDeploymentHandler::performAutonomousDepl(sd::SdCard sdCard) { + using namespace std::filesystem; + using namespace std; + auto initFile = [](const char* filename) { + ofstream of(filename); + of << "phase: init\n"; + of << "secs_since_start: 0\n"; + }; + auto handler = [](const char* filename) { + + ifstream file(filename); + string line; + string word; + unsigned int lineNum = 0; + AutonomousDeplState deplState; + while(std::getline(file, line)) { + if(lineNum == 0) { + std::istringstream iss(line); + if (lineNum == 0) { + iss >> word; + if(word.find("phase:") == string::npos) { + return false; + } + iss >> word; + if(word.find(PHASE_INIT_STR) != string::npos) { + deplState = AutonomousDeplState::INIT; + } else if(word.find(PHASE_FIRST_BURN_STR) != string::npos) { + deplState = AutonomousDeplState::FIRST_BURN; + } else if(word.find(PHASE_WAIT_STR) != string::npos) { + deplState = AutonomousDeplState::WAIT; + } else if(word.find(PHASE_SECOND_BURN_STR) != string::npos) { + deplState = AutonomousDeplState::SECOND_BURN; + } else if(word.find(PHASE_DONE) != string::npos) { + deplState = AutonomousDeplState::DONE; + } else { + return false; + } + } else if(lineNum == 1) { + iss >> word; + if(word.find("phase:") == string::npos) { + return false; + } + uint32_t secsSinceBoot = 0; + iss >> secsSinceBoot; + if (iss.bad()) { + return false; + } + } + } + lineNum++; + } + return true; + }; + if (sdCard == sd::SdCard::SLOT_0) { + if (not exists(SD_0_DEPLY_INFO)) { + initFile(SD_0_DEPLY_INFO); + } + if (not handler(SD_0_DEPLY_INFO)) { + initFile(SD_0_DEPLY_INFO); + } + } else if(sdCard == sd::SdCard::SLOT_1) { + if (not exists(SD_1_DEPLY_INFO)) { + initFile(SD_1_DEPLY_INFO); + } + if (not handler(SD_1_DEPLY_INFO)) { + initFile(SD_1_DEPLY_INFO); + } + } return returnvalue::OK; } @@ -176,7 +245,7 @@ void SolarArrayDeploymentHandler::readCommandQueue() { ReturnValue_t SolarArrayDeploymentHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t* data, size_t size) { - ReturnValue_t result; + ReturnValue_t result = returnvalue::OK; // if (stateMachine != WAIT_ON_DELOYMENT_COMMAND) { // sif::error << "SolarArrayDeploymentHandler::executeAction: Received command while not in" // << "waiting-on-command-state" << std::endl; diff --git a/mission/devices/SolarArrayDeploymentHandler.h b/mission/devices/SolarArrayDeploymentHandler.h index 9e0bdfa1..dc1db96d 100644 --- a/mission/devices/SolarArrayDeploymentHandler.h +++ b/mission/devices/SolarArrayDeploymentHandler.h @@ -3,6 +3,7 @@ #include +#include "eive/definitions.h" #include "devices/powerSwitcherList.h" #include "events/subsystemIdRanges.h" #include "fsfw/action/HasActionsIF.h" @@ -26,11 +27,29 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, public SystemObject, public HasActionsIF { public: + // Burn them for a custom amount limited by 120 secs static constexpr DeviceCommandId_t DEPLOY_SOLAR_ARRAYS_MANUALLY = 0x5; - static const char SD_0_DEPL_FILE[] = "/mnt/sd0/conf/deployment"; - static const char SD_1_DEPL_FILE[] = "/mnt/sd1/conf/deployment"; - static const char SD_0_DEPLY_INFO[] = "/mnt/sd0/conf/deployment_info.txt"; - static const char SD_1_DEPLY_INFO[] = "/mnt/sd1/conf/deployment_info.txt"; + // Careful with these command, not automatic off handling! + static constexpr DeviceCommandId_t FORCE_DEPLY_ON = 0x06; + static constexpr DeviceCommandId_t FORCE_DEPLY_OFF = 0x07; + + static constexpr uint32_t FIRST_BURN_START_TIME = config::SA_DEPL_BURN_TIME_SECS; + static constexpr uint32_t FIRST_BURN_END_TIME = FIRST_BURN_START_TIME + config::SA_DEPL_BURN_TIME_SECS; + static constexpr uint32_t FIRST_WAIT_START_TIME = FIRST_BURN_END_TIME; + static constexpr uint32_t FIRST_WAIT_END_TIME = FIRST_BURN_END_TIME + config::SA_DEPL_WAIT_TIME_SECS; + static constexpr uint32_t SECOND_BURN_START_TIME = FIRST_WAIT_END_TIME; + static constexpr uint32_t SECOND_BURN_END_TIME = SECOND_BURN_START_TIME + config::SA_DEPL_WAIT_TIME_SECS; + + 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"; /** * @brief constructor * @@ -74,6 +93,13 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, static const Event DEPL_SA1_GPIO_SWTICH_ON_FAILED = MAKE_EVENT(3, severity::HIGH); static const Event DEPL_SA2_GPIO_SWTICH_ON_FAILED = MAKE_EVENT(4, severity::HIGH); + enum AutonomousDeplState { + INIT, + FIRST_BURN, + WAIT, + SECOND_BURN, + DONE + }; // enum StateMachine { // WAIT_ON_DELOYMENT_COMMAND, // SWITCH_8V_ON, -- 2.34.1 From 15fb86ddb7fa840a37b0ac4ad2edfba7471fef38 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 12 Oct 2022 17:18:57 +0200 Subject: [PATCH 08/35] continue SA DEPL handler --- .../devices/SolarArrayDeploymentHandler.cpp | 343 ++++++++++-------- mission/devices/SolarArrayDeploymentHandler.h | 69 ++-- 2 files changed, 235 insertions(+), 177 deletions(-) diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index 47d93e09..7a1c06d4 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -1,14 +1,14 @@ #include "SolarArrayDeploymentHandler.h" +#include +#include +#include + #include "devices/gpioIds.h" #include "fsfw/ipc/QueueFactory.h" #include "fsfw/objectmanager/ObjectManager.h" #include "fsfw_hal/common/gpio/GpioCookie.h" -#include -#include -#include - SolarArrayDeploymentHandler::SolarArrayDeploymentHandler(object_id_t setObjectId_, GpioIF& gpioInterface, PowerSwitchIF& mainLineSwitcher_, @@ -32,7 +32,6 @@ SolarArrayDeploymentHandler::~SolarArrayDeploymentHandler() = default; ReturnValue_t SolarArrayDeploymentHandler::performOperation(uint8_t operationCode) { using namespace std::filesystem; - handleStateMachine(); auto activeSdc = sdcMan.getActiveSdCard(); if (activeSdc and activeSdc.value() == sd::SdCard::SLOT_0 and sdcMan.isSdCardUsable(activeSdc.value())) { @@ -47,6 +46,8 @@ ReturnValue_t SolarArrayDeploymentHandler::performOperation(uint8_t operationCod performAutonomousDepl(sd::SdCard::SLOT_1); } } + readCommandQueue(); + handleStateMachine(); return returnvalue::OK; } @@ -58,69 +59,104 @@ ReturnValue_t SolarArrayDeploymentHandler::performAutonomousDepl(sd::SdCard sdCa of << "phase: init\n"; of << "secs_since_start: 0\n"; }; - auto handler = [](const char* filename) { - - ifstream file(filename); - string line; - string word; - unsigned int lineNum = 0; - AutonomousDeplState deplState; - while(std::getline(file, line)) { - if(lineNum == 0) { - std::istringstream iss(line); - if (lineNum == 0) { - iss >> word; - if(word.find("phase:") == string::npos) { - return false; - } - iss >> word; - if(word.find(PHASE_INIT_STR) != string::npos) { - deplState = AutonomousDeplState::INIT; - } else if(word.find(PHASE_FIRST_BURN_STR) != string::npos) { - deplState = AutonomousDeplState::FIRST_BURN; - } else if(word.find(PHASE_WAIT_STR) != string::npos) { - deplState = AutonomousDeplState::WAIT; - } else if(word.find(PHASE_SECOND_BURN_STR) != string::npos) { - deplState = AutonomousDeplState::SECOND_BURN; - } else if(word.find(PHASE_DONE) != string::npos) { - deplState = AutonomousDeplState::DONE; - } else { - return false; - } - } else if(lineNum == 1) { - iss >> word; - if(word.find("phase:") == string::npos) { - return false; - } - uint32_t secsSinceBoot = 0; - iss >> secsSinceBoot; - if (iss.bad()) { - return false; - } - } - } - lineNum++; - } - return true; - }; if (sdCard == sd::SdCard::SLOT_0) { if (not exists(SD_0_DEPLY_INFO)) { initFile(SD_0_DEPLY_INFO); } - if (not handler(SD_0_DEPLY_INFO)) { + if (not autonomousDeplForFile(SD_0_DEPLY_INFO)) { initFile(SD_0_DEPLY_INFO); } - } else if(sdCard == sd::SdCard::SLOT_1) { + } else if (sdCard == sd::SdCard::SLOT_1) { if (not exists(SD_1_DEPLY_INFO)) { initFile(SD_1_DEPLY_INFO); } - if (not handler(SD_1_DEPLY_INFO)) { + if (not autonomousDeplForFile(SD_1_DEPLY_INFO)) { initFile(SD_1_DEPLY_INFO); } } return returnvalue::OK; } +bool SolarArrayDeploymentHandler::autonomousDeplForFile(const char* filename) { + using namespace std; + ifstream file(filename); + string line; + string word; + unsigned int lineNum = 0; + AutonomousDeplState deplState; + bool stateSwitch = false; + uint32_t secsSinceBoot = 0; + while (std::getline(file, line)) { + if (lineNum == 0) { + std::istringstream iss(line); + if (lineNum == 0) { + iss >> word; + if (word.find("phase:") == string::npos) { + return false; + } + iss >> word; + if (word.find(PHASE_INIT_STR) != string::npos) { + deplState = AutonomousDeplState::INIT; + } else if (word.find(PHASE_FIRST_BURN_STR) != string::npos) { + deplState = AutonomousDeplState::FIRST_BURN; + } else if (word.find(PHASE_WAIT_STR) != string::npos) { + deplState = AutonomousDeplState::WAIT; + } else if (word.find(PHASE_SECOND_BURN_STR) != string::npos) { + deplState = AutonomousDeplState::SECOND_BURN; + } else if (word.find(PHASE_DONE) != string::npos) { + deplState = AutonomousDeplState::DONE; + } else { + return false; + } + } else if (lineNum == 1) { + iss >> word; + if (word.find("phase:") == string::npos) { + return false; + } + + iss >> secsSinceBoot; + if (not initUptime) { + initUptime = secsSinceBoot; + } + if (iss.bad()) { + return false; + } + auto switchCheck = [&](AutonomousDeplState expected) { + if (deplState != expected) { + deplState = expected; + stateSwitch = true; + } + }; + if ((secsSinceBoot > FIRST_BURN_START_TIME) and (secsSinceBoot < FIRST_BURN_END_TIME)) { + switchCheck(AutonomousDeplState::FIRST_BURN); + } else if ((secsSinceBoot > WAIT_START_TIME) and (secsSinceBoot < WAIT_END_TIME)) { + switchCheck(AutonomousDeplState::WAIT); + } else if ((secsSinceBoot > SECOND_BURN_START_TIME) and + (secsSinceBoot < SECOND_BURN_END_TIME)) { + switchCheck(AutonomousDeplState::SECOND_BURN); + } else if (secsSinceBoot > SECOND_BURN_END_TIME) { + switchCheck(AutonomousDeplState::DONE); + } + } + } + lineNum++; + } + if (initUptime) { + secsSinceBoot = initUptime.value(); + } + // Uptime has increased by X seconds so we need to update the uptime count inside the file + secsSinceBoot += Clock::getUptime().tv_sec; + if (stateSwitch) { + if (deplState == AutonomousDeplState::FIRST_BURN or + deplState == AutonomousDeplState::SECOND_BURN) { + startFsm(true, true); + } else if (deplState == AutonomousDeplState::WAIT or deplState == AutonomousDeplState::DONE) { + startFsm(false, false); + } + } + return true; +} + ReturnValue_t SolarArrayDeploymentHandler::initialize() { ReturnValue_t result = actionHelper.initialize(commandQueue); if (result != returnvalue::OK) { @@ -130,104 +166,121 @@ ReturnValue_t SolarArrayDeploymentHandler::initialize() { } void SolarArrayDeploymentHandler::handleStateMachine() { - // switch (stateMachine) { - // case WAIT_ON_DELOYMENT_COMMAND: - // readCommandQueue(); - // break; - // case SWITCH_8V_ON: - // mainLineSwitcher.sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_ON); - // mainSwitchCountdown.setTimeout(mainLineSwitcher.getSwitchDelayMs()); - // stateMachine = WAIT_ON_8V_SWITCH; - // break; - // case WAIT_ON_8V_SWITCH: - // performWaitOn8VActions(); - // break; - // case SWITCH_DEPL_GPIOS: - // deploymentTransistorsOn(); - // break; - // case WAIT_ON_DEPLOYMENT_FINISH: - // handleDeploymentFinish(); - // break; - // case WAIT_FOR_MAIN_SWITCH_OFF: - // if (mainLineSwitcher.getSwitchState(mainLineSwitch) == PowerSwitchIF::SWITCH_OFF) { - // stateMachine = WAIT_ON_DELOYMENT_COMMAND; - // } else if (mainSwitchCountdown.hasTimedOut()) { - // triggerEvent(MAIN_SWITCH_OFF_TIMEOUT); - // sif::error << "SolarArrayDeploymentHandler::handleStateMachine: Failed to switch main" - // << " switch off" << std::endl; - // stateMachine = WAIT_ON_DELOYMENT_COMMAND; - // } - // break; - // default: - // sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Invalid state" << - // std::endl; break; - // } + if (stateMachine == MAIN_POWER_ON) { + mainLineSwitcher.sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_ON); + mainSwitchCountdown.setTimeout(mainLineSwitcher.getSwitchDelayMs()); + stateMachine = WAIT_MAIN_POWER_ON; + } + if (stateMachine == MAIN_POWER_OFF) { + // This should never fail + deploymentTransistorsOff(); + mainLineSwitcher.sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_ON); + mainSwitchCountdown.setTimeout(mainLineSwitcher.getSwitchDelayMs()); + stateMachine = WAIT_MAIN_POWER_OFF; + } + if (stateMachine == WAIT_MAIN_POWER_ON) { + if (checkMainPowerOn()) { + stateMachine = SWITCH_DEPL_GPIOS; + } + } + if (stateMachine == WAIT_MAIN_POWER_OFF) { + if (checkMainPowerOff()) { + finishFsm(returnvalue::OK); + } + } + if (stateMachine == SWITCH_DEPL_GPIOS) { + // This should never fail + deploymentTransistorsOn(); + finishFsm(returnvalue::OK); + } } -void SolarArrayDeploymentHandler::performWaitOn8VActions() { - // if (mainLineSwitcher.getSwitchState(mainLineSwitch) == PowerSwitchIF::SWITCH_ON) { - // stateMachine = SWITCH_DEPL_GPIOS; - // } else { - // if (mainSwitchCountdown.hasTimedOut()) { - // triggerEvent(MAIN_SWITCH_ON_TIMEOUT); - // actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, - // MAIN_SWITCH_TIMEOUT_FAILURE); - // stateMachine = WAIT_ON_DELOYMENT_COMMAND; - // } - // } +bool SolarArrayDeploymentHandler::checkMainPowerOn() { return checkMainPower(true); } + +bool SolarArrayDeploymentHandler::checkMainPowerOff() { return checkMainPower(false); } + +bool SolarArrayDeploymentHandler::checkMainPower(bool onOff) { + if ((onOff and mainLineSwitcher.getSwitchState(mainLineSwitch) == PowerSwitchIF::SWITCH_ON) or + (not onOff and + mainLineSwitcher.getSwitchState(mainLineSwitch) == PowerSwitchIF::SWITCH_OFF)) { + return true; + } + if (mainSwitchCountdown.hasTimedOut()) { + if (onOff) { + triggerEvent(MAIN_SWITCH_ON_TIMEOUT); + } else { + triggerEvent(MAIN_SWITCH_OFF_TIMEOUT); + } + if (retryCounter < 3) { + if (onOff) { + stateMachine = MAIN_POWER_ON; + } else { + stateMachine = MAIN_POWER_OFF; + } + retryCounter++; + } else { + finishFsm(MAIN_SWITCH_TIMEOUT_FAILURE); + } + } + return false; } -void SolarArrayDeploymentHandler::deploymentTransistorsOn() { - // ReturnValue_t result = returnvalue::OK; - // result = gpioInterface->pullHigh(deplSA1); - // if (result != returnvalue::OK) { - // sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" - // " array deployment switch 1 high " - // << std::endl; - // /* If gpio switch high failed, state machine is reset to wait for a command reinitiating - // * the deployment sequence. */ - // stateMachine = WAIT_ON_DELOYMENT_COMMAND; - // triggerEvent(DEPL_SA1_GPIO_SWTICH_ON_FAILED); - // actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, - // SWITCHING_DEPL_SA2_FAILED); mainLineSwitcher.sendSwitchCommand(mainLineSwitch, - // PowerSwitchIF::SWITCH_OFF); - // } - // result = gpioInterface->pullHigh(deplSA2); - // if (result != returnvalue::OK) { - // sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" - // " array deployment switch 2 high " - // << std::endl; - // stateMachine = WAIT_ON_DELOYMENT_COMMAND; - // triggerEvent(DEPL_SA2_GPIO_SWTICH_ON_FAILED); - // actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, - // SWITCHING_DEPL_SA2_FAILED); mainLineSwitcher.sendSwitchCommand(mainLineSwitch, - // PowerSwitchIF::SWITCH_OFF); - // } - // deploymentCountdown.setTimeout(burnTimeMs); - // stateMachine = WAIT_ON_DEPLOYMENT_FINISH; +bool SolarArrayDeploymentHandler::startFsm(std::optional sa1OnOff, + std::optional sa2OnOff) { + if ((stateMachine != StateMachine::IDLE) or (not sa1OnOff and not sa2OnOff)) { + return false; + } + retryCounter = 0; + return true; } -// void SolarArrayDeploymentHandler::handleDeploymentFinish() { -// ReturnValue_t result = returnvalue::OK; -// if (deploymentCountdown.hasTimedOut()) { -// actionHelper.finish(true, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, returnvalue::OK); -// result = gpioInterface->pullLow(deplSA1); -// if (result != returnvalue::OK) { -// sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" -// " array deployment switch 1 low " -// << std::endl; -// } -// result = gpioInterface->pullLow(deplSA2); -// if (result != returnvalue::OK) { -// sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" -// " array deployment switch 2 low " -// << std::endl; -// } -// mainLineSwitcher.sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF); -// mainSwitchCountdown.setTimeout(mainLineSwitcher.getSwitchDelayMs()); -// stateMachine = WAIT_FOR_MAIN_SWITCH_OFF; -// } -//} +void SolarArrayDeploymentHandler::finishFsm(ReturnValue_t resultForActionHelper) { + retryCounter = 0; + stateMachine = StateMachine::IDLE; + if (actionActive) { + actionHelper.finish(true, rememberCommanderId, activeCmd, resultForActionHelper); + } +} + +ReturnValue_t SolarArrayDeploymentHandler::deploymentTransistorsOn() { + ReturnValue_t result = gpioInterface.pullHigh(deplSA1); + if (result != returnvalue::OK) { + sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" + " array deployment switch 1 high " + << std::endl; + // If gpio switch high failed, state machine is reset to wait for a command re-initiating + // the deployment sequence. + triggerEvent(DEPL_SA1_GPIO_SWTICH_ON_FAILED); + } + result = gpioInterface.pullHigh(deplSA2); + if (result != returnvalue::OK) { + sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" + " array deployment switch 2 high " + << std::endl; + triggerEvent(DEPL_SA2_GPIO_SWTICH_ON_FAILED); + } + return result; +} + +ReturnValue_t SolarArrayDeploymentHandler::deploymentTransistorsOff() { + ReturnValue_t result = gpioInterface.pullLow(deplSA1); + if (result != returnvalue::OK) { + sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" + " array deployment switch 1 low" + << std::endl; + // If gpio switch high failed, state machine is reset to wait for a command re-initiating + // the deployment sequence. + triggerEvent(DEPL_SA1_GPIO_SWTICH_ON_FAILED); + } + result = gpioInterface.pullLow(deplSA2); + if (result != returnvalue::OK) { + sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" + " array deployment switch 2 low" + << std::endl; + triggerEvent(DEPL_SA2_GPIO_SWTICH_ON_FAILED); + } + return result; +} void SolarArrayDeploymentHandler::readCommandQueue() { CommandMessage command; diff --git a/mission/devices/SolarArrayDeploymentHandler.h b/mission/devices/SolarArrayDeploymentHandler.h index dc1db96d..2a5806e0 100644 --- a/mission/devices/SolarArrayDeploymentHandler.h +++ b/mission/devices/SolarArrayDeploymentHandler.h @@ -3,8 +3,8 @@ #include -#include "eive/definitions.h" #include "devices/powerSwitcherList.h" +#include "eive/definitions.h" #include "events/subsystemIdRanges.h" #include "fsfw/action/HasActionsIF.h" #include "fsfw/devicehandlers/CookieIF.h" @@ -34,11 +34,13 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, static constexpr DeviceCommandId_t FORCE_DEPLY_OFF = 0x07; static constexpr uint32_t FIRST_BURN_START_TIME = config::SA_DEPL_BURN_TIME_SECS; - static constexpr uint32_t FIRST_BURN_END_TIME = FIRST_BURN_START_TIME + config::SA_DEPL_BURN_TIME_SECS; - static constexpr uint32_t FIRST_WAIT_START_TIME = FIRST_BURN_END_TIME; - static constexpr uint32_t FIRST_WAIT_END_TIME = FIRST_BURN_END_TIME + config::SA_DEPL_WAIT_TIME_SECS; - static constexpr uint32_t SECOND_BURN_START_TIME = FIRST_WAIT_END_TIME; - static constexpr uint32_t SECOND_BURN_END_TIME = SECOND_BURN_START_TIME + config::SA_DEPL_WAIT_TIME_SECS; + 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; static constexpr char SD_0_DEPL_FILE[] = "/mnt/sd0/conf/deployment"; static constexpr char SD_1_DEPL_FILE[] = "/mnt/sd1/conf/deployment"; @@ -93,26 +95,32 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, static const Event DEPL_SA1_GPIO_SWTICH_ON_FAILED = MAKE_EVENT(3, severity::HIGH); static const Event DEPL_SA2_GPIO_SWTICH_ON_FAILED = MAKE_EVENT(4, severity::HIGH); - enum AutonomousDeplState { - INIT, - FIRST_BURN, - WAIT, - SECOND_BURN, - DONE + 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, }; - // enum StateMachine { - // WAIT_ON_DELOYMENT_COMMAND, - // SWITCH_8V_ON, - // WAIT_ON_8V_SWITCH, - // SWITCH_DEPL_GPIOS, - // WAIT_ON_DEPLOYMENT_FINISH, - // WAIT_FOR_MAIN_SWITCH_OFF - // }; - // - // StateMachine stateMachine = WAIT_ON_DELOYMENT_COMMAND; + + StateMachine stateMachine = IDLE; + bool actionActive = false; + ActionId_t activeCmd = HasActionsIF::INVALID_ACTION_ID; + std::optional initUptime; + uint8_t retryCounter = 3; + struct FsmInfo { + // false if OFF, true is ON + bool sa1OnOff = false; + bool sa2OnOff = false; + } fsmInfo; + + bool startFsm(std::optional sa1OnOff, std::optional sa2OnOff); + void finishFsm(ReturnValue_t resultForActionHelper); ReturnValue_t performAutonomousDepl(sd::SdCard sdCard); - + bool autonomousDeplForFile(const char* filename); /** * This countdown is used to check if the PCDU sets the 8V line on in the intended time. */ @@ -121,7 +129,7 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, /** * This countdown is used to wait for the burn wire being successful cut. */ - // Countdown deploymentCountdown; + Countdown deploymentCountdown; /** * The message queue id of the component commanding an action will be stored in this variable. @@ -161,18 +169,15 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, * @brief This function polls the 8V switch state and changes the state machine when the * switch has been enabled. */ - void performWaitOn8VActions(); + bool checkMainPowerOn(); + bool checkMainPowerOff(); + bool checkMainPower(bool onOff); /** * @brief This functions handles the switching of the solar array deployment transistors. */ - void deploymentTransistorsOn(); - - /** - * @brief This function performs actions to finish the deployment. Essentially switches - * are turned of after the burn time has expired. - */ - // void handleDeploymentFinish(); + ReturnValue_t deploymentTransistorsOn(); + ReturnValue_t deploymentTransistorsOff(); }; #endif /* MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_ */ -- 2.34.1 From 10da5cd45b1bb5552b3972e04ffc15edee2e3cf9 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 12 Oct 2022 17:21:10 +0200 Subject: [PATCH 09/35] action handler init --- .../devices/SolarArrayDeploymentHandler.cpp | 20 ++++++------------- mission/devices/SolarArrayDeploymentHandler.h | 2 +- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index 7a1c06d4..0b085cf6 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -299,20 +299,12 @@ ReturnValue_t SolarArrayDeploymentHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t* data, size_t size) { ReturnValue_t result = returnvalue::OK; - // if (stateMachine != WAIT_ON_DELOYMENT_COMMAND) { - // sif::error << "SolarArrayDeploymentHandler::executeAction: Received command while not in" - // << "waiting-on-command-state" << std::endl; - // return DEPLOYMENT_ALREADY_EXECUTING; - // } - // if (actionId != DEPLOY_SOLAR_ARRAYS) { - // sif::error << "SolarArrayDeploymentHandler::executeAction: Received invalid command" - // << std::endl; - // result = COMMAND_NOT_SUPPORTED; - // } else { - // stateMachine = SWITCH_8V_ON; - // rememberCommanderId = commandedBy; - // result = returnvalue::OK; - // } + if (actionId == FORCE_DEPLY_ON) { + } + if (actionId == FORCE_DEPLY_OFF) { + } + if (actionId == DEPLOY_SOLAR_ARRAYS_MANUALLY) { + } return result; } diff --git a/mission/devices/SolarArrayDeploymentHandler.h b/mission/devices/SolarArrayDeploymentHandler.h index 2a5806e0..b94ba67c 100644 --- a/mission/devices/SolarArrayDeploymentHandler.h +++ b/mission/devices/SolarArrayDeploymentHandler.h @@ -28,7 +28,7 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, public HasActionsIF { public: // Burn them for a custom amount limited by 120 secs - static constexpr DeviceCommandId_t DEPLOY_SOLAR_ARRAYS_MANUALLY = 0x5; + static constexpr DeviceCommandId_t DEPLOY_SOLAR_ARRAYS_MANUALLY = 0x05; // Careful with these command, not automatic off handling! static constexpr DeviceCommandId_t FORCE_DEPLY_ON = 0x06; static constexpr DeviceCommandId_t FORCE_DEPLY_OFF = 0x07; -- 2.34.1 From 22691b695038934d46fa1f1a8d737cec7fe498cd Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 12 Oct 2022 17:23:54 +0200 Subject: [PATCH 10/35] add TODO --- mission/devices/SolarArrayDeploymentHandler.cpp | 15 +++++++++++---- mission/devices/SolarArrayDeploymentHandler.h | 2 ++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index 0b085cf6..af281d1d 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -141,11 +141,15 @@ bool SolarArrayDeploymentHandler::autonomousDeplForFile(const char* filename) { } lineNum++; } - if (initUptime) { - secsSinceBoot = initUptime.value(); + bool updateUptime = false; + if(opDivider.checkAndIncrement()) { + if (initUptime) { + secsSinceBoot = initUptime.value(); + } + // Uptime has increased by X seconds so we need to update the uptime count inside the file + secsSinceBoot += Clock::getUptime().tv_sec; + updateUptime = true; } - // Uptime has increased by X seconds so we need to update the uptime count inside the file - secsSinceBoot += Clock::getUptime().tv_sec; if (stateSwitch) { if (deplState == AutonomousDeplState::FIRST_BURN or deplState == AutonomousDeplState::SECOND_BURN) { @@ -154,6 +158,9 @@ bool SolarArrayDeploymentHandler::autonomousDeplForFile(const char* filename) { startFsm(false, false); } } + if(stateSwitch or updateUptime) { + // TODO: Write new file here + } return true; } diff --git a/mission/devices/SolarArrayDeploymentHandler.h b/mission/devices/SolarArrayDeploymentHandler.h index b94ba67c..019c6bf6 100644 --- a/mission/devices/SolarArrayDeploymentHandler.h +++ b/mission/devices/SolarArrayDeploymentHandler.h @@ -1,6 +1,7 @@ #ifndef MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_ #define MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_ +#include #include #include "devices/powerSwitcherList.h" @@ -109,6 +110,7 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, bool actionActive = false; ActionId_t activeCmd = HasActionsIF::INVALID_ACTION_ID; std::optional initUptime; + PeriodicOperationDivider opDivider = PeriodicOperationDivider(5); uint8_t retryCounter = 3; struct FsmInfo { // false if OFF, true is ON -- 2.34.1 From e1b3688869c8d08e390302e760be11968798dbda Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 12 Oct 2022 19:55:20 +0200 Subject: [PATCH 11/35] finish file handling --- mission/devices/SolarArrayDeploymentHandler.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index af281d1d..dc5ae63e 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -110,7 +110,7 @@ bool SolarArrayDeploymentHandler::autonomousDeplForFile(const char* filename) { } } else if (lineNum == 1) { iss >> word; - if (word.find("phase:") == string::npos) { + if (word.find("secs_since_start:") == string::npos) { return false; } @@ -159,7 +159,20 @@ bool SolarArrayDeploymentHandler::autonomousDeplForFile(const char* filename) { } } if(stateSwitch or updateUptime) { - // TODO: Write new file here + std::ofstream of(filename); + of << "phase: " ; + if(deplState == AutonomousDeplState::INIT) { + of << PHASE_INIT_STR << "\n"; + } else if(deplState == AutonomousDeplState::FIRST_BURN) { + of << PHASE_FIRST_BURN_STR << "\n"; + } else if(deplState == AutonomousDeplState::WAIT) { + of << PHASE_WAIT_STR << "\n"; + } else if(deplState == AutonomousDeplState::SECOND_BURN) { + of << PHASE_SECOND_BURN_STR << "\n"; + } else if(deplState == AutonomousDeplState::DONE) { + of << PHASE_DONE<< "\n"; + } + of << "secs_since_start: " << std::to_string(secsSinceBoot) << "\n"; } return true; } -- 2.34.1 From 20b57906b7139e285d7f9c168f6918cde8a54ae0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 12 Oct 2022 19:55:47 +0200 Subject: [PATCH 12/35] added TODO --- mission/devices/SolarArrayDeploymentHandler.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index dc5ae63e..90054ecc 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -318,6 +318,7 @@ void SolarArrayDeploymentHandler::readCommandQueue() { ReturnValue_t SolarArrayDeploymentHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t* data, size_t size) { + // TODO: Finish command handling ReturnValue_t result = returnvalue::OK; if (actionId == FORCE_DEPLY_ON) { } -- 2.34.1 From db7f7bdae2f7670184feca973b2a1f349a1286ee Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 13 Oct 2022 15:09:47 +0200 Subject: [PATCH 13/35] continue SA DEPL impl --- .../devices/SolarArrayDeploymentHandler.cpp | 126 ++++++++++-------- mission/devices/SolarArrayDeploymentHandler.h | 30 ++++- 2 files changed, 94 insertions(+), 62 deletions(-) diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index 90054ecc..41d7ddbb 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -142,7 +142,7 @@ bool SolarArrayDeploymentHandler::autonomousDeplForFile(const char* filename) { lineNum++; } bool updateUptime = false; - if(opDivider.checkAndIncrement()) { + if (opDivider.checkAndIncrement()) { if (initUptime) { secsSinceBoot = initUptime.value(); } @@ -158,21 +158,21 @@ bool SolarArrayDeploymentHandler::autonomousDeplForFile(const char* filename) { startFsm(false, false); } } - if(stateSwitch or updateUptime) { - std::ofstream of(filename); - of << "phase: " ; - if(deplState == AutonomousDeplState::INIT) { - of << PHASE_INIT_STR << "\n"; - } else if(deplState == AutonomousDeplState::FIRST_BURN) { - of << PHASE_FIRST_BURN_STR << "\n"; - } else if(deplState == AutonomousDeplState::WAIT) { - of << PHASE_WAIT_STR << "\n"; - } else if(deplState == AutonomousDeplState::SECOND_BURN) { - of << PHASE_SECOND_BURN_STR << "\n"; - } else if(deplState == AutonomousDeplState::DONE) { - of << PHASE_DONE<< "\n"; - } - of << "secs_since_start: " << std::to_string(secsSinceBoot) << "\n"; + if (stateSwitch or updateUptime) { + std::ofstream of(filename); + of << "phase: "; + if (deplState == AutonomousDeplState::INIT) { + of << PHASE_INIT_STR << "\n"; + } else if (deplState == AutonomousDeplState::FIRST_BURN) { + of << PHASE_FIRST_BURN_STR << "\n"; + } else if (deplState == AutonomousDeplState::WAIT) { + of << PHASE_WAIT_STR << "\n"; + } else if (deplState == AutonomousDeplState::SECOND_BURN) { + of << PHASE_SECOND_BURN_STR << "\n"; + } else if (deplState == AutonomousDeplState::DONE) { + of << PHASE_DONE << "\n"; + } + of << "secs_since_start: " << std::to_string(secsSinceBoot) << "\n"; } return true; } @@ -192,8 +192,9 @@ void SolarArrayDeploymentHandler::handleStateMachine() { stateMachine = WAIT_MAIN_POWER_ON; } if (stateMachine == MAIN_POWER_OFF) { - // This should never fail - deploymentTransistorsOff(); + // These should never fail + deploymentTransistorsOff(DeploymentChannels::SA_1); + deploymentTransistorsOff(DeploymentChannels::SA_2); mainLineSwitcher.sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_ON); mainSwitchCountdown.setTimeout(mainLineSwitcher.getSwitchDelayMs()); stateMachine = WAIT_MAIN_POWER_OFF; @@ -210,7 +211,7 @@ void SolarArrayDeploymentHandler::handleStateMachine() { } if (stateMachine == SWITCH_DEPL_GPIOS) { // This should never fail - deploymentTransistorsOn(); + // deploymentTransistorsOn(); finishFsm(returnvalue::OK); } } @@ -262,42 +263,50 @@ void SolarArrayDeploymentHandler::finishFsm(ReturnValue_t resultForActionHelper) } } -ReturnValue_t SolarArrayDeploymentHandler::deploymentTransistorsOn() { - ReturnValue_t result = gpioInterface.pullHigh(deplSA1); - if (result != returnvalue::OK) { - sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" - " array deployment switch 1 high " - << std::endl; - // If gpio switch high failed, state machine is reset to wait for a command re-initiating - // the deployment sequence. - triggerEvent(DEPL_SA1_GPIO_SWTICH_ON_FAILED); - } - result = gpioInterface.pullHigh(deplSA2); - if (result != returnvalue::OK) { - sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" - " array deployment switch 2 high " - << std::endl; - triggerEvent(DEPL_SA2_GPIO_SWTICH_ON_FAILED); +ReturnValue_t SolarArrayDeploymentHandler::deploymentTransistorsOn(DeploymentChannels channel) { + ReturnValue_t result = returnvalue::FAILED; + if (channel == DeploymentChannels::SA_1) { + result = gpioInterface.pullHigh(deplSA1); + if (result != returnvalue::OK) { + sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" + " array deployment switch 1 high " + << std::endl; + // If gpio switch high failed, state machine is reset to wait for a command re-initiating + // the deployment sequence. + triggerEvent(DEPL_SA1_GPIO_SWTICH_ON_FAILED); + } + } else if (channel == DeploymentChannels::SA_2) { + result = gpioInterface.pullHigh(deplSA2); + if (result != returnvalue::OK) { + sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" + " array deployment switch 2 high " + << std::endl; + triggerEvent(DEPL_SA2_GPIO_SWTICH_ON_FAILED); + } } return result; } -ReturnValue_t SolarArrayDeploymentHandler::deploymentTransistorsOff() { - ReturnValue_t result = gpioInterface.pullLow(deplSA1); - if (result != returnvalue::OK) { - sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" - " array deployment switch 1 low" - << std::endl; - // If gpio switch high failed, state machine is reset to wait for a command re-initiating - // the deployment sequence. - triggerEvent(DEPL_SA1_GPIO_SWTICH_ON_FAILED); - } - result = gpioInterface.pullLow(deplSA2); - if (result != returnvalue::OK) { - sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" - " array deployment switch 2 low" - << std::endl; - triggerEvent(DEPL_SA2_GPIO_SWTICH_ON_FAILED); +ReturnValue_t SolarArrayDeploymentHandler::deploymentTransistorsOff(DeploymentChannels channel) { + ReturnValue_t result = returnvalue::FAILED; + if (channel == DeploymentChannels::SA_1) { + result = gpioInterface.pullLow(deplSA1); + if (result != returnvalue::OK) { + sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" + " array deployment switch 1 high " + << std::endl; + // If gpio switch high failed, state machine is reset to wait for a command re-initiating + // the deployment sequence. + triggerEvent(DEPL_SA1_GPIO_SWTICH_OFF_FAILED); + } + } else if (channel == DeploymentChannels::SA_2) { + result = gpioInterface.pullLow(deplSA2); + if (result != returnvalue::OK) { + sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" + " array deployment switch 2 high " + << std::endl; + triggerEvent(DEPL_SA2_GPIO_SWTICH_OFF_FAILED); + } } return result; } @@ -318,13 +327,18 @@ void SolarArrayDeploymentHandler::readCommandQueue() { ReturnValue_t SolarArrayDeploymentHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t* data, size_t size) { - // TODO: Finish command handling ReturnValue_t result = returnvalue::OK; - if (actionId == FORCE_DEPLY_ON) { - } - if (actionId == FORCE_DEPLY_OFF) { - } if (actionId == DEPLOY_SOLAR_ARRAYS_MANUALLY) { + ManualDeploymentCommand cmd; + if (size < cmd.getSerializedSize()) { + return HasActionsIF::INVALID_PARAMETERS; + } + result = cmd.deSerialize(&data, &size, SerializeIF::Endianness::NETWORK); + if (result != returnvalue::OK) { + return result; + } + } else { + return HasActionsIF::INVALID_ACTION_ID; } return result; } diff --git a/mission/devices/SolarArrayDeploymentHandler.h b/mission/devices/SolarArrayDeploymentHandler.h index 019c6bf6..d4f859a5 100644 --- a/mission/devices/SolarArrayDeploymentHandler.h +++ b/mission/devices/SolarArrayDeploymentHandler.h @@ -2,6 +2,7 @@ #define MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_ #include + #include #include "devices/powerSwitcherList.h" @@ -13,12 +14,30 @@ #include "fsfw/objectmanager/SystemObject.h" #include "fsfw/power/PowerSwitchIF.h" #include "fsfw/returnvalues/returnvalue.h" +#include "fsfw/serialize/SerialLinkedListAdapter.h" #include "fsfw/tasks/ExecutableObjectIF.h" #include "fsfw/timemanager/Countdown.h" #include "fsfw_hal/common/gpio/GpioIF.h" #include "mission/memory/SdCardMountedIF.h" #include "returnvalues/classIds.h" +enum DeploymentChannels : uint8_t { SA_1 = 1, SA_2 = 2 }; + +class ManualDeploymentCommand : SerialLinkedListAdapter { + public: + ManualDeploymentCommand() = default; + + void setLinks() { + setStart(&burnTime); + burnTime.setNext(&channel); + } + + private: + SerializeElement burnTime; + // Deployment channel SA1 or SA2 + SerializeElement channel; +}; + /** * @brief This class is used to control the solar array deployment. * @@ -28,11 +47,8 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, public SystemObject, public HasActionsIF { public: - // Burn them for a custom amount limited by 120 secs + //! Manual deployment of the solar arrays. Burn time and channels are supplied with TC parameters static constexpr DeviceCommandId_t DEPLOY_SOLAR_ARRAYS_MANUALLY = 0x05; - // Careful with these command, not automatic off handling! - static constexpr DeviceCommandId_t FORCE_DEPLY_ON = 0x06; - static constexpr DeviceCommandId_t FORCE_DEPLY_OFF = 0x07; static constexpr uint32_t FIRST_BURN_START_TIME = config::SA_DEPL_BURN_TIME_SECS; static constexpr uint32_t FIRST_BURN_END_TIME = @@ -95,6 +111,8 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, static const Event DEPLOYMENT_FAILED = MAKE_EVENT(2, severity::HIGH); static const Event DEPL_SA1_GPIO_SWTICH_ON_FAILED = MAKE_EVENT(3, severity::HIGH); static const Event DEPL_SA2_GPIO_SWTICH_ON_FAILED = MAKE_EVENT(4, severity::HIGH); + static const Event DEPL_SA1_GPIO_SWTICH_OFF_FAILED = MAKE_EVENT(5, severity::HIGH); + static const Event DEPL_SA2_GPIO_SWTICH_OFF_FAILED = MAKE_EVENT(6, severity::HIGH); enum AutonomousDeplState { INIT, FIRST_BURN, WAIT, SECOND_BURN, DONE }; enum StateMachine { @@ -178,8 +196,8 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, /** * @brief This functions handles the switching of the solar array deployment transistors. */ - ReturnValue_t deploymentTransistorsOn(); - ReturnValue_t deploymentTransistorsOff(); + ReturnValue_t deploymentTransistorsOn(DeploymentChannels channel); + ReturnValue_t deploymentTransistorsOff(DeploymentChannels channel); }; #endif /* MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_ */ -- 2.34.1 From 18e8827a849758fdab03240e04ba71799ad6aec3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 13 Oct 2022 15:13:19 +0200 Subject: [PATCH 14/35] add missing public keyword --- mission/devices/SolarArrayDeploymentHandler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mission/devices/SolarArrayDeploymentHandler.h b/mission/devices/SolarArrayDeploymentHandler.h index d4f859a5..5a627ea0 100644 --- a/mission/devices/SolarArrayDeploymentHandler.h +++ b/mission/devices/SolarArrayDeploymentHandler.h @@ -23,7 +23,7 @@ enum DeploymentChannels : uint8_t { SA_1 = 1, SA_2 = 2 }; -class ManualDeploymentCommand : SerialLinkedListAdapter { +class ManualDeploymentCommand : public SerialLinkedListAdapter { public: ManualDeploymentCommand() = default; -- 2.34.1 From 0ebd0a0c0bfb2a3991e30df8ed796e36815ebcca Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 13 Oct 2022 15:59:56 +0200 Subject: [PATCH 15/35] completed impl --- common/config/eive/definitions.h | 3 + .../devices/SolarArrayDeploymentHandler.cpp | 70 +++++++++++++++---- mission/devices/SolarArrayDeploymentHandler.h | 29 ++++++-- 3 files changed, 86 insertions(+), 16 deletions(-) diff --git a/common/config/eive/definitions.h b/common/config/eive/definitions.h index fb941edc..cd23b382 100644 --- a/common/config/eive/definitions.h +++ b/common/config/eive/definitions.h @@ -35,8 +35,11 @@ static constexpr uint32_t MAX_PATH_SIZE = 100; static constexpr uint32_t MAX_FILENAME_SIZE = 50; static constexpr uint32_t SA_DEPL_INIT_BUFFER_SECS = 120; +// Burn time for autonomous deployment static constexpr uint32_t SA_DEPL_BURN_TIME_SECS = 90; static constexpr uint32_t SA_DEPL_WAIT_TIME_SECS = 45 * 60; +// Maximum allowed burn time allowed by the software. +static constexpr uint32_t SA_DEPL_MAX_BURN_TIME = 120; } // namespace config diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index 41d7ddbb..567d9353 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -153,9 +153,12 @@ bool SolarArrayDeploymentHandler::autonomousDeplForFile(const char* filename) { if (stateSwitch) { if (deplState == AutonomousDeplState::FIRST_BURN or deplState == AutonomousDeplState::SECOND_BURN) { - startFsm(true, true); + // TODO: Update to be channel specific + // startFsmOn(channel, config::SA_DEPL_BURN_TIME_SECS); + //startFsm(true, true); } else if (deplState == AutonomousDeplState::WAIT or deplState == AutonomousDeplState::DONE) { - startFsm(false, false); + startFsmOff(); + //startFsm(false, false); } } if (stateSwitch or updateUptime) { @@ -193,10 +196,7 @@ void SolarArrayDeploymentHandler::handleStateMachine() { } if (stateMachine == MAIN_POWER_OFF) { // These should never fail - deploymentTransistorsOff(DeploymentChannels::SA_1); - deploymentTransistorsOff(DeploymentChannels::SA_2); - mainLineSwitcher.sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_ON); - mainSwitchCountdown.setTimeout(mainLineSwitcher.getSwitchDelayMs()); + allOff(); stateMachine = WAIT_MAIN_POWER_OFF; } if (stateMachine == WAIT_MAIN_POWER_ON) { @@ -211,8 +211,15 @@ void SolarArrayDeploymentHandler::handleStateMachine() { } if (stateMachine == SWITCH_DEPL_GPIOS) { // This should never fail - // deploymentTransistorsOn(); - finishFsm(returnvalue::OK); + deploymentTransistorsOn(fsmInfo.channel); + burnCountdown.setTimeout(fsmInfo.burnCountdown); + stateMachine = CHANNEL_ON; + } + if(stateMachine == CHANNEL_ON) { + if(burnCountdown.hasTimedOut()) { + allOff(); + stateMachine = WAIT_MAIN_POWER_OFF; + } } } @@ -246,20 +253,39 @@ bool SolarArrayDeploymentHandler::checkMainPower(bool onOff) { return false; } -bool SolarArrayDeploymentHandler::startFsm(std::optional sa1OnOff, - std::optional sa2OnOff) { - if ((stateMachine != StateMachine::IDLE) or (not sa1OnOff and not sa2OnOff)) { +bool SolarArrayDeploymentHandler::startFsmOn(DeploymentChannels channel, uint32_t burnCountdown_) { + if (stateMachine != StateMachine::IDLE) { return false; } + if(burnCountdown_ > config::SA_DEPL_MAX_BURN_TIME) { + burnCountdown_ = config::SA_DEPL_MAX_BURN_TIME; + } + fsmInfo.onOff = true; + fsmInfo.channel = channel; + fsmInfo.burnCountdown = burnCountdown_; retryCounter = 0; return true; } +void SolarArrayDeploymentHandler::startFsmOff() { + if(stateMachine != StateMachine::IDLE) { + // off commands override the state machine. Cancel any active action commands. + finishFsm(returnvalue::FAILED); + } + fsmInfo.onOff = false; + retryCounter = 0; + stateMachine = StateMachine::MAIN_POWER_ON; +} + void SolarArrayDeploymentHandler::finishFsm(ReturnValue_t resultForActionHelper) { retryCounter = 0; stateMachine = StateMachine::IDLE; if (actionActive) { - actionHelper.finish(true, rememberCommanderId, activeCmd, resultForActionHelper); + bool success = false; + if(resultForActionHelper == returnvalue::OK or resultForActionHelper == HasActionsIF::EXECUTION_FINISHED) { + success = true; + } + actionHelper.finish(success, rememberCommanderId, activeCmd, resultForActionHelper); } } @@ -287,6 +313,13 @@ ReturnValue_t SolarArrayDeploymentHandler::deploymentTransistorsOn(DeploymentCha return result; } +void SolarArrayDeploymentHandler::allOff() { + deploymentTransistorsOff(DeploymentChannels::SA_1); + deploymentTransistorsOff(DeploymentChannels::SA_2); + mainLineSwitcher.sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF); + mainSwitchCountdown.setTimeout(mainLineSwitcher.getSwitchDelayMs()); +} + ReturnValue_t SolarArrayDeploymentHandler::deploymentTransistorsOff(DeploymentChannels channel) { ReturnValue_t result = returnvalue::FAILED; if (channel == DeploymentChannels::SA_1) { @@ -337,6 +370,19 @@ ReturnValue_t SolarArrayDeploymentHandler::executeAction(ActionId_t actionId, if (result != returnvalue::OK) { return result; } + uint32_t burnCountdown = cmd.getBurnTime(); + DeploymentChannels channel; + result = cmd.getChannel(channel); + if(result != returnvalue::OK) { + return result; + } + if (not startFsmOn(channel, burnCountdown)) { + return HasActionsIF::IS_BUSY; + } + return result; + } else if(actionId == SWITCH_OFF_DEPLOYMENT) { + startFsmOff(); + return result; } else { return HasActionsIF::INVALID_ACTION_ID; } diff --git a/mission/devices/SolarArrayDeploymentHandler.h b/mission/devices/SolarArrayDeploymentHandler.h index 5a627ea0..d8fb27ed 100644 --- a/mission/devices/SolarArrayDeploymentHandler.h +++ b/mission/devices/SolarArrayDeploymentHandler.h @@ -32,6 +32,18 @@ class ManualDeploymentCommand : public SerialLinkedListAdapter { burnTime.setNext(&channel); } + uint32_t getBurnTime() const { + return burnTime.entry; + } + + ReturnValue_t getChannel(DeploymentChannels& channel_) const { + if (channel.entry == 1 or channel.entry == 2) { + channel_ = static_cast(channel.entry); + return returnvalue::OK; + } + return HasActionsIF::INVALID_PARAMETERS; + } + private: SerializeElement burnTime; // Deployment channel SA1 or SA2 @@ -49,6 +61,7 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, public: //! Manual deployment of the solar arrays. Burn time and channels are supplied with TC parameters static constexpr DeviceCommandId_t DEPLOY_SOLAR_ARRAYS_MANUALLY = 0x05; + static constexpr DeviceCommandId_t SWITCH_OFF_DEPLOYMENT = 0x06; static constexpr uint32_t FIRST_BURN_START_TIME = config::SA_DEPL_BURN_TIME_SECS; static constexpr uint32_t FIRST_BURN_END_TIME = @@ -122,6 +135,7 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, WAIT_MAIN_POWER_ON, WAIT_MAIN_POWER_OFF, SWITCH_DEPL_GPIOS, + CHANNEL_ON }; StateMachine stateMachine = IDLE; @@ -130,13 +144,18 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, std::optional initUptime; PeriodicOperationDivider opDivider = PeriodicOperationDivider(5); uint8_t retryCounter = 3; + + bool startFsmOn(DeploymentChannels channel, uint32_t burnCountdown); + void startFsmOff(); + struct FsmInfo { + DeploymentChannels channel; // false if OFF, true is ON - bool sa1OnOff = false; - bool sa2OnOff = false; + bool onOff; + uint32_t burnCountdown = config::SA_DEPL_MAX_BURN_TIME; } fsmInfo; - bool startFsm(std::optional sa1OnOff, std::optional sa2OnOff); + void finishFsm(ReturnValue_t resultForActionHelper); ReturnValue_t performAutonomousDepl(sd::SdCard sdCard); @@ -149,7 +168,7 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, /** * This countdown is used to wait for the burn wire being successful cut. */ - Countdown deploymentCountdown; + Countdown burnCountdown; /** * The message queue id of the component commanding an action will be stored in this variable. @@ -193,6 +212,8 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, bool checkMainPowerOff(); bool checkMainPower(bool onOff); + void allOff(); + /** * @brief This functions handles the switching of the solar array deployment transistors. */ -- 2.34.1 From d97e0a1a6ac8730148841fe5423178708165bbb5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 13 Oct 2022 16:04:34 +0200 Subject: [PATCH 16/35] update depl handler --- .../devices/SolarArrayDeploymentHandler.cpp | 23 +++++----- mission/devices/SolarArrayDeploymentHandler.h | 44 +++++++++---------- 2 files changed, 34 insertions(+), 33 deletions(-) diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index 567d9353..28922fd2 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -155,10 +155,10 @@ bool SolarArrayDeploymentHandler::autonomousDeplForFile(const char* filename) { deplState == AutonomousDeplState::SECOND_BURN) { // TODO: Update to be channel specific // startFsmOn(channel, config::SA_DEPL_BURN_TIME_SECS); - //startFsm(true, true); + // startFsm(true, true); } else if (deplState == AutonomousDeplState::WAIT or deplState == AutonomousDeplState::DONE) { startFsmOff(); - //startFsm(false, false); + // startFsm(false, false); } } if (stateSwitch or updateUptime) { @@ -215,8 +215,8 @@ void SolarArrayDeploymentHandler::handleStateMachine() { burnCountdown.setTimeout(fsmInfo.burnCountdown); stateMachine = CHANNEL_ON; } - if(stateMachine == CHANNEL_ON) { - if(burnCountdown.hasTimedOut()) { + if (stateMachine == CHANNEL_ON) { + if (burnCountdown.hasTimedOut()) { allOff(); stateMachine = WAIT_MAIN_POWER_OFF; } @@ -257,7 +257,7 @@ bool SolarArrayDeploymentHandler::startFsmOn(DeploymentChannels channel, uint32_ if (stateMachine != StateMachine::IDLE) { return false; } - if(burnCountdown_ > config::SA_DEPL_MAX_BURN_TIME) { + if (burnCountdown_ > config::SA_DEPL_MAX_BURN_TIME) { burnCountdown_ = config::SA_DEPL_MAX_BURN_TIME; } fsmInfo.onOff = true; @@ -268,7 +268,7 @@ bool SolarArrayDeploymentHandler::startFsmOn(DeploymentChannels channel, uint32_ } void SolarArrayDeploymentHandler::startFsmOff() { - if(stateMachine != StateMachine::IDLE) { + if (stateMachine != StateMachine::IDLE) { // off commands override the state machine. Cancel any active action commands. finishFsm(returnvalue::FAILED); } @@ -282,7 +282,8 @@ void SolarArrayDeploymentHandler::finishFsm(ReturnValue_t resultForActionHelper) stateMachine = StateMachine::IDLE; if (actionActive) { bool success = false; - if(resultForActionHelper == returnvalue::OK or resultForActionHelper == HasActionsIF::EXECUTION_FINISHED) { + if (resultForActionHelper == returnvalue::OK or + resultForActionHelper == HasActionsIF::EXECUTION_FINISHED) { success = true; } actionHelper.finish(success, rememberCommanderId, activeCmd, resultForActionHelper); @@ -373,16 +374,16 @@ ReturnValue_t SolarArrayDeploymentHandler::executeAction(ActionId_t actionId, uint32_t burnCountdown = cmd.getBurnTime(); DeploymentChannels channel; result = cmd.getChannel(channel); - if(result != returnvalue::OK) { + if (result != returnvalue::OK) { return result; } if (not startFsmOn(channel, burnCountdown)) { return HasActionsIF::IS_BUSY; } return result; - } else if(actionId == SWITCH_OFF_DEPLOYMENT) { - startFsmOff(); - return result; + } else if (actionId == SWITCH_OFF_DEPLOYMENT) { + startFsmOff(); + return result; } else { return HasActionsIF::INVALID_ACTION_ID; } diff --git a/mission/devices/SolarArrayDeploymentHandler.h b/mission/devices/SolarArrayDeploymentHandler.h index d8fb27ed..2d20606f 100644 --- a/mission/devices/SolarArrayDeploymentHandler.h +++ b/mission/devices/SolarArrayDeploymentHandler.h @@ -32,9 +32,7 @@ class ManualDeploymentCommand : public SerialLinkedListAdapter { burnTime.setNext(&channel); } - uint32_t getBurnTime() const { - return burnTime.entry; - } + uint32_t getBurnTime() const { return burnTime.entry; } ReturnValue_t getChannel(DeploymentChannels& channel_) const { if (channel.entry == 1 or channel.entry == 2) { @@ -111,6 +109,26 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, virtual ReturnValue_t initialize() override; private: + 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, + CHANNEL_ON + }; + + struct FsmInfo { + DeploymentChannels channel; + // false if OFF, true is ON + bool onOff; + bool dryRun; + uint32_t burnCountdown = config::SA_DEPL_MAX_BURN_TIME; + }; + 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); @@ -127,17 +145,7 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, static const Event DEPL_SA1_GPIO_SWTICH_OFF_FAILED = MAKE_EVENT(5, severity::HIGH); static const Event DEPL_SA2_GPIO_SWTICH_OFF_FAILED = MAKE_EVENT(6, severity::HIGH); - 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, - CHANNEL_ON - }; - + FsmInfo fsmInfo; StateMachine stateMachine = IDLE; bool actionActive = false; ActionId_t activeCmd = HasActionsIF::INVALID_ACTION_ID; @@ -148,14 +156,6 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, bool startFsmOn(DeploymentChannels channel, uint32_t burnCountdown); void startFsmOff(); - struct FsmInfo { - DeploymentChannels channel; - // false if OFF, true is ON - bool onOff; - uint32_t burnCountdown = config::SA_DEPL_MAX_BURN_TIME; - } fsmInfo; - - void finishFsm(ReturnValue_t resultForActionHelper); ReturnValue_t performAutonomousDepl(sd::SdCard sdCard); -- 2.34.1 From 773747dd54e34c929ef4a348047554e506fe3694 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 13 Oct 2022 17:34:33 +0200 Subject: [PATCH 17/35] implemented alternating GPIO SA Deployment --- common/config/eive/definitions.h | 4 +- .../devices/SolarArrayDeploymentHandler.cpp | 190 ++++++++++++------ mission/devices/SolarArrayDeploymentHandler.h | 31 ++- tmtc | 2 +- 4 files changed, 152 insertions(+), 75 deletions(-) diff --git a/common/config/eive/definitions.h b/common/config/eive/definitions.h index cd23b382..81792c20 100644 --- a/common/config/eive/definitions.h +++ b/common/config/eive/definitions.h @@ -36,8 +36,10 @@ static constexpr uint32_t MAX_FILENAME_SIZE = 50; static constexpr uint32_t SA_DEPL_INIT_BUFFER_SECS = 120; // Burn time for autonomous deployment -static constexpr uint32_t SA_DEPL_BURN_TIME_SECS = 90; +static constexpr uint32_t SA_DEPL_BURN_TIME_SECS = 180; static constexpr uint32_t SA_DEPL_WAIT_TIME_SECS = 45 * 60; +// HW constraints (current limit) mean that the GPIO channels need to be switched on in alternation +static constexpr uint32_t SA_DEPL_CHANNEL_ALTERNATION_INTERVAL_SECS = 5; // Maximum allowed burn time allowed by the software. static constexpr uint32_t SA_DEPL_MAX_BURN_TIME = 120; diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index 28922fd2..21d01ce7 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -37,13 +37,13 @@ ReturnValue_t SolarArrayDeploymentHandler::performOperation(uint8_t operationCod sdcMan.isSdCardUsable(activeSdc.value())) { if (exists(SD_0_DEPL_FILE)) { // perform autonomous deployment handling - performAutonomousDepl(sd::SdCard::SLOT_0); + performAutonomousDepl(sd::SdCard::SLOT_0, dryRunStringInFile(SD_0_DEPL_FILE)); } } else if (activeSdc and activeSdc.value() == sd::SdCard::SLOT_1 and sdcMan.isSdCardUsable(activeSdc.value())) { if (exists(SD_1_DEPL_FILE)) { // perform autonomous deployment handling - performAutonomousDepl(sd::SdCard::SLOT_1); + performAutonomousDepl(sd::SdCard::SLOT_1, dryRunStringInFile(SD_1_DEPL_FILE)); } } readCommandQueue(); @@ -51,7 +51,7 @@ ReturnValue_t SolarArrayDeploymentHandler::performOperation(uint8_t operationCod return returnvalue::OK; } -ReturnValue_t SolarArrayDeploymentHandler::performAutonomousDepl(sd::SdCard sdCard) { +ReturnValue_t SolarArrayDeploymentHandler::performAutonomousDepl(sd::SdCard sdCard, bool dryRun) { using namespace std::filesystem; using namespace std; auto initFile = [](const char* filename) { @@ -63,21 +63,21 @@ ReturnValue_t SolarArrayDeploymentHandler::performAutonomousDepl(sd::SdCard sdCa if (not exists(SD_0_DEPLY_INFO)) { initFile(SD_0_DEPLY_INFO); } - if (not autonomousDeplForFile(SD_0_DEPLY_INFO)) { + if (not autonomousDeplForFile(SD_0_DEPLY_INFO, dryRun)) { initFile(SD_0_DEPLY_INFO); } } else if (sdCard == sd::SdCard::SLOT_1) { if (not exists(SD_1_DEPLY_INFO)) { initFile(SD_1_DEPLY_INFO); } - if (not autonomousDeplForFile(SD_1_DEPLY_INFO)) { + if (not autonomousDeplForFile(SD_1_DEPLY_INFO, dryRun)) { initFile(SD_1_DEPLY_INFO); } } return returnvalue::OK; } -bool SolarArrayDeploymentHandler::autonomousDeplForFile(const char* filename) { +bool SolarArrayDeploymentHandler::autonomousDeplForFile(const char* filename, bool dryRun) { using namespace std; ifstream file(filename); string line; @@ -153,9 +153,8 @@ bool SolarArrayDeploymentHandler::autonomousDeplForFile(const char* filename) { if (stateSwitch) { if (deplState == AutonomousDeplState::FIRST_BURN or deplState == AutonomousDeplState::SECOND_BURN) { - // TODO: Update to be channel specific - // startFsmOn(channel, config::SA_DEPL_BURN_TIME_SECS); - // startFsm(true, true); + // TODO: Update whole procedure to work for both channels + startFsmOn(config::SA_DEPL_BURN_TIME_SECS, dryRun); } else if (deplState == AutonomousDeplState::WAIT or deplState == AutonomousDeplState::DONE) { startFsmOff(); // startFsm(false, false); @@ -210,12 +209,20 @@ void SolarArrayDeploymentHandler::handleStateMachine() { } } if (stateMachine == SWITCH_DEPL_GPIOS) { - // This should never fail - deploymentTransistorsOn(fsmInfo.channel); burnCountdown.setTimeout(fsmInfo.burnCountdown); - stateMachine = CHANNEL_ON; + // This should never fail + if (not fsmInfo.dryRun) { + channelAlternationCd.resetTimer(); + sa2Off(); + sa1On(); + fsmInfo.alternationDummy = true; + } + stateMachine = BURNING; } - if (stateMachine == CHANNEL_ON) { + if (stateMachine == BURNING) { + if (not fsmInfo.dryRun) { + saGpioAlternation(); + } if (burnCountdown.hasTimedOut()) { allOff(); stateMachine = WAIT_MAIN_POWER_OFF; @@ -253,7 +260,7 @@ bool SolarArrayDeploymentHandler::checkMainPower(bool onOff) { return false; } -bool SolarArrayDeploymentHandler::startFsmOn(DeploymentChannels channel, uint32_t burnCountdown_) { +bool SolarArrayDeploymentHandler::startFsmOn(uint32_t burnCountdown_, bool dryRun) { if (stateMachine != StateMachine::IDLE) { return false; } @@ -261,7 +268,7 @@ bool SolarArrayDeploymentHandler::startFsmOn(DeploymentChannels channel, uint32_ burnCountdown_ = config::SA_DEPL_MAX_BURN_TIME; } fsmInfo.onOff = true; - fsmInfo.channel = channel; + fsmInfo.dryRun = dryRun; fsmInfo.burnCountdown = burnCountdown_; retryCounter = 0; return true; @@ -290,59 +297,24 @@ void SolarArrayDeploymentHandler::finishFsm(ReturnValue_t resultForActionHelper) } } -ReturnValue_t SolarArrayDeploymentHandler::deploymentTransistorsOn(DeploymentChannels channel) { - ReturnValue_t result = returnvalue::FAILED; - if (channel == DeploymentChannels::SA_1) { - result = gpioInterface.pullHigh(deplSA1); - if (result != returnvalue::OK) { - sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" - " array deployment switch 1 high " - << std::endl; - // If gpio switch high failed, state machine is reset to wait for a command re-initiating - // the deployment sequence. - triggerEvent(DEPL_SA1_GPIO_SWTICH_ON_FAILED); - } - } else if (channel == DeploymentChannels::SA_2) { - result = gpioInterface.pullHigh(deplSA2); - if (result != returnvalue::OK) { - sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" - " array deployment switch 2 high " - << std::endl; - triggerEvent(DEPL_SA2_GPIO_SWTICH_ON_FAILED); - } - } - return result; -} - void SolarArrayDeploymentHandler::allOff() { - deploymentTransistorsOff(DeploymentChannels::SA_1); - deploymentTransistorsOff(DeploymentChannels::SA_2); + deploymentTransistorsOff(); mainLineSwitcher.sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF); mainSwitchCountdown.setTimeout(mainLineSwitcher.getSwitchDelayMs()); } -ReturnValue_t SolarArrayDeploymentHandler::deploymentTransistorsOff(DeploymentChannels channel) { - ReturnValue_t result = returnvalue::FAILED; - if (channel == DeploymentChannels::SA_1) { - result = gpioInterface.pullLow(deplSA1); - if (result != returnvalue::OK) { - sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" - " array deployment switch 1 high " - << std::endl; - // If gpio switch high failed, state machine is reset to wait for a command re-initiating - // the deployment sequence. - triggerEvent(DEPL_SA1_GPIO_SWTICH_OFF_FAILED); - } - } else if (channel == DeploymentChannels::SA_2) { - result = gpioInterface.pullLow(deplSA2); - if (result != returnvalue::OK) { - sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" - " array deployment switch 2 high " - << std::endl; - triggerEvent(DEPL_SA2_GPIO_SWTICH_OFF_FAILED); +bool SolarArrayDeploymentHandler::dryRunStringInFile(const char* filename) { + std::ifstream ifile(filename); + if (ifile.bad()) { + return false; + } + std::string line; + while (getline(ifile, line)) { + if (line.find("dryrun") != std::string::npos) { + return true; } } - return result; + return false; } void SolarArrayDeploymentHandler::readCommandQueue() { @@ -377,7 +349,7 @@ ReturnValue_t SolarArrayDeploymentHandler::executeAction(ActionId_t actionId, if (result != returnvalue::OK) { return result; } - if (not startFsmOn(channel, burnCountdown)) { + if (not startFsmOn(burnCountdown, cmd.isDryRun())) { return HasActionsIF::IS_BUSY; } return result; @@ -390,6 +362,100 @@ ReturnValue_t SolarArrayDeploymentHandler::executeAction(ActionId_t actionId, return result; } +ReturnValue_t SolarArrayDeploymentHandler::saGpioAlternation() { + ReturnValue_t status = returnvalue::OK; + ReturnValue_t result; + if (channelAlternationCd.hasTimedOut()) { + if (fsmInfo.alternationDummy) { + result = sa1Off(); + if (result != returnvalue::OK) { + status = result; + } + result = sa2On(); + if (result != returnvalue::OK) { + status = result; + } + } else { + result = sa1On(); + if (result != returnvalue::OK) { + status = result; + } + result = sa2Off(); + if (result != returnvalue::OK) { + status = result; + } + } + fsmInfo.alternationDummy = not fsmInfo.alternationDummy; + channelAlternationCd.resetTimer(); + } + return status; +} + +ReturnValue_t SolarArrayDeploymentHandler::deploymentTransistorsOff() { + ReturnValue_t status = returnvalue::OK; + ReturnValue_t result = sa1Off(); + if (result != returnvalue::OK) { + status = result; + } + result = sa2Off(); + if (result != returnvalue::OK) { + status = result; + } + return status; +} + +ReturnValue_t SolarArrayDeploymentHandler::sa1On() { + ReturnValue_t result = gpioInterface.pullHigh(deplSA1); + if (result != returnvalue::OK) { + sif::warning << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" + " array deployment switch 1 high" + << std::endl; + // If gpio switch high failed, state machine is reset to wait for a command re-initiating + // the deployment sequence. + triggerEvent(DEPL_SA1_GPIO_SWTICH_ON_FAILED); + } + return result; +} + +ReturnValue_t SolarArrayDeploymentHandler::sa1Off() { + ReturnValue_t result = gpioInterface.pullLow(deplSA1); + if (result != returnvalue::OK) { + sif::warning << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" + " array deployment switch 1 low" + << std::endl; + // If gpio switch high failed, state machine is reset to wait for a command re-initiating + // the deployment sequence. + triggerEvent(DEPL_SA1_GPIO_SWTICH_OFF_FAILED); + } + return result; +} + +ReturnValue_t SolarArrayDeploymentHandler::sa2On() { + ReturnValue_t result = gpioInterface.pullHigh(deplSA2); + if (result != returnvalue::OK) { + sif::warning << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" + " array deployment switch 2 high" + << std::endl; + // If gpio switch high failed, state machine is reset to wait for a command re-initiating + // the deployment sequence. + triggerEvent(DEPL_SA2_GPIO_SWTICH_ON_FAILED); + } + return result; +} + +ReturnValue_t SolarArrayDeploymentHandler::sa2Off() { + ReturnValue_t result = gpioInterface.pullLow(deplSA2); + if (result != returnvalue::OK) { + sif::warning << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" + " array deployment switch 2 low" + << std::endl; + // If gpio switch high failed, state machine is reset to wait for a command re-initiating + // the deployment sequence. + triggerEvent(DEPL_SA2_GPIO_SWTICH_OFF_FAILED); + } + return result; +} + MessageQueueId_t SolarArrayDeploymentHandler::getCommandQueue() const { return commandQueue->getId(); } diff --git a/mission/devices/SolarArrayDeploymentHandler.h b/mission/devices/SolarArrayDeploymentHandler.h index 2d20606f..08fd4b47 100644 --- a/mission/devices/SolarArrayDeploymentHandler.h +++ b/mission/devices/SolarArrayDeploymentHandler.h @@ -42,10 +42,13 @@ class ManualDeploymentCommand : public SerialLinkedListAdapter { return HasActionsIF::INVALID_PARAMETERS; } + bool isDryRun() const { return dryRun.entry; } + private: SerializeElement burnTime; // Deployment channel SA1 or SA2 SerializeElement channel; + SerializeElement dryRun; }; /** @@ -61,7 +64,7 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, static constexpr DeviceCommandId_t DEPLOY_SOLAR_ARRAYS_MANUALLY = 0x05; static constexpr DeviceCommandId_t SWITCH_OFF_DEPLOYMENT = 0x06; - static constexpr uint32_t FIRST_BURN_START_TIME = config::SA_DEPL_BURN_TIME_SECS; + static constexpr uint32_t FIRST_BURN_START_TIME = config::SA_DEPL_INIT_BUFFER_SECS; 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; @@ -118,14 +121,16 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, WAIT_MAIN_POWER_ON, WAIT_MAIN_POWER_OFF, SWITCH_DEPL_GPIOS, - CHANNEL_ON + BURNING }; struct FsmInfo { - DeploymentChannels channel; + // Not required anymore + // DeploymentChannels channel; // false if OFF, true is ON bool onOff; bool dryRun; + bool alternationDummy = false; uint32_t burnCountdown = config::SA_DEPL_MAX_BURN_TIME; }; @@ -153,13 +158,14 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, PeriodicOperationDivider opDivider = PeriodicOperationDivider(5); uint8_t retryCounter = 3; - bool startFsmOn(DeploymentChannels channel, uint32_t burnCountdown); + bool startFsmOn(uint32_t burnCountdown, bool dryRun); void startFsmOff(); void finishFsm(ReturnValue_t resultForActionHelper); - ReturnValue_t performAutonomousDepl(sd::SdCard sdCard); - bool autonomousDeplForFile(const char* filename); + ReturnValue_t performAutonomousDepl(sd::SdCard sdCard, bool dryRun); + bool dryRunStringInFile(const char* filename); + bool autonomousDeplForFile(const char* filename, bool dryRun); /** * This countdown is used to check if the PCDU sets the 8V line on in the intended time. */ @@ -170,6 +176,8 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, */ Countdown burnCountdown; + Countdown channelAlternationCd = Countdown(config::SA_DEPL_CHANNEL_ALTERNATION_INTERVAL_SECS); + /** * 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. @@ -214,11 +222,12 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, void allOff(); - /** - * @brief This functions handles the switching of the solar array deployment transistors. - */ - ReturnValue_t deploymentTransistorsOn(DeploymentChannels channel); - ReturnValue_t deploymentTransistorsOff(DeploymentChannels channel); + ReturnValue_t deploymentTransistorsOff(); + ReturnValue_t saGpioAlternation(); + ReturnValue_t sa1On(); + ReturnValue_t sa1Off(); + ReturnValue_t sa2On(); + ReturnValue_t sa2Off(); }; #endif /* MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_ */ diff --git a/tmtc b/tmtc index 4c3f5f28..50abe69f 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 4c3f5f28256be0dbfc5b46ea87f8f484c93a9996 +Subproject commit 50abe69f261b7d2a3345d86bd7042514ff845fd3 -- 2.34.1 From f9ee01b02d61d324e5743e03d887eb75cf1d20d0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 13 Oct 2022 17:35:57 +0200 Subject: [PATCH 18/35] removed TODO --- mission/devices/SolarArrayDeploymentHandler.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index 21d01ce7..e350c803 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -153,11 +153,9 @@ bool SolarArrayDeploymentHandler::autonomousDeplForFile(const char* filename, bo if (stateSwitch) { if (deplState == AutonomousDeplState::FIRST_BURN or deplState == AutonomousDeplState::SECOND_BURN) { - // TODO: Update whole procedure to work for both channels startFsmOn(config::SA_DEPL_BURN_TIME_SECS, dryRun); } else if (deplState == AutonomousDeplState::WAIT or deplState == AutonomousDeplState::DONE) { startFsmOff(); - // startFsm(false, false); } } if (stateSwitch or updateUptime) { -- 2.34.1 From 0e8a085f979c6aaa072b052a8c0283bd15393b60 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 13 Oct 2022 17:48:32 +0200 Subject: [PATCH 19/35] add debug mode --- .../devices/SolarArrayDeploymentHandler.cpp | 73 ++++++++++++------- 1 file changed, 47 insertions(+), 26 deletions(-) diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index e350c803..92283749 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -9,6 +9,8 @@ #include "fsfw/objectmanager/ObjectManager.h" #include "fsfw_hal/common/gpio/GpioCookie.h" +static constexpr bool DEBUG_MODE = true; + SolarArrayDeploymentHandler::SolarArrayDeploymentHandler(object_id_t setObjectId_, GpioIF& gpioInterface, PowerSwitchIF& mainLineSwitcher_, @@ -177,51 +179,59 @@ bool SolarArrayDeploymentHandler::autonomousDeplForFile(const char* filename, bo return true; } -ReturnValue_t SolarArrayDeploymentHandler::initialize() { - ReturnValue_t result = actionHelper.initialize(commandQueue); - if (result != returnvalue::OK) { - return ObjectManagerIF::CHILD_INIT_FAILED; - } - return SystemObject::initialize(); -} - void SolarArrayDeploymentHandler::handleStateMachine() { if (stateMachine == MAIN_POWER_ON) { mainLineSwitcher.sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_ON); mainSwitchCountdown.setTimeout(mainLineSwitcher.getSwitchDelayMs()); stateMachine = WAIT_MAIN_POWER_ON; + if (DEBUG_MODE) { + sif::debug << "SA DEPL FSM: MAIN_POWER_ON done -> WAIT_MAIN_POWER_ON" << std::endl; + } } if (stateMachine == MAIN_POWER_OFF) { // These should never fail allOff(); stateMachine = WAIT_MAIN_POWER_OFF; + if (DEBUG_MODE) { + sif::debug << "SA DEPL FSM: MAIN_POWER_OFF done -> WAIT_MAIN_POWER_OFF" << std::endl; + } } if (stateMachine == WAIT_MAIN_POWER_ON) { if (checkMainPowerOn()) { + if (DEBUG_MODE) { + sif::debug << "SA DEPL FSM: WAIT_MAIN_POWER_ON done -> SWITCH_DEPL_GPIOS" << std::endl; + } stateMachine = SWITCH_DEPL_GPIOS; } } if (stateMachine == WAIT_MAIN_POWER_OFF) { if (checkMainPowerOff()) { + if (DEBUG_MODE) { + sif::debug << "SA DEPL FSM: WAIT_MAIN_POWER_OFF done -> FSM DONE" << std::endl; + } finishFsm(returnvalue::OK); } } if (stateMachine == SWITCH_DEPL_GPIOS) { burnCountdown.setTimeout(fsmInfo.burnCountdown); // This should never fail + channelAlternationCd.resetTimer(); if (not fsmInfo.dryRun) { - channelAlternationCd.resetTimer(); sa2Off(); sa1On(); fsmInfo.alternationDummy = true; } + if (DEBUG_MODE) { + sif::debug << "SA DEPL FSM: SWITCH_DEPL_GPIOS done -> BURNING" << std::endl; + } stateMachine = BURNING; } if (stateMachine == BURNING) { - if (not fsmInfo.dryRun) { - saGpioAlternation(); - } + saGpioAlternation(); if (burnCountdown.hasTimedOut()) { + if (DEBUG_MODE) { + sif::debug << "SA DEPL FSM: BURNING done -> WAIT_MAIN_POWER_OFF" << std::endl; + } allOff(); stateMachine = WAIT_MAIN_POWER_OFF; } @@ -285,6 +295,9 @@ void SolarArrayDeploymentHandler::startFsmOff() { void SolarArrayDeploymentHandler::finishFsm(ReturnValue_t resultForActionHelper) { retryCounter = 0; stateMachine = StateMachine::IDLE; + fsmInfo.dryRun = false; + fsmInfo.onOff = false; + fsmInfo.alternationDummy = false; if (actionActive) { bool success = false; if (resultForActionHelper == returnvalue::OK or @@ -315,19 +328,6 @@ bool SolarArrayDeploymentHandler::dryRunStringInFile(const char* filename) { return false; } -void SolarArrayDeploymentHandler::readCommandQueue() { - CommandMessage command; - ReturnValue_t result = commandQueue->receiveMessage(&command); - if (result != returnvalue::OK) { - return; - } - - result = actionHelper.handleActionMessage(&command); - if (result == returnvalue::OK) { - return; - } -} - ReturnValue_t SolarArrayDeploymentHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t* data, size_t size) { @@ -363,7 +363,7 @@ ReturnValue_t SolarArrayDeploymentHandler::executeAction(ActionId_t actionId, ReturnValue_t SolarArrayDeploymentHandler::saGpioAlternation() { ReturnValue_t status = returnvalue::OK; ReturnValue_t result; - if (channelAlternationCd.hasTimedOut()) { + if (channelAlternationCd.hasTimedOut() and not fsmInfo.dryRun) { if (fsmInfo.alternationDummy) { result = sa1Off(); if (result != returnvalue::OK) { @@ -454,6 +454,27 @@ ReturnValue_t SolarArrayDeploymentHandler::sa2Off() { return result; } +void SolarArrayDeploymentHandler::readCommandQueue() { + CommandMessage command; + ReturnValue_t result = commandQueue->receiveMessage(&command); + if (result != returnvalue::OK) { + return; + } + + result = actionHelper.handleActionMessage(&command); + if (result == returnvalue::OK) { + return; + } +} + MessageQueueId_t SolarArrayDeploymentHandler::getCommandQueue() const { return commandQueue->getId(); } + +ReturnValue_t SolarArrayDeploymentHandler::initialize() { + ReturnValue_t result = actionHelper.initialize(commandQueue); + if (result != returnvalue::OK) { + return ObjectManagerIF::CHILD_INIT_FAILED; + } + return SystemObject::initialize(); +} -- 2.34.1 From a4bf47499efbaf1e785e0ce466035704919669b3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 13 Oct 2022 18:11:05 +0200 Subject: [PATCH 20/35] remove channel param from cmd --- mission/devices/SolarArrayDeploymentHandler.cpp | 5 ----- mission/devices/SolarArrayDeploymentHandler.h | 12 +----------- tmtc | 2 +- 3 files changed, 2 insertions(+), 17 deletions(-) diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index 92283749..72bcace4 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -342,11 +342,6 @@ ReturnValue_t SolarArrayDeploymentHandler::executeAction(ActionId_t actionId, return result; } uint32_t burnCountdown = cmd.getBurnTime(); - DeploymentChannels channel; - result = cmd.getChannel(channel); - if (result != returnvalue::OK) { - return result; - } if (not startFsmOn(burnCountdown, cmd.isDryRun())) { return HasActionsIF::IS_BUSY; } diff --git a/mission/devices/SolarArrayDeploymentHandler.h b/mission/devices/SolarArrayDeploymentHandler.h index 08fd4b47..a5f56a5f 100644 --- a/mission/devices/SolarArrayDeploymentHandler.h +++ b/mission/devices/SolarArrayDeploymentHandler.h @@ -29,25 +29,15 @@ class ManualDeploymentCommand : public SerialLinkedListAdapter { void setLinks() { setStart(&burnTime); - burnTime.setNext(&channel); + burnTime.setNext(&dryRun); } uint32_t getBurnTime() const { return burnTime.entry; } - ReturnValue_t getChannel(DeploymentChannels& channel_) const { - if (channel.entry == 1 or channel.entry == 2) { - channel_ = static_cast(channel.entry); - return returnvalue::OK; - } - return HasActionsIF::INVALID_PARAMETERS; - } - bool isDryRun() const { return dryRun.entry; } private: SerializeElement burnTime; - // Deployment channel SA1 or SA2 - SerializeElement channel; SerializeElement dryRun; }; diff --git a/tmtc b/tmtc index 50abe69f..adf2327e 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 50abe69f261b7d2a3345d86bd7042514ff845fd3 +Subproject commit adf2327e6dda748c627b98c857683c6f783bb78a -- 2.34.1 From 213787d435098305795fe1652eb2486482870f4c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 13 Oct 2022 18:15:28 +0200 Subject: [PATCH 21/35] start SA depl task --- bsp_q7s/core/InitMission.cpp | 1 + tmtc | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/bsp_q7s/core/InitMission.cpp b/bsp_q7s/core/InitMission.cpp index 8872fc1f..df36df33 100644 --- a/bsp_q7s/core/InitMission.cpp +++ b/bsp_q7s/core/InitMission.cpp @@ -313,6 +313,7 @@ void initmission::initTasks() { #endif /* OBSW_USE_CCSDS_IP_CORE == 1 */ sysCtrlTask->startTask(); + solarArrayDeplTask->startTask(); taskStarter(pstTasks, "PST task vector"); taskStarter(pusTasks, "PUS task vector"); diff --git a/tmtc b/tmtc index adf2327e..55f27b83 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit adf2327e6dda748c627b98c857683c6f783bb78a +Subproject commit 55f27b83be5df1afafea5cdd4decc1bf49c3c799 -- 2.34.1 From d8907d5cccbe026556034169b75cad3cfe92cdb0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 13 Oct 2022 18:20:17 +0200 Subject: [PATCH 22/35] important fix --- mission/devices/SolarArrayDeploymentHandler.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mission/devices/SolarArrayDeploymentHandler.h b/mission/devices/SolarArrayDeploymentHandler.h index a5f56a5f..eb5afb53 100644 --- a/mission/devices/SolarArrayDeploymentHandler.h +++ b/mission/devices/SolarArrayDeploymentHandler.h @@ -25,7 +25,9 @@ enum DeploymentChannels : uint8_t { SA_1 = 1, SA_2 = 2 }; class ManualDeploymentCommand : public SerialLinkedListAdapter { public: - ManualDeploymentCommand() = default; + ManualDeploymentCommand() { + setLinks(); + } void setLinks() { setStart(&burnTime); -- 2.34.1 From b783e9865ed69a688c7828f637b2d58298692528 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 13 Oct 2022 18:39:14 +0200 Subject: [PATCH 23/35] start the FSM properly --- mission/devices/SolarArrayDeploymentHandler.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index 72bcace4..dee6a203 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -278,6 +278,7 @@ bool SolarArrayDeploymentHandler::startFsmOn(uint32_t burnCountdown_, bool dryRu fsmInfo.onOff = true; fsmInfo.dryRun = dryRun; fsmInfo.burnCountdown = burnCountdown_; + stateMachine = StateMachine::MAIN_POWER_ON; retryCounter = 0; return true; } -- 2.34.1 From 4714c15d6502b1dd03628f7ed2efc3b43c61fd7a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 13 Oct 2022 18:42:47 +0200 Subject: [PATCH 24/35] some more fixes --- mission/devices/SolarArrayDeploymentHandler.cpp | 12 +++++++----- mission/devices/SolarArrayDeploymentHandler.h | 4 ++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index dee6a203..9c311651 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -213,7 +213,7 @@ void SolarArrayDeploymentHandler::handleStateMachine() { } } if (stateMachine == SWITCH_DEPL_GPIOS) { - burnCountdown.setTimeout(fsmInfo.burnCountdown); + burnCountdown.setTimeout(fsmInfo.burnCountdownMs); // This should never fail channelAlternationCd.resetTimer(); if (not fsmInfo.dryRun) { @@ -268,16 +268,16 @@ bool SolarArrayDeploymentHandler::checkMainPower(bool onOff) { return false; } -bool SolarArrayDeploymentHandler::startFsmOn(uint32_t burnCountdown_, bool dryRun) { +bool SolarArrayDeploymentHandler::startFsmOn(uint32_t burnCountdownSecs, bool dryRun) { if (stateMachine != StateMachine::IDLE) { return false; } - if (burnCountdown_ > config::SA_DEPL_MAX_BURN_TIME) { - burnCountdown_ = config::SA_DEPL_MAX_BURN_TIME; + if (burnCountdownSecs > config::SA_DEPL_MAX_BURN_TIME) { + burnCountdownSecs = config::SA_DEPL_MAX_BURN_TIME; } fsmInfo.onOff = true; fsmInfo.dryRun = dryRun; - fsmInfo.burnCountdown = burnCountdown_; + fsmInfo.burnCountdownMs = burnCountdownSecs * 1000; stateMachine = StateMachine::MAIN_POWER_ON; retryCounter = 0; return true; @@ -346,9 +346,11 @@ ReturnValue_t SolarArrayDeploymentHandler::executeAction(ActionId_t actionId, if (not startFsmOn(burnCountdown, cmd.isDryRun())) { return HasActionsIF::IS_BUSY; } + actionActive = true; return result; } else if (actionId == SWITCH_OFF_DEPLOYMENT) { startFsmOff(); + actionActive = true; return result; } else { return HasActionsIF::INVALID_ACTION_ID; diff --git a/mission/devices/SolarArrayDeploymentHandler.h b/mission/devices/SolarArrayDeploymentHandler.h index eb5afb53..00d67d4e 100644 --- a/mission/devices/SolarArrayDeploymentHandler.h +++ b/mission/devices/SolarArrayDeploymentHandler.h @@ -123,7 +123,7 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, bool onOff; bool dryRun; bool alternationDummy = false; - uint32_t burnCountdown = config::SA_DEPL_MAX_BURN_TIME; + uint32_t burnCountdownMs = config::SA_DEPL_MAX_BURN_TIME; }; static const uint8_t INTERFACE_ID = CLASS_ID::SA_DEPL_HANDLER; @@ -150,7 +150,7 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, PeriodicOperationDivider opDivider = PeriodicOperationDivider(5); uint8_t retryCounter = 3; - bool startFsmOn(uint32_t burnCountdown, bool dryRun); + bool startFsmOn(uint32_t burnCountdownSecs, bool dryRun); void startFsmOff(); void finishFsm(ReturnValue_t resultForActionHelper); -- 2.34.1 From f939bfc4691c97aebb6b17e41cf6f4fb7e209882 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 13 Oct 2022 18:44:50 +0200 Subject: [PATCH 25/35] remember commander --- mission/devices/SolarArrayDeploymentHandler.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index 9c311651..d5d37fe3 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -347,10 +347,12 @@ ReturnValue_t SolarArrayDeploymentHandler::executeAction(ActionId_t actionId, return HasActionsIF::IS_BUSY; } actionActive = true; + rememberCommanderId = commandedBy; return result; } else if (actionId == SWITCH_OFF_DEPLOYMENT) { startFsmOff(); actionActive = true; + rememberCommanderId = commandedBy; return result; } else { return HasActionsIF::INVALID_ACTION_ID; -- 2.34.1 From 470f0ad7e875a9fc56469a55a9382ad16b8ee4fa Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 13 Oct 2022 18:52:44 +0200 Subject: [PATCH 26/35] convert some debug output into info output --- mission/devices/SolarArrayDeploymentHandler.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index d5d37fe3..eb50c840 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -184,17 +184,13 @@ void SolarArrayDeploymentHandler::handleStateMachine() { mainLineSwitcher.sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_ON); mainSwitchCountdown.setTimeout(mainLineSwitcher.getSwitchDelayMs()); stateMachine = WAIT_MAIN_POWER_ON; - if (DEBUG_MODE) { - sif::debug << "SA DEPL FSM: MAIN_POWER_ON done -> WAIT_MAIN_POWER_ON" << std::endl; - } + sif::info << "S/A Deployment: Deployment power line on" << std::endl; } if (stateMachine == MAIN_POWER_OFF) { // These should never fail allOff(); stateMachine = WAIT_MAIN_POWER_OFF; - if (DEBUG_MODE) { - sif::debug << "SA DEPL FSM: MAIN_POWER_OFF done -> WAIT_MAIN_POWER_OFF" << std::endl; - } + sif::info << "S/A Deployment: Deployment power line off" << std::endl; } if (stateMachine == WAIT_MAIN_POWER_ON) { if (checkMainPowerOn()) { @@ -209,6 +205,7 @@ void SolarArrayDeploymentHandler::handleStateMachine() { if (DEBUG_MODE) { sif::debug << "SA DEPL FSM: WAIT_MAIN_POWER_OFF done -> FSM DONE" << std::endl; } + sif::info << "S/A Deployment: FSM done" << std::endl; finishFsm(returnvalue::OK); } } @@ -221,9 +218,7 @@ void SolarArrayDeploymentHandler::handleStateMachine() { sa1On(); fsmInfo.alternationDummy = true; } - if (DEBUG_MODE) { - sif::debug << "SA DEPL FSM: SWITCH_DEPL_GPIOS done -> BURNING" << std::endl; - } + sif::info << "S/A Deployment: Burning" << std::endl; stateMachine = BURNING; } if (stateMachine == BURNING) { -- 2.34.1 From 69f34acbd2cf9c0142e181a0d1b340a7d3e7317c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 14 Oct 2022 11:55:21 +0200 Subject: [PATCH 27/35] rerun generator script --- generators/bsp_q7s_events.csv | 13 ++++++---- generators/events/translateEvents.cpp | 23 +++++++++++----- generators/objects/translateObjects.cpp | 2 +- linux/fsfwconfig/events/translateEvents.cpp | 23 +++++++++++----- linux/fsfwconfig/objects/translateObjects.cpp | 2 +- .../devices/SolarArrayDeploymentHandler.cpp | 2 ++ mission/devices/SolarArrayDeploymentHandler.h | 26 ++++++++++++------- tmtc | 2 +- 8 files changed, 61 insertions(+), 32 deletions(-) diff --git a/generators/bsp_q7s_events.csv b/generators/bsp_q7s_events.csv index 49cdc610..cff23c21 100644 --- a/generators/bsp_q7s_events.csv +++ b/generators/bsp_q7s_events.csv @@ -92,11 +92,14 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path 11405;0x2c8d;SWITCH_ALREADY_OFF;LOW;;mission/devices/HeaterHandler.h 11406;0x2c8e;MAIN_SWITCH_TIMEOUT;MEDIUM;;mission/devices/HeaterHandler.h 11407;0x2c8f;FAULTY_HEATER_WAS_ON;LOW;;mission/devices/HeaterHandler.h -11500;0x2cec;MAIN_SWITCH_ON_TIMEOUT;LOW;;mission/devices/SolarArrayDeploymentHandler.h -11501;0x2ced;MAIN_SWITCH_OFF_TIMEOUT;LOW;;mission/devices/SolarArrayDeploymentHandler.h -11502;0x2cee;DEPLOYMENT_FAILED;HIGH;;mission/devices/SolarArrayDeploymentHandler.h -11503;0x2cef;DEPL_SA1_GPIO_SWTICH_ON_FAILED;HIGH;;mission/devices/SolarArrayDeploymentHandler.h -11504;0x2cf0;DEPL_SA2_GPIO_SWTICH_ON_FAILED;HIGH;;mission/devices/SolarArrayDeploymentHandler.h +11500;0x2cec;BURN_PHASE_START;INFO;P1: Burn duration in milliseconds, P2: Dry run flag;mission/devices/SolarArrayDeploymentHandler.h +11501;0x2ced;BURN_PHASE_DONE;INFO;P1: Burn duration in milliseconds, P2: Dry run flag;mission/devices/SolarArrayDeploymentHandler.h +11502;0x2cee;MAIN_SWITCH_ON_TIMEOUT;LOW;;mission/devices/SolarArrayDeploymentHandler.h +11503;0x2cef;MAIN_SWITCH_OFF_TIMEOUT;LOW;;mission/devices/SolarArrayDeploymentHandler.h +11504;0x2cf0;DEPL_SA1_GPIO_SWTICH_ON_FAILED;HIGH;;mission/devices/SolarArrayDeploymentHandler.h +11505;0x2cf1;DEPL_SA2_GPIO_SWTICH_ON_FAILED;HIGH;;mission/devices/SolarArrayDeploymentHandler.h +11506;0x2cf2;DEPL_SA1_GPIO_SWTICH_OFF_FAILED;HIGH;;mission/devices/SolarArrayDeploymentHandler.h +11507;0x2cf3;DEPL_SA2_GPIO_SWTICH_OFF_FAILED;HIGH;;mission/devices/SolarArrayDeploymentHandler.h 11601;0x2d51;MEMORY_READ_RPT_CRC_FAILURE;LOW;PLOC crc failure in telemetry packet;linux/devices/ploc/PlocMPSoCHandler.h 11602;0x2d52;ACK_FAILURE;LOW;PLOC receive acknowledgment failure report P1: Command Id which leads the acknowledgment failure report P2: The status field inserted by the MPSoC into the data field;linux/devices/ploc/PlocMPSoCHandler.h 11603;0x2d53;EXE_FAILURE;LOW;PLOC receive execution failure report P1: Command Id which leads the execution failure report P2: The status field inserted by the MPSoC into the data field;linux/devices/ploc/PlocMPSoCHandler.h diff --git a/generators/events/translateEvents.cpp b/generators/events/translateEvents.cpp index 8711750b..f175b6e4 100644 --- a/generators/events/translateEvents.cpp +++ b/generators/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 225 translations. + * @brief Auto-generated event translation file. Contains 228 translations. * @details - * Generated on: 2022-10-10 11:15:49 + * Generated on: 2022-10-14 11:53:48 */ #include "translateEvents.h" @@ -98,11 +98,14 @@ const char *SWITCH_ALREADY_ON_STRING = "SWITCH_ALREADY_ON"; const char *SWITCH_ALREADY_OFF_STRING = "SWITCH_ALREADY_OFF"; const char *MAIN_SWITCH_TIMEOUT_STRING = "MAIN_SWITCH_TIMEOUT"; const char *FAULTY_HEATER_WAS_ON_STRING = "FAULTY_HEATER_WAS_ON"; +const char *BURN_PHASE_START_STRING = "BURN_PHASE_START"; +const char *BURN_PHASE_DONE_STRING = "BURN_PHASE_DONE"; const char *MAIN_SWITCH_ON_TIMEOUT_STRING = "MAIN_SWITCH_ON_TIMEOUT"; const char *MAIN_SWITCH_OFF_TIMEOUT_STRING = "MAIN_SWITCH_OFF_TIMEOUT"; -const char *DEPLOYMENT_FAILED_STRING = "DEPLOYMENT_FAILED"; const char *DEPL_SA1_GPIO_SWTICH_ON_FAILED_STRING = "DEPL_SA1_GPIO_SWTICH_ON_FAILED"; const char *DEPL_SA2_GPIO_SWTICH_ON_FAILED_STRING = "DEPL_SA2_GPIO_SWTICH_ON_FAILED"; +const char *DEPL_SA1_GPIO_SWTICH_OFF_FAILED_STRING = "DEPL_SA1_GPIO_SWTICH_OFF_FAILED"; +const char *DEPL_SA2_GPIO_SWTICH_OFF_FAILED_STRING = "DEPL_SA2_GPIO_SWTICH_OFF_FAILED"; const char *MEMORY_READ_RPT_CRC_FAILURE_STRING = "MEMORY_READ_RPT_CRC_FAILURE"; const char *ACK_FAILURE_STRING = "ACK_FAILURE"; const char *EXE_FAILURE_STRING = "EXE_FAILURE"; @@ -416,15 +419,21 @@ const char *translateEvents(Event event) { case (11407): return FAULTY_HEATER_WAS_ON_STRING; case (11500): - return MAIN_SWITCH_ON_TIMEOUT_STRING; + return BURN_PHASE_START_STRING; case (11501): - return MAIN_SWITCH_OFF_TIMEOUT_STRING; + return BURN_PHASE_DONE_STRING; case (11502): - return DEPLOYMENT_FAILED_STRING; + return MAIN_SWITCH_ON_TIMEOUT_STRING; case (11503): - return DEPL_SA1_GPIO_SWTICH_ON_FAILED_STRING; + return MAIN_SWITCH_OFF_TIMEOUT_STRING; case (11504): + return DEPL_SA1_GPIO_SWTICH_ON_FAILED_STRING; + case (11505): return DEPL_SA2_GPIO_SWTICH_ON_FAILED_STRING; + case (11506): + return DEPL_SA1_GPIO_SWTICH_OFF_FAILED_STRING; + case (11507): + return DEPL_SA2_GPIO_SWTICH_OFF_FAILED_STRING; case (11601): return MEMORY_READ_RPT_CRC_FAILURE_STRING; case (11602): diff --git a/generators/objects/translateObjects.cpp b/generators/objects/translateObjects.cpp index 910fe8fd..19c18ca2 100644 --- a/generators/objects/translateObjects.cpp +++ b/generators/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 138 translations. - * Generated on: 2022-10-10 11:15:49 + * Generated on: 2022-10-14 11:53:48 */ #include "translateObjects.h" diff --git a/linux/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index 8711750b..f175b6e4 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 225 translations. + * @brief Auto-generated event translation file. Contains 228 translations. * @details - * Generated on: 2022-10-10 11:15:49 + * Generated on: 2022-10-14 11:53:48 */ #include "translateEvents.h" @@ -98,11 +98,14 @@ const char *SWITCH_ALREADY_ON_STRING = "SWITCH_ALREADY_ON"; const char *SWITCH_ALREADY_OFF_STRING = "SWITCH_ALREADY_OFF"; const char *MAIN_SWITCH_TIMEOUT_STRING = "MAIN_SWITCH_TIMEOUT"; const char *FAULTY_HEATER_WAS_ON_STRING = "FAULTY_HEATER_WAS_ON"; +const char *BURN_PHASE_START_STRING = "BURN_PHASE_START"; +const char *BURN_PHASE_DONE_STRING = "BURN_PHASE_DONE"; const char *MAIN_SWITCH_ON_TIMEOUT_STRING = "MAIN_SWITCH_ON_TIMEOUT"; const char *MAIN_SWITCH_OFF_TIMEOUT_STRING = "MAIN_SWITCH_OFF_TIMEOUT"; -const char *DEPLOYMENT_FAILED_STRING = "DEPLOYMENT_FAILED"; const char *DEPL_SA1_GPIO_SWTICH_ON_FAILED_STRING = "DEPL_SA1_GPIO_SWTICH_ON_FAILED"; const char *DEPL_SA2_GPIO_SWTICH_ON_FAILED_STRING = "DEPL_SA2_GPIO_SWTICH_ON_FAILED"; +const char *DEPL_SA1_GPIO_SWTICH_OFF_FAILED_STRING = "DEPL_SA1_GPIO_SWTICH_OFF_FAILED"; +const char *DEPL_SA2_GPIO_SWTICH_OFF_FAILED_STRING = "DEPL_SA2_GPIO_SWTICH_OFF_FAILED"; const char *MEMORY_READ_RPT_CRC_FAILURE_STRING = "MEMORY_READ_RPT_CRC_FAILURE"; const char *ACK_FAILURE_STRING = "ACK_FAILURE"; const char *EXE_FAILURE_STRING = "EXE_FAILURE"; @@ -416,15 +419,21 @@ const char *translateEvents(Event event) { case (11407): return FAULTY_HEATER_WAS_ON_STRING; case (11500): - return MAIN_SWITCH_ON_TIMEOUT_STRING; + return BURN_PHASE_START_STRING; case (11501): - return MAIN_SWITCH_OFF_TIMEOUT_STRING; + return BURN_PHASE_DONE_STRING; case (11502): - return DEPLOYMENT_FAILED_STRING; + return MAIN_SWITCH_ON_TIMEOUT_STRING; case (11503): - return DEPL_SA1_GPIO_SWTICH_ON_FAILED_STRING; + return MAIN_SWITCH_OFF_TIMEOUT_STRING; case (11504): + return DEPL_SA1_GPIO_SWTICH_ON_FAILED_STRING; + case (11505): return DEPL_SA2_GPIO_SWTICH_ON_FAILED_STRING; + case (11506): + return DEPL_SA1_GPIO_SWTICH_OFF_FAILED_STRING; + case (11507): + return DEPL_SA2_GPIO_SWTICH_OFF_FAILED_STRING; case (11601): return MEMORY_READ_RPT_CRC_FAILURE_STRING; case (11602): diff --git a/linux/fsfwconfig/objects/translateObjects.cpp b/linux/fsfwconfig/objects/translateObjects.cpp index 910fe8fd..19c18ca2 100644 --- a/linux/fsfwconfig/objects/translateObjects.cpp +++ b/linux/fsfwconfig/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 138 translations. - * Generated on: 2022-10-10 11:15:49 + * Generated on: 2022-10-14 11:53:48 */ #include "translateObjects.h" diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index eb50c840..cd64fd7b 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -219,6 +219,7 @@ void SolarArrayDeploymentHandler::handleStateMachine() { fsmInfo.alternationDummy = true; } sif::info << "S/A Deployment: Burning" << std::endl; + triggerEvent(BURN_PHASE_START, fsmInfo.burnCountdownMs, fsmInfo.dryRun); stateMachine = BURNING; } if (stateMachine == BURNING) { @@ -228,6 +229,7 @@ void SolarArrayDeploymentHandler::handleStateMachine() { sif::debug << "SA DEPL FSM: BURNING done -> WAIT_MAIN_POWER_OFF" << std::endl; } allOff(); + triggerEvent(BURN_PHASE_DONE, fsmInfo.burnCountdownMs, fsmInfo.dryRun); stateMachine = WAIT_MAIN_POWER_OFF; } } diff --git a/mission/devices/SolarArrayDeploymentHandler.h b/mission/devices/SolarArrayDeploymentHandler.h index 00d67d4e..c7494b8a 100644 --- a/mission/devices/SolarArrayDeploymentHandler.h +++ b/mission/devices/SolarArrayDeploymentHandler.h @@ -25,9 +25,7 @@ enum DeploymentChannels : uint8_t { SA_1 = 1, SA_2 = 2 }; class ManualDeploymentCommand : public SerialLinkedListAdapter { public: - ManualDeploymentCommand() { - setLinks(); - } + ManualDeploymentCommand() { setLinks(); } void setLinks() { setStart(&burnTime); @@ -134,13 +132,21 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, static const ReturnValue_t SWITCHING_DEPL_SA2_FAILED = MAKE_RETURN_CODE(0xA4); static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SA_DEPL_HANDLER; - static const Event MAIN_SWITCH_ON_TIMEOUT = MAKE_EVENT(0, severity::LOW); - static const Event MAIN_SWITCH_OFF_TIMEOUT = MAKE_EVENT(1, severity::LOW); - static const Event DEPLOYMENT_FAILED = MAKE_EVENT(2, severity::HIGH); - static const Event DEPL_SA1_GPIO_SWTICH_ON_FAILED = MAKE_EVENT(3, severity::HIGH); - static const Event DEPL_SA2_GPIO_SWTICH_ON_FAILED = MAKE_EVENT(4, severity::HIGH); - static const Event DEPL_SA1_GPIO_SWTICH_OFF_FAILED = MAKE_EVENT(5, severity::HIGH); - static const Event DEPL_SA2_GPIO_SWTICH_OFF_FAILED = MAKE_EVENT(6, severity::HIGH); + + //! [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); FsmInfo fsmInfo; StateMachine stateMachine = IDLE; diff --git a/tmtc b/tmtc index 55f27b83..772c86ab 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 55f27b83be5df1afafea5cdd4decc1bf49c3c799 +Subproject commit 772c86ab04c453b12459d65327fdaaf4d1472279 -- 2.34.1 From 19c73167c9e028b8778d6107f2189c2c67539bd3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 14 Oct 2022 13:13:23 +0200 Subject: [PATCH 28/35] bugfixes for alternation --- mission/devices/SolarArrayDeploymentHandler.cpp | 9 +++++---- mission/devices/SolarArrayDeploymentHandler.h | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index cd64fd7b..513ddbff 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -371,14 +371,15 @@ ReturnValue_t SolarArrayDeploymentHandler::saGpioAlternation() { status = result; } } else { + result = sa2Off(); + if (result != returnvalue::OK) { + status = result; + } result = sa1On(); if (result != returnvalue::OK) { status = result; } - result = sa2Off(); - if (result != returnvalue::OK) { - status = result; - } + } fsmInfo.alternationDummy = not fsmInfo.alternationDummy; channelAlternationCd.resetTimer(); diff --git a/mission/devices/SolarArrayDeploymentHandler.h b/mission/devices/SolarArrayDeploymentHandler.h index c7494b8a..32892688 100644 --- a/mission/devices/SolarArrayDeploymentHandler.h +++ b/mission/devices/SolarArrayDeploymentHandler.h @@ -174,7 +174,7 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, */ Countdown burnCountdown; - Countdown channelAlternationCd = Countdown(config::SA_DEPL_CHANNEL_ALTERNATION_INTERVAL_SECS); + Countdown channelAlternationCd = Countdown(config::SA_DEPL_CHANNEL_ALTERNATION_INTERVAL_SECS * 1000); /** * The message queue id of the component commanding an action will be stored in this variable. -- 2.34.1 From bcef1f5d33e2da3ab97e2a6b06f1d4dc0b39db36 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 14 Oct 2022 13:30:35 +0200 Subject: [PATCH 29/35] small delay --- mission/devices/SolarArrayDeploymentHandler.cpp | 13 ++++++++----- mission/devices/SolarArrayDeploymentHandler.h | 3 ++- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index 513ddbff..1c6375be 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -1,5 +1,7 @@ #include "SolarArrayDeploymentHandler.h" +#include + #include #include #include @@ -366,20 +368,21 @@ ReturnValue_t SolarArrayDeploymentHandler::saGpioAlternation() { if (result != returnvalue::OK) { status = result; } + TaskFactory::delayTask(1); result = sa2On(); if (result != returnvalue::OK) { status = result; } } else { - result = sa2Off(); - if (result != returnvalue::OK) { - status = result; - } + result = sa2Off(); + if (result != returnvalue::OK) { + status = result; + } + TaskFactory::delayTask(1); result = sa1On(); if (result != returnvalue::OK) { status = result; } - } fsmInfo.alternationDummy = not fsmInfo.alternationDummy; channelAlternationCd.resetTimer(); diff --git a/mission/devices/SolarArrayDeploymentHandler.h b/mission/devices/SolarArrayDeploymentHandler.h index 32892688..20a558c6 100644 --- a/mission/devices/SolarArrayDeploymentHandler.h +++ b/mission/devices/SolarArrayDeploymentHandler.h @@ -174,7 +174,8 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, */ Countdown burnCountdown; - Countdown channelAlternationCd = Countdown(config::SA_DEPL_CHANNEL_ALTERNATION_INTERVAL_SECS * 1000); + Countdown channelAlternationCd = + Countdown(config::SA_DEPL_CHANNEL_ALTERNATION_INTERVAL_SECS * 1000); /** * The message queue id of the component commanding an action will be stored in this variable. -- 2.34.1 From 5d721706f3e4a3392e1dd08fe52d56eb6d98c7f0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 14 Oct 2022 14:17:20 +0200 Subject: [PATCH 30/35] bugfix for autonomous handling --- common/config/eive/definitions.h | 2 +- .../devices/SolarArrayDeploymentHandler.cpp | 92 +++++++++---------- 2 files changed, 46 insertions(+), 48 deletions(-) diff --git a/common/config/eive/definitions.h b/common/config/eive/definitions.h index 81792c20..33d37812 100644 --- a/common/config/eive/definitions.h +++ b/common/config/eive/definitions.h @@ -41,7 +41,7 @@ static constexpr uint32_t SA_DEPL_WAIT_TIME_SECS = 45 * 60; // HW constraints (current limit) mean that the GPIO channels need to be switched on in alternation static constexpr uint32_t SA_DEPL_CHANNEL_ALTERNATION_INTERVAL_SECS = 5; // Maximum allowed burn time allowed by the software. -static constexpr uint32_t SA_DEPL_MAX_BURN_TIME = 120; +static constexpr uint32_t SA_DEPL_MAX_BURN_TIME = 180; } // namespace config diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index cd64fd7b..baa35861 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -89,56 +89,54 @@ bool SolarArrayDeploymentHandler::autonomousDeplForFile(const char* filename, bo bool stateSwitch = false; uint32_t secsSinceBoot = 0; while (std::getline(file, line)) { + std::istringstream iss(line); if (lineNum == 0) { - std::istringstream iss(line); - if (lineNum == 0) { - iss >> word; - if (word.find("phase:") == string::npos) { - return false; - } - iss >> word; - if (word.find(PHASE_INIT_STR) != string::npos) { - deplState = AutonomousDeplState::INIT; - } else if (word.find(PHASE_FIRST_BURN_STR) != string::npos) { - deplState = AutonomousDeplState::FIRST_BURN; - } else if (word.find(PHASE_WAIT_STR) != string::npos) { - deplState = AutonomousDeplState::WAIT; - } else if (word.find(PHASE_SECOND_BURN_STR) != string::npos) { - deplState = AutonomousDeplState::SECOND_BURN; - } else if (word.find(PHASE_DONE) != string::npos) { - deplState = AutonomousDeplState::DONE; - } else { - return false; - } - } else if (lineNum == 1) { - iss >> word; - if (word.find("secs_since_start:") == string::npos) { - return false; - } + iss >> word; + if (word.find("phase:") == string::npos) { + return false; + } + iss >> word; + if (word.find(PHASE_INIT_STR) != string::npos) { + deplState = AutonomousDeplState::INIT; + } else if (word.find(PHASE_FIRST_BURN_STR) != string::npos) { + deplState = AutonomousDeplState::FIRST_BURN; + } else if (word.find(PHASE_WAIT_STR) != string::npos) { + deplState = AutonomousDeplState::WAIT; + } else if (word.find(PHASE_SECOND_BURN_STR) != string::npos) { + deplState = AutonomousDeplState::SECOND_BURN; + } else if (word.find(PHASE_DONE) != string::npos) { + deplState = AutonomousDeplState::DONE; + } else { + return false; + } + } else if (lineNum == 1) { + iss >> word; + if (word.find("secs_since_start:") == string::npos) { + return false; + } - iss >> secsSinceBoot; - if (not initUptime) { - initUptime = secsSinceBoot; - } - if (iss.bad()) { - return false; - } - auto switchCheck = [&](AutonomousDeplState expected) { - if (deplState != expected) { - deplState = expected; - stateSwitch = true; - } - }; - if ((secsSinceBoot > FIRST_BURN_START_TIME) and (secsSinceBoot < FIRST_BURN_END_TIME)) { - switchCheck(AutonomousDeplState::FIRST_BURN); - } else if ((secsSinceBoot > WAIT_START_TIME) and (secsSinceBoot < WAIT_END_TIME)) { - switchCheck(AutonomousDeplState::WAIT); - } else if ((secsSinceBoot > SECOND_BURN_START_TIME) and - (secsSinceBoot < SECOND_BURN_END_TIME)) { - switchCheck(AutonomousDeplState::SECOND_BURN); - } else if (secsSinceBoot > SECOND_BURN_END_TIME) { - switchCheck(AutonomousDeplState::DONE); + iss >> secsSinceBoot; + if (not initUptime) { + initUptime = secsSinceBoot; + } + if (iss.bad()) { + return false; + } + auto switchCheck = [&](AutonomousDeplState expected) { + if (deplState != expected) { + deplState = expected; + stateSwitch = true; } + }; + if ((secsSinceBoot > FIRST_BURN_START_TIME) and (secsSinceBoot < FIRST_BURN_END_TIME)) { + switchCheck(AutonomousDeplState::FIRST_BURN); + } else if ((secsSinceBoot > WAIT_START_TIME) and (secsSinceBoot < WAIT_END_TIME)) { + switchCheck(AutonomousDeplState::WAIT); + } else if ((secsSinceBoot > SECOND_BURN_START_TIME) and + (secsSinceBoot < SECOND_BURN_END_TIME)) { + switchCheck(AutonomousDeplState::SECOND_BURN); + } else if (secsSinceBoot > SECOND_BURN_END_TIME) { + switchCheck(AutonomousDeplState::DONE); } } lineNum++; -- 2.34.1 From 99f703a2eb143e8e8bf688b9fbbed6fe5e9c69f5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 14 Oct 2022 14:34:35 +0200 Subject: [PATCH 31/35] some more important bugfixes --- .../devices/SolarArrayDeploymentHandler.cpp | 86 ++++++++++--------- mission/devices/SolarArrayDeploymentHandler.h | 1 + 2 files changed, 46 insertions(+), 41 deletions(-) diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index df3f0805..88b3d7bf 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -36,22 +36,27 @@ SolarArrayDeploymentHandler::~SolarArrayDeploymentHandler() = default; ReturnValue_t SolarArrayDeploymentHandler::performOperation(uint8_t operationCode) { using namespace std::filesystem; - auto activeSdc = sdcMan.getActiveSdCard(); - if (activeSdc and activeSdc.value() == sd::SdCard::SLOT_0 and - sdcMan.isSdCardUsable(activeSdc.value())) { - if (exists(SD_0_DEPL_FILE)) { - // perform autonomous deployment handling - performAutonomousDepl(sd::SdCard::SLOT_0, dryRunStringInFile(SD_0_DEPL_FILE)); - } - } else if (activeSdc and activeSdc.value() == sd::SdCard::SLOT_1 and - sdcMan.isSdCardUsable(activeSdc.value())) { - if (exists(SD_1_DEPL_FILE)) { - // perform autonomous deployment handling - performAutonomousDepl(sd::SdCard::SLOT_1, dryRunStringInFile(SD_1_DEPL_FILE)); + if (opDivider.checkAndIncrement()) { + auto activeSdc = sdcMan.getActiveSdCard(); + if (activeSdc and activeSdc.value() == sd::SdCard::SLOT_0 and + sdcMan.isSdCardUsable(activeSdc.value())) { + if (exists(SD_0_DEPL_FILE)) { + // perform autonomous deployment handling + performAutonomousDepl(sd::SdCard::SLOT_0, dryRunStringInFile(SD_0_DEPL_FILE)); + } + } else if (activeSdc and activeSdc.value() == sd::SdCard::SLOT_1 and + sdcMan.isSdCardUsable(activeSdc.value())) { + if (exists(SD_1_DEPL_FILE)) { + // perform autonomous deployment handling + performAutonomousDepl(sd::SdCard::SLOT_1, dryRunStringInFile(SD_1_DEPL_FILE)); + } } } readCommandQueue(); handleStateMachine(); + if (firstCycle) { + firstCycle = false; + } return returnvalue::OK; } @@ -113,17 +118,21 @@ bool SolarArrayDeploymentHandler::autonomousDeplForFile(const char* filename, bo } } else if (lineNum == 1) { iss >> word; + if (iss.bad()) { + return false; + } if (word.find("secs_since_start:") == string::npos) { return false; } iss >> secsSinceBoot; - if (not initUptime) { - initUptime = secsSinceBoot; - } if (iss.bad()) { return false; } + if (not initUptime) { + initUptime = secsSinceBoot; + } + auto switchCheck = [&](AutonomousDeplState expected) { if (deplState != expected) { deplState = expected; @@ -143,39 +152,34 @@ bool SolarArrayDeploymentHandler::autonomousDeplForFile(const char* filename, bo } lineNum++; } - bool updateUptime = false; - if (opDivider.checkAndIncrement()) { - if (initUptime) { - secsSinceBoot = initUptime.value(); - } - // Uptime has increased by X seconds so we need to update the uptime count inside the file - secsSinceBoot += Clock::getUptime().tv_sec; - updateUptime = true; + if (initUptime) { + secsSinceBoot = initUptime.value(); } - if (stateSwitch) { + // Uptime has increased by X seconds so we need to update the uptime count inside the file + secsSinceBoot += Clock::getUptime().tv_sec; + if (stateSwitch or firstCycle) { if (deplState == AutonomousDeplState::FIRST_BURN or deplState == AutonomousDeplState::SECOND_BURN) { startFsmOn(config::SA_DEPL_BURN_TIME_SECS, dryRun); - } else if (deplState == AutonomousDeplState::WAIT or deplState == AutonomousDeplState::DONE) { + } else if (deplState == AutonomousDeplState::WAIT or deplState == AutonomousDeplState::DONE or + deplState == AutonomousDeplState::INIT) { startFsmOff(); } } - if (stateSwitch or updateUptime) { - std::ofstream of(filename); - of << "phase: "; - if (deplState == AutonomousDeplState::INIT) { - of << PHASE_INIT_STR << "\n"; - } else if (deplState == AutonomousDeplState::FIRST_BURN) { - of << PHASE_FIRST_BURN_STR << "\n"; - } else if (deplState == AutonomousDeplState::WAIT) { - of << PHASE_WAIT_STR << "\n"; - } else if (deplState == AutonomousDeplState::SECOND_BURN) { - of << PHASE_SECOND_BURN_STR << "\n"; - } else if (deplState == AutonomousDeplState::DONE) { - of << PHASE_DONE << "\n"; - } - of << "secs_since_start: " << std::to_string(secsSinceBoot) << "\n"; + std::ofstream of(filename); + of << "phase: "; + if (deplState == AutonomousDeplState::INIT) { + of << PHASE_INIT_STR << "\n"; + } else if (deplState == AutonomousDeplState::FIRST_BURN) { + of << PHASE_FIRST_BURN_STR << "\n"; + } else if (deplState == AutonomousDeplState::WAIT) { + of << PHASE_WAIT_STR << "\n"; + } else if (deplState == AutonomousDeplState::SECOND_BURN) { + of << PHASE_SECOND_BURN_STR << "\n"; + } else if (deplState == AutonomousDeplState::DONE) { + of << PHASE_DONE << "\n"; } + of << "secs_since_start: " << std::to_string(secsSinceBoot) << "\n"; return true; } @@ -287,7 +291,7 @@ void SolarArrayDeploymentHandler::startFsmOff() { } fsmInfo.onOff = false; retryCounter = 0; - stateMachine = StateMachine::MAIN_POWER_ON; + stateMachine = StateMachine::MAIN_POWER_OFF; } void SolarArrayDeploymentHandler::finishFsm(ReturnValue_t resultForActionHelper) { diff --git a/mission/devices/SolarArrayDeploymentHandler.h b/mission/devices/SolarArrayDeploymentHandler.h index 20a558c6..2e4c775e 100644 --- a/mission/devices/SolarArrayDeploymentHandler.h +++ b/mission/devices/SolarArrayDeploymentHandler.h @@ -151,6 +151,7 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, FsmInfo fsmInfo; StateMachine stateMachine = IDLE; bool actionActive = false; + bool firstCycle = true; ActionId_t activeCmd = HasActionsIF::INVALID_ACTION_ID; std::optional initUptime; PeriodicOperationDivider opDivider = PeriodicOperationDivider(5); -- 2.34.1 From 3cff1c48e9c58ebd24a1573b8bb92af43a412bbf Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 14 Oct 2022 14:55:37 +0200 Subject: [PATCH 32/35] some more testing and bugfixes --- common/config/eive/definitions.h | 4 +- generators/bsp_q7s_events.csv | 1 + generators/events/translateEvents.cpp | 7 +- generators/objects/translateObjects.cpp | 2 +- linux/fsfwconfig/events/translateEvents.cpp | 7 +- linux/fsfwconfig/objects/translateObjects.cpp | 2 +- .../devices/SolarArrayDeploymentHandler.cpp | 156 +++++++++--------- mission/devices/SolarArrayDeploymentHandler.h | 6 +- tmtc | 2 +- 9 files changed, 100 insertions(+), 87 deletions(-) diff --git a/common/config/eive/definitions.h b/common/config/eive/definitions.h index 33d37812..d15b5ea6 100644 --- a/common/config/eive/definitions.h +++ b/common/config/eive/definitions.h @@ -36,8 +36,8 @@ static constexpr uint32_t MAX_FILENAME_SIZE = 50; static constexpr uint32_t SA_DEPL_INIT_BUFFER_SECS = 120; // Burn time for autonomous deployment -static constexpr uint32_t SA_DEPL_BURN_TIME_SECS = 180; -static constexpr uint32_t SA_DEPL_WAIT_TIME_SECS = 45 * 60; +static constexpr uint32_t SA_DEPL_BURN_TIME_SECS = 60; // 180; +static constexpr uint32_t SA_DEPL_WAIT_TIME_SECS = 90; // 45 * 60; // HW constraints (current limit) mean that the GPIO channels need to be switched on in alternation static constexpr uint32_t SA_DEPL_CHANNEL_ALTERNATION_INTERVAL_SECS = 5; // Maximum allowed burn time allowed by the software. diff --git a/generators/bsp_q7s_events.csv b/generators/bsp_q7s_events.csv index cff23c21..5a662fb5 100644 --- a/generators/bsp_q7s_events.csv +++ b/generators/bsp_q7s_events.csv @@ -100,6 +100,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path 11505;0x2cf1;DEPL_SA2_GPIO_SWTICH_ON_FAILED;HIGH;;mission/devices/SolarArrayDeploymentHandler.h 11506;0x2cf2;DEPL_SA1_GPIO_SWTICH_OFF_FAILED;HIGH;;mission/devices/SolarArrayDeploymentHandler.h 11507;0x2cf3;DEPL_SA2_GPIO_SWTICH_OFF_FAILED;HIGH;;mission/devices/SolarArrayDeploymentHandler.h +11508;0x2cf4;AUTONOMOUS_DEPLOYMENT_COMPLETED;INFO;;mission/devices/SolarArrayDeploymentHandler.h 11601;0x2d51;MEMORY_READ_RPT_CRC_FAILURE;LOW;PLOC crc failure in telemetry packet;linux/devices/ploc/PlocMPSoCHandler.h 11602;0x2d52;ACK_FAILURE;LOW;PLOC receive acknowledgment failure report P1: Command Id which leads the acknowledgment failure report P2: The status field inserted by the MPSoC into the data field;linux/devices/ploc/PlocMPSoCHandler.h 11603;0x2d53;EXE_FAILURE;LOW;PLOC receive execution failure report P1: Command Id which leads the execution failure report P2: The status field inserted by the MPSoC into the data field;linux/devices/ploc/PlocMPSoCHandler.h diff --git a/generators/events/translateEvents.cpp b/generators/events/translateEvents.cpp index f175b6e4..b27c54fc 100644 --- a/generators/events/translateEvents.cpp +++ b/generators/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 228 translations. + * @brief Auto-generated event translation file. Contains 229 translations. * @details - * Generated on: 2022-10-14 11:53:48 + * Generated on: 2022-10-14 14:54:47 */ #include "translateEvents.h" @@ -106,6 +106,7 @@ const char *DEPL_SA1_GPIO_SWTICH_ON_FAILED_STRING = "DEPL_SA1_GPIO_SWTICH_ON_FAI const char *DEPL_SA2_GPIO_SWTICH_ON_FAILED_STRING = "DEPL_SA2_GPIO_SWTICH_ON_FAILED"; const char *DEPL_SA1_GPIO_SWTICH_OFF_FAILED_STRING = "DEPL_SA1_GPIO_SWTICH_OFF_FAILED"; const char *DEPL_SA2_GPIO_SWTICH_OFF_FAILED_STRING = "DEPL_SA2_GPIO_SWTICH_OFF_FAILED"; +const char *AUTONOMOUS_DEPLOYMENT_COMPLETED_STRING = "AUTONOMOUS_DEPLOYMENT_COMPLETED"; const char *MEMORY_READ_RPT_CRC_FAILURE_STRING = "MEMORY_READ_RPT_CRC_FAILURE"; const char *ACK_FAILURE_STRING = "ACK_FAILURE"; const char *EXE_FAILURE_STRING = "EXE_FAILURE"; @@ -434,6 +435,8 @@ const char *translateEvents(Event event) { return DEPL_SA1_GPIO_SWTICH_OFF_FAILED_STRING; case (11507): return DEPL_SA2_GPIO_SWTICH_OFF_FAILED_STRING; + case (11508): + return AUTONOMOUS_DEPLOYMENT_COMPLETED_STRING; case (11601): return MEMORY_READ_RPT_CRC_FAILURE_STRING; case (11602): diff --git a/generators/objects/translateObjects.cpp b/generators/objects/translateObjects.cpp index 19c18ca2..a855e48a 100644 --- a/generators/objects/translateObjects.cpp +++ b/generators/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 138 translations. - * Generated on: 2022-10-14 11:53:48 + * Generated on: 2022-10-14 14:54:47 */ #include "translateObjects.h" diff --git a/linux/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index f175b6e4..b27c54fc 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 228 translations. + * @brief Auto-generated event translation file. Contains 229 translations. * @details - * Generated on: 2022-10-14 11:53:48 + * Generated on: 2022-10-14 14:54:47 */ #include "translateEvents.h" @@ -106,6 +106,7 @@ const char *DEPL_SA1_GPIO_SWTICH_ON_FAILED_STRING = "DEPL_SA1_GPIO_SWTICH_ON_FAI const char *DEPL_SA2_GPIO_SWTICH_ON_FAILED_STRING = "DEPL_SA2_GPIO_SWTICH_ON_FAILED"; const char *DEPL_SA1_GPIO_SWTICH_OFF_FAILED_STRING = "DEPL_SA1_GPIO_SWTICH_OFF_FAILED"; const char *DEPL_SA2_GPIO_SWTICH_OFF_FAILED_STRING = "DEPL_SA2_GPIO_SWTICH_OFF_FAILED"; +const char *AUTONOMOUS_DEPLOYMENT_COMPLETED_STRING = "AUTONOMOUS_DEPLOYMENT_COMPLETED"; const char *MEMORY_READ_RPT_CRC_FAILURE_STRING = "MEMORY_READ_RPT_CRC_FAILURE"; const char *ACK_FAILURE_STRING = "ACK_FAILURE"; const char *EXE_FAILURE_STRING = "EXE_FAILURE"; @@ -434,6 +435,8 @@ const char *translateEvents(Event event) { return DEPL_SA1_GPIO_SWTICH_OFF_FAILED_STRING; case (11507): return DEPL_SA2_GPIO_SWTICH_OFF_FAILED_STRING; + case (11508): + return AUTONOMOUS_DEPLOYMENT_COMPLETED_STRING; case (11601): return MEMORY_READ_RPT_CRC_FAILURE_STRING; case (11602): diff --git a/linux/fsfwconfig/objects/translateObjects.cpp b/linux/fsfwconfig/objects/translateObjects.cpp index 19c18ca2..a855e48a 100644 --- a/linux/fsfwconfig/objects/translateObjects.cpp +++ b/linux/fsfwconfig/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 138 translations. - * Generated on: 2022-10-14 11:53:48 + * Generated on: 2022-10-14 14:54:47 */ #include "translateObjects.h" diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index 88b3d7bf..eaecae37 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -60,6 +60,62 @@ ReturnValue_t SolarArrayDeploymentHandler::performOperation(uint8_t operationCod return returnvalue::OK; } +void SolarArrayDeploymentHandler::handleStateMachine() { + if (stateMachine == MAIN_POWER_ON) { + mainLineSwitcher.sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_ON); + mainSwitchCountdown.setTimeout(mainLineSwitcher.getSwitchDelayMs()); + stateMachine = WAIT_MAIN_POWER_ON; + sif::info << "S/A Deployment: Deployment power line on" << std::endl; + } + if (stateMachine == MAIN_POWER_OFF) { + // These should never fail + allOff(); + stateMachine = WAIT_MAIN_POWER_OFF; + sif::info << "S/A Deployment: Deployment power line off" << std::endl; + } + if (stateMachine == WAIT_MAIN_POWER_ON) { + if (checkMainPowerOn()) { + if (DEBUG_MODE) { + sif::debug << "SA DEPL FSM: WAIT_MAIN_POWER_ON done -> SWITCH_DEPL_GPIOS" << std::endl; + } + stateMachine = SWITCH_DEPL_GPIOS; + } + } + if (stateMachine == WAIT_MAIN_POWER_OFF) { + if (checkMainPowerOff()) { + if (DEBUG_MODE) { + sif::debug << "SA DEPL FSM: WAIT_MAIN_POWER_OFF done -> FSM DONE" << std::endl; + } + sif::info << "S/A Deployment: FSM done" << std::endl; + finishFsm(returnvalue::OK); + } + } + if (stateMachine == SWITCH_DEPL_GPIOS) { + burnCountdown.setTimeout(fsmInfo.burnCountdownMs); + // This should never fail + channelAlternationCd.resetTimer(); + if (not fsmInfo.dryRun) { + sa2Off(); + sa1On(); + fsmInfo.alternationDummy = true; + } + sif::info << "S/A Deployment: Burning" << std::endl; + triggerEvent(BURN_PHASE_START, fsmInfo.burnCountdownMs, fsmInfo.dryRun); + stateMachine = BURNING; + } + if (stateMachine == BURNING) { + saGpioAlternation(); + if (burnCountdown.hasTimedOut()) { + if (DEBUG_MODE) { + sif::debug << "SA DEPL FSM: BURNING done -> WAIT_MAIN_POWER_OFF" << std::endl; + } + allOff(); + triggerEvent(BURN_PHASE_DONE, fsmInfo.burnCountdownMs, fsmInfo.dryRun); + stateMachine = WAIT_MAIN_POWER_OFF; + } + } +} + ReturnValue_t SolarArrayDeploymentHandler::performAutonomousDepl(sd::SdCard sdCard, bool dryRun) { using namespace std::filesystem; using namespace std; @@ -72,21 +128,22 @@ ReturnValue_t SolarArrayDeploymentHandler::performAutonomousDepl(sd::SdCard sdCa if (not exists(SD_0_DEPLY_INFO)) { initFile(SD_0_DEPLY_INFO); } - if (not autonomousDeplForFile(SD_0_DEPLY_INFO, dryRun)) { + if (not autonomousDeplForFile(sd::SdCard::SLOT_0, SD_0_DEPLY_INFO, dryRun)) { initFile(SD_0_DEPLY_INFO); } } else if (sdCard == sd::SdCard::SLOT_1) { if (not exists(SD_1_DEPLY_INFO)) { initFile(SD_1_DEPLY_INFO); } - if (not autonomousDeplForFile(SD_1_DEPLY_INFO, dryRun)) { + if (not autonomousDeplForFile(sd::SdCard::SLOT_1, SD_1_DEPLY_INFO, dryRun)) { initFile(SD_1_DEPLY_INFO); } } return returnvalue::OK; } -bool SolarArrayDeploymentHandler::autonomousDeplForFile(const char* filename, bool dryRun) { +bool SolarArrayDeploymentHandler::autonomousDeplForFile(sd::SdCard sdCard, const char* filename, + bool dryRun) { using namespace std; ifstream file(filename); string line; @@ -166,79 +223,31 @@ bool SolarArrayDeploymentHandler::autonomousDeplForFile(const char* filename, bo startFsmOff(); } } - std::ofstream of(filename); - of << "phase: "; - if (deplState == AutonomousDeplState::INIT) { - of << PHASE_INIT_STR << "\n"; - } else if (deplState == AutonomousDeplState::FIRST_BURN) { - of << PHASE_FIRST_BURN_STR << "\n"; - } else if (deplState == AutonomousDeplState::WAIT) { - of << PHASE_WAIT_STR << "\n"; - } else if (deplState == AutonomousDeplState::SECOND_BURN) { - of << PHASE_SECOND_BURN_STR << "\n"; - } else if (deplState == AutonomousDeplState::DONE) { - of << PHASE_DONE << "\n"; + if (deplState == AutonomousDeplState::DONE) { + remove(filename); + if (sdCard == sd::SdCard::SLOT_0) { + remove(SD_0_DEPL_FILE); + } else { + remove(SD_1_DEPL_FILE); + } + triggerEvent(AUTONOMOUS_DEPLOYMENT_COMPLETED); + } else { + std::ofstream of(filename); + of << "phase: "; + if (deplState == AutonomousDeplState::INIT) { + of << PHASE_INIT_STR << "\n"; + } else if (deplState == AutonomousDeplState::FIRST_BURN) { + of << PHASE_FIRST_BURN_STR << "\n"; + } else if (deplState == AutonomousDeplState::WAIT) { + of << PHASE_WAIT_STR << "\n"; + } else if (deplState == AutonomousDeplState::SECOND_BURN) { + of << PHASE_SECOND_BURN_STR << "\n"; + } + of << "secs_since_start: " << std::to_string(secsSinceBoot) << "\n"; } - of << "secs_since_start: " << std::to_string(secsSinceBoot) << "\n"; return true; } -void SolarArrayDeploymentHandler::handleStateMachine() { - if (stateMachine == MAIN_POWER_ON) { - mainLineSwitcher.sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_ON); - mainSwitchCountdown.setTimeout(mainLineSwitcher.getSwitchDelayMs()); - stateMachine = WAIT_MAIN_POWER_ON; - sif::info << "S/A Deployment: Deployment power line on" << std::endl; - } - if (stateMachine == MAIN_POWER_OFF) { - // These should never fail - allOff(); - stateMachine = WAIT_MAIN_POWER_OFF; - sif::info << "S/A Deployment: Deployment power line off" << std::endl; - } - if (stateMachine == WAIT_MAIN_POWER_ON) { - if (checkMainPowerOn()) { - if (DEBUG_MODE) { - sif::debug << "SA DEPL FSM: WAIT_MAIN_POWER_ON done -> SWITCH_DEPL_GPIOS" << std::endl; - } - stateMachine = SWITCH_DEPL_GPIOS; - } - } - if (stateMachine == WAIT_MAIN_POWER_OFF) { - if (checkMainPowerOff()) { - if (DEBUG_MODE) { - sif::debug << "SA DEPL FSM: WAIT_MAIN_POWER_OFF done -> FSM DONE" << std::endl; - } - sif::info << "S/A Deployment: FSM done" << std::endl; - finishFsm(returnvalue::OK); - } - } - if (stateMachine == SWITCH_DEPL_GPIOS) { - burnCountdown.setTimeout(fsmInfo.burnCountdownMs); - // This should never fail - channelAlternationCd.resetTimer(); - if (not fsmInfo.dryRun) { - sa2Off(); - sa1On(); - fsmInfo.alternationDummy = true; - } - sif::info << "S/A Deployment: Burning" << std::endl; - triggerEvent(BURN_PHASE_START, fsmInfo.burnCountdownMs, fsmInfo.dryRun); - stateMachine = BURNING; - } - if (stateMachine == BURNING) { - saGpioAlternation(); - if (burnCountdown.hasTimedOut()) { - if (DEBUG_MODE) { - sif::debug << "SA DEPL FSM: BURNING done -> WAIT_MAIN_POWER_OFF" << std::endl; - } - allOff(); - triggerEvent(BURN_PHASE_DONE, fsmInfo.burnCountdownMs, fsmInfo.dryRun); - stateMachine = WAIT_MAIN_POWER_OFF; - } - } -} - bool SolarArrayDeploymentHandler::checkMainPowerOn() { return checkMainPower(true); } bool SolarArrayDeploymentHandler::checkMainPowerOff() { return checkMainPower(false); } @@ -276,7 +285,6 @@ bool SolarArrayDeploymentHandler::startFsmOn(uint32_t burnCountdownSecs, bool dr if (burnCountdownSecs > config::SA_DEPL_MAX_BURN_TIME) { burnCountdownSecs = config::SA_DEPL_MAX_BURN_TIME; } - fsmInfo.onOff = true; fsmInfo.dryRun = dryRun; fsmInfo.burnCountdownMs = burnCountdownSecs * 1000; stateMachine = StateMachine::MAIN_POWER_ON; @@ -289,7 +297,6 @@ void SolarArrayDeploymentHandler::startFsmOff() { // off commands override the state machine. Cancel any active action commands. finishFsm(returnvalue::FAILED); } - fsmInfo.onOff = false; retryCounter = 0; stateMachine = StateMachine::MAIN_POWER_OFF; } @@ -298,7 +305,6 @@ void SolarArrayDeploymentHandler::finishFsm(ReturnValue_t resultForActionHelper) retryCounter = 0; stateMachine = StateMachine::IDLE; fsmInfo.dryRun = false; - fsmInfo.onOff = false; fsmInfo.alternationDummy = false; if (actionActive) { bool success = false; diff --git a/mission/devices/SolarArrayDeploymentHandler.h b/mission/devices/SolarArrayDeploymentHandler.h index 2e4c775e..a5b3a10e 100644 --- a/mission/devices/SolarArrayDeploymentHandler.h +++ b/mission/devices/SolarArrayDeploymentHandler.h @@ -117,8 +117,6 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, struct FsmInfo { // Not required anymore // DeploymentChannels channel; - // false if OFF, true is ON - bool onOff; bool dryRun; bool alternationDummy = false; uint32_t burnCountdownMs = config::SA_DEPL_MAX_BURN_TIME; @@ -147,6 +145,8 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, event::makeEvent(SUBSYSTEM_ID, 6, severity::HIGH); static constexpr Event DEPL_SA2_GPIO_SWTICH_OFF_FAILED = event::makeEvent(SUBSYSTEM_ID, 7, severity::HIGH); + static constexpr Event AUTONOMOUS_DEPLOYMENT_COMPLETED = + event::makeEvent(SUBSYSTEM_ID, 8, severity::INFO); FsmInfo fsmInfo; StateMachine stateMachine = IDLE; @@ -164,7 +164,7 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, ReturnValue_t performAutonomousDepl(sd::SdCard sdCard, bool dryRun); bool dryRunStringInFile(const char* filename); - bool autonomousDeplForFile(const char* filename, bool dryRun); + bool autonomousDeplForFile(sd::SdCard sdCard, const char* filename, bool dryRun); /** * This countdown is used to check if the PCDU sets the 8V line on in the intended time. */ diff --git a/tmtc b/tmtc index 772c86ab..646cf1a1 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 772c86ab04c453b12459d65327fdaaf4d1472279 +Subproject commit 646cf1a14e0fa61d5e91e26a46017be557bad642 -- 2.34.1 From e9a4c631274a2e1ad7c41a8fa177d3e392ec7e5e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 14 Oct 2022 15:05:44 +0200 Subject: [PATCH 33/35] fix one shot flag --- mission/devices/SolarArrayDeploymentHandler.cpp | 8 ++++---- mission/devices/SolarArrayDeploymentHandler.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index eaecae37..3985eb21 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -54,9 +54,6 @@ ReturnValue_t SolarArrayDeploymentHandler::performOperation(uint8_t operationCod } readCommandQueue(); handleStateMachine(); - if (firstCycle) { - firstCycle = false; - } return returnvalue::OK; } @@ -214,7 +211,7 @@ bool SolarArrayDeploymentHandler::autonomousDeplForFile(sd::SdCard sdCard, const } // Uptime has increased by X seconds so we need to update the uptime count inside the file secsSinceBoot += Clock::getUptime().tv_sec; - if (stateSwitch or firstCycle) { + if (stateSwitch or firstAutonomousCycle) { if (deplState == AutonomousDeplState::FIRST_BURN or deplState == AutonomousDeplState::SECOND_BURN) { startFsmOn(config::SA_DEPL_BURN_TIME_SECS, dryRun); @@ -245,6 +242,9 @@ bool SolarArrayDeploymentHandler::autonomousDeplForFile(sd::SdCard sdCard, const } of << "secs_since_start: " << std::to_string(secsSinceBoot) << "\n"; } + if (firstAutonomousCycle) { + firstAutonomousCycle = false; + } return true; } diff --git a/mission/devices/SolarArrayDeploymentHandler.h b/mission/devices/SolarArrayDeploymentHandler.h index a5b3a10e..b935b096 100644 --- a/mission/devices/SolarArrayDeploymentHandler.h +++ b/mission/devices/SolarArrayDeploymentHandler.h @@ -151,7 +151,7 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, FsmInfo fsmInfo; StateMachine stateMachine = IDLE; bool actionActive = false; - bool firstCycle = true; + bool firstAutonomousCycle = true; ActionId_t activeCmd = HasActionsIF::INVALID_ACTION_ID; std::optional initUptime; PeriodicOperationDivider opDivider = PeriodicOperationDivider(5); -- 2.34.1 From c800ddfa3197ed1950461c84dd869b7ce34bca6f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 14 Oct 2022 15:33:34 +0200 Subject: [PATCH 34/35] basic SD card remount FDIR --- bsp_q7s/OBSWConfig.h.in | 8 +++++-- bsp_q7s/core/CoreController.cpp | 23 ++++++++++++++----- bsp_q7s/core/CoreController.h | 8 +++++++ .../devices/SolarArrayDeploymentHandler.cpp | 4 ++++ 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/bsp_q7s/OBSWConfig.h.in b/bsp_q7s/OBSWConfig.h.in index 260ccc2d..f3cfa907 100644 --- a/bsp_q7s/OBSWConfig.h.in +++ b/bsp_q7s/OBSWConfig.h.in @@ -20,7 +20,6 @@ // Set to 1 if telecommands are received via the PDEC IP Core #define OBSW_TC_FROM_PDEC 0 -#define OBSW_ENABLE_TIMERS 1 #define OBSW_ADD_GOMSPACE_PCDU @OBSW_ADD_GOMSPACE_PCDU@ #define OBSW_ADD_MGT @OBSW_ADD_MGT@ #define OBSW_ADD_BPX_BATTERY_HANDLER @OBSW_ADD_BPX_BATTERY_HANDLER@ @@ -41,7 +40,11 @@ #define OBSW_ADD_PL_PCDU @OBSW_ADD_PL_PCDU@ #define OBSW_ADD_SYRLINKS @OBSW_ADD_SYRLINKS@ #define OBSW_ENABLE_SYRLINKS_TRANSMIT_TIMEOUT 0 -#define OBSW_MPSOC_JTAG_BOOT 0 + +// Configuration parameter which causes the core controller to try to keep at least one SD card +// working +#define OBSW_SD_CARD_MUST_BE_ON 1 +#define OBSW_ENABLE_TIMERS 1 // This is a really tricky switch.. It initializes the PCDU switches to their default states // at powerup. I think it would be better @@ -59,6 +62,7 @@ #define OBSW_SWITCH_TO_NORMAL_MODE_AFTER_STARTUP 1 #define OBSW_PRINT_MISSED_DEADLINES 1 +#define OBSW_MPSOC_JTAG_BOOT 0 #define OBSW_STAR_TRACKER_GROUND_CONFIG 1 #define OBSW_SYRLINKS_SIMULATED 1 #define OBSW_ADD_TEST_CODE 0 diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 30d5228d..95700148 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -4,7 +4,6 @@ #include #include -#include "OBSWConfig.h" #include "OBSWVersion.h" #include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/timemanager/Stopwatch.h" @@ -1243,16 +1242,16 @@ void CoreController::performMountedSdCardOperations() { } timeFileHandler(); }; - bool clearOneShotFlag = false; + bool someSdCardActive = false; if (sdInfo.active == sd::SdCard::SLOT_0 and sdcMan->isSdCardUsable(sd::SdCard::SLOT_0)) { mountedSdCardOp(sd::SdCard::SLOT_0, config::SD_0_MOUNT_POINT); - clearOneShotFlag = true; + someSdCardActive = true; } if (sdInfo.active == sd::SdCard::SLOT_1 and sdcMan->isSdCardUsable(sd::SdCard::SLOT_1)) { mountedSdCardOp(sd::SdCard::SLOT_1, config::SD_1_MOUNT_POINT); - clearOneShotFlag = true; + someSdCardActive = true; } - if (clearOneShotFlag) { + if (someSdCardActive) { performOneShotSdCardOpsSwitch = true; } } @@ -1295,7 +1294,19 @@ ReturnValue_t CoreController::performSdCardCheck() { if (active.second == sd::SdState::MOUNTED) { sdCardCheck(sd::SdCard::SLOT_1); } - +#if OBSW_SD_CARD_MUST_BE_ON == 1 + // This is FDIR. The core controller will attempt once to get some SD card working + bool someSdCardActive = false; + if ((sdInfo.active == sd::SdCard::SLOT_0 and sdcMan->isSdCardUsable(sd::SdCard::SLOT_0)) or + (sdInfo.active == sd::SdCard::SLOT_1 and sdcMan->isSdCardUsable(sd::SdCard::SLOT_1))) { + someSdCardActive = true; + } + if (not someSdCardActive and remountAttemptFlag) { + triggerEvent(NO_SD_CARD_ACTIVE); + initSdCardBlocking(); + remountAttemptFlag = false; + } +#endif return returnvalue::OK; } diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index 3c205e4a..460c0f8a 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -7,6 +7,7 @@ #include #include "CoreDefinitions.h" +#include "OBSWConfig.h" #include "bsp_q7s/fs/SdCardManager.h" #include "events/subsystemIdRanges.h" #include "fsfw/controller/ExtendedControllerBase.h" @@ -102,6 +103,9 @@ class CoreController : public ExtendedControllerBase { event::makeEvent(SUBSYSTEM_ID, 2, severity::MEDIUM); //! Trying to find a way how to determine that the reboot came from ProASIC3 or PCDU.. static constexpr Event REBOOT_HW = event::makeEvent(SUBSYSTEM_ID, 3, severity::MEDIUM); + //! [EXPORT] : [COMMENT] No SD card was active. Core controller will attempt to re-initialize + //! a SD card. + static constexpr Event NO_SD_CARD_ACTIVE = event::makeEvent(SUBSYSTEM_ID, 4, severity::HIGH); CoreController(object_id_t objectId); virtual ~CoreController(); @@ -219,6 +223,10 @@ class CoreController : public ExtendedControllerBase { core::HkSet hkSet; +#if OBSW_SD_CARD_MUST_BE_ON == 1 + bool remountAttemptFlag = true; +#endif + ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, LocalDataPoolManager& poolManager) override; Countdown sdCardCheckCd = Countdown(120000); diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index 3985eb21..affc0e2e 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -50,6 +50,10 @@ ReturnValue_t SolarArrayDeploymentHandler::performOperation(uint8_t operationCod // perform autonomous deployment handling performAutonomousDepl(sd::SdCard::SLOT_1, dryRunStringInFile(SD_1_DEPL_FILE)); } + } else { + // TODO: This is FDIR domain. If both SD cards are not available for whatever reason, + // there is not much we can do except somehow use the scratch buffer which is + // not non-volatile. Implementation effort is considerable as well. } } readCommandQueue(); -- 2.34.1 From 43f25e80025fc422e59ce4b114a933a46e83ff74 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 14 Oct 2022 20:37:02 +0200 Subject: [PATCH 35/35] default time windows --- common/config/eive/definitions.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/config/eive/definitions.h b/common/config/eive/definitions.h index d15b5ea6..33d37812 100644 --- a/common/config/eive/definitions.h +++ b/common/config/eive/definitions.h @@ -36,8 +36,8 @@ static constexpr uint32_t MAX_FILENAME_SIZE = 50; static constexpr uint32_t SA_DEPL_INIT_BUFFER_SECS = 120; // Burn time for autonomous deployment -static constexpr uint32_t SA_DEPL_BURN_TIME_SECS = 60; // 180; -static constexpr uint32_t SA_DEPL_WAIT_TIME_SECS = 90; // 45 * 60; +static constexpr uint32_t SA_DEPL_BURN_TIME_SECS = 180; +static constexpr uint32_t SA_DEPL_WAIT_TIME_SECS = 45 * 60; // HW constraints (current limit) mean that the GPIO channels need to be switched on in alternation static constexpr uint32_t SA_DEPL_CHANNEL_ALTERNATION_INTERVAL_SECS = 5; // Maximum allowed burn time allowed by the software. -- 2.34.1