| View previous topic :: View next topic |
| Author |
Message |
ginge Site Admin
Joined: 14 Jan 2006 Posts: 1029 Location: Manchester, UK
|
Posted: Wed Jul 18, 2007 7:22 pm Post subject: PID Velocity Control loop |
|
|
Hi all,
I am just implementing a new feature for OpenServo that could be considered very experimental... Velocity control.
A velocity control loop runs inside of the position PID loop to precisely follow a commanded velocity. This is pretty useful when you want to slew between two positions and you are fighting gravity half of the time. The gravity assisted acceleration downward is throttled back to fit the required velocity, while the uphill motion is powered up accordingly.
The second portion of the new algorithm is a feedforward control. This injects a small amount of the seek position (about 30%) into the velocity controller to further stabilise everything.
Sounds great right?
Well, actually it gets kind of messy. There are quite a few variables that need to be added to the main PID algorithm, namely these
Velocity P gain
Velocity I gain
Velocity D gain
Feedforward gain
so that is 4 new registers that need to be added... hmm.
Along with this is the problem of balancing the two algorithms. What once worked fairly well across a broad range of servos now becomes a fine balancing act which fits only a small section of servo types.
There are scaling factors associated with the Velocity loop, the feedforward gains and the final scaling values.
10 tuning values that need to be balanced. Hmm.
It took me nearly a whole day to tune the velocity and PID gains for my robot arm, not something I would like to repeat in a hurry. It's a real shame each motor needs doing individually... that is a fair chunk of my life just messing with 10 PID values.
The last issue is resolution. The current speed estimator takes the current position from the previous position for speed... unfortunately you are not always getting a resolution greater than units of ADC/10ms. My robot typically moves at 1unit/10ms as it is massive. This resolution is pretty poor at keeping a good velocity. Hopefully Back EMF estimation, slated for V3, will solve some of these worries.
Okay, so I painted a pretty bleak picture here, but there is salvation. What it will require to fix this horrible mess of an idea is some way of dealing with all of these registers that are being developed.
I am thinking of revisiting the "window writing" method that was discussed elsewhere for this one, but if anyone has any bright ideas
So, I can see the worth in this idea, but it is going to make the OpenServo a pain in the arse to tune well. Where we only had the P and D values to fiddle with, we now have 8 others.
If I spend a little while longer getting the balance of values right, I should be able to create a safe set of figures that would work over a fair range of devices without needing to tune too much.
Any ideas on how to expose more registers without using all of the register space up?
Barry _________________ http://www.headfuzz.co.uk/
http://www.robotfuzz.co.uk/ |
|
| Back to top |
|
 |
kbb
Joined: 01 Jun 2007 Posts: 180
|
Posted: Wed Jul 18, 2007 9:51 pm Post subject: Re: PID Velocity Control loop |
|
|
| ginge wrote: | | Any ideas on how to expose more registers without using all of the register space up? |
Barry,
I can't find the description of “window writing”, maybe it is what I describe here?
Option 1. Extend all register addressing to two bytes. The problem with that is it means more bandwidth usage (several messy/nasty “cures” came to mind, so I won’t even mention them).
Option 2. On the theory that some registers are not that frequently accessed “operationally”: Use “bank switching”. A register is set aside (in “bank 0”, as your will see) to select which register bank is being read/written. So, for example, the usual PID values are in “bank 1”, when you select “bank 2” by (writing a 2 to the “bank select register”, the velocity values replace the usual PID values at same address as the PID values). Some registers (position, seek, power, etc.) would remain at the same address all the time (e.g. in “bank 0”, “bank 0” is always selected) because of the frequency with which they are likely to be accessed. All the “other” banks share the same set of addresses. Just to provide an example (fictitious): bank 0 is “0x00 to 0x3f”, bank 1 is “0x40 to 0x7f”, bank 2 is also “0x40 to 0x7f”, ..., bank n is also “0x40 to 0x7f”.
Kevin. |
|
| Back to top |
|
 |
ginge Site Admin
Joined: 14 Jan 2006 Posts: 1029 Location: Manchester, UK
|
Posted: Wed Jul 18, 2007 9:58 pm Post subject: |
|
|
Hi kevin,
We looked into using a portion of the OpenServo register space for bank switching, it looks to be the best long term solution.
The window method was a quick hack of an idea that gives you 8 bytes that can be read or written to using commands. The first 2 bytes are the command selection, and the remaining 6 bytes are for the command options . Think command 0x0001 = "velocity pid" then write the pids in, 0x0002 = read status registers.
Very much like a limited bank select where each bank is a discrete function. It looked to be a good way of increasing the register range of OpenServo by a huge amount, while keeping simplicity.
Barry _________________ http://www.headfuzz.co.uk/
http://www.robotfuzz.co.uk/ |
|
| Back to top |
|
 |
ginge Site Admin
Joined: 14 Jan 2006 Posts: 1029 Location: Manchester, UK
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|