1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
|
#define fmi2TypesPlatform_h
#define fmi2TypesPlatform "default" /* Compatible */
typedef struct servo_loop_fmi2Component_s* fmi2Component;
typedef void* fmi2ComponentEnvironment; /* Pointer to FMU environment */
typedef void* fmi2FMUstate; /* Pointer to internal FMU state */
typedef unsigned int fmi2ValueReference;
typedef double fmi2Real;
typedef int fmi2Integer;
typedef int fmi2Boolean;
typedef char fmi2Char;
typedef const fmi2Char* fmi2String;
typedef char fmi2Byte;
#define fmi2True 1
#define fmi2False 0
#include "fmi2/fmi2Functions.h"
#include <stdint.h>
#include <stdio.h>
void ModelicaFormatMessage(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vprintf(fmt, args);
va_end(args);
}
typedef struct servo_loop_fmi2Component_s {
fmi2Real currentTime;
fmi2Integer fmi2IntegerVars[3];
fmi2Boolean fmi2BooleanVars[3];
fmi2Real fmi2RealParameter[1];
fmi2Integer fmi2IntegerParameter[1];
fmi2Boolean fmi2BooleanParameter[2];
fmi2String fmi2StringParameter[1];
void* extObjs[4];
} servo_loop_fmi2Component;
servo_loop_fmi2Component servo_loop_component = {
.fmi2IntegerVars = {
0 /*integerExpression1._y*/,
0 /*triggeredAdd1._local_set*/,
0 /*triggeredAdd1._y*/,
},
.fmi2BooleanVars = {
fmi2False /*$whenCondition1*/,
fmi2False /*booleanExpression1._y*/,
fmi2False /*triggeredAdd1._local_reset*/,
},
.fmi2RealParameter = {
0.002 /*synchronizeRealtime1._actualInterval*/,
},
.fmi2IntegerParameter = {
0 /*triggeredAdd1._y_start*/,
},
.fmi2BooleanParameter = {
fmi2False /*triggeredAdd1._use_reset*/,
fmi2False /*triggeredAdd1._use_set*/,
},
};
#include <math.h>
/* TODO: Generate used builtin functions before SimCode */
static inline double om_mod(double x, double y)
{
return x-floor(x/y)*y;
}
#include "MDDAVRTimer.h"
#include "MDDAVRRealTime.h"
#include "MDDAVRAnalog.h"
static inline void Modelica__DeviceDrivers_EmbeddedTargets_AVR_Functions_PWM_set(fmi2Component comp, void* om_pwm, fmi2Integer om_value);
static inline void* Modelica__DeviceDrivers_EmbeddedTargets_AVR_Functions_PWM_Init_constructor(fmi2Component comp, void* om_timer, fmi2Integer om_pin, fmi2Integer om_initialValue, fmi2Boolean om_inverted);
static inline void Modelica__DeviceDrivers_EmbeddedTargets_AVR_Functions_PWM_Init_destructor(fmi2Component comp, void* om_pwm);
static inline void Modelica__DeviceDrivers_EmbeddedTargets_AVR_Functions_RealTimeSynchronization_wait(fmi2Component comp, void* om_rt);
static inline void* Modelica__DeviceDrivers_EmbeddedTargets_AVR_Functions_RealTimeSynchronization_Init_constructor(fmi2Component comp, void* om_timer, fmi2Integer om_timerValue, fmi2Integer om_numTimerInterruptsPerCycle);
static inline void Modelica__DeviceDrivers_EmbeddedTargets_AVR_Functions_RealTimeSynchronization_Init_destructor(fmi2Component comp, void* om_rt);
static inline void* Modelica__DeviceDrivers_EmbeddedTargets_AVR_Functions_Timers_Timer_constructor(fmi2Component comp, fmi2Integer om_timerSelect, fmi2Integer om_clockSelect, fmi2Boolean om_clearTimerOnMatch);
static inline void Modelica__DeviceDrivers_EmbeddedTargets_AVR_Functions_Timers_Timer_destructor(fmi2Component comp, void* om_timer);
static inline void Modelica__DeviceDrivers_EmbeddedTargets_AVR_Functions_PWM_set(fmi2Component comp, void* om_pwm, fmi2Integer om_value)
{
MDD_avr_pwm_set(om_pwm, om_value);
}
static inline void* Modelica__DeviceDrivers_EmbeddedTargets_AVR_Functions_PWM_Init_constructor(fmi2Component comp, void* om_timer, fmi2Integer om_pin, fmi2Integer om_initialValue, fmi2Boolean om_inverted)
{
void* om_pwm;
om_pwm = MDD_avr_pwm_init(om_timer, om_pin, om_initialValue, om_inverted);
return om_pwm;
}
static inline void Modelica__DeviceDrivers_EmbeddedTargets_AVR_Functions_PWM_Init_destructor(fmi2Component comp, void* om_pwm)
{
MDD_avr_pwm_close(om_pwm);
}
static inline void Modelica__DeviceDrivers_EmbeddedTargets_AVR_Functions_RealTimeSynchronization_wait(fmi2Component comp, void* om_rt)
{
MDD_avr_rt_wait(om_rt);
}
static inline void* Modelica__DeviceDrivers_EmbeddedTargets_AVR_Functions_RealTimeSynchronization_Init_constructor(fmi2Component comp, void* om_timer, fmi2Integer om_timerValue, fmi2Integer om_numTimerInterruptsPerCycle)
{
void* om_rt;
om_rt = MDD_avr_rt_init(om_timer, om_timerValue, om_numTimerInterruptsPerCycle);
return om_rt;
}
static inline void Modelica__DeviceDrivers_EmbeddedTargets_AVR_Functions_RealTimeSynchronization_Init_destructor(fmi2Component comp, void* om_rt)
{
MDD_avr_rt_close(om_rt);
}
static inline void* Modelica__DeviceDrivers_EmbeddedTargets_AVR_Functions_Timers_Timer_constructor(fmi2Component comp, fmi2Integer om_timerSelect, fmi2Integer om_clockSelect, fmi2Boolean om_clearTimerOnMatch)
{
void* om_timer;
om_timer = MDD_avr_timer_init(om_timerSelect, om_clockSelect, om_clearTimerOnMatch);
return om_timer;
}
static inline void Modelica__DeviceDrivers_EmbeddedTargets_AVR_Functions_Timers_Timer_destructor(fmi2Component comp, void* om_timer)
{
MDD_avr_timer_close(om_timer);
}
fmi2Component servo_loop_fmi2Instantiate(fmi2String name, fmi2Type ty, fmi2String GUID, fmi2String resources, const fmi2CallbackFunctions* functions, fmi2Boolean visible, fmi2Boolean loggingOn)
{
static int initDone=0;
if (initDone) {
return NULL;
}
return &servo_loop_component;
}
fmi2Status servo_loop_fmi2SetupExperiment(fmi2Component comp, fmi2Boolean toleranceDefined, fmi2Real tolerance, fmi2Real startTime, fmi2Boolean stopTimeDefined, fmi2Real stopTime)
{
return fmi2OK;
}
fmi2Status servo_loop_fmi2EnterInitializationMode(fmi2Component comp)
{
comp->extObjs[0] /* pwm._clock EXTOBJ: Modelica_DeviceDrivers.EmbeddedTargets.AVR.Functions.Timers.Timer */ = Modelica__DeviceDrivers_EmbeddedTargets_AVR_Functions_Timers_Timer_constructor(comp, 2, 7, fmi2True);
comp->extObjs[1] /* pwm._pwm[1] EXTOBJ: Modelica_DeviceDrivers.EmbeddedTargets.AVR.Functions.PWM.Init */ = Modelica__DeviceDrivers_EmbeddedTargets_AVR_Functions_PWM_Init_constructor(comp, comp->extObjs[0] /* pwm._clock EXTOBJ: Modelica_DeviceDrivers.EmbeddedTargets.AVR.Functions.Timers.Timer */, 1, 0, fmi2False);
comp->extObjs[2] /* synchronizeRealtime1._clock EXTOBJ: Modelica_DeviceDrivers.EmbeddedTargets.AVR.Functions.Timers.Timer */ = Modelica__DeviceDrivers_EmbeddedTargets_AVR_Functions_Timers_Timer_constructor(comp, 1, 4, fmi2False);
comp->extObjs[3] /* synchronizeRealtime1._sync EXTOBJ: Modelica_DeviceDrivers.EmbeddedTargets.AVR.Functions.RealTimeSynchronization.Init */ = Modelica__DeviceDrivers_EmbeddedTargets_AVR_Functions_RealTimeSynchronization_Init_constructor(comp, comp->extObjs[2] /* synchronizeRealtime1._clock EXTOBJ: Modelica_DeviceDrivers.EmbeddedTargets.AVR.Functions.Timers.Timer */, 249, 2);
return fmi2OK;
}
fmi2Status servo_loop_fmi2ExitInitializationMode(fmi2Component comp)
{
return fmi2OK;
}
static fmi2Status servo_loop_functionODE(fmi2Component comp)
{
}
static fmi2Status servo_loop_functionOutputs(fmi2Component comp)
{
comp->fmi2BooleanVars[0] /* $whenCondition1 DISCRETE */ = (om_mod(comp->currentTime,0.2))>(0.1); /* equation 9 */
#error "[CodegenEmbeddedC.tpl:346:14-346:14] Unsupported equation: ..."
comp->fmi2BooleanVars[1] /* booleanExpression1._y DISCRETE */ = comp->fmi2BooleanVars[0] /* $whenCondition1 DISCRETE */; /* equation 11 */Modelica__DeviceDrivers_EmbeddedTargets_AVR_Functions_RealTimeSynchronization_wait(comp, comp->extObjs[3] /* synchronizeRealtime1._sync EXTOBJ: Modelica_DeviceDrivers.EmbeddedTargets.AVR.Functions.RealTimeSynchronization.Init */);Modelica__DeviceDrivers_EmbeddedTargets_AVR_Functions_PWM_set(comp, comp->extObjs[1] /* pwm._pwm[1] EXTOBJ: Modelica_DeviceDrivers.EmbeddedTargets.AVR.Functions.PWM.Init */, comp->fmi2IntegerVars[2] /* triggeredAdd1._y DISCRETE */);
}
fmi2Status servo_loop_fmi2DoStep(fmi2Component comp, fmi2Real currentCommunicationPoint, fmi2Real communicationStepSize, fmi2Boolean noSetFMUStatePriorToCurrentPoint)
{
comp->currentTime = currentCommunicationPoint;
/* TODO: Calculate time/state-dependent variables here... */
servo_loop_functionOutputs(comp);
return fmi2OK;
}
int main(int argc, char **argv)
{
int terminateSimulation = 0;
fmi2Status status = fmi2OK;
fmi2CallbackFunctions cbf = {
.logger = NULL,
.allocateMemory = NULL /*calloc*/,
.freeMemory = NULL /*free*/,
.stepFinished = NULL, //synchronous execution
.componentEnvironment = NULL
};
fmi2Component comp = servo_loop_fmi2Instantiate("", fmi2CoSimulation, "", "", &cbf, fmi2False, fmi2False);
if (comp==NULL) {
return 1;
}
servo_loop_fmi2SetupExperiment(comp, fmi2False, 0.0, 0.0, fmi2False, 1.0);
servo_loop_fmi2EnterInitializationMode(comp);
// Set start-values? Nah...
servo_loop_fmi2ExitInitializationMode(comp);
double currentTime = 0.0;
double h = 0.002;
uint32_t i = 0;
while (status == fmi2OK) {
//retrieve outputs
// fmi2GetReal(m, ..., 1, &y1);
//set inputs
// fmi2SetReal(m, ..., 1, &y2);
//call slave and check status
status = servo_loop_fmi2DoStep(comp, currentTime, h, fmi2True);
switch (status) {
case fmi2Discard:
case fmi2Error:
case fmi2Fatal:
case fmi2Pending /* Cannot happen */:
terminateSimulation = 1;
break;
case fmi2OK:
case fmi2Warning:
break;
}
if (terminateSimulation) {
break;
}
i++;
/* increment master time */
currentTime = 0.0 + h*i;
}
#if 0
if ((status != fmi2Error) && (status != fmi2Fatal)) {
fmi2Terminate(m);
}
if (status != fmi2Fatal) {
fmi2FreeInstance(m);
}
#endif
}
|