@@ -281,7 +281,8 @@ The state is internally handled by C `static` variables, so the generated code i
281
281
- `simplify`: A function for symbolic simplification. You may try `Sympy.simplify`, but for large systems, this will take a long time to compute.
282
282
- `cse`: Perform common subexpression elimination. This generally improves the performance of the generated code.
283
283
"""
284
- function ccode (G:: TransferFunction ; simplify = identity, cse = true )
284
+ function ccode (G:: TransferFunction ; simplify = identity, cse = true , static= true , double= true )
285
+ numT = double ? " double" : " float"
285
286
(G. nu == 1 && G. ny == 1 ) || throw (ArgumentError (" C-code generation for transfer functions does not support multiple inputs or outputs, convert the transfer function to a statespace system using ss(G) and call ccode on that instead." ))
286
287
P = Sym (G)
287
288
P. has (z) || error (" Did not find `z` in symbolic expression" )
@@ -299,16 +300,25 @@ function ccode(G::TransferFunction; simplify = identity, cse = true)
299
300
vars = sort (vars, by = string)
300
301
var_str = " "
301
302
for var in vars
302
- var_str *= " , double $(var) "
303
+ var_str *= " , $numT $(var) "
303
304
end
304
305
305
306
nu, ny = length (n), length (d)
307
+ decl = if static
308
+ """
309
+ $numT transfer_function($numT ui$(var_str) ) {
310
+ static $numT u[$(nu) ] = {0};
311
+ static $numT y[$(ny) ] = {0};
312
+ """
313
+ else
314
+ """
315
+ $numT transfer_function($numT *u, $numT *y, $numT ui$(var_str) ) {
316
+ """
317
+ end
306
318
code = """
307
319
#include <stdio.h>\n
308
320
#include <math.h>\n
309
- double transfer_function(double ui$(var_str) ) {
310
- static double u[$(nu) ] = {0};
311
- static double y[$(ny) ] = {0};
321
+ $decl
312
322
int i;
313
323
for (i=$(nu- 1 ) ; i > 0; --i) {
314
324
u[i] = u[i-1];
@@ -328,7 +338,7 @@ double transfer_function(double ui$(var_str)) {
328
338
n = final[1 : length (n)]
329
339
d = final[length (n)+ 1 : end ]
330
340
for se in subex
331
- code *= " double $(se[1 ]) = $(sp. ccode (se[2 ])) ;\n "
341
+ code *= " $numT $(se[1 ]) = $(sp. ccode (se[2 ])) ;\n "
332
342
end
333
343
end
334
344
for (i, n) in enumerate (n)
@@ -348,7 +358,8 @@ double transfer_function(double ui$(var_str)) {
348
358
code
349
359
end
350
360
351
- function ccode (sys:: StateSpace{<:Discrete} ; cse = true , function_name = " transfer_function" )
361
+ function ccode (sys:: StateSpace{<:Discrete} ; cse = true , function_name = " transfer_function" , static= true , double= true )
362
+ numT = double ? " double" : " float"
352
363
nx = sys. nx
353
364
nu = sys. nu
354
365
ny = sys. ny
@@ -363,7 +374,7 @@ function ccode(sys::StateSpace{<:Discrete}; cse = true, function_name = "transfe
363
374
vars = sort (vars, by = string)
364
375
var_str = " "
365
376
for var in vars
366
- var_str *= " , double $(var) "
377
+ var_str *= " , $numT $(var) "
367
378
end
368
379
else
369
380
var_str = " "
@@ -374,14 +385,23 @@ function ccode(sys::StateSpace{<:Discrete}; cse = true, function_name = "transfe
374
385
y = mul! (y, sys. C, x) + sys. D * u
375
386
# @show y = sp.collect.(y, x)
376
387
377
- u_str = nu == 1 ? " double u" : " double *u"
388
+ u_str = nu == 1 ? " $numT u" : " $numT *u"
378
389
390
+ decl = if static
391
+ """
392
+ void $(function_name) ($numT *y, $(u_str)$(var_str) ) {
393
+ static $numT x[$(nx) ] = {0}; // Current state
394
+ """
395
+ else
396
+ """
397
+ void $(function_name) ($numT *x, $numT *y, $(u_str)$(var_str) ) {
398
+ """
399
+ end
379
400
code = """
380
401
#include <stdio.h>\n
381
402
#include <math.h>\n
382
- void $(function_name) (double *y, $(u_str)$(var_str) ) {
383
- static double x[$(nx) ] = {0}; // Current state
384
- double xp[$(nx) ] = {0}; // Next state
403
+ $decl
404
+ $numT xp[$(nx) ] = {0}; // Next state
385
405
int i;
386
406
"""
387
407
if cse
@@ -391,7 +411,7 @@ void $(function_name)(double *y, $(u_str)$(var_str)) {
391
411
y = final[][length (x1)+ 1 : end ]
392
412
code *= " \n // Common sub expressions. These are all called xi, but are unrelated to the state x\n "
393
413
for se in subex
394
- code *= " double $(se[1 ]) = $(sp. ccode (se[2 ])) ;\n "
414
+ code *= " $numT $(se[1 ]) = $(sp. ccode (se[2 ])) ;\n "
395
415
end
396
416
end
397
417
code *= " \n // Advance the state xp = Ax + Bu\n "
0 commit comments