Controller design

Hi,

so I have the step response of a system. I measured the output when on the input there was a step.

Plotting the curve I found it might be approximated by a transfer function like this:

P(s) = kh * 1 / (1 + s*tau)

In other words, the plant is a first-order system, the time constant is about 0.5 s.

The first question is: how to find kh?

The signal I acquired is the output of the 12 bit ADC (sampling time of

5 ms) and of course it is amplified by the front-end op-amps. If I draw both the signal acquired and the calculated step response of the above t.f. I get kh = 600 to make equal the two curves. But the calculated step response use a unit step: in my system the 'unit' I used is the maximum power delivered by the motors... I'm wondering how to determine the value of this constant.

Once determined I want to design my controller. I don't ask for the right one, rather if in this case I can follow what Tim Wescott wrote in his great book ("Applied Control Theory for Embedded Systems").

Given the continuous step response in 's' domain -> transform it in the time domain -> sample (@ 5 ms, the ADC sampling time) and convert to 'z' domain -> P(z) is found dividing by z/(z-1). Can I?

Now I should be able to design the controller in the 'z' domain because I provide it the plant "as seen" from the digital circuits.

The last question is scilab related. Written the plant transfer function in 'z' domain (P) and the controller one (C), the system is composed of the controller cascaded by the plant and a unit feedback line. How to implement this in scilab without found by hand the closed-loop transfer function? I ask this because I'd like to change the controller t.f. on-the-fly to see the overall step response.

Thanks in advance, Marco / iw2nzm

Reply to
Marco Trapanese
Loading thread data ...

kh is your scaling factor in transforming your input vector X(s) into your output vector Y(s) in the equation Y(s) = P(s) * X(s). Very often, it's just a simple multiplication constant.

Reply to
linnix

Take your input, complete with units (DAC counts? Volts?) and your output, complete with units (ADC counts, I bet), and divide them. You should get something like 600 inches/volt, or 600 RPM/volt, or 600 (input counts)/(output counts), etc.

If P(z) is your z-domain translation of P(s), then your transfer function can be found with

z - 1 H(z) = P(z) ----- z

I think this is what you mean...

Yes, as long as you keep in mind that your step response measurement may have inaccuracies

Usually I write a scilab function to calculate the closed-loop transfer function, and use that.

--
Tim Wescott
Control systems and communications consulting
http://www.wescottdesign.com

Need to learn how to apply control theory in your embedded system?
"Applied Control Theory for Embedded Systems" by Tim Wescott
Elsevier/Newnes, http://www.wescottdesign.com/actfes/actfes.html
Reply to
Tim Wescott

Well, of course the input and output are DAC and ADC counts (the former @ 8 bit the latter @ 12 bit). However, the actual units should be °/s (angular velocity). For example if I take an input of 255 the ADC will read 3800 (2048 is the relative zero) so the output will be 3800-2048 = 1752. If I divide them I get 0.145... But does it have sense? May I compare two values on different scales (8 bit DAC and 12 bit ADC) ?

I'm sorry but I'm still confused about this :(

Yes.

Yes I know. But for my application I guess I can have some inaccuracies without a lot of problems.

Are you saying to write the transfer function of both controller and plant as polynomials (i.e. C = 1 / (z - 1) ) calulate the closed-loop t.f. (i.e. H = C*P / (1 + C*P) ) and finally create the system through syslin?

Thank you Tim for taking the time to answer, Marco / iw2nzm

Reply to
Marco Trapanese

It can, indeed, be confusing -- even to the experienced.

Your 0.145 ADC count/DAC count does, indeed make sense. You'd have to rescale it if you changed to a 12-count DAC, but as you've stated it it makes sense.

It also makes sense to find the constant after the DAC and before the ADC

-- in this case I think it's degrees/sec/volt, although you haven't mentioned volts so I can't be sure.

If you have the luxury of using floating point you can convert your ADC reading to degrees/second, compute a "voltage" from your controller and convert that to DAC counts as you write to the DAC. Usually one doesn't want to be so extravagant in one's choice of processor, so usually floating point is too dang slow. If it isn't, you can leverage it to make the code much easier to understand.

Scilab treats ratios of polynomials as transfer functions automatically, and builds the variables 's' and 'z' into the system automatically too. So to make a z domain transfer function you just need to write

C = 1 / (%z - 1); C.dt = (your sampling interval);

Note that it even keeps track of your sampling interval, which is cool. You can use these transfer functions nearly anywhere that you would use a linear system (which is kept in state-space form). The only drawback is that for complex systems you run into problems with numerical precision; it is more accurate to use the line:

C = 1 / (%z - 1); C.dt = (your sampling interval); C = tf2ss(C);

You can still cascade systems by 'multiplication', so C * H will generate the system of C cascaded with H. For feedback you use the './' operator:

H_ol = C * H; H_cl = (C * H) ./ 1; // apply unity feedback

I'm going to be adding information on my website on using Scilab with the book's material, so feel free to keep an eye on it.

--
Tim Wescott
Control systems and communications consulting
http://www.wescottdesign.com

Need to learn how to apply control theory in your embedded system?
"Applied Control Theory for Embedded Systems" by Tim Wescott
Elsevier/Newnes, http://www.wescottdesign.com/actfes/actfes.html
Reply to
Tim Wescott

Ok!

Yes, I understand what you mean. At the moment I use a Microchip 8 bit microcontroller so I try to avoid to use floating point math. But in the future I'm going to rewrite the firmware using a Rabbit module: this one supports well float variables. I found very useful the code examples on your CD. On my books there are no practical C examples so one doesn't know how to implement a controller in the real life!

No, that isn't cool... it's *very* cool! I didn't know this feature! Great!

It's simpler than expected! I'm learning a lot of thing in these days :)

I'll do, of course. I'm very interested on this argument.

Thanks again Tim,

Marco / iw2nzm

Reply to
Marco Trapanese

I should also mention that your design technique appears to have two glaring omissions so far, both of which you may be considering on the side:

First, the technique of measuring a step response and fitting a curve to it tends to depreciate any high-frequency effects of your plant. In some cases this matters not at all, because you are limited in your ability to push the system response very high. In other cases one's ability to control a plant is largely limited by the presence of mechanical resonances; these tend to get lost in the noise of a step-response plot, yet can, along with higher-frequency phase lag, be the most significant limitation to high performance servo systems.

Second, you are still engaged in linear design -- don't forget to take your nonlinearities into account. You'll have actuator saturation if nothing else, but you may also have friction (unless you use really good bearings), backlash (if you have gears), and other effects. Even having an assembly with loose bolts can provide enough complex and weird effects to defy analysis or tuning, until some guy with gray hair comes by and tells you to tighten everything up.

--
Tim Wescott
Control systems and communications consulting
http://www.wescottdesign.com

Need to learn how to apply control theory in your embedded system?
"Applied Control Theory for Embedded Systems" by Tim Wescott
Elsevier/Newnes, http://www.wescottdesign.com/actfes/actfes.html
Reply to
Tim Wescott

Hi Tim,

I proceeded on this way because the plant I need to control is a small but heavy underwater vehicle. So I might assume it's a first order system, as first step, of course.

I'm not an experienced designer so I'd like to use first an approximate model and do the controller to work. Then I'll improve both the plant model and the controller transfer function.

Rather than measure a step response what do you suggest?

Marco / iw2nzm

Reply to
Marco Trapanese

Tim,

about this I'm getting lost. Please, take a look to this short code:

T = 5; // Ton and Toff dt = 0.01; // sampling time tau = 0.5; // time constant of the 1st order system

kh = 5; // plant constant kp = 3; // proportional gain ki = 0.05; // derivative gain

t1 = -ones(1, T/dt).*50; // a negative step t2 = zeros(1, T/dt); // and its return t = cat(2, t1, t2); // to zero

P = kh * (1-exp(-dt/tau))/(%z-exp(-dt/tau)); P.dt = dt; // plant model C = kp + ki / (%z - 1); // controller tf H = kh*(P * C) / (1 + P * C); // c.l. tf // ^^^^^ // see later

O = C / (1 + P * C); // output of C

yP = flts(t, tf2ss(P)); yH = flts(t, tf2ss(H)); yO = flts(t, tf2ss(O));

plot2d2("onn", ((0:size(t, 'c') - 1).*dt)', yP', style=[color("red")]) plot2d2("onn", ((0:size(t, 'c') - 1).*dt)', yH', style=[color("green")]) plot2d2("onn", ((0:size(t, 'c') - 1).*dt)', yO')

Plots have sense if I insert the 'kh' constant in the forward gain of the closed-loop transfer function (see ^^^^^). If I remove it the final value is not the expected.

What I did is surely wrong. Where is the right place to insert the kh?

Another question: I'm concerned about drive saturation. When I'll write the C code there will be no problem: I'll check the drive value and I'll limit within the correct range.

But how to simulate in scilab? For example the output of the controller (yO) must be less of + - 255. How may I change the above code to do that?

Thanks! Marco / iw2nzm

Reply to
Marco Trapanese

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.