How does one keep their DR4B in one position? When we tell it to go down, the momentum carries the lift all the way down to its rest position. We tried PID, but the lift moves too slow to get to any one position when going downwards. What should we do?
Do you have rubber bands on it?
Of course. 24 of them, to be exact. Just enough to keep the rd4b in any one position when there is no motor power being acted on it.
You could try putting the lift at a lower power when it’s going down.
Putting your lift at a lower power when it goes down should help, also you can put a brake on it so when you release the button it puts the motors at a really low positive value to stop it from going down and then set them to zero. This may not be the best for your motors but it’s an option.
You could make a PID loop only active while the lift buttons aren’t pressed. I messed with it once last year and it worked really nicely.
And if momentum is bringing your lift down when you move down, I think you might need more rubber bands. Are you counterbalancing to the limit? Triangle banding?
Alternatively, just make your joystick run through your PID. Have two target values for your pid. One set by buttons/code (in auton) and another that overrides the first when a joystick is being used. When the joystick is moved, the target PID value should move at a speed relative to the input of the joystick. Just make sure to set limits, so that you can’t set your target outside of reasonable values. We did this in starstruck for our arm and it worked beautifully. It gives you the speed benefits of manual control, and the holding power benefits of PID.
It depends how you’re controlling it. If you use buttons, set the PID to either the very top of its range or the very bottom, depending on what buttons are pressed. For example, if the ‘up’ button is pressed, set the PID target to the highest the lift can go. This should move it at full speed while also dampening it at the end so it doesn’t slam closed, which is generally not good for neither your DR4B assembly, nor the motor. When you release the button, set the target to its current position, so it holds.
If you use a joystick to control it, that makes it a bit more complicated, because the driver most likely expects variable speed control. There are a few ways to do this. @ethan_matlack’s solution would work, although I don’t personally like it because it doesn’t give direct control over the motor. As @Vex 9185 suggested, you could simply disable the PID while the joystick isn’t near 0 and feed the motor power directly, then turn it back on when the joystick returns to 0. This would work fine and give direct control over the motor, but it wouldn’t protect the lift from slamming down into the chassis. In my opinion, the best solution is to have a variable built into your PID controller called
max_power
or something, and limit the output of the PID to be between
max_power
and
-max_power
. This way, you can set the target of the lift to the top or bottom, just like with buttons, depending on the direction of the joystick. Set
max_power
to the absolute value of the joystick value, and you have speed control over your lift as well. Just make sure to reset
max_power
to 127 when the joystick returns to zero.
Thank you for the help! I will try the PID controller loop stuff tomorrow. The reason our pid wasnt working was probably because the PID I was using made the lift slow down as it approached the target, but did not oscillate around the target (because it was a function and not a loop) which is why the momentum of the lift going down affected it so much.
How do you set it to current value? In my feeble attempt: If the value changes then so the target and no motor power. How would you fix it?
Declare the variable with global scope. Then, while the button is moving, keep updating your so called “target.” When you do release the button, in the else part, call the function that will cause it to hold. The target of that function will be the "target"variable that was updated when it was still moving. Does that make sense?
Update: So I tried the PID loop and it worked beautifully! However, I found it better not to use the current value of the potentiometers when doing user control because it made the lift very rough to use. I did something like this:
while(true)
{
if( button == pressed)
}
PIDrequestedPos = max_pos; //or min_pos depending on if this were the down or up button
currentPos = (left_pot + right_pot)/2 //just the average of the 2 potentiometers
}
else
{
PIDrequestedPos = currentPos;
}
}
and while it worked, the second I released the button the lift would suddenly snap to the exact position of when I released the button. I felt like this would be more annoying than advantageous to my drivers who preferred a smoothly moving lift with a bit of momentum. Anyways, thanks for the help guys!