-
Notifications
You must be signed in to change notification settings - Fork 79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DCSupplySimulator: Add C++ simulation module #499
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <generated/interfaces/power_supply_DC/Implementation.hpp> | ||
|
||
// 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<power_supply_DCImplBase> p_main, Conf& config) : | ||
ModuleBase(info), p_main(std::move(p_main)), config(config){}; | ||
|
||
const std::unique_ptr<power_supply_DCImplBase> 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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// Copyright (C) 2023 chargebyte GmbH | ||
// Copyright (C) 2023 Contributors to EVerest | ||
|
||
#include <chrono> | ||
#include <mutex> | ||
|
||
#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<float>(this->config.max_voltage), | ||
.min_export_voltage_V = static_cast<float>(this->config.min_voltage), | ||
.max_export_current_A = static_cast<float>(this->config.max_current), | ||
.min_export_current_A = static_cast<float>(this->config.min_current), | ||
.max_export_power_W = static_cast<float>(this->config.max_power), | ||
.max_import_voltage_V = static_cast<float>(this->config.max_voltage), | ||
.min_import_voltage_V = static_cast<float>(this->config.min_voltage), | ||
.max_import_current_A = static_cast<float>(this->config.max_current), | ||
.min_import_current_A = static_cast<float>(this->config.min_current), | ||
.max_import_power_W = static_cast<float>(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<float>(this->connector_voltage); | ||
voltage_current.current_A = static_cast<float>(this->connector_current); | ||
|
||
this->mod->p_main->publish_voltage_current(voltage_current); | ||
} | ||
} | ||
} // namespace main | ||
} // namespace module |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <generated/interfaces/power_supply_DC/Implementation.hpp> | ||
|
||
#include "../DCSupplySimulator.hpp" | ||
|
||
// ev@75ac1216-19eb-4182-a85c-820f1fc2c091:v1 | ||
// insert your custom include headers here | ||
#include <mutex> | ||
#include <utils/thread.hpp> | ||
// 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<DCSupplySimulator>& mod, Conf& config) : | ||
Check warning on line 36 in modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp Codacy Production / Codacy Static Code Analysismodules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp#L36
|
||
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<DCSupplySimulator>& 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; | ||
Check notice on line 63 in modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp Codacy Production / Codacy Static Code Analysismodules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp#L63
|
||
double settings_connector_import_voltage; | ||
Check notice on line 64 in modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp Codacy Production / Codacy Static Code Analysismodules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp#L64
|
||
double settings_connector_max_export_current; | ||
Check notice on line 65 in modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp Codacy Production / Codacy Static Code Analysismodules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp#L65
|
||
double settings_connector_max_import_current; | ||
Check notice on line 66 in modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp Codacy Production / Codacy Static Code Analysismodules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp#L66
|
||
types::power_supply_DC::Mode mode; | ||
double connector_voltage; | ||
Check notice on line 68 in modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp Codacy Production / Codacy Static Code Analysismodules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp#L68
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As far as I can see connector_voltage and connector_current are used in the worker thread without locking the mutex. Also the set mode command handler does not use the mutex. Please review all access and add locks or use std::atomic here if it is ok that voltage/current do not both need to be locked at the same time. |
||
double connector_current; | ||
Check notice on line 69 in modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp Codacy Production / Codacy Static Code Analysismodules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp#L69
|
||
std::mutex power_supply_values_mutex; | ||
Everest::Thread power_supply_thread_handle; | ||
void power_supply_worker(void); | ||
|
||
static constexpr int LOOP_SLEEP_MS{500}; | ||
Check notice on line 74 in modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp Codacy Production / Codacy Static Code Analysismodules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp#L74
|
||
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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could remove JsDCSupplySimulator probably with this PR and update the configs in core to use the C++ version
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not yet, as the car sides of the SIL configs use JsDCSupplySimulator's
powermeter
interface implementation. That is not covered in this PR. (Should it be?)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah right, not neccesarily now, but I'd like to drop the JS module at some point