10

I'm trying to use Yampa for some basic system simulation like I'd do in Simulink. In this case I want to simulate a spring and damper system, introduced by this simulink tutorial. I've written the following signal functions to represent the system:

system = time >>> force >>> displacement

force = constant (m * g)

displacement = feedback (-) (velocity >>> integral) (gain $ k / m) 0
velocity     = feedback (-) integral                (gain $ c / m) 0

Where the feedback function creates a basic feedback loop and is implemented like this:

feedback op a b b0 = loopPre b0 inner
    where inner = arr (uncurry op) >>> a >>> (identity &&& b)

Oh, and:

gain x = arr (*x)

With sensible positive constants, I get a wildly unstable system:

plot of displacement/time

Is there something obviously wrong in the way I'm constructing feedback loops or applying the integration?

Daniel Buckmaster
  • 7,108
  • 6
  • 39
  • 57

1 Answers1

7

Change integral to imIntegral 0

displacement = feedback (-) (velocity >>> imIntegral 0) (gain $ k / m) 0
velocity     = feedback (-) (imIntegral 0)            (gain $ c / m) 0

From spring.hs:

Yampa

Using Simulink:

Simulink

Something funny is happening in the integral function, changing to imIntegral 0 gives the same curve as in matlab.

My guess is that Integral is delayed by one sample, since it doesn't have a starting value, changing the behaviour of the loop.

MdxBhmt
  • 1,310
  • 8
  • 16
  • Excellent, thanks heaps for that! I had done some simple tests with `integral` so I didn't think that was an issue. By 'the scale is off', do you mean the horizontal axis? My code doesn't plot time, just the # of each data point. – Daniel Buckmaster Oct 20 '13 at 21:39
  • darn, nevermind about that, when I was comparing matlab and simulink I had something off that made the diference in the y scale. – MdxBhmt Oct 20 '13 at 21:59
  • 1
    Adding a transport delay in simulink makes the system unstable similarly to the one you've found, so that's must be it. – MdxBhmt Oct 20 '13 at 22:22
  • 1
    Oh, of course. Try simulating a system that's just `time >>> integral >>> integral`. The first couple of samples are 0 while the integrators warm up. I had no idea that small delay would be enough to destroy the system stability. – Daniel Buckmaster Oct 20 '13 at 23:11
  • 1
    It is! Since you are adding a transport delay in the feedback loop, you add a lot of phase in your system, which is similar to throwing the poles around. edit: yeah, just simulated that code, it shows a 2 samples delay, one for each integrator. – MdxBhmt Oct 21 '13 at 02:51