Skip to content

Commit cdfdeb2

Browse files
committed
binary updates
1 parent 8374a74 commit cdfdeb2

13 files changed

Lines changed: 243 additions & 12 deletions

ecospy/EcosSimulation.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from .lib import dll, EcosLib
22
from .EcosSimulationStructure import EcosSimulationStructure
3-
from ctypes import c_bool, c_int, c_void_p, c_double, c_char_p, c_size_t, POINTER, Structure, CFUNCTYPE, byref, \
3+
from ctypes import c_bool, c_int, c_void_p, c_double, c_char_p, c_size_t, c_uint8, POINTER, Structure, CFUNCTYPE, byref, \
44
create_string_buffer
55

66

@@ -98,6 +98,10 @@ def __init__(self, step_size: float, ssp_path: str = None, structure: EcosSimula
9898
self._set_string.argtypes = [c_void_p, c_char_p, c_char_p]
9999
self._set_string.restype = c_bool
100100

101+
self._set_binary = dll.ecos_simulation_set_binary
102+
self._set_binary.argtypes = [c_void_p, c_char_p, POINTER(c_uint8), c_size_t]
103+
self._set_binary.restype = c_bool
104+
101105
self._create_listener = dll.ecos_simulation_listener_create
102106
self._create_listener.argtypes = [ListenerConfig]
103107
self._create_listener.restype = c_void_p
@@ -314,6 +318,10 @@ def set_string(self, identifier: str, value: str):
314318
if not self._set_string(self.sim, identifier.encode(), value.encode()):
315319
raise Exception(EcosLib.get_last_error())
316320

321+
def set_binary(self, identifier: str, value: bytes):
322+
if not self._set_binary(self.sim, identifier.encode(), (value_type := (c_uint8 * len(value))(*value)), len(value)):
323+
raise Exception(EcosLib.get_last_error())
324+
317325
def init(self, start_time: int = 0, parameter_set: str = None):
318326
"""
319327
Initialize the simulation with a start time and an optional parameter set.

include/ecos/ecos.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#define LIBECOS_ECOS_H
44

55
#include <cstddef>
6+
#include <cstdint>
67

78
/* Visibility macros */
89
#if defined(_WIN32) || defined(__CYGWIN__)
@@ -65,11 +66,13 @@ LIBECOS_API bool ecos_simulation_get_integer(ecos_simulation_t* sim, const char*
6566
LIBECOS_API bool ecos_simulation_get_real(ecos_simulation_t* sim, const char* identifier, double* value);
6667
LIBECOS_API bool ecos_simulation_get_bool(ecos_simulation_t* sim, const char* identifier, bool* value);
6768
LIBECOS_API bool ecos_simulation_get_string(ecos_simulation_t* sim, const char* identifier, char* value);
69+
LIBECOS_API bool ecos_simulation_get_binary(ecos_simulation_t* sim, const char* identifier, uint8_t* value, size_t* len);
6870

6971
LIBECOS_API bool ecos_simulation_set_integer(ecos_simulation_t* sim, const char* identifier, int value);
7072
LIBECOS_API bool ecos_simulation_set_real(ecos_simulation_t* sim, const char* identifier, double value);
7173
LIBECOS_API bool ecos_simulation_set_bool(ecos_simulation_t* sim, const char* identifier, bool value);
7274
LIBECOS_API bool ecos_simulation_set_string(ecos_simulation_t* sim, const char* identifier, const char* value);
75+
LIBECOS_API bool ecos_simulation_set_binary(ecos_simulation_t* sim, const char* identifier, const uint8_t* value, size_t len);
7376

7477
LIBECOS_API bool ecos_simulation_terminate(ecos_simulation_t* sim);
7578
LIBECOS_API bool ecos_simulation_reset(ecos_simulation_t* sim);
@@ -100,7 +103,7 @@ typedef struct ecos_simulation_listener_config
100103

101104
LIBECOS_API ecos_simulation_listener_t* ecos_simulation_listener_create(ecos_simulation_listener_config config);
102105

103-
//Note: this function transfers ownership of listener to simulation
106+
// Note: this function transfers ownership of listener to simulation
104107
LIBECOS_API void ecos_simulation_add_listener(ecos_simulation_t* sim, const char* name, ecos_simulation_listener_t* listener);
105108
LIBECOS_API void ecos_simulation_remove_listener(ecos_simulation_t* sim, const char* name);
106109

include/ecos/property.hpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,9 @@ class properties
150150
for (auto& p : boolProperties_ | std::views::values) {
151151
p.applySet();
152152
}
153+
for (auto& p : binaryProperties_ | std::views::values) {
154+
p.applySet();
155+
}
153156

154157
for (const auto& l : listeners_) {
155158
l->post_sets();
@@ -190,6 +193,15 @@ class properties
190193
return nullptr;
191194
}
192195

196+
property_t<std::vector<uint8_t>>* get_binary_property(const std::string& name)
197+
{
198+
if (binaryProperties_.contains(name)) {
199+
auto& property = binaryProperties_.at(name);
200+
return &property;
201+
}
202+
return nullptr;
203+
}
204+
193205
property_t<bool>* get_bool_property(const std::string& name)
194206
{
195207
if (boolProperties_.contains(name)) {
@@ -219,6 +231,11 @@ class properties
219231
return stringProperties_;
220232
}
221233

234+
[[nodiscard]] const std::unordered_map<std::string, property_t<std::vector<uint8_t>>>& get_binaries()
235+
{
236+
return binaryProperties_;
237+
}
238+
222239
void add_real_property(property_t<double> p)
223240
{
224241
realProperties_.emplace(p.id().variable_name(), std::move(p));
@@ -234,6 +251,11 @@ class properties
234251
stringProperties_.emplace(p.id().variable_name(), std::move(p));
235252
}
236253

254+
void add_binary_property(property_t<std::vector<uint8_t>> p)
255+
{
256+
binaryProperties_.emplace(p.id().variable_name(), std::move(p));
257+
}
258+
237259
void add_bool_property(property_t<bool> p)
238260
{
239261
boolProperties_.emplace(p.id().variable_name(), std::move(p));
@@ -262,6 +284,9 @@ class properties
262284
std::ranges::transform(stringProperties_, std::back_inserter(names), [](auto& pair) {
263285
return pair.first;
264286
});
287+
std::ranges::transform(binaryProperties_, std::back_inserter(names), [](auto& pair) {
288+
return pair.first;
289+
});
265290
return names;
266291
}
267292

@@ -276,6 +301,7 @@ class properties
276301
std::unordered_map<std::string, property_t<bool>> boolProperties_;
277302
std::unordered_map<std::string, property_t<double>> realProperties_;
278303
std::unordered_map<std::string, property_t<std::string>> stringProperties_;
304+
std::unordered_map<std::string, property_t<std::vector<uint8_t>>> binaryProperties_;
279305
};
280306

281307
} // namespace ecos

include/ecos/simulation.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ class simulation
9292
[[nodiscard]] property_t<double>* get_real_property(const variable_identifier& identifier) const;
9393
[[nodiscard]] property_t<int>* get_int_property(const variable_identifier& identifier) const;
9494
[[nodiscard]] property_t<std::string>* get_string_property(const variable_identifier& identifier) const;
95+
[[nodiscard]] property_t<std::vector<uint8_t>>* get_binary_property(const variable_identifier& identifier) const;
9596
[[nodiscard]] property_t<bool>* get_bool_property(const variable_identifier& identifier) const;
9697

9798
[[nodiscard]] const std::vector<std::unique_ptr<model_instance>>& get_instances() const;

src/ecos/ecos.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,26 @@ bool ecos_simulation_get_string(ecos_simulation_t* sim, const char* identifier,
352352
}
353353
}
354354

355+
bool ecos_simulation_get_binary(ecos_simulation_t* sim, const char* identifier, uint8_t* value, size_t* len)
356+
{
357+
try {
358+
const auto prop = sim->cpp_sim->get_binary_property(identifier);
359+
if (!prop) {
360+
g_last_error_msg = "No string property named" + std::string(identifier) + " found!";
361+
return false;
362+
}
363+
const auto propValue = prop->get_value();
364+
std::memcpy(value, propValue.data(), propValue.size());
365+
*len = propValue.size();
366+
367+
return true;
368+
} catch (...) {
369+
handle_current_exception();
370+
return false;
371+
}
372+
}
373+
374+
355375
bool ecos_simulation_set_integer(ecos_simulation_t* sim, const char* identifier, int value)
356376
{
357377
try {
@@ -416,6 +436,22 @@ bool ecos_simulation_set_string(ecos_simulation_t* sim, const char* identifier,
416436
}
417437
}
418438

439+
bool ecos_simulation_set_binary(ecos_simulation_t* sim, const char* identifier, const uint8_t* value, size_t len)
440+
{
441+
try {
442+
const auto prop = sim->cpp_sim->get_binary_property(identifier);
443+
if (!prop) {
444+
g_last_error_msg = "No binary property " + std::string(identifier) + " found!";
445+
return false;
446+
}
447+
prop->set_value(std::vector(value, value + len));
448+
return true;
449+
} catch (...) {
450+
handle_current_exception();
451+
return false;
452+
}
453+
}
454+
419455

420456
void ecos_simulation_add_listener(ecos_simulation_t* sim, const char* name, ecos_simulation_listener_t* listener)
421457
{

src/ecos/fmi/fmi_model_instance.hpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
#include "fmilibcpp/buffered_slave.hpp"
66

7-
#include "ecos/model_instance.hpp"
87
#include "ecos/logger/logger.hpp"
8+
#include "ecos/model_instance.hpp"
99

1010
namespace ecos
1111
{
@@ -101,6 +101,21 @@ class fmi_model_instance : public model_instance
101101
return bBuf.back();
102102
});
103103
properties_.add_bool_property(std::move(p));
104+
} else if (v.is_binary()) {
105+
auto p = property_t<std::vector<uint8_t>>(
106+
{slave_->instanceName, propertyName},
107+
[&v, this] {
108+
vrBuf[0] = v.vr;
109+
slave_->get_binary(vrBuf, binBuf);
110+
return binBuf.back();
111+
},
112+
[&v, this](auto value) {
113+
vrBuf[0] = v.vr;
114+
binBuf[0] = value;
115+
slave_->set_binary(vrBuf, binBuf);
116+
return binBuf.back();
117+
});
118+
properties_.add_binary_property(std::move(p));
104119
} else {
105120
throw std::runtime_error("Assertion error");
106121
}
@@ -164,6 +179,7 @@ class fmi_model_instance : public model_instance
164179
std::vector<int> iBuf = std::vector<int>(1);
165180
std::vector<bool> bBuf = std::vector<bool>(1);
166181
std::vector<std::string> sBuf = std::vector<std::string>(1);
182+
std::vector<std::vector<uint8_t>> binBuf = std::vector<std::vector<uint8_t>>(1);
167183
std::unique_ptr<fmilibcpp::buffered_slave> slave_;
168184

169185
struct prop_lister : property_listener

src/ecos/simulation.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,17 @@ property_t<std::string>* simulation::get_string_property(const variable_identifi
342342
return nullptr;
343343
}
344344

345+
property_t<std::vector<uint8_t>>* simulation::get_binary_property(const variable_identifier& identifier) const
346+
{
347+
for (const auto& instance : pimpl_->instances_) {
348+
if (instance->instanceName() == identifier.instance_name()) {
349+
auto p = instance->get_properties().get_binary_property(identifier.variable_name());
350+
if (p) return p;
351+
}
352+
}
353+
return nullptr;
354+
}
355+
345356
property_t<bool>* simulation::get_bool_property(const variable_identifier& identifier) const
346357
{
347358
for (const auto& instance : pimpl_->instances_) {

src/fmilibcpp/buffered_slave.hpp

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44

55
#include "slave.hpp"
66

7+
#include <memory>
78
#include <set>
89
#include <unordered_map>
910
#include <utility>
10-
#include <memory>
1111

1212
namespace fmilibcpp
1313
{
@@ -116,6 +116,18 @@ class buffered_slave : public slave
116116
return true;
117117
}
118118

119+
bool get_binary(const std::vector<value_ref>& vrs, std::vector<std::vector<uint8_t>>& values) override
120+
{
121+
for (unsigned i = 0; i < vrs.size(); i++) {
122+
const value_ref vr = vrs[i];
123+
if (std::ranges::find(bytesToFetch_, vr) == bytesToFetch_.end()) {
124+
mark_for_reading(get_model_description().get_by_vr<std::vector<uint8_t>>(vr)->name);
125+
}
126+
values[i] = bytesGetCache_.at(vr);
127+
}
128+
return true;
129+
}
130+
119131
bool set_integer(const std::vector<value_ref>& vrs, const std::vector<int>& values) override
120132
{
121133
for (unsigned i = 0; i < vrs.size(); i++) {
@@ -152,6 +164,15 @@ class buffered_slave : public slave
152164
return true;
153165
}
154166

167+
bool set_binary(const std::vector<value_ref>& vrs, const std::vector<std::vector<uint8_t>>& values) override
168+
{
169+
for (unsigned i = 0; i < vrs.size(); i++) {
170+
const value_ref vr = vrs[i];
171+
bytesSetCache_[vr] = values[i];
172+
}
173+
return true;
174+
}
175+
155176
void transferCachedSets()
156177
{
157178
if (!integerSetCache_.empty()) {
@@ -194,6 +215,16 @@ class buffered_slave : public slave
194215
slave_->set_boolean(vrs, values);
195216
boolSetCache_.clear();
196217
}
218+
if (!bytesSetCache_.empty()) {
219+
std::vector<value_ref> vrs;
220+
std::vector<std::vector<uint8_t>> values;
221+
for (const auto& [vr, value] : bytesSetCache_) {
222+
vrs.emplace_back(vr);
223+
values.emplace_back(value);
224+
}
225+
slave_->set_binary(vrs, values);
226+
bytesSetCache_.clear();
227+
}
197228
}
198229

199230
void receiveCachedGets()
@@ -238,6 +269,16 @@ class buffered_slave : public slave
238269
booleanGetCache_[vr] = __booleanGetCache_[i];
239270
}
240271
}
272+
if (!bytesToFetch_.empty()) {
273+
__bytesGetCache_.resize(bytesToFetch_.size());
274+
slave_->get_binary(bytesToFetch_, __bytesGetCache_);
275+
276+
bytesGetCache_.clear();
277+
for (unsigned i = 0; i < bytesToFetch_.size(); i++) {
278+
const value_ref vr = bytesToFetch_[i];
279+
bytesGetCache_[vr] = __bytesGetCache_[i];
280+
}
281+
}
241282
}
242283

243284
void mark_for_reading(const std::string& variableName)
@@ -260,6 +301,8 @@ class buffered_slave : public slave
260301
stringsToFetch_.emplace_back(vr);
261302
} else if (v->is_boolean()) {
262303
booleansToFetch_.emplace_back(vr);
304+
} else if (v->is_binary()) {
305+
bytesToFetch_.emplace_back(vr);
263306
}
264307

265308
marked_variables.insert(variableName);
@@ -273,6 +316,8 @@ class buffered_slave : public slave
273316
stringGetCache_[vr] = slave_->get_string(vr);
274317
} else if (v->is_boolean()) {
275318
booleanGetCache_[vr] = slave_->get_boolean(vr);
319+
} else if (v->is_binary()) {
320+
bytesGetCache_[vr] = slave_->get_binary(vr);
276321
}
277322
}
278323
}
@@ -289,21 +334,25 @@ class buffered_slave : public slave
289334
std::unordered_map<value_ref, double> realSetCache_;
290335
std::unordered_map<value_ref, std::string> stringSetCache_;
291336
std::unordered_map<value_ref, bool> boolSetCache_;
337+
std::unordered_map<value_ref, std::vector<uint8_t>> bytesSetCache_;
292338

293339
std::unordered_map<value_ref, int> integerGetCache_;
294340
std::unordered_map<value_ref, double> realGetCache_;
295341
std::unordered_map<value_ref, std::string> stringGetCache_;
296342
std::unordered_map<value_ref, bool> booleanGetCache_;
343+
std::unordered_map<value_ref, std::vector<uint8_t>> bytesGetCache_;
297344

298345
std::vector<int> __integerGetCache_;
299346
std::vector<double> __realGetCache_;
300347
std::vector<std::string> __stringGetCache_;
301348
std::vector<bool> __booleanGetCache_;
349+
std::vector<std::vector<uint8_t>> __bytesGetCache_;
302350

303351
std::vector<value_ref> integersToFetch_;
304352
std::vector<value_ref> realsToFetch_;
305353
std::vector<value_ref> stringsToFetch_;
306354
std::vector<value_ref> booleansToFetch_;
355+
std::vector<value_ref> bytesToFetch_;
307356

308357
std::set<std::string> marked_variables;
309358

0 commit comments

Comments
 (0)