@@ -281,7 +281,8 @@ The state is internally handled by C `static` variables, so the generated code i
281281- `simplify`: A function for symbolic simplification. You may try `Sympy.simplify`, but for large systems, this will take a long time to compute.
282282- `cse`: Perform common subexpression elimination. This generally improves the performance of the generated code.
283283"""
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"
285286 (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." ))
286287 P = Sym (G)
287288 P. has (z) || error (" Did not find `z` in symbolic expression" )
@@ -299,16 +300,25 @@ function ccode(G::TransferFunction; simplify = identity, cse = true)
299300 vars = sort (vars, by = string)
300301 var_str = " "
301302 for var in vars
302- var_str *= " , double $(var) "
303+ var_str *= " , $numT $(var) "
303304 end
304305
305306 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
306318 code = """
307319#include <stdio.h>\n
308320#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
312322 int i;
313323 for (i=$(nu- 1 ) ; i > 0; --i) {
314324 u[i] = u[i-1];
@@ -328,7 +338,7 @@ double transfer_function(double ui$(var_str)) {
328338 n = final[1 : length (n)]
329339 d = final[length (n)+ 1 : end ]
330340 for se in subex
331- code *= " double $(se[1 ]) = $(sp. ccode (se[2 ])) ;\n "
341+ code *= " $numT $(se[1 ]) = $(sp. ccode (se[2 ])) ;\n "
332342 end
333343 end
334344 for (i, n) in enumerate (n)
@@ -348,7 +358,8 @@ double transfer_function(double ui$(var_str)) {
348358 code
349359end
350360
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"
352363 nx = sys. nx
353364 nu = sys. nu
354365 ny = sys. ny
@@ -363,7 +374,7 @@ function ccode(sys::StateSpace{<:Discrete}; cse = true, function_name = "transfe
363374 vars = sort (vars, by = string)
364375 var_str = " "
365376 for var in vars
366- var_str *= " , double $(var) "
377+ var_str *= " , $numT $(var) "
367378 end
368379 else
369380 var_str = " "
@@ -374,14 +385,23 @@ function ccode(sys::StateSpace{<:Discrete}; cse = true, function_name = "transfe
374385 y = mul! (y, sys. C, x) + sys. D * u
375386 # @show y = sp.collect.(y, x)
376387
377- u_str = nu == 1 ? " double u" : " double *u"
388+ u_str = nu == 1 ? " $numT u" : " $numT *u"
378389
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
379400 code = """
380401#include <stdio.h>\n
381402#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
385405 int i;
386406"""
387407 if cse
@@ -391,7 +411,7 @@ void $(function_name)(double *y, $(u_str)$(var_str)) {
391411 y = final[][length (x1)+ 1 : end ]
392412 code *= " \n // Common sub expressions. These are all called xi, but are unrelated to the state x\n "
393413 for se in subex
394- code *= " double $(se[1 ]) = $(sp. ccode (se[2 ])) ;\n "
414+ code *= " $numT $(se[1 ]) = $(sp. ccode (se[2 ])) ;\n "
395415 end
396416 end
397417 code *= " \n // Advance the state xp = Ax + Bu\n "
0 commit comments