From 3d619bb0a9655dfe5d5c66a73e7929bd38a572c9 Mon Sep 17 00:00:00 2001 From: Fabian Hartung Date: Wed, 1 Mar 2023 07:46:08 +0100 Subject: [PATCH] DCSupplySimulator: Add C++ simulation module This C++ module emulates the behavior of the existing JsDCSupplySimulator. Unlike JsDCSupplySimulator, it does not provide the powermeter simulation interface though. This should be implemented in a separate C++ module. Co-authored-by: Cornelius Claussen Co-authored-by: Fabian Hartung Co-authored-by: Mohannad Oraby Co-authored-by: Moritz Barsnick Signed-off-by: Fabian Hartung Signed-off-by: Moritz Barsnick --- modules/simulation/CMakeLists.txt | 1 + .../DCSupplySimulator/CMakeLists.txt | 23 ++++ .../DCSupplySimulator/DCSupplySimulator.cpp | 17 +++ .../DCSupplySimulator/DCSupplySimulator.hpp | 58 +++++++++ .../main/power_supply_DCImpl.cpp | 123 ++++++++++++++++++ .../main/power_supply_DCImpl.hpp | 86 ++++++++++++ .../DCSupplySimulator/manifest.yaml | 36 +++++ 7 files changed, 344 insertions(+) create mode 100644 modules/simulation/DCSupplySimulator/CMakeLists.txt create mode 100644 modules/simulation/DCSupplySimulator/DCSupplySimulator.cpp create mode 100644 modules/simulation/DCSupplySimulator/DCSupplySimulator.hpp create mode 100644 modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.cpp create mode 100644 modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp create mode 100644 modules/simulation/DCSupplySimulator/manifest.yaml diff --git a/modules/simulation/CMakeLists.txt b/modules/simulation/CMakeLists.txt index 6d8798987..f0894f160 100644 --- a/modules/simulation/CMakeLists.txt +++ b/modules/simulation/CMakeLists.txt @@ -1,3 +1,4 @@ +ev_add_module(DCSupplySimulator) ev_add_module(JsCarSimulator) ev_add_module(JsDCSupplySimulator) ev_add_module(JsIMDSimulator) diff --git a/modules/simulation/DCSupplySimulator/CMakeLists.txt b/modules/simulation/DCSupplySimulator/CMakeLists.txt new file mode 100644 index 000000000..bac307954 --- /dev/null +++ b/modules/simulation/DCSupplySimulator/CMakeLists.txt @@ -0,0 +1,23 @@ +# +# AUTO GENERATED - MARKED REGIONS WILL BE KEPT +# template version 3 +# + +# module setup: +# - ${MODULE_NAME}: module name +ev_setup_cpp_module() + +# ev@bcc62523-e22b-41d7-ba2f-825b493a3c97:v1 +# insert your custom targets and additional config variables here +# needed for std::scoped_lock +target_compile_features(${MODULE_NAME} PUBLIC cxx_std_17) +# ev@bcc62523-e22b-41d7-ba2f-825b493a3c97:v1 + +target_sources(${MODULE_NAME} + PRIVATE + "main/power_supply_DCImpl.cpp" +) + +# ev@c55432ab-152c-45a9-9d2e-7281d50c69c3:v1 +# insert other things like install cmds etc here +# ev@c55432ab-152c-45a9-9d2e-7281d50c69c3:v1 diff --git a/modules/simulation/DCSupplySimulator/DCSupplySimulator.cpp b/modules/simulation/DCSupplySimulator/DCSupplySimulator.cpp new file mode 100644 index 000000000..33a76effb --- /dev/null +++ b/modules/simulation/DCSupplySimulator/DCSupplySimulator.cpp @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright (C) 2023 chargebyte GmbH +// Copyright (C) 2023 Contributors to EVerest + +#include "DCSupplySimulator.hpp" + +namespace module { + +void DCSupplySimulator::init() { + invoke_init(*p_main); +} + +void DCSupplySimulator::ready() { + invoke_ready(*p_main); +} + +} // namespace module diff --git a/modules/simulation/DCSupplySimulator/DCSupplySimulator.hpp b/modules/simulation/DCSupplySimulator/DCSupplySimulator.hpp new file mode 100644 index 000000000..daf5a827d --- /dev/null +++ b/modules/simulation/DCSupplySimulator/DCSupplySimulator.hpp @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright chargebyte GmbH and Contributors to EVerest +#ifndef DCSUPPLY_SIMULATOR_HPP +#define DCSUPPLY_SIMULATOR_HPP + +// +// AUTO GENERATED - MARKED REGIONS WILL BE KEPT +// template version 2 +// + +#include "ld-ev.hpp" + +// headers for provided interface implementations +#include + +// ev@4bf81b14-a215-475c-a1d3-0a484ae48918:v1 +// insert your custom include headers here +// ev@4bf81b14-a215-475c-a1d3-0a484ae48918:v1 + +namespace module { + +struct Conf {}; + +class DCSupplySimulator : public Everest::ModuleBase { +public: + DCSupplySimulator() = delete; + DCSupplySimulator(const ModuleInfo& info, std::unique_ptr p_main, Conf& config) : + ModuleBase(info), p_main(std::move(p_main)), config(config){}; + + const std::unique_ptr p_main; + const Conf& config; + + // ev@1fce4c5e-0ab8-41bb-90f7-14277703d2ac:v1 + // insert your public definitions here + // ev@1fce4c5e-0ab8-41bb-90f7-14277703d2ac:v1 + +protected: + // ev@4714b2ab-a24f-4b95-ab81-36439e1478de:v1 + // insert your protected definitions here + // ev@4714b2ab-a24f-4b95-ab81-36439e1478de:v1 + +private: + friend class LdEverest; + void init(); + void ready(); + + // ev@211cfdbe-f69a-4cd6-a4ec-f8aaa3d1b6c8:v1 + // insert your private definitions here + // ev@211cfdbe-f69a-4cd6-a4ec-f8aaa3d1b6c8:v1 +}; + +// ev@087e516b-124c-48df-94fb-109508c7cda9:v1 +// insert other definitions here +// ev@087e516b-124c-48df-94fb-109508c7cda9:v1 + +} // namespace module + +#endif // DCSUPPLY_SIMULATOR_HPP diff --git a/modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.cpp b/modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.cpp new file mode 100644 index 000000000..d98831881 --- /dev/null +++ b/modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.cpp @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright (C) 2023 chargebyte GmbH +// Copyright (C) 2023 Contributors to EVerest + +#include +#include + +#include "power_supply_DCImpl.hpp" + +namespace module { +namespace main { + +void power_supply_DCImpl::init() { + this->connector_voltage = 0.0; + this->connector_current = 0.0; + + this->power_supply_thread_handle = std::thread(&power_supply_DCImpl::power_supply_worker, this); +} + +void power_supply_DCImpl::ready() { +} + +types::power_supply_DC::Capabilities power_supply_DCImpl::handle_getCapabilities() { + types::power_supply_DC::Capabilities Capabilities = { + .bidirectional = this->config.bidirectional, + .current_regulation_tolerance_A = 2.0, + .peak_current_ripple_A = 2.0, + .max_export_voltage_V = static_cast(this->config.max_voltage), + .min_export_voltage_V = static_cast(this->config.min_voltage), + .max_export_current_A = static_cast(this->config.max_current), + .min_export_current_A = static_cast(this->config.min_current), + .max_export_power_W = static_cast(this->config.max_power), + .max_import_voltage_V = static_cast(this->config.max_voltage), + .min_import_voltage_V = static_cast(this->config.min_voltage), + .max_import_current_A = static_cast(this->config.max_current), + .min_import_current_A = static_cast(this->config.min_current), + .max_import_power_W = static_cast(this->config.max_power), + .conversion_efficiency_import = 0.85, + .conversion_efficiency_export = 0.9, + }; + return Capabilities; +} + +void power_supply_DCImpl::handle_setMode(types::power_supply_DC::Mode& value) { + this->mode = value; + + std::scoped_lock access_lock(this->power_supply_values_mutex); + if ((value == types::power_supply_DC::Mode::Off) || (value == types::power_supply_DC::Mode::Fault)) { + this->connector_voltage = 0.0; + this->connector_current = 0.0; + } else if (value == types::power_supply_DC::Mode::Export) { + this->connector_voltage = this->settings_connector_export_voltage; + this->connector_current = this->settings_connector_max_export_current; + } else if (value == types::power_supply_DC::Mode::Import) { + this->connector_voltage = this->settings_connector_import_voltage; + this->connector_current = this->settings_connector_max_import_current; + } + + mod->p_main->publish_mode(value); +} + +void power_supply_DCImpl::clampVoltageCurrent(double& voltage, double& current) { + voltage = voltage < this->config.min_voltage ? this->config.min_voltage + : voltage > this->config.max_voltage ? this->config.max_voltage + : voltage; + + current = current < this->config.min_current ? this->config.min_current + : current > this->config.max_current ? this->config.max_current + : current; +} + +void power_supply_DCImpl::handle_setExportVoltageCurrent(double& voltage, double& current) { + double temp_voltage = voltage; + double temp_current = current; + + clampVoltageCurrent(temp_voltage, temp_current); + + std::scoped_lock access_lock(this->power_supply_values_mutex); + this->settings_connector_export_voltage = temp_voltage; + this->settings_connector_max_export_current = temp_current; + + if (this->mode == types::power_supply_DC::Mode::Export) { + this->connector_voltage = this->settings_connector_export_voltage; + this->connector_current = this->settings_connector_max_export_current; + } +} + +void power_supply_DCImpl::handle_setImportVoltageCurrent(double& voltage, double& current) { + double temp_voltage = voltage; + double temp_current = current; + + clampVoltageCurrent(temp_voltage, temp_current); + + std::scoped_lock access_lock(this->power_supply_values_mutex); + this->settings_connector_import_voltage = temp_voltage; + this->settings_connector_max_import_current = temp_current; + + if (this->mode == types::power_supply_DC::Mode::Import) { + this->connector_voltage = this->settings_connector_import_voltage; + this->connector_current = -this->settings_connector_max_import_current; + } +} + +void power_supply_DCImpl::power_supply_worker(void) { + types::power_supply_DC::VoltageCurrent voltage_current; + + while (true) { + if (this->power_supply_thread_handle.shouldExit()) { + break; + } + + // set interval for publishing + std::this_thread::sleep_for(std::chrono::milliseconds(LOOP_SLEEP_MS)); + + std::scoped_lock access_lock(this->power_supply_values_mutex); + voltage_current.voltage_V = static_cast(this->connector_voltage); + voltage_current.current_A = static_cast(this->connector_current); + + this->mod->p_main->publish_voltage_current(voltage_current); + } +} +} // namespace main +} // namespace module diff --git a/modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp b/modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp new file mode 100644 index 000000000..2a3dfc30f --- /dev/null +++ b/modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright chargebyte GmbH and Contributors to EVerest +#ifndef MAIN_POWER_SUPPLY_DC_IMPL_HPP +#define MAIN_POWER_SUPPLY_DC_IMPL_HPP + +// +// AUTO GENERATED - MARKED REGIONS WILL BE KEPT +// template version 3 +// + +#include + +#include "../DCSupplySimulator.hpp" + +// ev@75ac1216-19eb-4182-a85c-820f1fc2c091:v1 +// insert your custom include headers here +#include +#include +// ev@75ac1216-19eb-4182-a85c-820f1fc2c091:v1 + +namespace module { +namespace main { + +struct Conf { + bool bidirectional; + double max_power; + double min_voltage; + double max_voltage; + double min_current; + double max_current; +}; + +class power_supply_DCImpl : public power_supply_DCImplBase { +public: + power_supply_DCImpl() = delete; + power_supply_DCImpl(Everest::ModuleAdapter* ev, const Everest::PtrContainer& mod, Conf& config) : + power_supply_DCImplBase(ev, "main"), mod(mod), config(config){}; + + // ev@8ea32d28-373f-4c90-ae5e-b4fcc74e2a61:v1 + // insert your public definitions here + // ev@8ea32d28-373f-4c90-ae5e-b4fcc74e2a61:v1 + +protected: + // command handler functions (virtual) + virtual types::power_supply_DC::Capabilities handle_getCapabilities() override; + virtual void handle_setMode(types::power_supply_DC::Mode& value) override; + virtual void handle_setExportVoltageCurrent(double& voltage, double& current) override; + virtual void handle_setImportVoltageCurrent(double& voltage, double& current) override; + + // ev@d2d1847a-7b88-41dd-ad07-92785f06f5c4:v1 + // insert your protected definitions here + // ev@d2d1847a-7b88-41dd-ad07-92785f06f5c4:v1 + +private: + const Everest::PtrContainer& mod; + const Conf& config; + + virtual void init() override; + virtual void ready() override; + + // ev@3370e4dd-95f4-47a9-aaec-ea76f34a66c9:v1 + // insert your private definitions here + double settings_connector_export_voltage; + double settings_connector_import_voltage; + double settings_connector_max_export_current; + double settings_connector_max_import_current; + types::power_supply_DC::Mode mode; + double connector_voltage; + double connector_current; + std::mutex power_supply_values_mutex; + Everest::Thread power_supply_thread_handle; + void power_supply_worker(void); + + static constexpr int LOOP_SLEEP_MS{500}; + void clampVoltageCurrent(double& voltage, double& current); + // ev@3370e4dd-95f4-47a9-aaec-ea76f34a66c9:v1 +}; + +// ev@3d7da0ad-02c2-493d-9920-0bbbd56b9876:v1 +// insert other definitions here +// ev@3d7da0ad-02c2-493d-9920-0bbbd56b9876:v1 + +} // namespace main +} // namespace module + +#endif // MAIN_POWER_SUPPLY_DC_IMPL_HPP diff --git a/modules/simulation/DCSupplySimulator/manifest.yaml b/modules/simulation/DCSupplySimulator/manifest.yaml new file mode 100644 index 000000000..7a65540cf --- /dev/null +++ b/modules/simulation/DCSupplySimulator/manifest.yaml @@ -0,0 +1,36 @@ +description: Implementation of a programmable power supply for DC charging +provides: + main: + interface: power_supply_DC + description: Main interface for the power supply + config: + bidirectional: + description: Set to true to for bidirectional supply + type: boolean + default: true + max_power: + description: Max supported power in watt + type: number + default: 150000 + min_voltage: + description: Min supported voltage + type: number + default: 200.0 + max_voltage: + description: Max supported voltage + type: number + default: 900.0 + min_current: + description: Min supported current + type: number + default: 1.0 + max_current: + description: Max supported current + type: number + default: 200.0 +metadata: + license: https://opensource.org/licenses/Apache-2.0 + authors: + - Cornelius Claussen (Pionix GmbH) + - Fabian Hartung (chargebyte GmbH) + - Mohannad Oraby (chargebyte GmbH)