[Dprglist] Power vs Velocity for PID controllers

Karim Virani pondersome64 at gmail.com
Tue Apr 21 16:59:10 PDT 2020


Hi Murray,

I mostly have questions. I'll be a bit verbose 'cause I might be able to
reuse some of this with my team.

1. You said you were using a Thunderborg motor controller. Is it this one:
https://www.piborg.org/motor-control-1135/thunderborg

2. What is your purpose - what are you trying to accomplish? Controlling an
arm for example is different than controlling a differential drive. Are you
controlling for speed? For position? For differential rotation?

3. I see the same problems with nomenclature all the time with my team and
the systems we work with. With the api we use, setpower() might be a proxy
for setting a normalized voltage or might be a proxy for set speed
depending on how we've configured motor control and encoders. But looking
up the thunderborg, I don't see evidence for any kind of feedback. There's
no mention of current monitoring built into the motor controller. It also
doesn't seem to have inputs for quadrature encoders; and I didn't see any
mention in your post about adding your own encoders in the system.

Maybe you over simplified the psuedo code, but going from what you posted,
it seems you are just doing a get_power that simply returns the power you
previously set in the prior run of the loop. I don't see any new feedback
entering your algoritm. It seems to me that if your target power
(normalized voltage) is unchanging, your error will always be zero and
you'll never adjust the power at all. Is your error changing?

4. The concept of stacking PIDs always seems weird to me. Not that we never
do it. There are cases where we might want a lower level motor controller
to set a steady velocity while a higher level controller drives toward a
final position. But these are controlling two different things. Only the
low level one is controlling the motor. The other is controlling the target
for the low level controller. Typically the low level one would normally
operate at a finer grain time scale than the higher level controller.
Otherwise it doesn't make sense to have two levels. Make sure you really
need two controllers. It can make debugging much harder and might not be
adding that much benefit.

We have to think clearly about what we are trying to do. For a simple DC
motor we typically only have control over one output and that is voltage.
The voltage will generally relate to speed given a ton of real world
caveats. Note I didn't say the voltage is perfectly linearly proportional
to speed. It's because of those caveats that we take input from encoders to
correct the system. But we need to decide what we are trying to control and
that will give us how we calculate your error. Yup, velocity is just the
derivative of position and automatically calculates in your PID algoritm if
it's based on encoder input. But if you want to control velocity then your
error should be the difference between your target and measured velocities.

5. Going back to your psuedo code - I don't see any correction for the time
between loops. I see this in a lot of PID implementations - they often
assume a constant time between calls. Because we use cooperative
multitasking we never assume that we have a constant elapsed time and we
always normalize inputs to  the amount of elapsed time between feedback
measurements. Be aware this also intrisically converts measurements to
velocity, but the benefit is that if your control loop changes duration or
varies in duration, it won't require you to retune your PID constants.

6. Also in your psuedo code - I don't see any handling for integral windup.
That's a whole other level of discussion, so I won't go into it now. I
would just be careful about introducing the integral - we find it to be the
most tricky of the terms to tune and control. This could also bring up a
whole discussion of the regimes over which each of the P, I and D terms
operate - which could also be an extensive discussion. The question is, do
you need the I term at all? It's the term than brings in the near-zero
precision to your control system, but can also wreak a lot of havoc if you
don't have windup control. David talks about a leaky integrator as one of
his favorite anti windup mecanisms. There are a variety of others and the
optimal combination might be application specific.

7. I just saw your update. So you do have encoders in the system. But you
might not be using them yet? Again, is your error actually ever non zero?
You have to calculate your error from the difference between what your
sensors/encoders are actually measuring and what you want them to be (your
setpoint). It makes sense to us to first scale our encoder input to some
kind of natural units. For example we will calibrate the number of
ticks_per_meter or ticks_per_degree (or radian) that maps our encoder
readings to the real world. Drive your robot for one second, measure how
far it moved, divide into the number of ticks it moved during that run.
Then we'll have a low level functions that scale those encoder values to
our real world units and change them to velocities if needed.

I'm not sure about this, but I think I see some dissonance in your phrasing
about adjusting the voltage so you should somehow need to get voltage as an
input to the error calculation? Don't dwell on the voltage. It's not an
input to the error calc. It's just what you adjust against. It's the job of
the measured error and the PID constants and calculation to adjust it. If
you share your actual code we might be better able to help.

HTH,

Karim

On Tue, Apr 21, 2020 at 5:24 PM Murray Altheim via DPRGlist <
dprglist at lists.dprg.org> wrote:

> No, Doug, unless you got something wrong your description is very helpful,
> one
> of the more helpful descriptions of the P, PI, PD, and PID variations, and
> why
> one might use each. Indeed, in all the descriptions I've found online this
> was one of the more helpful, nice, straightforward, and with enough detail
> to
> actually help out on the variations, thanks!
>
> What I did last night was resurrect the controller I'd written that uses a
> value I'd mistakenly called "power" (in the code as well) when I meant the
> value sent to the motor controller. It now acts as a PID controller for
> what
> I'm assuming is actually voltage.
>
> In some ways that was largely successful. I was tweaking the P, I and D
> constants (as one does) but I think it was mostly functional. I was using
> the value from GetMotor() to set SetMotor(). Probably voltage. Maybe power,
> I don't know the guts of the ThunderBorg firmware, but a value between 0.0
> and 1.0.
>
> I think David A. in his video mentioned that there wasn't a direct
> relationship
> between voltage and velocity, but between torque and velocity. You can see
> his
> explanation (in describing the PWM of an H-bridge controller) at 20:15:
>
>     https://www.youtube.com/watch?v=8CXReb7f0Eo
>
> "the speed of the motors is not really proportional to the voltage, it's
> actually
> the torque of the DC motors is proportional to the current."
>
> To clarify my difficulty, what I think I'm doing wrong is that my current
> PID
> controller takes the value I'm sending the robot (I think voltage) as the
> input,
> does its PID computation, then sets the output (again, as I think voltage),
> whatever is sent to SetMotor().
>
> What I am not able to do is figure out how to change the input to the
> *velocity*
> I'm getting from the encoders. Yes, I can certainly use the velocity
> measurement
> as input (I have a function for that), but because I can't "set velocity",
> only
> the value I sent to SetMotor(), which I think is voltage or some
> surrogate, I
> can't figure out what the relationship is between velocity and voltage in
> the
> code. It's not a direct relationship.
>
> So what I've done (so far, last night) is take my "voltage"-based PID
> controller
> and wrap it with a velocity-based PID controller. I'm not sure if that's
> either
> necessary or sensible, but that's where I'm at right now.
>
> This will (very likely) be easier to deal with in a conversation, so I'm
> looking forward to today's/this evening's video conference.
>
> Cheers,
>
> Murray
>
> On 22/04/20 3:58 am, secretary at dprg.org wrote:
> [...]
> > Now take this scenario, your robot with encoder feedback is moving on a
> > level floor at a given speed set by your PID (or P, or PI, or PD)
> controller,
> > then it comes to the ramp. If you have a P controller the speed will
> change
> > to a certain level as the controller increases the voltage (and thus the
> > current and torque) to some value that is lower than your level speed but
> > higher than it would be without any feedback. The reason that it doesn't
> > maintain perfect speed control is because the feedback value comes close
> to > the desired (reference) value, a P controller loses its ability to
> change
> > the output, in a sense it runs out of steam the closer it gets. So for a
> P
> > controller there will always have an offset from the desired speed set by
> > your reference signal. Often this is all you need. If you have a PI
> > controller, the I portion of the controller will allow your output to
> match
> > your reference setting at the expense of adding more instability
> (however,
> > it maintains response even as speed approaches reference). For most
> robots
> > this is usually all you need. Adding a D component (i.e., PID vs PI) can
> > add response with reduced oscillations in output if done right, but it
> adds
> > a level of trickiness to the tuning.  I often use only a P, or PI
> controller,
> > in my robot depending on what I am doing. I often wrap a velocity PI
> inside
> > of a heading P controller. In the case of a line following robot, a PD >
> controller is often used. What the D does is add response to rapid changes.
> > The robot will not run at the reference setting with PD, for that can
> only
> > be done with an I component in the controller. Note that both I and D
> have
> > a dt component, you must keep loop time constant or adjust for varying
> it.
> > Also, please note that the above is somewhat general, people with more
> > knowledge may have a better understanding than me.  I hope others will
> > jump in and correct me where I have gone off base.
> ...........................................................................
> Murray Altheim <murray18 at altheim dot com>                       = =  ===
> http://www.altheim.com/murray/                                     ===
> ===
>                                                                     = =
> ===
>      In the evening
>      The rice leaves in the garden
>      Rustle in the autumn wind
>      That blows through my reed hut.
>             -- Minamoto no Tsunenobu
>
> _______________________________________________
> DPRGlist mailing list
> DPRGlist at lists.dprg.org
> http://lists.dprg.org/listinfo.cgi/dprglist-dprg.org
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.dprg.org/pipermail/dprglist-dprg.org/attachments/20200421/a56f7ccc/attachment.html>


More information about the DPRGlist mailing list