Skip to content

Commit

Permalink
DCSupplySimulator: Add C++ simulation module
Browse files Browse the repository at this point in the history
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 <[email protected]>
Co-authored-by: Fabian Hartung <[email protected]>
Co-authored-by: Mohannad Oraby <[email protected]>
Co-authored-by: Moritz Barsnick <[email protected]>

Signed-off-by: Fabian Hartung <[email protected]>
Signed-off-by: Moritz Barsnick <[email protected]>
  • Loading branch information
FaHaGit authored and barsnick committed Jan 24, 2024
1 parent e2077b7 commit 3d619bb
Show file tree
Hide file tree
Showing 7 changed files with 344 additions and 0 deletions.
1 change: 1 addition & 0 deletions modules/simulation/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
ev_add_module(DCSupplySimulator)
ev_add_module(JsCarSimulator)
ev_add_module(JsDCSupplySimulator)
ev_add_module(JsIMDSimulator)
Expand Down
23 changes: 23 additions & 0 deletions modules/simulation/DCSupplySimulator/CMakeLists.txt
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
17 changes: 17 additions & 0 deletions modules/simulation/DCSupplySimulator/DCSupplySimulator.cpp
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
58 changes: 58 additions & 0 deletions modules/simulation/DCSupplySimulator/DCSupplySimulator.hpp
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
123 changes: 123 additions & 0 deletions modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.cpp
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
86 changes: 86 additions & 0 deletions modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp
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;

Check notice on line 25 in modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp#L25

struct member 'Conf::bidirectional' is never used.
double max_power;

Check notice on line 26 in modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp#L26

struct member 'Conf::max_power' is never used.
double min_voltage;

Check notice on line 27 in modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp#L27

struct member 'Conf::min_voltage' is never used.
double max_voltage;

Check notice on line 28 in modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp#L28

struct member 'Conf::max_voltage' is never used.
double min_current;

Check notice on line 29 in modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp#L29

struct member 'Conf::min_current' is never used.
double max_current;

Check notice on line 30 in modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp#L30

struct member 'Conf::max_current' is never used.
};

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

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp#L36

Member variable 'power_supply_DCImpl::settings_connector_export_voltage' is not initialized in the constructor.
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

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp#L63

class member 'power_supply_DCImpl::settings_connector_export_voltage' is never used.
double settings_connector_import_voltage;

Check notice on line 64 in modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp#L64

class member 'power_supply_DCImpl::settings_connector_import_voltage' is never used.
double settings_connector_max_export_current;

Check notice on line 65 in modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp#L65

class member 'power_supply_DCImpl::settings_connector_max_export_current' is never used.
double settings_connector_max_import_current;

Check notice on line 66 in modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp#L66

class member 'power_supply_DCImpl::settings_connector_max_import_current' is never used.
types::power_supply_DC::Mode mode;
double connector_voltage;

Check notice on line 68 in modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp#L68

class member 'power_supply_DCImpl::connector_voltage' is never used.
double connector_current;

Check notice on line 69 in modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp#L69

class member 'power_supply_DCImpl::connector_current' is never used.
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

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

modules/simulation/DCSupplySimulator/main/power_supply_DCImpl.hpp#L74

class member 'power_supply_DCImpl::LOOP_SLEEP_MS' is never used.
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
36 changes: 36 additions & 0 deletions modules/simulation/DCSupplySimulator/manifest.yaml
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)

0 comments on commit 3d619bb

Please sign in to comment.