0

I am trying to follow this tutorial, implemented

function transfer_function = tf(numerator, denominator)
    transfer_function = syslin('c', poly(numerator, "s", "coeff") / poly(denominator, "s", "coeff"));
endfunction

// physical constants:

R = 2.0;                // Ohms
L = 0.5;                // Henrys
Km = 0.1;               // torque constant
Kb = 0.1;               // back emf constant
Kf = 0.2;               // Nms
J = 0.02;               // kg.m^2/s^2

// state-space model:

h1 = tf(Km, [L R]);            // armature
h2 = tf(1, [J Kf]);            // eqn of motion

dcm = tf2ss(h2) * [h1, 1];       // w = h2 * (h1 * Va + Td)

that returns

--> dcm
 dcm  = 


 dcm(1)  (state-space system:)

  "lss"  "A"  "B"  "C"  "D"  "X0"  "dt"

 dcm(2)= A matrix =

  -0.1   0.5 
   0.   -0.25

 dcm(3)= B matrix =

   0.          2.236068
   0.2236068   0.      

 dcm(4)= C matrix =

   2.236068   0.

 dcm(5)= D matrix =

   0.   0.

 dcm(6)= X0 (initial state) =

   0.
   0.

 dcm(7)= Time domain =

  "c"

which is different from what MATLAB yields:

>> dcm

dcm =
 
  A = 
        x1   x2
   x1  -10  3.2
   x2    0   -4
 
  B = 
        u1   u2
   x1    0    8
   x2  0.5    0
 
  C = 
         x1    x2
   y1  6.25     0
 
  D = 
       u1  u2
   y1   0   0
 
Continuous-time state-space model.

now my questions are:

  • Did I implement the minimal tf() function correctly, or there is a more complete/canonical version available/possible?
  • Is the tf2ss() the equivalent of MATLAB's ss() or there is another built-in function available?
  • If there is no ss() equivalent available, what is a minimal implementation that delivers the identical results as the above MATLAB tutorial?
Foad S. Farimani
  • 12,396
  • 15
  • 78
  • 193

1 Answers1

0

My implementation of the tf() function, was flawed. Using

function transfer_function = tf(numerator, denominator)
    transfer_function = syslin('c', poly(numerator($:-1:1), "s", "coeff") / poly(denominator($:-1:1), "s", "coeff"));
endfunction

now I get

--> dcm
 dcm  = 


 dcm(1)  (state-space system:)

  "lss"  "A"  "B"  "C"  "D"  "X0"  "dt"

 dcm(2)= A matrix =

  -10.   3.1622777
   0.   -4.       

 dcm(3)= B matrix =

   0.          7.0710678
   0.4472136   0.       

 dcm(4)= C matrix =

   7.0710678   0.

 dcm(5)= D matrix =

   0.   0.

 dcm(6)= X0 (initial state) =

   0.
   0.

 dcm(7)= Time domain =

  "c"

which is pretty close, but not quite right!

Foad S. Farimani
  • 12,396
  • 15
  • 78
  • 193
  • 1
    The state-space minimal representation of a given transfer function is not unique, hence, wanting the same results as Matlab is useless. However, it seems that Matlab uses only multiplication by powers of 2 when normalizing B,C,D – Stéphane Mottelet Feb 15 '22 at 07:29
  • @StéphaneMottelet so the Scilab solution above is more accurate? – Foad S. Farimani Feb 15 '22 at 07:39
  • 1
    No, the converse, as multiplication or division by 2 keeps the floating point precision. – Stéphane Mottelet Feb 15 '22 at 07:46
  • @StéphaneMottelet If MATLAB's results are more accurate then, how can I improve the above `tf()` function? I was also wondering if there is anything equivalent, already built into Scilab? – Foad S. Farimani Feb 15 '22 at 07:50
  • 1
    tf2ss(f) with f a rational (quotient of polynomials) or tf2ss(s) with s = syslin('c',f) should yield the same result, but this is not the case, although both results give different but equivalent (in an input-output sense) state-space representation. I don't think Matlab's result is that more accurate. Just different, but still correct, as Scilab ones. – Stéphane Mottelet Feb 15 '22 at 14:07