NEW! Quadrature Encoder + PID Controller
Kye
Posts: 2,200
Haven't been able to post many driver updates in a while. Thank school for that .
Anyway, here's a new piece of code that I designed for the stingray robot with quadrature encoders installed. http://www.lynxmotion.com/p-448-quadrature-motor-encoder-wcable.aspx
I don't know why Parallax does not sell these encoders. They work perfectly with the motors in the stingray robot. They also can be directly interfaced to the 5V port on the robot controller board. So everything is REALLY easy.
So, What's nice about this driver is that it preforms the sampling of the quadrature encoder... feeds that to an instantaneous speed measurement algorithm... then using that speed measurement it uses PID control to drive the motor the quadrature encoder is installed on to turn at a target speed.
All this power and control is handled in one core for the user. The API is posted below.
Anyway, here's a new piece of code that I designed for the stingray robot with quadrature encoders installed. http://www.lynxmotion.com/p-448-quadrature-motor-encoder-wcable.aspx
I don't know why Parallax does not sell these encoders. They work perfectly with the motors in the stingray robot. They also can be directly interfaced to the 5V port on the robot controller board. So everything is REALLY easy.
So, What's nice about this driver is that it preforms the sampling of the quadrature encoder... feeds that to an instantaneous speed measurement algorithm... then using that speed measurement it uses PID control to drive the motor the quadrature encoder is installed on to turn at a target speed.
All this power and control is handled in one core for the user. The API is posted below.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // PWM1C Proportional Integral Derivative Engine // // Author: Kwabena W. Agyeman // Updated: 10/15/2010 // Designed For: P8X32A // Version: 1.0 // // Copyright (c) 2010 Kwabena W. Agyeman // See end of file for terms of use. // // Update History: // // v1.0 - Original release - 10/15/2010. // // For each included copy of this object only one spin interpreter should acess it at a time. // // Nyamekye, /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Feedback Circuit: // // Motor Left - To H-Bridge, driven by the propeller chip. // // Motor Right - To H-Bridge, driven by the propeller chip. // // Encoder Left - From the quadrature encoder, driven by the encoder. // // Encoder Right - From the quadrature encoder, driven by the encoder. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Object "PWM1C_PIDEngine" Interface: PUB quadraturePosition(deltaPosition) PUB quadratureSpeed(targetSpeed) PUB PIDEngineStart(motorLeft, motorRight, encoderLeft, encoderRight, PGain, IGain, DGain) PUB PIDEngineStop Program: 136 Longs Variable: 4 Longs ______________________________________ PUB quadraturePosition(deltaPosition) 4 Stack Longs //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Returns the delta or absolute position of the quadrature encoder in ticks. // // DeltaPosition - True to get the delta position since the last call. False to get the absolute position since last call. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// _________________________________ PUB quadratureSpeed(targetSpeed) 4 Stack Longs //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Drives the quadrature encoder at a target speed using proportional, integral, and derivative control. // // TargetSpeed - The target speed in ticks per second. The target speed should be reachable by the system. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// __________________________________________________________________________________________ PUB PIDEngineStart(motorLeft, motorRight, encoderLeft, encoderRight, PGain, IGain, DGain) 13 Stack Longs //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Starts up the PID driver running on a cog. // // Returns true on success and false on failure. // // MotorLeft - The left drive pin of the h-bridge. -1 to disable output. // MotorRight - The right drive pin of the h-bridge. -1 to disable output. // EncoderLeft - The left leading signal pin of a quadrature encoder. -1 to disable input. // EncoderRight - The right leading signal pin of a quadrature encoder. -1 to disable input. // PGain - Power of two gain for the proportional drive. (0 to 31). Where zero disables the proportional factor. // IGain - Power of two gain for the integral drive. (0 to 31). Where zero disables the integral factor. // DGain - Power of two gain for the derivative drive. (0 to 31). Where zero disables the derivative factor. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// __________________ PUB PIDEngineStop 3 Stack Longs //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Shuts down the PID driver running on a cog. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // TERMS OF USE: MIT License /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the // Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////I'll be posting this to the OBEX soon. Enjoy!
Comments
John Abshier
Then play arround with the pin numbers of the encoder and motor until the wheel starts to spin slowly vs just going at full speed in one direction or another.
The alogrithm can't home in on the target if the effect it applies goes the opposite direction that it thinks.
I haven't got many hits from people asking about this driver. It really does give almost perfect speed control to the stingray robot if you have quadrature encoders installed.
Happy Turkey Day.
Personally, I'm not in a mode where this code makes sense to run. That's probably all it is. Everybody is doing their thing, sometimes aligned with a code project, sometimes not.
I'm going to see if I can try this out on the weekend since I have the Stingray motor kit, lynxmotion encoders, and the Parallax control board for the Singray. When I briefly looked over the demo code to see what pins you assigned to the encoder I was a bit puzzled since I only see one pin for the right and one pin for the left instead of two pins each. Are you only using half of each encoder??
Robert
Because one leads the other when the wheel is spinning left, etc.
Direction is completely arbitrary although there does appear to be some consistency with industrial servos. I'll see if I can find out what it is ...
It wasn't clear when I first looked at it and it appeared that you were using two motors and two encoders (using only 1 channel per encoder) instead of just one motor and encoder combo.
Robert
Thanks though,
Ok, dug out an old 24 volt, 100 line, single-ended, push-pull encoder that came off a PLC. Hooked it up to a power pack and scope ... and ... A leads B when turning the shaft clockwise and viewed from the shaft attachment end. This makes sense. It is the way I would have built it myself.
And motors typically have the encoder attached on the rear end of the motor, so there wouldn't be any reversal of direction from that.
So, from my sample of one, if this is the norm, then it would explain why I've noticed some consistency.
As for naming; you could use quadrature, phase or channel. Channel is the common name in industry because there is always a third signal allocated in the cabling - known as an index or reference - so you have Channel A, Channel B and Channel C. Channel C can also be labeled Channel Z or Channel I to denote it's special reference finding purpose.
Any one of these points can cause a direction reversal. Consequently, software/jumper settings for flipping the direction is a common feature on servo drives.
I am running very successfully on my stingray but like most hardware I had to tweek the PID values slightly (P=15,I=12,D=12) as there was initially considerable overshoot and about 2 seconds of hunting when given a step setting (IE start with 10k after a few seconds goto 50K wait again and goto 10k) I did it mostly by ear with the bot sitting on its stand. Tricky adjustment but take your time it works great.
Please if you have time give the object a review. Thanks,
This will take some of the bumpiness out of speed changes and in the case of the stingray maybe keep the tail from lifting.
WaddaUsay Kye (I also gave the object a review)
Thanks,
I don't know what's wrong here. Do you have any idea about this?
Thanks.
P/S: The piece of code for testing is below:
I've been playing around with encoders a lot lately and something like this just happened to me. I had the encoder pins switched from what they should be on one of the motors. Switching the wires solved the problem.
You wouldn't have to switch the physical pins with Kye's method. You could just switch the pin names in the call the the PID object.
If the encoder pins are switched, the motor will think it has never reached the correct speed and just go to top speed no matter the speed setting (except zero).
The PID object works on my Stingray now. But I still have one thing I do not understand. The value input to quadratureSpeed function is 3875 but when the output of deltaPosition is around 1530. Is there some kind of ratio between the input and output value?
On this I am going to try the encoders out of a ball mouse on the tread drives so these drivers will be tried out. The Prop will give all of the display options too.
The problem is the physical mechanical make-up of the system. You'll notice that by just tapping the stingray wheel (very little deflection) the encoder object reads about +-40 counts, yes it is that sensitive. This makes it very hard to control the system. My PID driver object is pretty minimal in design. Its meant to work good enough. Not prefect.
If you want position feedback control you will need to adjust the speed input value until the delta changes at the right value per second. You could do this by using PID! o_O
---
There's actually alot of messy stuff in the code that runs the PID control for the encoder feedback. Doing speed control using encoders is not as simple as you would think. There is a really subtle but huge problem with making the system work right that is due to the sample rate the system runs at and when you calculate the speed.
Position feedback control with encoders is actually easier. But my driver does speed control instead.
I guess I would need another PID loop in the code to give you position control. Or I could have done position control first with speed control on-top of position control. Or maybe I could have done some numerical methods stuff...
Anyway,
Thanks,