On this years robot we are using an Encoder to tell the Elevator that is placing the tubes the distance it’s going up and down, We want the Elevator to slow down when it reaches X height/# of rotations of the motor AKA a Speed Curve. I have no idea how to code this ::rtm:: I don’t know how to approch this or where to start :eek: , if you have some sample code to help me get started that would be greatly appriciated.
That’s what PID does. The §roportional term causes a slow down as the target setpoint is approached.
Here’s an example of a motor position slaved to the position of a joystick.
I would recommend PID to control this. Our team is doing a similar thing, and this is working well.
Quick overview of PID.
P-Proportional Gain-Bases motor output based off of how far away from the target you are. The higher the number, the faster you approach your goal, but it is less accurate at holding that position
I-Integral Change-Look at how error has accumulated over time, and correct for it. The higher the number, the further back it looks, which will slow down your approach as you get closer (but will hold it closer to where you want).
D-Derivative Time- Look at how fast the rate is changing and compensate so it does not overshoot your goal. The higher the number, the further ahead it looks, which will slow down your approach
Most likely, you will only need the P part, which should hold it close enough to where you want. I would increase the number until the elevator has a visible shake to it. (from the P part over-correcting)
If this is confusing, try messing with the “General Auto PID Simulator” in the FRC examples. Its a good way to figure out the relationship between P,I, and D
Once you start actually testing your elevator, be sure to have preprogrammed upper and lower limits so you dont break your elevator as well as a few setpoints to move to. If the elevator does not seem to slow down as it approaches a setpoint, you may have the motor wired inversely with the encoder output. Either reverse the motor, or change the P value to be negative instead of positive.
Thank you all for your quick responses! However, our team mentor says that we cannot use PID controllers because it would lead to a host of other problems :eek:. Are there other alternative solutions for the aforementioned problem?
What you described in your first post is exactly a P-only controller. Whether you implement it yourself or with the built in PID VI, the same issues will still be present.
Tell them you only want a proportional controller, that is often all you need for position anyway. Once that is working well, it is easy to add a bit of I if the position is off a bit.
It would be useful to know if there are other reasons what the host of problems is.
It seems that we were confused as to what a PID is. Our team mentor told us that it was something that plugged into a jaguar, while you guys were referring to PID in the code (though im still not sure what a PID actually is).
Is the code that Mark linked to using a potentiometer to slow down motor speed in the PID? Currently, we are solely using an encoder on our elevator motor. Do I need to wire a potentiometer in order to slow down the movement of the motor as it gets closer to its set points or can this be achieved without a potentiometer?
You can use the encoder you have on the elevator motor. The proportional controller that Greg is referring to can be implemented easily in any language. If you use Labview, it is available to you on the vi pallette. If you are using C++ or Java, it is easy to implement. The PIDController Class is described well here: http://www.wbrobotics.com/javadoc/edu/wpi/first/wpilibj/PIDController.html
All any of the code does is compare (subtract) your current encoder value from the desired encoder value, giving you an error value. The §roportional controller multiplies the P constant times the error and scales your motor output. As the error gets less, you can see that the motor value will fall, slowing down the motor.
There is a (-x) on Joystick 2 axis 2 because going forward gives -1 for some reason, and we have no clue how to calibrate the logitech attack 3 joysticks. It shouldn’t change anything in the code, right?
When I deployed this and clicked enable on DS, the elevator suddenly started moving up, and about halfway, it started jerking down and up. By then I rushed to click disable, but no one was moving the joystick during the deployment. Why did the elevator start moving on its own? Since the joystick wasn’t moving, its value was 0, and the encoder reset its value to 0 when I clicked enable, so it shouldnt move, right?
Or did I miss something while coding the PID? (Wasn’t really sure what the 3,0,0 for PID meant in mark’s code, so I just tried using 1 and keeping it simple).
If i’m following the math correctly…It’s probably that +1 that makes the joystick send out a value other than 0 because in this case it will only be 0 if the joystick is all the way back.
You might want to try preset heights controlled by buttons. It seems that you’ll need to hold the joystick at that position in order for the hight to remain there.
We still want joystick control of the elevator, but i wanted to use PID to slow down motor control as it hits the upper and lower limits (which I wanted to be recognized by a specific value from the encoder.
The elevator is controlled by axis 2. Lets say the upper limit is 1000 rotations, and the elevator starts at its bottom limit - 0. I want the motor to slow down as it reaches either of those two values so we don’t overshoot and blow the motor. How should I go about doing that then?
You can use the joystick to select a value, only if you use a button to take a ‘snapshot’ of that value. That way, you will use that value as the new setpoint and the elevator will slow as it approaches it.
While that might work, I want to be able to use the joystick to freely move the elevator for when we are hanging a tube in the middle peg or maybe for some other reason.
Could I have PID start slowing down the motor when it reaches 200 rotations close to either limit point? Or should I just use a bunch of case structures and comparisons to give the elevator different speeds based on its position? I’ve never used or heard of PID before, so I have no clue as to what it can or cant do.
oh, and for the second option above, is there a case structure that would let me run a set of code for a range of values (such as 0<n<200)?
PID control describes the means to control a process (elevator motion) by it’s measured position (encoder) and your desired position (setpoint). You can use the PID code provided in Labview or the C++ or Java libraries, starting with only a Proportional constant.
So, you must choose a setpoint for the elevator to go to. If you are changing it with the joystick, then the elevator will simply go to that value.
It sounds like you have two separate issues. The first is defining the setpoint, which other people have addressed.
The second problem is the tuning of the PID constants. I recommend that you read PID without a PHD. Your problem is that your P constant is too high. With a P constant of 1, if your encoder is 1 tick away from your setpoint, the motor would be going full speed and blow right past the setpoint. When it gets 1 tick away the other direction, it would reverse direction full speed. This causes the oscillation that you see. If instead you made the P constant be 0.1, then 10 ticks away it would be full speed, but 5 ticks away it would be half speed. Think about how far away you think the elevator should start to slow down, and you can figure out an approximate value for P. From there, you will probably need to experimentally change the value so that it behaves the way you want.
Since I can’t really use PIDs to slow down the motor when it reaches either limit, and allow free control of the motor through joystick otherwise, I tried another method that doesnt involve PIDs or case structures.
I made a function f(x) = .2 + .8sin(pi*x/1000) , and am using this to control the motor. X is an input that has the value of the encoder’s position, and f(x) is multiplied with the joystick axis value to get the motor speed. When the position is near either limit, it will have a minimum speed of .2, allowing the motor to still move, yet not overshoot too badly that will cause harm. When it is not in the middle, it has a higher motor speed, allowing the motor to move from one side to the other as fast as it can.
I have that code combined with the limit switch code (using encoders) so that the elevator can’t keep going up when it hits the top limit, and vice versa for the bottom. This code should technically work, right?
If you reverse your decision and want to use PIDs, you may want to consider joystick control where some input takes the elevator between a few known height set points – say floor, lower peg, feed slot, middle peg, upper peg.
For more control, if the driver presses and holds a button, the joystick value is sent directly to the motor. OR you can make it to where this mode changes the set point.