2
$\begingroup$

I'm implementing a program in Java that was delivered in Simulink. My expertise is limited, and I'm stuck on converting a derivative block.

The simulink code applies a du/dt block to the input data. I'm doing the following in my code:

du_dt = (signal[i] - signal[i-1])/time[i]; 

where signal is an array of data samples, and time is an array of elapsed time (in seconds) between sample i and sample i-1.

my java program is generating much larger derivative values than my simulink program. doing some digging, i see that the simulink man8al talks about the derivative definition as

$ y(k)=\frac{1}{\Delta t}(u(k)-u(k-1)) $

and taking the z-transform

$ \frac{Y(z)}{u(z)}=\frac{1-z^{-1}}{\Delta t}=\frac{z-1}{\Delta t\cdot z} $

my undergrad in mathematics stops short of being able to understand what the z-transform is and how to translate it into code. any help?

EDIT

Here's a link to the simulink manual page describing this: http://www.mathworks.com/help/toolbox/simulink/slref/derivative.html

EDIT 2

As requested, here's the data of the Simulink output and mine:

0.0, 0.0 1211.4359554191567, 692.2491173823755 573.0790390610672, 859.6185585916019 346.12455869118764, 461.4994115882501 807.6239702794378, 634.5616909338439 230.74970579412505, 692.2491173823755 286.53951953053365, 401.1553273427467 519.1868380367816, 634.5616909338443 -288.43713224265656, 403.8119851397189 -57.307903906106624, 343.8474234366401 -173.06227934559388, 57.68742644853153  0   0 1.01133071339275    1.01133071339275 -1.38227619434410   -1.38227619434408 -1.43825420168704   -1.43825420168706 -0.640385232441365  -0.640385232441365 -0.157483736804270  -0.157483736804270 -1.01133071339275   -1.01133071339275 -2.92203612549265   -1.96668341944271 -3.77588310208105   1.68679338272849 -2.98846441805972   1.44870448691124 -2.96756384761120   -0.629934947217123 

The first section is mine, the second is the simulink. The indices are aligned, the data is two-dimensional but the derivative is of each individual dimension (so it's like two separate data sets)

  • 0
    Even more disturbing than the magnitude variance is that the signs of the two derivatives are different.2012-04-02

2 Answers 2

2

Regarding your question about implementing the z transform in code: The z transform is a one time frame advance in the sample series. The 1/z transform is a one time frame delay in the sample series. So you can see directly that your java code implements ${1 - z^{-1}\over \Delta t} = {z-1\over z \Delta t}$. The ${1\over z}$ transform is easy to implement in computer code. Just retain the signal value from the prior time frame. The only problem is in deciding how to initialize the prior frame value for the first call. On the first frame, it is normally best to initialize first-frame prior values as though the signal has been steady. That avoids initial transients that may take a long time to die out. So your Java code would start with signal[0] = signal[1]; More complicated Tustin transformations that use z would require solving for the correct signal prior values that the first frame should use for a steady state initialization.

1

The simple command

du_dt = (signal[i] - signal[i-1])/time[i];

is a correct translation of time derivative. One should be aware, though, that this approach greatly amplifies noise. Several noise-robust differentiators are described by Pavel Holoborodko.

Looking at the output of Java, I conclude that the input was not the same in both columns. Yet, the simulink output is the same in both columns most of the time. This suggests that two programs do not really do the same thing. There is not enough information to find exactly what the second one is doing.

But there is something notable in rows 5-6 of java output:

807.6239702794378, 634.5616909338439 230.74970579412505, 692.2491173823755 

Namely,

807.6239702794378 - 230.74970579412505 = 576.87426448531275 634.5616909338439 - 692.2491173823755 = -57.6874264485316 

There may be some sign and order-of-magnitude issues here.