1 | /* |
2 | * File: van_der_pol_osc.c |
3 | * |
4 | * Code generated for Simulink model 'van_der_pol_osc'. |
5 | * |
6 | * Model version : 1.5 |
7 | * Simulink Coder version : 8.10 (R2016a) 10-Feb-2016 |
8 | * C/C++ source code generated on : Sun Jun 05 15:57:58 2016 |
9 | * |
10 | * Target selection: ert.tlc |
11 | * Embedded hardware selection: ARM Compatible->ARM Cortex |
12 | * Code generation objectives: |
13 | * 1. Execution efficiency |
14 | * 2. RAM efficiency |
15 | * Validation result: Not run |
16 | */ |
17 | |
18 | #include "van_der_pol_osc.h" |
19 | #define NumBitsPerChar 8U |
20 | |
21 | /* Private macros used by the generated code to access rtModel */ |
22 | #ifndef rtmIsMajorTimeStep |
23 | # define rtmIsMajorTimeStep(rtm) (((rtm)->Timing.simTimeStep) == MAJOR_TIME_STEP) |
24 | #endif |
25 | |
26 | #ifndef rtmIsMinorTimeStep |
27 | # define rtmIsMinorTimeStep(rtm) (((rtm)->Timing.simTimeStep) == MINOR_TIME_STEP) |
28 | #endif |
29 | |
30 | #ifndef rtmGetTPtr |
31 | # define rtmGetTPtr(rtm) ((rtm)->Timing.t) |
32 | #endif |
33 | |
34 | #ifndef rtmSetTPtr |
35 | # define rtmSetTPtr(rtm, val) ((rtm)->Timing.t = (val)) |
36 | #endif |
37 | |
38 | /* Continuous states */ |
39 | X rtX; |
40 | |
41 | /* Block signals and states (auto storage) */ |
42 | DW rtDW; |
43 | |
44 | /* Real-time model */ |
45 | RT_MODEL rtM_; |
46 | RT_MODEL *const rtM = &rtM_; |
47 | extern real_T rt_powd_snf(real_T u0, real_T u1); |
48 | |
49 | /* private model entry point functions */ |
50 | extern void van_der_pol_osc_derivatives(void); |
51 | extern real_T rtGetInf(void); |
52 | extern real32_T rtGetInfF(void); |
53 | extern real_T rtGetMinusInf(void); |
54 | extern real32_T rtGetMinusInfF(void); |
55 | extern real_T rtGetNaN(void); |
56 | extern real32_T rtGetNaNF(void); |
57 | extern real_T rtInf; |
58 | extern real_T rtMinusInf; |
59 | extern real_T rtNaN; |
60 | extern real32_T rtInfF; |
61 | extern real32_T rtMinusInfF; |
62 | extern real32_T rtNaNF; |
63 | extern void rt_InitInfAndNaN(size_t realSize); |
64 | extern boolean_T rtIsInf(real_T value); |
65 | extern boolean_T rtIsInfF(real32_T value); |
66 | extern boolean_T rtIsNaN(real_T value); |
67 | extern boolean_T rtIsNaNF(real32_T value); |
68 | typedef struct { |
69 | struct { |
70 | uint32_T wordH; |
71 | uint32_T wordL; |
72 | } words; |
73 | } BigEndianIEEEDouble; |
74 | |
75 | typedef struct { |
76 | struct { |
77 | uint32_T wordL; |
78 | uint32_T wordH; |
79 | } words; |
80 | } LittleEndianIEEEDouble; |
81 | |
82 | typedef struct { |
83 | union { |
84 | real32_T wordLreal; |
85 | uint32_T wordLuint; |
86 | } wordL; |
87 | } IEEESingle; |
88 | |
89 | real_T rtInf; |
90 | real_T rtMinusInf; |
91 | real_T rtNaN; |
92 | real32_T rtInfF; |
93 | real32_T rtMinusInfF; |
94 | real32_T rtNaNF; |
95 | |
96 | /* |
97 | * Initialize rtInf needed by the generated code. |
98 | * Inf is initialized as non-signaling. Assumes IEEE. |
99 | */ |
100 | real_T rtGetInf(void) |
101 | { |
102 | size_t bitsPerReal = sizeof(real_T) * (NumBitsPerChar); |
103 | real_T inf = 0.0; |
104 | if (bitsPerReal == 32U) { |
105 | inf = rtGetInfF(); |
106 | } else { |
107 | union { |
108 | LittleEndianIEEEDouble bitVal; |
109 | real_T fltVal; |
110 | } tmpVal; |
111 | |
112 | tmpVal.bitVal.words.wordH = 0x7FF00000U; |
113 | tmpVal.bitVal.words.wordL = 0x00000000U; |
114 | inf = tmpVal.fltVal; |
115 | } |
116 | |
117 | return inf; |
118 | } |
119 | |
120 | /* |
121 | * Initialize rtInfF needed by the generated code. |
122 | * Inf is initialized as non-signaling. Assumes IEEE. |
123 | */ |
124 | real32_T rtGetInfF(void) |
125 | { |
126 | IEEESingle infF; |
127 | infF.wordL.wordLuint = 0x7F800000U; |
128 | return infF.wordL.wordLreal; |
129 | } |
130 | |
131 | /* |
132 | * Initialize rtMinusInf needed by the generated code. |
133 | * Inf is initialized as non-signaling. Assumes IEEE. |
134 | */ |
135 | real_T rtGetMinusInf(void) |
136 | { |
137 | size_t bitsPerReal = sizeof(real_T) * (NumBitsPerChar); |
138 | real_T minf = 0.0; |
139 | if (bitsPerReal == 32U) { |
140 | minf = rtGetMinusInfF(); |
141 | } else { |
142 | union { |
143 | LittleEndianIEEEDouble bitVal; |
144 | real_T fltVal; |
145 | } tmpVal; |
146 | |
147 | tmpVal.bitVal.words.wordH = 0xFFF00000U; |
148 | tmpVal.bitVal.words.wordL = 0x00000000U; |
149 | minf = tmpVal.fltVal; |
150 | } |
151 | |
152 | return minf; |
153 | } |
154 | |
155 | /* |
156 | * Initialize rtMinusInfF needed by the generated code. |
157 | * Inf is initialized as non-signaling. Assumes IEEE. |
158 | */ |
159 | real32_T rtGetMinusInfF(void) |
160 | { |
161 | IEEESingle minfF; |
162 | minfF.wordL.wordLuint = 0xFF800000U; |
163 | return minfF.wordL.wordLreal; |
164 | } |
165 | |
166 | /* |
167 | * Initialize rtNaN needed by the generated code. |
168 | * NaN is initialized as non-signaling. Assumes IEEE. |
169 | */ |
170 | real_T rtGetNaN(void) |
171 | { |
172 | size_t bitsPerReal = sizeof(real_T) * (NumBitsPerChar); |
173 | real_T nan = 0.0; |
174 | if (bitsPerReal == 32U) { |
175 | nan = rtGetNaNF(); |
176 | } else { |
177 | union { |
178 | LittleEndianIEEEDouble bitVal; |
179 | real_T fltVal; |
180 | } tmpVal; |
181 | |
182 | tmpVal.bitVal.words.wordH = 0xFFF80000U; |
183 | tmpVal.bitVal.words.wordL = 0x00000000U; |
184 | nan = tmpVal.fltVal; |
185 | } |
186 | |
187 | return nan; |
188 | } |
189 | |
190 | /* |
191 | * Initialize rtNaNF needed by the generated code. |
192 | * NaN is initialized as non-signaling. Assumes IEEE. |
193 | */ |
194 | real32_T rtGetNaNF(void) |
195 | { |
196 | IEEESingle nanF = { { 0 } }; |
197 | |
198 | nanF.wordL.wordLuint = 0xFFC00000U; |
199 | return nanF.wordL.wordLreal; |
200 | } |
201 | |
202 | /* |
203 | * Initialize the rtInf, rtMinusInf, and rtNaN needed by the |
204 | * generated code. NaN is initialized as non-signaling. Assumes IEEE. |
205 | */ |
206 | void rt_InitInfAndNaN(size_t realSize) |
207 | { |
208 | (void) (realSize); |
209 | rtNaN = rtGetNaN(); |
210 | rtNaNF = rtGetNaNF(); |
211 | rtInf = rtGetInf(); |
212 | rtInfF = rtGetInfF(); |
213 | rtMinusInf = rtGetMinusInf(); |
214 | rtMinusInfF = rtGetMinusInfF(); |
215 | } |
216 | |
217 | /* Test if value is infinite */ |
218 | boolean_T rtIsInf(real_T value) |
219 | { |
220 | return (boolean_T)((value==rtInf || value==rtMinusInf) ? 1U : 0U); |
221 | } |
222 | |
223 | /* Test if single-precision value is infinite */ |
224 | boolean_T rtIsInfF(real32_T value) |
225 | { |
226 | return (boolean_T)(((value)==rtInfF || (value)==rtMinusInfF) ? 1U : 0U); |
227 | } |
228 | |
229 | /* Test if value is not a number */ |
230 | boolean_T rtIsNaN(real_T value) |
231 | { |
232 | return (boolean_T)((value!=value) ? 1U : 0U); |
233 | } |
234 | |
235 | /* Test if single-precision value is not a number */ |
236 | boolean_T rtIsNaNF(real32_T value) |
237 | { |
238 | return (boolean_T)(((value!=value) ? 1U : 0U)); |
239 | } |
240 | |
241 | /* |
242 | * This function updates continuous states using the ODE3 fixed-step |
243 | * solver algorithm |
244 | */ |
245 | static void rt_ertODEUpdateContinuousStates(RTWSolverInfo *si ) |
246 | { |
247 | /* Solver Matrices */ |
248 | static const real_T rt_ODE3_A[3] = { |
249 | 1.0/2.0, 3.0/4.0, 1.0 |
250 | }; |
251 | |
252 | static const real_T rt_ODE3_B[3][3] = { |
253 | { 1.0/2.0, 0.0, 0.0 }, |
254 | |
255 | { 0.0, 3.0/4.0, 0.0 }, |
256 | |
257 | { 2.0/9.0, 1.0/3.0, 4.0/9.0 } |
258 | }; |
259 | |
260 | time_T t = rtsiGetT(si); |
261 | time_T tnew = rtsiGetSolverStopTime(si); |
262 | time_T h = rtsiGetStepSize(si); |
263 | real_T *x = rtsiGetContStates(si); |
264 | ODE3_IntgData *id = (ODE3_IntgData *)rtsiGetSolverData(si); |
265 | real_T *y = id->y; |
266 | real_T *f0 = id->f[0]; |
267 | real_T *f1 = id->f[1]; |
268 | real_T *f2 = id->f[2]; |
269 | real_T hB[3]; |
270 | int_T i; |
271 | int_T nXc = 2; |
272 | rtsiSetSimTimeStep(si,MINOR_TIME_STEP); |
273 | |
274 | /* Save the state values at time t in y, we'll use x as ynew. */ |
275 | (void) memcpy(y, x, |
276 | (uint_T)nXc*sizeof(real_T)); |
277 | |
278 | /* Assumes that rtsiSetT and ModelOutputs are up-to-date */ |
279 | /* f0 = f(t,y) */ |
280 | rtsiSetdX(si, f0); |
281 | van_der_pol_osc_derivatives(); |
282 | |
283 | /* f(:,2) = feval(odefile, t + hA(1), y + f*hB(:,1), args(:)(*)); */ |
284 | hB[0] = h * rt_ODE3_B[0][0]; |
285 | for (i = 0; i < nXc; i++) { |
286 | x[i] = y[i] + (f0[i]*hB[0]); |
287 | } |
288 | |
289 | rtsiSetT(si, t + h*rt_ODE3_A[0]); |
290 | rtsiSetdX(si, f1); |
291 | van_der_pol_osc_step(); |
292 | van_der_pol_osc_derivatives(); |
293 | |
294 | /* f(:,3) = feval(odefile, t + hA(2), y + f*hB(:,2), args(:)(*)); */ |
295 | for (i = 0; i <= 1; i++) { |
296 | hB[i] = h * rt_ODE3_B[1][i]; |
297 | } |
298 | |
299 | for (i = 0; i < nXc; i++) { |
300 | x[i] = y[i] + (f0[i]*hB[0] + f1[i]*hB[1]); |
301 | } |
302 | |
303 | rtsiSetT(si, t + h*rt_ODE3_A[1]); |
304 | rtsiSetdX(si, f2); |
305 | van_der_pol_osc_step(); |
306 | van_der_pol_osc_derivatives(); |
307 | |
308 | /* tnew = t + hA(3); |
309 | ynew = y + f*hB(:,3); */ |
310 | for (i = 0; i <= 2; i++) { |
311 | hB[i] = h * rt_ODE3_B[2][i]; |
312 | } |
313 | |
314 | for (i = 0; i < nXc; i++) { |
315 | x[i] = y[i] + (f0[i]*hB[0] + f1[i]*hB[1] + f2[i]*hB[2]); |
316 | } |
317 | |
318 | rtsiSetT(si, tnew); |
319 | rtsiSetSimTimeStep(si,MAJOR_TIME_STEP); |
320 | } |
321 | |
322 | real_T rt_powd_snf(real_T u0, real_T u1) |
323 | { |
324 | real_T y; |
325 | real_T tmp; |
326 | real_T tmp_0; |
327 | if (rtIsNaN(u0) || rtIsNaN(u1)) { |
328 | y = (rtNaN); |
329 | } else { |
330 | tmp = fabs(u0); |
331 | tmp_0 = fabs(u1); |
332 | if (rtIsInf(u1)) { |
333 | if (tmp == 1.0) { |
334 | y = (rtNaN); |
335 | } else if (tmp > 1.0) { |
336 | if (u1 > 0.0) { |
337 | y = (rtInf); |
338 | } else { |
339 | y = 0.0; |
340 | } |
341 | } else if (u1 > 0.0) { |
342 | y = 0.0; |
343 | } else { |
344 | y = (rtInf); |
345 | } |
346 | } else if (tmp_0 == 0.0) { |
347 | y = 1.0; |
348 | } else if (tmp_0 == 1.0) { |
349 | if (u1 > 0.0) { |
350 | y = u0; |
351 | } else { |
352 | y = 1.0 / u0; |
353 | } |
354 | } else if (u1 == 2.0) { |
355 | y = u0 * u0; |
356 | } else if ((u1 == 0.5) && (u0 >= 0.0)) { |
357 | y = sqrt(u0); |
358 | } else if ((u0 < 0.0) && (u1 > floor(u1))) { |
359 | y = (rtNaN); |
360 | } else { |
361 | y = pow(u0, u1); |
362 | } |
363 | } |
364 | |
365 | return y; |
366 | } |
367 | |
368 | /* Model step function */ |
369 | void van_der_pol_osc_step(void) |
370 | { |
371 | if (rtmIsMajorTimeStep(rtM)) { |
372 | /* set solver stop time */ |
373 | rtsiSetSolverStopTime(&rtM->solverInfo,((rtM->Timing.clockTick0+1)* |
374 | rtM->Timing.stepSize0)); |
375 | } /* end MajorTimeStep */ |
376 | |
377 | /* Update absolute time of base rate at minor time step */ |
378 | if (rtmIsMinorTimeStep(rtM)) { |
379 | rtM->Timing.t[0] = rtsiGetT(&rtM->solverInfo); |
380 | } |
381 | |
382 | /* Integrator: '<Root>/Integrator' */ |
383 | rtDW.Integrator = rtX.Integrator_CSTATE; |
384 | |
385 | /* Sum: '<Root>/Sum' incorporates: |
386 | * Constant: '<Root>/Constant' |
387 | * Constant: '<Root>/Constant1' |
388 | * Gain: '<Root>/Gain' |
389 | * Integrator: '<Root>/Integrator1' |
390 | * Math: '<Root>/Math Function' |
391 | * Product: '<Root>/Product' |
392 | * Sum: '<Root>/Sum1' |
393 | */ |
394 | rtDW.Sum = (1.0 |
395 | - rt_powd_snf(rtX.Integrator1_CSTATE, 2.0)) |
396 | * 5.0 |
397 | * rtDW.Integrator |
398 | - rtX.Integrator1_CSTATE; |
399 | if (rtmIsMajorTimeStep(rtM)) { |
400 | rt_ertODEUpdateContinuousStates(&rtM->solverInfo); |
401 | |
402 | /* Update absolute time for base rate */ |
403 | /* The "clockTick0" counts the number of times the code of this task has |
404 | * been executed. The absolute time is the multiplication of "clockTick0" |
405 | * and "Timing.stepSize0". Size of "clockTick0" ensures timer will not |
406 | * overflow during the application lifespan selected. |
407 | */ |
408 | ++rtM->Timing.clockTick0; |
409 | rtM->Timing.t[0] = rtsiGetSolverStopTime(&rtM->solverInfo); |
410 | |
411 | { |
412 | /* Update absolute timer for sample time: [1.6s, 0.0s] */ |
413 | /* The "clockTick1" counts the number of times the code of this task has |
414 | * been executed. The resolution of this integer timer is 1.6, which is the step size |
415 | * of the task. Size of "clockTick1" ensures timer will not overflow during the |
416 | * application lifespan selected. |
417 | */ |
418 | rtM->Timing.clockTick1++; |
419 | } |
420 | } /* end MajorTimeStep */ |
421 | } |
422 | |
423 | /* Derivatives for root system: '<Root>' */ |
424 | void van_der_pol_osc_derivatives(void) |
425 | { |
426 | XDot *_rtXdot; |
427 | _rtXdot = ((XDot *) rtM->ModelData.derivs); |
428 | |
429 | /* Derivatives for Integrator: '<Root>/Integrator1' */ |
430 | _rtXdot->Integrator1_CSTATE = rtDW.Integrator; |
431 | |
432 | /* Derivatives for Integrator: '<Root>/Integrator' */ |
433 | _rtXdot->Integrator_CSTATE = rtDW.Sum; |
434 | } |
435 | |
436 | /* Model initialize function */ |
437 | void van_der_pol_osc_initialize(void) |
438 | { |
439 | /* Registration code */ |
440 | |
441 | /* initialize non-finites */ |
442 | rt_InitInfAndNaN(sizeof(real_T)); |
443 | |
444 | { |
445 | /* Setup solver object */ |
446 | rtsiSetSimTimeStepPtr(&rtM->solverInfo, &rtM->Timing.simTimeStep); |
447 | rtsiSetTPtr(&rtM->solverInfo, &rtmGetTPtr(rtM)); |
448 | rtsiSetStepSizePtr(&rtM->solverInfo, &rtM->Timing.stepSize0); |
449 | rtsiSetdXPtr(&rtM->solverInfo, &rtM->ModelData.derivs); |
450 | rtsiSetContStatesPtr(&rtM->solverInfo, (real_T **) |
451 | &rtM->ModelData.contStates); |
452 | rtsiSetNumContStatesPtr(&rtM->solverInfo, &rtM->Sizes.numContStates); |
453 | rtsiSetNumPeriodicContStatesPtr(&rtM->solverInfo, |
454 | &rtM->Sizes.numPeriodicContStates); |
455 | rtsiSetPeriodicContStateIndicesPtr(&rtM->solverInfo, |
456 | &rtM->ModelData.periodicContStateIndices); |
457 | rtsiSetPeriodicContStateRangesPtr(&rtM->solverInfo, |
458 | &rtM->ModelData.periodicContStateRanges); |
459 | rtsiSetErrorStatusPtr(&rtM->solverInfo, (&rtmGetErrorStatus(rtM))); |
460 | rtsiSetRTModelPtr(&rtM->solverInfo, rtM); |
461 | } |
462 | |
463 | rtsiSetSimTimeStep(&rtM->solverInfo, MAJOR_TIME_STEP); |
464 | rtM->ModelData.intgData.y = rtM->ModelData.odeY; |
465 | rtM->ModelData.intgData.f[0] = rtM->ModelData.odeF[0]; |
466 | rtM->ModelData.intgData.f[1] = rtM->ModelData.odeF[1]; |
467 | rtM->ModelData.intgData.f[2] = rtM->ModelData.odeF[2]; |
468 | rtM->ModelData.contStates = ((X *) &rtX); |
469 | rtsiSetSolverData(&rtM->solverInfo, (void *)&rtM->ModelData.intgData); |
470 | rtsiSetSolverName(&rtM->solverInfo,"ode3"); |
471 | rtmSetTPtr(rtM, &rtM->Timing.tArray[0]); |
472 | rtM->Timing.stepSize0 = 1.6; |
473 | |
474 | /* InitializeConditions for Integrator: '<Root>/Integrator1' */ |
475 | rtX.Integrator1_CSTATE = 2.0; |
476 | |
477 | /* InitializeConditions for Integrator: '<Root>/Integrator' */ |
478 | rtX.Integrator_CSTATE = 1.0; |
479 | } |
480 | |
481 | /* |
482 | * File trailer for generated code. |
483 | * |
484 | * [EOF] |
485 | */ |
486 | |