From eddd637b2eaeb17d39d75bc769151ef17cbb1009 Mon Sep 17 00:00:00 2001 From: Sebastian Lukas Date: Wed, 8 May 2024 12:31:10 +0200 Subject: [PATCH] Adding run thread, fix: sim restarts again Signed-off-by: Sebastian Lukas --- modules/EvManager/main/CarSimulation.cpp | 4 +- modules/EvManager/main/CarSimulation.hpp | 6 +- modules/EvManager/main/SimulationData.hpp | 3 +- modules/EvManager/main/car_simulatorImpl.cpp | 72 +++++++++++--------- modules/EvManager/main/car_simulatorImpl.hpp | 7 +- 5 files changed, 50 insertions(+), 42 deletions(-) diff --git a/modules/EvManager/main/CarSimulation.cpp b/modules/EvManager/main/CarSimulation.cpp index 9474a186f0..163a03966b 100644 --- a/modules/EvManager/main/CarSimulation.cpp +++ b/modules/EvManager/main/CarSimulation.cpp @@ -7,7 +7,7 @@ #include -void CarSimulation::stateMachine() { +void CarSimulation::state_machine() { using types::ev_board_support::EvCpState; const auto stateHasChanged = sim_data.state != sim_data.lastState; @@ -21,8 +21,6 @@ void CarSimulation::stateMachine() { r_ev_board_support->call_allow_power_on(false); // Wait for physical plugin (ev BSP sees state A on CP and not Disconnected) - // If we have auto_exec configured, restart simulation when it was unplugged - EVLOG_info << "Unplug detected, restarting simulation."; sim_data.slacState = "UNMATCHED"; r_ev[0]->call_stop_charging(); } diff --git a/modules/EvManager/main/CarSimulation.hpp b/modules/EvManager/main/CarSimulation.hpp index 172061a380..5bc21a8357 100644 --- a/modules/EvManager/main/CarSimulation.hpp +++ b/modules/EvManager/main/CarSimulation.hpp @@ -28,6 +28,10 @@ class CarSimulation { return sim_data.state; } + void set_state(SimState state) { + sim_data.state = state; + } + void setBspEvent(types::board_support_common::Event event) { sim_data.actualBspEvent = event; } @@ -68,7 +72,7 @@ class CarSimulation { sim_data.dc_power_on = dcPowerOn; } - void stateMachine(); + void state_machine(); bool sleep(const CmdArguments&, size_t); bool iec_wait_pwr_ready(const CmdArguments&); bool iso_wait_pwm_is_running(const CmdArguments& arguments); diff --git a/modules/EvManager/main/SimulationData.hpp b/modules/EvManager/main/SimulationData.hpp index 4900898bd7..d5c8749c71 100644 --- a/modules/EvManager/main/SimulationData.hpp +++ b/modules/EvManager/main/SimulationData.hpp @@ -23,6 +23,7 @@ enum class SimState { ISO_POWER_READY, ISO_CHARGING_REGULATED, BCB_TOGGLE, + UNDEFINED, }; struct SimulationData { @@ -30,7 +31,7 @@ struct SimulationData { SimulationData() = default; SimState state{SimState::UNPLUGGED}; - SimState lastState{SimState::UNPLUGGED}; + SimState lastState{SimState::UNDEFINED}; std::string slacState{"UNMATCHED"}; std::optional sleepTicksLeft{}; diff --git a/modules/EvManager/main/car_simulatorImpl.cpp b/modules/EvManager/main/car_simulatorImpl.cpp index bfeff6db74..87fbd6bb64 100644 --- a/modules/EvManager/main/car_simulatorImpl.cpp +++ b/modules/EvManager/main/car_simulatorImpl.cpp @@ -9,11 +9,12 @@ namespace module::main { void car_simulatorImpl::init() { - enabled = false; loopIntervalMs = DEFAULT_LOOP_INTERVAL_MS; registerAllCommands(); subscribeToExternalMQTT(); subscribeToVariablesOnInit(); + + std::thread(&car_simulatorImpl::run, this).detach(); } void car_simulatorImpl::ready() { @@ -43,13 +44,7 @@ void car_simulatorImpl::handle_enable(bool& value) { callEVBoardSupportFunctions(); - if (value) { - enabled = true; - simulationThread = std::thread{&car_simulatorImpl::handleSimulationLoop, this}; - } else { - enabled = false; - simulationThread.join(); - } + enabled = value; mod->r_ev_board_support->call_enable(value); publish_enabled(value); @@ -65,7 +60,7 @@ void car_simulatorImpl::handle_executeChargingSession(std::string& value) { updateCommandQueue(value); - std::lock_guard lock{carSimulationMutex}; + const std::lock_guard lock{carSimulationMutex}; if (!commandQueue.empty()) { executionActive = true; } @@ -81,27 +76,32 @@ void car_simulatorImpl::handle_modifyChargingSession(std::string& value) { updateCommandQueue(value); - std::lock_guard lock{carSimulationMutex}; + const std::lock_guard lock{carSimulationMutex}; if (!commandQueue.empty()) { executionActive = true; } } -void car_simulatorImpl::handleSimulationLoop() { - while (enabled) { - if (executionActive) { - runSimulationLoop(); - std::this_thread::sleep_for(std::chrono::milliseconds(loopIntervalMs)); - } - } - EVLOG_debug << "Finished simulation."; +void car_simulatorImpl::run() { + while (true) { + if (enabled == true && executionActive == true) { - resetCarSimulationDefaults(); + const auto finished = run_simulation_loop(); - // If we have auto_exec_infinite configured, restart simulation when it is done - if (mod->config.auto_exec && mod->config.auto_exec_infinite) { - auto valueCopy = mod->config.auto_exec_commands; - handle_executeChargingSession(valueCopy); + if (finished) { + EVLOG_info << "Finished simulation."; + this->executionActive = false; + + resetCarSimulationDefaults(); + + // If we have auto_exec_infinite configured, restart simulation when it is done + if (mod->config.auto_exec && mod->config.auto_exec_infinite) { + auto value_copy = mod->config.auto_exec_commands; + handle_executeChargingSession(value_copy); + } + } + } + std::this_thread::sleep_for(std::chrono::milliseconds(loopIntervalMs)); } } @@ -178,28 +178,33 @@ void car_simulatorImpl::registerAllCommands() { } } -void car_simulatorImpl::runSimulationLoop() { +bool car_simulatorImpl::run_simulation_loop() { // Execute sim commands until a command blocks, or we are finished - std::lock_guard lock{carSimulationMutex}; + const std::lock_guard lock{carSimulationMutex}; while (executionActive && !commandQueue.empty()) { auto& currentCommand = commandQueue.front(); - auto commandBlocked = false; + auto command_blocked = false; try { - commandBlocked = !currentCommand.execute(); + command_blocked = !currentCommand.execute(); } catch (const std::exception& e) { EVLOG_error << e.what(); } - if (!commandBlocked) { + if (!command_blocked) { commandQueue.pop(); } else { break; // command blocked, wait for timer to run this function again } } - car_simulation->stateMachine(); + car_simulation->state_machine(); + + if (commandQueue.empty()) { + return true; + } + return false; } bool car_simulatorImpl::checkCanExecute() { @@ -217,13 +222,14 @@ bool car_simulatorImpl::checkCanExecute() { void car_simulatorImpl::subscribeToVariablesOnInit() { // subscribe bsp_event - std::lock_guard lock{carSimulationMutex}; + const std::lock_guard lock{carSimulationMutex}; using types::board_support_common::BspEvent; mod->r_ev_board_support->subscribe_bsp_event([this](const auto& bsp_event) { car_simulation->setBspEvent(bsp_event.event); if (bsp_event.event == types::board_support_common::Event::Disconnected && - car_simulation->getState() == SimState::UNPLUGGED) { + car_simulation->getState() != SimState::UNPLUGGED) { executionActive = false; + car_simulation->set_state(SimState::UNPLUGGED); } }); @@ -299,12 +305,12 @@ void car_simulatorImpl::subscribeToExternalMQTT() { }); } void car_simulatorImpl::resetCarSimulationDefaults() { - std::lock_guard lock{carSimulationMutex}; + const std::lock_guard lock{carSimulationMutex}; car_simulation->reset(); } void car_simulatorImpl::updateCommandQueue(std::string& value) { - std::lock_guard lock{carSimulationMutex}; + const std::lock_guard lock{carSimulationMutex}; commandQueue = SimulationCommand::parseSimCommands(value, *command_registry); } } // namespace module::main diff --git a/modules/EvManager/main/car_simulatorImpl.hpp b/modules/EvManager/main/car_simulatorImpl.hpp index 66a6179ea6..8dab5505bc 100644 --- a/modules/EvManager/main/car_simulatorImpl.hpp +++ b/modules/EvManager/main/car_simulatorImpl.hpp @@ -51,10 +51,10 @@ class car_simulatorImpl : public car_simulatorImplBase { // ev@3370e4dd-95f4-47a9-aaec-ea76f34a66c9:v1 + void run(); void handle_modifyChargingSession(std::string& value); bool checkCanExecute(); - void handleSimulationLoop(); - void runSimulationLoop(); + bool run_simulation_loop(); void registerAllCommands(); void subscribeToVariablesOnInit(); void setupEVParameters(); @@ -68,11 +68,10 @@ class car_simulatorImpl : public car_simulatorImplBase { std::mutex carSimulationMutex; std::unique_ptr car_simulation; - bool enabled; + bool enabled{false}; std::atomic executionActive{false}; size_t loopIntervalMs{}; - std::thread simulationThread; std::queue commandQueue; // ev@3370e4dd-95f4-47a9-aaec-ea76f34a66c9:v1