Translating encoder ticks/PID feedback to pwm
rwgast_logicdesign
Posts: 1,464
Im sorry if this question sounds rediculoud but ive been reading for hours and cant come up with a solution to scalind a pid algorithim to a how fast to pulse a pwm line. Basically I just want to keep a my motors at the same speed using PID and encoders along with a compass to compensate for any long term encoder error.
So basically the idea is if one encoder is at 400 ticks and the other is at 300 slow one down by 50 ticks and speed one up by 50. But how do you scale encoder ticks to a 1 through 255 pwm setting, or and duty cycle for that matter.
So basically the idea is if one encoder is at 400 ticks and the other is at 300 slow one down by 50 ticks and speed one up by 50. But how do you scale encoder ticks to a 1 through 255 pwm setting, or and duty cycle for that matter.
Comments
Once you get that working the integral and derivative can be added on later, but a proportional scheme gives you most of the bang for the buck. I'm about to learn a whole lot more about PID because I need it for some projects in the planning stage. It's really useful for fast line following where the line is allowed to have sharp bends for example.
There are many approaches, so consider this just my approach for velocity control (for odometry I always work in encoder "ticks"):
- first I convert encoder "ticks" on each sample to a theoretical PWM value (i.e., I scale the ticks read to a motor speed value). In my case, I usually use 128 as stop, 255 as full forward, 0 as full reverse. So if I sample encoder ticks every 20ms, I convert the speed (count) and direction to a 0-128-255 value. I usually use the equivalent of */ or ** (mid-multiply or high-multiply) and I take into account rounding errors to get the best measured speed.
- that "speed" can now be comapred directly to my "desired" user speed. So if my converted speed from reading encoder ticks is 138 (a slow forward) and my target speed is 140, I know I have an error of 2. That error can be fed into your P, I and D terms. Given that you are working in "speeds", the result can be put right back into your PWM values.
- for practical purposes, I've found that using an impulse factor gave me much better results than straight PID. There are a number of after-market motion controllers (motor drivers with built in encoder feedback and PID algorithms built-in) that use this approach. Essentially, I take the target user speed and scale that to about 80% as my "base" output figure. The rest of the final PWM value is derived from PID correction. I also always account for integral wind-up (a max integral saved error) for the I term and I usually clear the saved I term to 0 upon a direction change.
- for figuring the scaling factor for ticks to speed, I usually run the motors at 80% duty and measure the ticks output. That's "full speed". The other 20% gives me overhead to run the motors at higher duties to hit target speeds comfortably (especially as batteries run down).
Zoot gave me a better answer than i could have hoped for, there is info on PID all over but nothing about a reasonable way to scale it to a meanigfull dutty cycle. Id also like to take compass reading every so often and and use a PID loop to make the bot follow a straight heading, kind of keeping the encoders in check.
I was originally going to make my Arduino based motor controller handel the PID for the encoders, but im not sure it will handel 2000 interupts per second to well let alone 4500 if i upgrade to 4 wheel drive. Im staring to think i might let the propeller handel the encoders, as thats where the compass will be attached to also.
-Phil
I've used this with CR servos since they coast when you don't pulse them, so keeping the pulse counts synchronized is easy. But with a PWM/H bridge pair I figured it would require over correcting the faster motor until the other side catches up, then speeding it up again to match. This seemed pretty complicated which is one reason why I abandoned my encoder hacked S1
Do you put the side that is ahead into coast mode on the S2?
The biggest reason I abandoned my encoder hacked S1 was it lacked dynamic breaking which CR servos have. Without that accurate odometry is really hard because you tend to coast past where you want to go. Erco, hacked the S1 farther to add this feature.
You don't fail until you give up!
Perhaps I should say I indefinitely postponed work on it to pursue more fruitful avenues of robotic self expression?