Skip to content

Commit 987efe5

Browse files
Merge branch 'master' of github.com:INTO-CPS-Association/unifmu
2 parents 1d51f0b + e89220f commit 987efe5

File tree

6 files changed

+105
-53
lines changed

6 files changed

+105
-53
lines changed

assets/csharp/model.cs

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,18 @@
88

99
public class Model
1010
{
11-
public double real_a { get; set; } = 0.0f;
12-
public double real_b { get; set; } = 0.0f;
13-
public double real_c { get; set; } = 0.0f;
14-
public int integer_a { get; set; } = 0;
15-
public int integer_b { get; set; } = 0;
16-
public int integer_c { get; set; } = 0;
17-
public bool boolean_a { get; set; } = false;
18-
public bool boolean_b { get; set; } = false;
19-
public bool boolean_c { get; set; } = false;
20-
public string string_a { get; set; } = "";
21-
public string string_b { get; set; } = "";
22-
public string string_c { get; set; } = "";
11+
public double real_a { get; set; }
12+
public double real_b { get; set; }
13+
public double real_c { get; set; }
14+
public int integer_a { get; set; }
15+
public int integer_b { get; set; }
16+
public int integer_c { get; set; }
17+
public bool boolean_a { get; set; }
18+
public bool boolean_b { get; set; }
19+
public bool boolean_c { get; set; }
20+
public string string_a { get; set; }
21+
public string string_b { get; set; }
22+
public string string_c { get; set; }
2323

2424
private Dictionary<uint, PropertyInfo> reference_to_attributes = new Dictionary<uint, PropertyInfo>();
2525

@@ -42,7 +42,9 @@ public Model()
4242
{ 11, this.GetType().GetProperty("string_c") },
4343
};
4444

45+
Fmi2Reset();
4546
}
47+
4648
public Fmi2Status Fmi2DoStep(double currentTime, double stepSize, bool noStepPrior)
4749
{
4850
UpdateOutputs();
@@ -118,6 +120,16 @@ public Fmi2Status Fmi2CancelStep()
118120

119121
public Fmi2Status Fmi2Reset()
120122
{
123+
this.real_a = 0;
124+
this.real_b = 0;
125+
this.integer_a = 0;
126+
this.integer_b = 0;
127+
this.boolean_a = false;
128+
this.boolean_b = false;
129+
this.string_a = "";
130+
this.string_b = "";
131+
this.UpdateOutputs();
132+
121133
return Fmi2Status.Fmi2Ok;
122134
}
123135

assets/java/src/main/java/Model.java

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,18 @@
99

1010
public class Model {
1111

12-
public Double real_a = 0.0;
13-
public Double real_b = 0.0;
14-
public Double real_c = 0.0;
15-
public Integer integer_a = 0;
16-
public Integer integer_b = 0;
17-
public Integer integer_c = 0;
18-
public Boolean boolean_a = false;
19-
public Boolean boolean_b = false;
20-
public Boolean boolean_c = false;
21-
public String string_a = "";
22-
public String string_b = "";
23-
public String string_c = "";
12+
public Double real_a;
13+
public Double real_b;
14+
public Double real_c;
15+
public Integer integer_a;
16+
public Integer integer_b;
17+
public Integer integer_c;
18+
public Boolean boolean_a;
19+
public Boolean boolean_b;
20+
public Boolean boolean_c;
21+
public String string_a;
22+
public String string_b;
23+
public String string_c;
2424

2525
private ArrayList<Field> references_to_attributes;
2626

@@ -41,6 +41,7 @@ public Model() throws Exception {
4141
this.references_to_attributes.add(this.getClass().getField("string_b"));
4242
this.references_to_attributes.add(this.getClass().getField("string_c"));
4343

44+
fmi2Reset();
4445
}
4546

4647
public Fmi2Status fmi2DoStep(double current_time, double step_size, boolean noStepPrior) {
@@ -105,17 +106,15 @@ public Fmi2Status fmi2SetupExperiment(double start_time, Double stop_time, Doubl
105106

106107
public Fmi2Status fmi2Reset() {
107108
this.real_a = 0.0;
108-
this.real_c = 0.0;
109-
this.integer_a = 0;
110109
this.real_b = 0.0;
110+
this.integer_a = 0;
111111
this.integer_b = 0;
112-
this.integer_c = 0;
113112
this.boolean_a = false;
114113
this.boolean_b = false;
115-
this.boolean_c = false;
116114
this.string_a = "";
117115
this.string_b = "";
118-
this.string_c = "";
116+
update_outputs();
117+
119118
return Fmi2Status.OK;
120119
}
121120

assets/python/fmi2/model.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
class Model:
55
def __init__(self) -> None:
6+
67
self.real_a = 0.0
78
self.real_b = 0.0
89
self.integer_a = 0
@@ -27,7 +28,7 @@ def __init__(self) -> None:
2728
11: "string_c",
2829
}
2930

30-
self._update_outputs()
31+
self.fmi2Reset()
3132

3233
# ================= FMI2 =================
3334

@@ -54,19 +55,33 @@ def fmi2Terminate(self):
5455
return Fmi2Status.ok
5556

5657
def fmi2Reset(self):
58+
self.real_a = 0.0
59+
self.real_b = 0.0
60+
self.integer_a = 0
61+
self.integer_b = 0
62+
self.boolean_a = False
63+
self.boolean_b = False
64+
self.string_a = ""
65+
self.string_b = ""
66+
self._update_outputs()
67+
5768
return Fmi2Status.ok
5869

5970
def fmi2SerializeFmuState(self):
6071
bytes = pickle.dumps(
6172
(
6273
self.real_a,
6374
self.real_b,
75+
self.real_c,
6476
self.integer_a,
6577
self.integer_b,
78+
self.integer_c,
6679
self.boolean_a,
6780
self.boolean_b,
81+
self.boolean_c,
6882
self.string_a,
6983
self.string_b,
84+
self.string_c,
7085
)
7186
)
7287
return Fmi2Status.ok, bytes
@@ -75,22 +90,29 @@ def fmi2DeserializeFmuState(self, bytes):
7590
(
7691
real_a,
7792
real_b,
93+
real_c,
7894
integer_a,
7995
integer_b,
96+
integer_c,
8097
boolean_a,
8198
boolean_b,
99+
boolean_c,
82100
string_a,
83101
string_b,
102+
string_c,
84103
) = pickle.loads(bytes)
85104
self.real_a = real_a
86105
self.real_b = real_b
106+
self.real_c = real_c
87107
self.integer_a = integer_a
88108
self.integer_b = integer_b
109+
self.integer_c = integer_c
89110
self.boolean_a = boolean_a
90111
self.boolean_b = boolean_b
112+
self.boolean_c = boolean_c
91113
self.string_a = string_a
92114
self.string_b = string_b
93-
self._update_outputs()
115+
self.string_c = string_c
94116

95117
return Fmi2Status.ok
96118

cli/tests/common/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -524,11 +524,11 @@ impl BreakableFmu for LocalFmu {
524524

525525
fn do_step_function_line_number(&self) -> u64 {
526526
match self.language() {
527-
FmuBackendImplementationLanguage::CSharp => 48,
527+
FmuBackendImplementationLanguage::CSharp => 50,
528528
FmuBackendImplementationLanguage::Java => 47,
529529
FmuBackendImplementationLanguage::Python => {
530530
match self.version() {
531-
FmiVersion::Fmi2 => 37,
531+
FmiVersion::Fmi2 => 38,
532532
FmiVersion::Fmi3 => 116
533533
}
534534
},

cli/tests/python_tests/fmu_tests.py

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -153,34 +153,35 @@ def inner(fmu, model_description):
153153
assert strings == ["", "", ""], f"Initially fetched values were {strings}, should have been ['', '', '']"
154154

155155
print("Fetching FMU state")
156-
state = fmu.getFMUstate()
156+
initial_state = fmu.getFMUstate()
157157
rerolled_time = sim_time
158158

159159
print(f"Updating inputs at time {sim_time}")
160160
fmu.setReal([vrs["real_a"],vrs["real_b"]],[1.0,2.0])
161161
fmu.setInteger([vrs["integer_a"],vrs["integer_b"]],[1,2])
162162
fmu.setBoolean([vrs["boolean_a"],vrs["boolean_b"]],[True,False])
163163
fmu.setString([vrs["string_a"],vrs["string_b"]],["Hello, ","World!"])
164+
updated_state = fmu.getFMUstate()
164165

165166
print(f"Doing a step of size {step_size} at time {sim_time}")
166-
fmu.doStep(sim_time, step_size) == fmi2OK, f"doStep returned with error , should have been return value: {fmi2OK}"
167+
fmu.doStep(sim_time, step_size) == fmi2OK, f"doStep returned with error, should have been return value: {fmi2OK}"
167168
sim_time += step_size
168169

169-
170170
print("Fetching evolved values")
171-
real_c = fmu.getReal([vrs["real_c"]])[0]
172-
integer_c = fmu.getInteger([vrs["integer_c"]])[0]
173-
boolean_c = fmu.getBoolean([vrs["boolean_c"]])[0]
174-
string_c = fmu.getString([vrs["string_c"]])[0].decode("utf-8")
171+
reals = fmu.getReal([vrs["real_a"], vrs["real_b"],vrs["real_c"]])
172+
integers = fmu.getInteger([vrs["integer_a"], vrs["integer_b"], vrs["integer_c"]])
173+
booleans = fmu.getBoolean([vrs["boolean_a"], vrs["boolean_b"], vrs["boolean_c"]])
174+
strings = fmu.getString([vrs["string_a"], vrs["string_b"], vrs["string_c"]])
175+
strings = [string.decode("utf-8") for string in strings]
175176

176177
print("Asserting evolved values")
177-
assert real_c == 3.0, f"Evolved value real_c was {real_c}, should have been 0.0"
178-
assert integer_c == 3, f"Evolved value integer_c was {integer_c}, should have been 0"
179-
assert boolean_c == True, f"Evolved value boolean_c was {boolean_c}, should have been True"
180-
assert string_c == "Hello, World!", f"Evolved value string_c was '{string_c}', should have been 'Hello, World!'"
178+
assert reals == [1.0, 2.0, 3.0], f"Evolved value real_c was {reals}, should have been [1.0, 2.0, 3.0]"
179+
assert integers == [1, 2, 3], f"Evolved value integer_c was {integers}, should have been [1, 2, 3]"
180+
assert booleans == [True, False, True], f"Evolved value boolean_c was {booleans}, should have been [True, False, True]"
181+
assert strings == ["Hello, ", "World!", "Hello, World!"], f"Evolved value string_c was '{strings}', should have been [Hello, , World!, Hello, World!]"
181182

182183
print("Rerolling FMU state")
183-
fmu.setFMUstate(state)
184+
fmu.setFMUstate(initial_state)
184185
print("Resetting time")
185186
sim_time = rerolled_time
186187

@@ -197,10 +198,11 @@ def inner(fmu, model_description):
197198
assert bools == [False, False, False], f"Rerolled values were {bools}, should have been [False, False, False]"
198199
assert strings == ["", "", ""], f"Rerolled values were {strings}, should have been ['', '', '']"
199200

200-
print("Will doStep and then reset FMU")
201+
print("Testing reset")
202+
fmu.setFMUstate(updated_state)
201203
fmu.doStep(sim_time, step_size) == fmi2OK, f"doStep returned with error, should have been return value: {fmi2OK}"
202204
sim_time += step_size
203-
205+
204206
assert fmu.reset() == fmi2OK, f"reset returned with error, should have been return value: {fmi2OK}"
205207
# setupExperiment and enterInitializationMode has to be called after reset()
206208
assert fmu.setupExperiment(startTime=start_time) == fmi2OK, f"setupExperiment returned with error, should have been return value: {fmi2OK}"
@@ -212,17 +214,17 @@ def inner(fmu, model_description):
212214
integers = fmu.getInteger([vrs["integer_a"], vrs["integer_b"], vrs["integer_c"]])
213215
bools = fmu.getBoolean([vrs["boolean_a"], vrs["boolean_b"], vrs["boolean_c"]])
214216
strings = fmu.getString([vrs["string_a"], vrs["string_b"], vrs["string_c"]])
215-
# We need to decode strings from bytes to utf-8
216217
strings = [string.decode("utf-8") for string in strings]
217218

218219
print("Asserting values after reset")
219-
assert reals == [0.0, 0.0, 0.0], f"Initially fetched values were {reals}, should have been [0.0, 0.0, 0.0]"
220+
assert reals == [0.0, 0.0, 0.0], f"Initially fetched values were {reals}, cshould have been [0.0, 0.0, 0.0]"
220221
assert integers == [0, 0, 0], f"Initially fetched values were {integers}, should have been [0, 0, 0]"
221222
assert bools == [False, False, False], f"Initially fetched values were {bools}, should have been [False, False, False]"
222223
assert strings == ["", "", ""], f"Initially fetched values were {strings}, should have been ['', '', '']"
223224

224-
print(f"Test is done - freeing FMU state")
225-
fmu.freeFMUState(state)
225+
print(f"Test is done - freeing FMU states")
226+
fmu.freeFMUState(initial_state)
227+
fmu.freeFMUState(updated_state)
226228
print("FMU state freed successfully")
227229
print("fmi2_simulate: Test Complete")
228230

fmiapi/src/fmi2.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1377,8 +1377,15 @@ pub extern "C" fn fmi2FreeFMUstate(
13771377

13781378
/// Copies the state of a slave into a buffer provided by the environment
13791379
///
1380-
/// Oddly, the length of the buffer is also provided,
1381-
/// as i would expect the environment to have enquired about the state size by calling fmi2SerializedFMUstateSize.
1380+
/// # Parameters
1381+
/// - `slave`: A reference to the FMU slave instance
1382+
/// - `state`: A reference to the state of the FMU
1383+
/// - `data`: A pointer to the buffer where the state will be copied
1384+
/// - `size`: The size of the buffer
1385+
///
1386+
/// # Returns
1387+
/// - `Fmi2Status::Ok`: If the operation succeeds and the FMU state is successfully serialized and stored.
1388+
/// - `Fmi2Status::Error`: If an error occurs during the serialization or if invalid pointers are provided.
13821389
#[no_mangle]
13831390
/// We assume that the buffer is sufficiently large
13841391
pub extern "C" fn fmi2SerializeFMUstate(
@@ -1452,6 +1459,16 @@ pub unsafe extern "C" fn fmi2DeSerializeFMUstate(
14521459
Fmi2Status::Ok
14531460
}
14541461

1462+
/// Retrieves the size of the serialized state of the FMU
1463+
///
1464+
/// # Parameters
1465+
/// - `slave`: A reference to the FMU slave instance
1466+
/// - `state`: A reference to the state of the FMU
1467+
/// - `size`: A reference to the size of the serialized state
1468+
///
1469+
/// # Returns
1470+
/// - `Fmi2Status::Ok`: If the operation succeeds and the size of the serialized state is successfully retrieved.
1471+
14551472
#[no_mangle]
14561473
pub extern "C" fn fmi2SerializedFMUstateSize(
14571474
slave: &Fmi2Slave,

0 commit comments

Comments
 (0)