diff --git a/cmake/dependencies.cmake b/cmake/dependencies.cmake index 97b48995973d463e157a5d7bc6b70b6c9eb64702..ab4872b2a0ccc323429989208e81fa317caee663 100644 --- a/cmake/dependencies.cmake +++ b/cmake/dependencies.cmake @@ -27,6 +27,7 @@ set(OBSW_INCLUDE_DIRS set(MAIN_COMPUTER src/boards/Main/Data/ABKTrajectorySet.cpp src/boards/Main/PersistentVars/PersistentVars.cpp + src/boards/Main/HIL/HIL.cpp src/boards/Main/Sensors/Sensors.cpp src/boards/Main/AlgoReference/AlgoReference.cpp src/boards/Main/Radio/Radio.cpp diff --git a/src/boards/Main/CanHandler/CanHandler.cpp b/src/boards/Main/CanHandler/CanHandler.cpp index 51b1246597d22db78c519eea1975b9e3402e4142..541e0f000a85a474ce278148b4d98d9011696e92 100644 --- a/src/boards/Main/CanHandler/CanHandler.cpp +++ b/src/boards/Main/CanHandler/CanHandler.cpp @@ -73,7 +73,7 @@ bool CanHandler::start() static_cast<int16_t>(stats.logNumber), static_cast<uint8_t>(state), state == FlightModeManagerState::ARMED, - getModule<PersistentVars>()->getHilMode(), + PersistentVars::getHilMode(), stats.lastWriteError == 0, }); }, diff --git a/src/boards/Main/CanHandler/CanHandler.h b/src/boards/Main/CanHandler/CanHandler.h index 5730c0b2ab70ca2ab097fbaef218b4cea8e6392f..60c7c47fef40d960e1cf4f9e3b21e35b8e1103e9 100644 --- a/src/boards/Main/CanHandler/CanHandler.h +++ b/src/boards/Main/CanHandler/CanHandler.h @@ -39,7 +39,7 @@ class Actuators; class CanHandler : public Boardcore::InjectableWithDeps<BoardScheduler, Actuators, Sensors, - FlightModeManager, PersistentVars> + FlightModeManager> { public: struct CanStatus diff --git a/src/boards/Main/Configs/HILSimulationConfig.h b/src/boards/Main/Configs/HILSimulationConfig.h index cbb6d9da138b1caccac66fb32110d0bd92520841..4e66179d1e49106e82886e514ba4232a9da937ff 100644 --- a/src/boards/Main/Configs/HILSimulationConfig.h +++ b/src/boards/Main/Configs/HILSimulationConfig.h @@ -36,11 +36,7 @@ namespace Config namespace HIL { -// clang-format off -// Indent to avoid the linter complaining about using namespace - using namespace Boardcore::Units::Frequency; - using namespace std::chrono_literals; -// clang-format on +/* linter off */ using namespace Boardcore::Units::Frequency; constexpr bool IS_FULL_HIL = false; constexpr bool ENABLE_HW = false; diff --git a/src/boards/Main/HIL/HIL.cpp b/src/boards/Main/HIL/HIL.cpp new file mode 100644 index 0000000000000000000000000000000000000000..df612388640501e79055094cd3887cf154a81e6c --- /dev/null +++ b/src/boards/Main/HIL/HIL.cpp @@ -0,0 +1,304 @@ +/* Copyright (c) 2024 Skyward Experimental Rocketry + * Author: Emilio Corigliano + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "HIL.h" + +#include <Main/Actuators/Actuators.h> +#include <Main/Buses.h> +#include <Main/Configs/HILSimulationConfig.h> +#include <Main/Configs/MEAConfig.h> +#include <Main/Configs/SensorsConfig.h> +#include <Main/HIL/HILData.h> +#include <common/Events.h> +#include <events/EventBroker.h> +#include <hil/HIL.h> +#include <interfaces-impl/hwmapping.h> +#include <utils/DependencyManager/DependencyManager.h> + +#include "HILData.h" + +namespace Main +{ + +MainHILPhasesManager::MainHILPhasesManager( + std::function<Boardcore::TimedTrajectoryPoint()> getCurrentPosition) + : Boardcore::HILPhasesManager<MainFlightPhases, SimulatorData, + ActuatorData>(getCurrentPosition) +{ + flagsFlightPhases = {{MainFlightPhases::SIM_FLYING, false}, + {MainFlightPhases::SIM_ASCENT, false}, + {MainFlightPhases::SIM_BURNING, false}, + {MainFlightPhases::SIM_AEROBRAKES, false}, + {MainFlightPhases::SIM_PARA1, false}, + {MainFlightPhases::SIM_PARA2, false}, + {MainFlightPhases::SIMULATION_STARTED, false}, + {MainFlightPhases::CALIBRATION, false}, + {MainFlightPhases::CALIBRATION_OK, false}, + {MainFlightPhases::ARMED, false}, + {MainFlightPhases::LIFTOFF_PIN_DETACHED, false}, + {MainFlightPhases::LIFTOFF, false}, + {MainFlightPhases::AEROBRAKES, false}, + {MainFlightPhases::APOGEE, false}, + {MainFlightPhases::PARA1, false}, + {MainFlightPhases::PARA2, false}, + {MainFlightPhases::SIMULATION_STOPPED, false}}; + + prev_flagsFlightPhases = flagsFlightPhases; + + // Subscribe to all the topics + auto& eventBroker = Boardcore::EventBroker::getInstance(); + eventBroker.subscribe(this, Common::TOPIC_ABK); + eventBroker.subscribe(this, Common::TOPIC_ADA); + eventBroker.subscribe(this, Common::TOPIC_MEA); + eventBroker.subscribe(this, Common::TOPIC_DPL); + eventBroker.subscribe(this, Common::TOPIC_CAN); + eventBroker.subscribe(this, Common::TOPIC_FLIGHT); + eventBroker.subscribe(this, Common::TOPIC_FMM); + eventBroker.subscribe(this, Common::TOPIC_FSR); + eventBroker.subscribe(this, Common::TOPIC_NAS); + eventBroker.subscribe(this, Common::TOPIC_TMTC); + eventBroker.subscribe(this, Common::TOPIC_MOTOR); + eventBroker.subscribe(this, Common::TOPIC_TARS); + eventBroker.subscribe(this, Common::TOPIC_ALT); +} + +void MainHILPhasesManager::processFlagsImpl( + const SimulatorData& simulatorData, + std::vector<MainFlightPhases>& changed_flags) +{ + if (simulatorData.signal == + static_cast<float>(HILSignal::SIMULATION_STARTED)) + { + miosix::reboot(); + } + + if (simulatorData.signal == + static_cast<float>(HILSignal::SIMULATION_STOPPED)) + { + Boardcore::EventBroker::getInstance().post(Common::TMTC_FORCE_LANDING, + Common::TOPIC_TMTC); + } + + if (simulatorData.signal == + static_cast<float>(HILSignal::SIMULATION_FORCE_LAUNCH)) + { + Boardcore::EventBroker::getInstance().post(Common::TMTC_ARM, + Common::TOPIC_TMTC); + Thread::sleep(250); + Boardcore::EventBroker::getInstance().post(Common::TMTC_FORCE_LAUNCH, + Common::TOPIC_TMTC); + } + + // set true when the first packet from the simulator arrives + if (isSetTrue(MainFlightPhases::SIMULATION_STARTED)) + { + t_start = Boardcore::TimestampTimer::getTimestamp(); + + printf("[HIL] ------- SIMULATION STARTED ! ------- \n"); + changed_flags.push_back(MainFlightPhases::SIMULATION_STARTED); + } + + if (flagsFlightPhases[MainFlightPhases::SIM_FLYING]) + { + if (isSetTrue(MainFlightPhases::SIM_FLYING)) + { + registerOutcomes(MainFlightPhases::SIM_FLYING); + printf("[HIL] ------- SIMULATOR LIFTOFF ! ------- \n"); + changed_flags.push_back(MainFlightPhases::SIM_FLYING); + } + } +} + +void MainHILPhasesManager::printOutcomes() +{ + printf("OUTCOMES: (times dt from liftoff)\n\n"); + printf("Simulation time: %.3f [sec]\n\n", + (double)(t_stop - t_start) / 1000000.0f); + + printf("Motor stopped burning (simulation flag): \n"); + outcomes[MainFlightPhases::SIM_BURNING].print(t_liftoff); + + printf("Airbrakes exit shadowmode: \n"); + outcomes[MainFlightPhases::AEROBRAKES].print(t_liftoff); + + printf("Apogee: \n"); + outcomes[MainFlightPhases::APOGEE].print(t_liftoff); + + printf("Parachute 1: \n"); + outcomes[MainFlightPhases::PARA1].print(t_liftoff); + + printf("Parachute 2: \n"); + outcomes[MainFlightPhases::PARA2].print(t_liftoff); + + printf("Simulation Stopped: \n"); + outcomes[MainFlightPhases::SIMULATION_STOPPED].print(t_liftoff); + + // auto cpuMeter = Boardcore::CpuMeter::getCpuStats(); + // printf("max cpu usage: %+.3f\n", cpuMeter.maxValue); + // printf("avg cpu usage: %+.3f\n", cpuMeter.mean); + // printf("min free heap: %+.3lu\n", cpuMeter.minFreeHeap); + // printf("max free stack:%+.3lu\n", cpuMeter.minFreeStack); +} + +void MainHILPhasesManager::handleEventImpl( + const Boardcore::Event& e, std::vector<MainFlightPhases>& changed_flags) +{ + switch (e) + { + case Common::Events::FMM_INIT_ERROR: + printf("[HIL] ------- INIT FAILED ! ------- \n"); + case Common::Events::FMM_INIT_OK: + setFlagFlightPhase(MainFlightPhases::CALIBRATION, true); + printf("[HIL] ------- CALIBRATION ! ------- \n"); + changed_flags.push_back(MainFlightPhases::CALIBRATION); + break; + case Common::Events::FLIGHT_DISARMED: + setFlagFlightPhase(MainFlightPhases::CALIBRATION_OK, true); + printf("[HIL] CALIBRATION OK!\n"); + changed_flags.push_back(MainFlightPhases::CALIBRATION_OK); + break; + case Common::Events::FLIGHT_ARMED: + setFlagFlightPhase(MainFlightPhases::ARMED, true); + printf("[HIL] ------- READY TO LAUNCH ! ------- \n"); + changed_flags.push_back(MainFlightPhases::ARMED); + break; + case Common::Events::FLIGHT_LAUNCH_PIN_DETACHED: + setFlagFlightPhase(MainFlightPhases::LIFTOFF_PIN_DETACHED, true); + printf("[HIL] ------- LIFTOFF PIN DETACHED ! ------- \n"); + changed_flags.push_back(MainFlightPhases::LIFTOFF_PIN_DETACHED); + break; + case Common::Events::FLIGHT_LIFTOFF: + case Common::Events::TMTC_FORCE_LAUNCH: + t_liftoff = Boardcore::TimestampTimer::getTimestamp(); + printf("[HIL] ------- LIFTOFF -------: %f, %f \n", + getCurrentPosition().z, getCurrentPosition().vz); + changed_flags.push_back(MainFlightPhases::LIFTOFF); + break; + case Common::Events::FLIGHT_MOTOR_SHUTDOWN: + printf("[HIL] ------- SHUTDOWN -------: %f, %f \n", + getCurrentPosition().z, getCurrentPosition().vz); + changed_flags.push_back(MainFlightPhases::SHUTDOWN); + case Common::Events::ABK_SHADOW_MODE_TIMEOUT: + setFlagFlightPhase(MainFlightPhases::AEROBRAKES, true); + registerOutcomes(MainFlightPhases::AEROBRAKES); + printf("[HIL] ABK shadow mode timeout\n"); + changed_flags.push_back(MainFlightPhases::AEROBRAKES); + break; + case Common::Events::ADA_SHADOW_MODE_TIMEOUT: + printf("[HIL] ADA shadow mode timeout\n"); + break; + case Common::Events::ABK_DISABLE: + setFlagFlightPhase(MainFlightPhases::AEROBRAKES, false); + printf("[HIL] ABK disabled\n"); + break; + case Common::Events::FLIGHT_APOGEE_DETECTED: + case Common::Events::CAN_APOGEE_DETECTED: + setFlagFlightPhase(MainFlightPhases::AEROBRAKES, false); + registerOutcomes(MainFlightPhases::APOGEE); + printf("[HIL] ------- APOGEE DETECTED ! ------- %f, %f \n", + getCurrentPosition().z, getCurrentPosition().vz); + changed_flags.push_back(MainFlightPhases::APOGEE); + break; + case Common::Events::FLIGHT_DROGUE_DESCENT: + case Common::Events::TMTC_FORCE_EXPULSION: + setFlagFlightPhase(MainFlightPhases::PARA1, true); + registerOutcomes(MainFlightPhases::PARA1); + printf("[HIL] ------- PARA1 ! -------%f, %f \n", + getCurrentPosition().z, getCurrentPosition().vz); + changed_flags.push_back(MainFlightPhases::PARA1); + break; + case Common::Events::FLIGHT_WING_DESCENT: + case Common::Events::FLIGHT_DPL_ALT_DETECTED: + case Common::Events::TMTC_FORCE_DEPLOYMENT: + setFlagFlightPhase(MainFlightPhases::PARA1, false); + setFlagFlightPhase(MainFlightPhases::PARA2, true); + registerOutcomes(MainFlightPhases::PARA2); + printf("[HIL] ------- PARA2 ! ------- %f, %f \n", + getCurrentPosition().z, getCurrentPosition().vz); + changed_flags.push_back(MainFlightPhases::PARA2); + break; + case Common::Events::FLIGHT_LANDING_DETECTED: + case Common::Events::TMTC_FORCE_LANDING: + t_stop = Boardcore::TimestampTimer::getTimestamp(); + setFlagFlightPhase(MainFlightPhases::PARA2, false); + setFlagFlightPhase(MainFlightPhases::SIMULATION_STOPPED, true); + changed_flags.push_back(MainFlightPhases::SIMULATION_STOPPED); + registerOutcomes(MainFlightPhases::SIMULATION_STOPPED); + printf("[HIL] ------- SIMULATION STOPPED ! -------: %f \n\n\n", + (double)t_stop / 1000000.0f); + printOutcomes(); + break; + default: + printf("%s event\n", Common::getEventString(e).c_str()); + } +} + +MainHIL::MainHIL() + : Boardcore::HIL<MainFlightPhases, SimulatorData, ActuatorData>( + nullptr, nullptr, [this]() { return updateActuatorData(); }, + 1000 / Config::HIL::SIMULATION_RATE.value()) +{ +} + +bool MainHIL::start() +{ + auto* nas = getModule<NASController>(); + auto& hilUsart = getModule<Buses>()->getHILUart(); + + hilPhasesManager = new MainHILPhasesManager( + [nas]() + { return Boardcore::TimedTrajectoryPoint(nas->getNASState()); }); + + hilTransceiver = new MainHILTransceiver(hilUsart, hilPhasesManager); + + return Boardcore::HIL<MainFlightPhases, SimulatorData, + ActuatorData>::start(); +} + +ActuatorData MainHIL::updateActuatorData() +{ + auto actuators = getModule<Actuators>(); + + ADAStateHIL adaStateHIL{getModule<ADAController>()->getADAState(), + getModule<ADAController>()->getState()}; + + NASStateHIL nasStateHIL{getModule<NASController>()->getNASState(), + getModule<NASController>()->getState()}; + + AirBrakesStateHIL abkStateHIL{getModule<ABKController>()->getState()}; + + MEAStateHIL meaStateHIL{getModule<MEAController>()->getMEAState(), + getModule<MEAController>()->getState()}; + + ActuatorsStateHIL actuatorsStateHIL{ + actuators->getServoPosition(ServosList::AIR_BRAKES_SERVO), + actuators->getServoPosition(ServosList::EXPULSION_SERVO), + (actuators->isCanServoOpen(ServosList::MAIN_VALVE) ? 1.f : 0.f), + (actuators->isCanServoOpen(ServosList::VENTING_VALVE) ? 1.f : 0.f), + static_cast<float>(miosix::gpios::mainDeploy::value())}; + + // Returning the feedback for the simulator + return ActuatorData{adaStateHIL, nasStateHIL, abkStateHIL, meaStateHIL, + actuatorsStateHIL}; +} + +} // namespace Main \ No newline at end of file diff --git a/src/boards/Main/HIL/HIL.h b/src/boards/Main/HIL/HIL.h index dc6cc12bfb84fd3788a6894aabeb5dd4df6b8ade..bb13a25605f67aface55aa81e324c6ef96f029e9 100644 --- a/src/boards/Main/HIL/HIL.h +++ b/src/boards/Main/HIL/HIL.h @@ -25,17 +25,16 @@ #include <Main/Actuators/Actuators.h> #include <Main/Buses.h> #include <Main/Configs/HILSimulationConfig.h> -#include <Main/Configs/MEAConfig.h> -#include <Main/Configs/SensorsConfig.h> #include <Main/HIL/HILData.h> +#include <Main/StateMachines/ABKController/ABKController.h> +#include <Main/StateMachines/ADAController/ADAController.h> +#include <Main/StateMachines/FlightModeManager/FlightModeManager.h> +#include <Main/StateMachines/MEAController/MEAController.h> +#include <Main/StateMachines/NASController/NASController.h> #include <common/Events.h> -#include <events/EventBroker.h> #include <hil/HIL.h> -#include <interfaces-impl/hwmapping.h> #include <utils/DependencyManager/DependencyManager.h> -#include "HILData.h" - namespace Main { @@ -53,212 +52,17 @@ class MainHILPhasesManager { public: explicit MainHILPhasesManager( - std::function<Boardcore::TimedTrajectoryPoint()> getCurrentPosition) - : Boardcore::HILPhasesManager<MainFlightPhases, SimulatorData, - ActuatorData>(getCurrentPosition) - { - flagsFlightPhases = {{MainFlightPhases::SIM_FLYING, false}, - {MainFlightPhases::SIM_ASCENT, false}, - {MainFlightPhases::SIM_BURNING, false}, - {MainFlightPhases::SIM_AEROBRAKES, false}, - {MainFlightPhases::SIM_PARA1, false}, - {MainFlightPhases::SIM_PARA2, false}, - {MainFlightPhases::SIMULATION_STARTED, false}, - {MainFlightPhases::CALIBRATION, false}, - {MainFlightPhases::CALIBRATION_OK, false}, - {MainFlightPhases::ARMED, false}, - {MainFlightPhases::LIFTOFF_PIN_DETACHED, false}, - {MainFlightPhases::LIFTOFF, false}, - {MainFlightPhases::AEROBRAKES, false}, - {MainFlightPhases::APOGEE, false}, - {MainFlightPhases::PARA1, false}, - {MainFlightPhases::PARA2, false}, - {MainFlightPhases::SIMULATION_STOPPED, false}}; - - prev_flagsFlightPhases = flagsFlightPhases; - - // Subscribe to all the topics - auto& eventBroker = Boardcore::EventBroker::getInstance(); - eventBroker.subscribe(this, Common::TOPIC_ABK); - eventBroker.subscribe(this, Common::TOPIC_ADA); - eventBroker.subscribe(this, Common::TOPIC_MEA); - eventBroker.subscribe(this, Common::TOPIC_DPL); - eventBroker.subscribe(this, Common::TOPIC_CAN); - eventBroker.subscribe(this, Common::TOPIC_FLIGHT); - eventBroker.subscribe(this, Common::TOPIC_FMM); - eventBroker.subscribe(this, Common::TOPIC_FSR); - eventBroker.subscribe(this, Common::TOPIC_NAS); - eventBroker.subscribe(this, Common::TOPIC_TMTC); - eventBroker.subscribe(this, Common::TOPIC_MOTOR); - eventBroker.subscribe(this, Common::TOPIC_TARS); - eventBroker.subscribe(this, Common::TOPIC_ALT); - } - - void processFlagsImpl(const SimulatorData& simulatorData, - std::vector<MainFlightPhases>& changed_flags) override - { - if (simulatorData.signal == 1) - { - miosix::reboot(); - } - - if (simulatorData.signal == 2) - { - Boardcore::EventBroker::getInstance().post( - Common::TMTC_FORCE_LANDING, Common::TOPIC_TMTC); - } - - if (simulatorData.signal == 3) - { - Boardcore::EventBroker::getInstance().post( - Common::TMTC_FORCE_LAUNCH, Common::TOPIC_TMTC); - } - - // set true when the first packet from the simulator arrives - if (isSetTrue(MainFlightPhases::SIMULATION_STARTED)) - { - t_start = Boardcore::TimestampTimer::getTimestamp(); - - printf("[HIL] ------- SIMULATION STARTED ! ------- \n"); - changed_flags.push_back(MainFlightPhases::SIMULATION_STARTED); - } - - if (flagsFlightPhases[MainFlightPhases::SIM_FLYING]) - { - if (isSetTrue(MainFlightPhases::SIM_FLYING)) - { - registerOutcomes(MainFlightPhases::SIM_FLYING); - printf("[HIL] ------- SIMULATOR LIFTOFF ! ------- \n"); - changed_flags.push_back(MainFlightPhases::SIM_FLYING); - } - } - } - - void printOutcomes() - { - printf("OUTCOMES: (times dt from liftoff)\n\n"); - printf("Simulation time: %.3f [sec]\n\n", - (double)(t_stop - t_start) / 1000000.0f); - - printf("Motor stopped burning (simulation flag): \n"); - outcomes[MainFlightPhases::SIM_BURNING].print(t_liftoff); - - printf("Airbrakes exit shadowmode: \n"); - outcomes[MainFlightPhases::AEROBRAKES].print(t_liftoff); - - printf("Apogee: \n"); - outcomes[MainFlightPhases::APOGEE].print(t_liftoff); + std::function<Boardcore::TimedTrajectoryPoint()> getCurrentPosition); - printf("Parachute 1: \n"); - outcomes[MainFlightPhases::PARA1].print(t_liftoff); + void processFlagsImpl( + const SimulatorData& simulatorData, + std::vector<MainFlightPhases>& changed_flags) override; - printf("Parachute 2: \n"); - outcomes[MainFlightPhases::PARA2].print(t_liftoff); - - printf("Simulation Stopped: \n"); - outcomes[MainFlightPhases::SIMULATION_STOPPED].print(t_liftoff); - - // auto cpuMeter = Boardcore::CpuMeter::getCpuStats(); - // printf("max cpu usage: %+.3f\n", cpuMeter.maxValue); - // printf("avg cpu usage: %+.3f\n", cpuMeter.mean); - // printf("min free heap: %+.3lu\n", cpuMeter.minFreeHeap); - // printf("max free stack:%+.3lu\n", cpuMeter.minFreeStack); - } + void printOutcomes(); private: void handleEventImpl(const Boardcore::Event& e, - std::vector<MainFlightPhases>& changed_flags) override - { - switch (e) - { - case Common::Events::FMM_INIT_ERROR: - printf("[HIL] ------- INIT FAILED ! ------- \n"); - case Common::Events::FMM_INIT_OK: - setFlagFlightPhase(MainFlightPhases::CALIBRATION, true); - printf("[HIL] ------- CALIBRATION ! ------- \n"); - changed_flags.push_back(MainFlightPhases::CALIBRATION); - break; - case Common::Events::FLIGHT_DISARMED: - setFlagFlightPhase(MainFlightPhases::CALIBRATION_OK, true); - printf("[HIL] CALIBRATION OK!\n"); - changed_flags.push_back(MainFlightPhases::CALIBRATION_OK); - break; - case Common::Events::FLIGHT_ARMED: - setFlagFlightPhase(MainFlightPhases::ARMED, true); - printf("[HIL] ------- READY TO LAUNCH ! ------- \n"); - changed_flags.push_back(MainFlightPhases::ARMED); - break; - case Common::Events::FLIGHT_LAUNCH_PIN_DETACHED: - setFlagFlightPhase(MainFlightPhases::LIFTOFF_PIN_DETACHED, - true); - printf("[HIL] ------- LIFTOFF PIN DETACHED ! ------- \n"); - changed_flags.push_back(MainFlightPhases::LIFTOFF_PIN_DETACHED); - break; - case Common::Events::FLIGHT_LIFTOFF: - case Common::Events::TMTC_FORCE_LAUNCH: - t_liftoff = Boardcore::TimestampTimer::getTimestamp(); - printf("[HIL] ------- LIFTOFF -------: %f, %f \n", - getCurrentPosition().z, getCurrentPosition().vz); - changed_flags.push_back(MainFlightPhases::LIFTOFF); - break; - case Common::Events::FLIGHT_MOTOR_SHUTDOWN: - printf("[HIL] ------- SHUTDOWN -------: %f, %f \n", - getCurrentPosition().z, getCurrentPosition().vz); - changed_flags.push_back(MainFlightPhases::SHUTDOWN); - case Common::Events::ABK_SHADOW_MODE_TIMEOUT: - setFlagFlightPhase(MainFlightPhases::AEROBRAKES, true); - registerOutcomes(MainFlightPhases::AEROBRAKES); - printf("[HIL] ABK shadow mode timeout\n"); - changed_flags.push_back(MainFlightPhases::AEROBRAKES); - break; - case Common::Events::ADA_SHADOW_MODE_TIMEOUT: - printf("[HIL] ADA shadow mode timeout\n"); - break; - case Common::Events::ABK_DISABLE: - setFlagFlightPhase(MainFlightPhases::AEROBRAKES, false); - printf("[HIL] ABK disabled\n"); - break; - case Common::Events::FLIGHT_APOGEE_DETECTED: - case Common::Events::CAN_APOGEE_DETECTED: - setFlagFlightPhase(MainFlightPhases::AEROBRAKES, false); - registerOutcomes(MainFlightPhases::APOGEE); - printf("[HIL] ------- APOGEE DETECTED ! ------- %f, %f \n", - getCurrentPosition().z, getCurrentPosition().vz); - changed_flags.push_back(MainFlightPhases::APOGEE); - break; - case Common::Events::FLIGHT_DROGUE_DESCENT: - case Common::Events::TMTC_FORCE_EXPULSION: - setFlagFlightPhase(MainFlightPhases::PARA1, true); - registerOutcomes(MainFlightPhases::PARA1); - printf("[HIL] ------- PARA1 ! -------%f, %f \n", - getCurrentPosition().z, getCurrentPosition().vz); - changed_flags.push_back(MainFlightPhases::PARA1); - break; - case Common::Events::FLIGHT_WING_DESCENT: - case Common::Events::FLIGHT_DPL_ALT_DETECTED: - case Common::Events::TMTC_FORCE_DEPLOYMENT: - setFlagFlightPhase(MainFlightPhases::PARA1, false); - setFlagFlightPhase(MainFlightPhases::PARA2, true); - registerOutcomes(MainFlightPhases::PARA2); - printf("[HIL] ------- PARA2 ! ------- %f, %f \n", - getCurrentPosition().z, getCurrentPosition().vz); - changed_flags.push_back(MainFlightPhases::PARA2); - break; - case Common::Events::FLIGHT_LANDING_DETECTED: - case Common::Events::TMTC_FORCE_LANDING: - t_stop = Boardcore::TimestampTimer::getTimestamp(); - setFlagFlightPhase(MainFlightPhases::PARA2, false); - setFlagFlightPhase(MainFlightPhases::SIMULATION_STOPPED, true); - changed_flags.push_back(MainFlightPhases::SIMULATION_STOPPED); - registerOutcomes(MainFlightPhases::SIMULATION_STOPPED); - printf("[HIL] ------- SIMULATION STOPPED ! -------: %f \n\n\n", - (double)t_stop / 1000000.0f); - printOutcomes(); - break; - default: - printf("%s event\n", Common::getEventString(e).c_str()); - } - } + std::vector<MainFlightPhases>& changed_flags) override; }; class MainHIL @@ -266,58 +70,14 @@ class MainHIL public Boardcore::InjectableWithDeps<Buses, Actuators, FlightModeManager, ADAController, NASController, MEAController, ABKController> - { public: - MainHIL() - : Boardcore::HIL<MainFlightPhases, SimulatorData, ActuatorData>( - nullptr, nullptr, [this]() { return updateActuatorData(); }, - 1000 / Config::HIL::SIMULATION_RATE.value()) - { - } - - bool start() override - { - auto* nas = getModule<NASController>(); - auto& hilUsart = getModule<Buses>()->getHILUart(); - - hilPhasesManager = new MainHILPhasesManager( - [nas]() - { return Boardcore::TimedTrajectoryPoint(nas->getNASState()); }); - - hilTransceiver = new MainHILTransceiver(hilUsart, hilPhasesManager); + MainHIL(); - return Boardcore::HIL<MainFlightPhases, SimulatorData, - ActuatorData>::start(); - } + bool start() override; private: - ActuatorData updateActuatorData() - { - auto actuators = getModule<Actuators>(); - - ADAStateHIL adaStateHIL{getModule<ADAController>()->getADAState(), - getModule<ADAController>()->getState()}; - - NASStateHIL nasStateHIL{getModule<NASController>()->getNASState(), - getModule<NASController>()->getState()}; - - AirBrakesStateHIL abkStateHIL{getModule<ABKController>()->getState()}; - - MEAStateHIL meaStateHIL{getModule<MEAController>()->getMEAState(), - getModule<MEAController>()->getState()}; - - ActuatorsStateHIL actuatorsStateHIL{ - actuators->getServoPosition(ServosList::AIR_BRAKES_SERVO), - actuators->getServoPosition(ServosList::EXPULSION_SERVO), - (actuators->isCanServoOpen(ServosList::MAIN_VALVE) ? 1.f : 0.f), - (actuators->isCanServoOpen(ServosList::VENTING_VALVE) ? 1.f : 0.f), - static_cast<float>(miosix::gpios::mainDeploy::value())}; - - // Returning the feedback for the simulator - return ActuatorData{adaStateHIL, nasStateHIL, abkStateHIL, meaStateHIL, - actuatorsStateHIL}; - }; + ActuatorData updateActuatorData(); }; } // namespace Main \ No newline at end of file diff --git a/src/boards/Main/HIL/HILData.h b/src/boards/Main/HIL/HILData.h index db77d29159241f3cf2ec49a13cb7ac0fcddaae50..8aa67209ca8a102afaedeefabf787f3ffd623ac2 100644 --- a/src/boards/Main/HIL/HILData.h +++ b/src/boards/Main/HIL/HILData.h @@ -25,26 +25,19 @@ #include <Main/Configs/HILSimulationConfig.h> #include <sensors/HILSimulatorData.h> -// FMM -#include <Main/StateMachines/FlightModeManager/FlightModeManager.h> - // ADA -#include <Main/StateMachines/ADAController/ADAController.h> #include <Main/StateMachines/ADAController/ADAControllerData.h> #include <algorithms/ADA/ADAData.h> // NAS -#include <Main/StateMachines/NASController/NASController.h> #include <Main/StateMachines/NASController/NASControllerData.h> #include <algorithms/NAS/NASState.h> // ABK -#include <Main/StateMachines/ABKController/ABKController.h> #include <Main/StateMachines/ABKController/ABKControllerData.h> #include <algorithms/AirBrakes/AirBrakesInterp.h> // MEA -#include <Main/StateMachines/MEAController/MEAController.h> #include <Main/StateMachines/MEAController/MEAControllerData.h> #include <algorithms/MEA/MEAData.h> @@ -69,6 +62,13 @@ using MainPitotSimulatorData = using MainTemperatureSimulatorData = Boardcore::TemperatureSimulatorData<Config::HIL::N_DATA_TEMP>; +enum class HILSignal : int +{ + SIMULATION_STARTED = 1, + SIMULATION_STOPPED = 2, + SIMULATION_FORCE_LAUNCH = 3 +}; + enum class MainFlightPhases { SIM_FLYING, @@ -108,7 +108,8 @@ struct ADAStateHIL { } - ADAStateHIL(Boardcore::ADAState adaState, Main::ADAControllerState state) + ADAStateHIL(const Boardcore::ADAState& adaState, + const Main::ADAControllerState& state) : mslAltitude(adaState.mslAltitude), aglAltitude(adaState.aglAltitude), verticalSpeed(adaState.verticalSpeed), apogeeDetected(state >= ADAControllerState::ACTIVE_DROGUE_DESCENT), @@ -156,7 +157,8 @@ struct NASStateHIL { } - NASStateHIL(Boardcore::NASState nasState, Main::NASControllerState state) + NASStateHIL(const Boardcore::NASState& nasState, + const Main::NASControllerState& state) : n(nasState.n), e(nasState.e), d(nasState.d), vn(nasState.vn), ve(nasState.ve), vd(nasState.vd), qx(nasState.qx), qy(nasState.qy), qz(nasState.qz), qw(nasState.qw), @@ -191,7 +193,7 @@ struct AirBrakesStateHIL AirBrakesStateHIL() : updating(0) {} - AirBrakesStateHIL(Main::ABKControllerState state) + explicit AirBrakesStateHIL(const Main::ABKControllerState& state) : updating(state >= Main::ABKControllerState::ACTIVE) { } @@ -217,7 +219,8 @@ struct MEAStateHIL { } - MEAStateHIL(Boardcore::MEAState meaState, Main::MEAControllerState state) + MEAStateHIL(const Boardcore::MEAState& meaState, + const Main::MEAControllerState& state) : correctedPressure(meaState.estimatedPressure), estimatedMass(meaState.estimatedMass), estimatedApogee(meaState.estimatedApogee), @@ -314,9 +317,10 @@ struct ActuatorData { } - ActuatorData(ADAStateHIL adaState, NASStateHIL nasState, - AirBrakesStateHIL airBrakesState, MEAStateHIL meaState, - ActuatorsStateHIL actuatorsState) + ActuatorData(const ADAStateHIL& adaState, const NASStateHIL& nasState, + const AirBrakesStateHIL& airBrakesState, + const MEAStateHIL& meaState, + const ActuatorsStateHIL& actuatorsState) : adaState(adaState), nasState(nasState), airBrakesState(airBrakesState), meaState(meaState), actuatorsState(actuatorsState) diff --git a/src/boards/Main/PersistentVars/PersistentVars.cpp b/src/boards/Main/PersistentVars/PersistentVars.cpp index c07ec5df6ccb244f775f75be59c3136ccf196598..2ac4c53d915bc97a6607ebcf3a375931836168ba 100644 --- a/src/boards/Main/PersistentVars/PersistentVars.cpp +++ b/src/boards/Main/PersistentVars/PersistentVars.cpp @@ -22,21 +22,27 @@ #include "PersistentVars.h" +#include <arch/common/drivers/stm32_bsram.h> +#include <miosix.h> + using namespace miosix; +static bool PRESERVE hilMode = false; + namespace Main { -bool PRESERVE PersistentVars::hilMode = false; - -PersistentVars::PersistentVars() {} +namespace PersistentVars +{ -void PersistentVars::setHilMode(bool _hilMode) +void setHilMode(bool _hilMode) { BSRAM::EnableWriteLock l; hilMode = _hilMode; } -bool PersistentVars::getHilMode() { return hilMode; } +bool getHilMode() { return hilMode; } + +} // namespace PersistentVars } // namespace Main \ No newline at end of file diff --git a/src/boards/Main/PersistentVars/PersistentVars.h b/src/boards/Main/PersistentVars/PersistentVars.h index 937aaf78aa509f555df27949f8a79991c9698e33..d533078bf4f74a3a4cd1331acb02cc4efcc97866 100644 --- a/src/boards/Main/PersistentVars/PersistentVars.h +++ b/src/boards/Main/PersistentVars/PersistentVars.h @@ -22,23 +22,16 @@ #pragma once -#include <arch/common/drivers/stm32_bsram.h> -#include <utils/DependencyManager/DependencyManager.h> - namespace Main { -class PersistentVars : public Boardcore::Injectable +namespace PersistentVars { -public: - PersistentVars(); - void setHilMode(bool _hilMode); +void setHilMode(bool _hilMode); - bool getHilMode(); +bool getHilMode(); -private: - static bool PRESERVE hilMode; -}; +} // namespace PersistentVars } // namespace Main \ No newline at end of file diff --git a/src/boards/Main/Radio/Radio.cpp b/src/boards/Main/Radio/Radio.cpp index 661723b096c51378944466ce2c88cef36b74fe2d..89e7630b0cd6d65a4a81f8d36dc06fbdcdedf973 100644 --- a/src/boards/Main/Radio/Radio.cpp +++ b/src/boards/Main/Radio/Radio.cpp @@ -740,7 +740,7 @@ bool Radio::enqueueSystemTm(uint8_t tmId) tm.motor_can_status = canStatus.isMotorConnected() ? 1 : 0; tm.rig_can_status = canStatus.isRigConnected() ? 1 : 0; - tm.hil_state = getModule<PersistentVars>()->getHilMode() ? 1 : 0; + tm.hil_state = PersistentVars::getHilMode() ? 1 : 0; mavlink_msg_rocket_stats_tm_encode(Config::Radio::MAV_SYSTEM_ID, Config::Radio::MAV_COMPONENT_ID, diff --git a/src/boards/Main/Radio/Radio.h b/src/boards/Main/Radio/Radio.h index 3702162be9c33a89be7c5ce6a8810e5dd3970ee3..fff2e20e830532f1aaa9243fa827a4a16d4e1d7d 100644 --- a/src/boards/Main/Radio/Radio.h +++ b/src/boards/Main/Radio/Radio.h @@ -47,11 +47,10 @@ using MavDriver = Boardcore::MavlinkDriver<Boardcore::SX1278Fsk::MTU, Config::Radio::MAV_OUT_QUEUE_SIZE, Config::Radio::MAV_MAX_LENGTH>; -class Radio - : public Boardcore::InjectableWithDeps< - Buses, BoardScheduler, Actuators, PinHandler, CanHandler, Sensors, - FlightModeManager, ADAController, NASController, MEAController, - ABKController, StatsRecorder, AlgoReference, PersistentVars> +class Radio : public Boardcore::InjectableWithDeps< + Buses, BoardScheduler, Actuators, PinHandler, CanHandler, + Sensors, FlightModeManager, ADAController, NASController, + MEAController, ABKController, StatsRecorder, AlgoReference> { public: Radio() {} diff --git a/src/boards/Main/StateMachines/FlightModeManager/FlightModeManager.cpp b/src/boards/Main/StateMachines/FlightModeManager/FlightModeManager.cpp index 1fdc127889aacebcde7254f85e5472536357b094..f45fb98a13454fc3771855361fd7cec6d4a706bd 100644 --- a/src/boards/Main/StateMachines/FlightModeManager/FlightModeManager.cpp +++ b/src/boards/Main/StateMachines/FlightModeManager/FlightModeManager.cpp @@ -32,6 +32,22 @@ using namespace Common; using namespace Boardcore; using namespace miosix; +void enterHilMode() +{ + PersistentVars::setHilMode(true); + reboot(); +} + +void exitHilMode() +{ + // Reboot only if in HIL mode + if (PersistentVars::getHilMode()) + { + PersistentVars::setHilMode(false); + reboot(); + } +} + FlightModeManager::FlightModeManager() : HSM{&FlightModeManager::state_on_ground, STACK_DEFAULT_FOR_PTHREAD, Config::Scheduler::FMM_PRIORITY} @@ -78,16 +94,12 @@ State FlightModeManager::state_on_ground(const Event& event) getModule<CanHandler>()->sendEvent( CanConfig::EventId::EXIT_HIL_MODE); miosix::Thread::sleep(1000); - // Fallthrough + exitHilMode(); + return HANDLED; } case CAN_EXIT_HIL_MODE: { - // Reboot only if in HIL mode - if (getModule<PersistentVars>()->getHilMode()) - { - getModule<PersistentVars>()->setHilMode(false); - miosix::reboot(); - } + exitHilMode(); return HANDLED; } default: @@ -433,13 +445,13 @@ State FlightModeManager::state_test_mode(const Event& event) getModule<CanHandler>()->sendEvent( CanConfig::EventId::ENTER_HIL_MODE); Thread::sleep(1000); - // Fallthrough + enterHilMode(); + return HANDLED; } case CAN_ENTER_HIL_MODE: { - getModule<PersistentVars>()->setHilMode(true); - reboot(); - __builtin_unreachable(); + enterHilMode(); + return HANDLED; } default: { diff --git a/src/boards/Main/StateMachines/FlightModeManager/FlightModeManager.h b/src/boards/Main/StateMachines/FlightModeManager/FlightModeManager.h index 409645cc84668ba576f61834cd0b906f7af0b96d..ef2ff49ee5556a9bb45e212475097ae91d56cf22 100644 --- a/src/boards/Main/StateMachines/FlightModeManager/FlightModeManager.h +++ b/src/boards/Main/StateMachines/FlightModeManager/FlightModeManager.h @@ -39,8 +39,7 @@ namespace Main class FlightModeManager : public Boardcore::InjectableWithDeps<Actuators, Sensors, CanHandler, - StatsRecorder, AlgoReference, - PersistentVars>, + StatsRecorder, AlgoReference>, public Boardcore::HSM<FlightModeManager> { public: diff --git a/src/entrypoints/Main/main-entry.cpp b/src/entrypoints/Main/main-entry.cpp index 11c46d54a3e98f407fa1d4bfb2a15df029cbe994..2fb33cf7c8b380dd9285ef6c129d38b7a1ba11a0 100644 --- a/src/entrypoints/Main/main-entry.cpp +++ b/src/entrypoints/Main/main-entry.cpp @@ -62,9 +62,8 @@ int main() bool initResult = true; - PersistentVars *persistentVars = new PersistentVars(); - Buses *buses = new Buses(); - BoardScheduler *scheduler = new BoardScheduler(); + Buses *buses = new Buses(); + BoardScheduler *scheduler = new BoardScheduler(); Sensors *sensors; Actuators *actuators = new Actuators(); @@ -81,7 +80,7 @@ int main() MainHIL *hil = nullptr; // HIL - if (persistentVars->getHilMode()) + if (PersistentVars::getHilMode()) { std::cout << "MAIN SimulatorData: " << sizeof(SimulatorData) << ", ActuatorData: " << sizeof(ActuatorData) << std::endl; @@ -109,8 +108,7 @@ int main() }); // Insert modules - initResult = initResult && manager.insert<PersistentVars>(persistentVars) && - manager.insert<Buses>(buses) && + initResult = initResult && manager.insert<Buses>(buses) && manager.insert<BoardScheduler>(scheduler) && manager.insert<Sensors>(sensors) && manager.insert<Radio>(radio) && @@ -226,7 +224,7 @@ int main() std::cout << "Error failed to start SD" << std::endl; } - if (persistentVars->getHilMode()) + if (PersistentVars::getHilMode()) { std::cout << "Starting HIL" << std::endl; hil->start();