Hey guys! So it is a little more than half way through the season and my team has seen various teams are able to lift a decent amount of game objects and keep them lifted in the air while still driving. For example, we’ve seen teams grab like a cube or maybe 3-5 stars, lift them up, and keep these objects lifted while still driving around and the lift never drops back down unless powered! This seems to be very advantageous and so my team has been trying to figure out how to do such a feat with no success. We were just wondering how other teams are accomplishing this?
We use a potentiometer on the lift arm axle to read where the lift is, and have set points for low, mid, and fully raised. We use 2 buttons, one that when pressed raises the arm so we can drive, and press it again raises it all the way. The other button drops it back down to the ground. It uses a very primitive style P loop to keep the arm where it should be, but it doesn’t tweak and works amazingly well.
Code is your friend unless you are using a 4 bar with rubber bands.
Short answer is PID or some derivative of it. My team has found that using pre-set lift heights is much more difficult to drive with than just buttons that move it up or down, so we have the lift move up and down a 127/-127 and activate PID when we let go. I can share the code if you want it.
@creatorthomas What if we ARE using a 4 bar with rubber bands? Is there a simple solution in that case? As of right now, our team is using one button that we keep pressing so that every time the arm sinks, we press the button to raise the arm back up.
@mwang17 if you could share your code that would be very helpful! Thanks!
Here is our code for adjusting the arm motor power, you will have to change a lot of the numbers to be relative for you. 4096 on the lift potentiometer is all the way down, and armCurrent is the variable you set to where you want the arm to be. It will work on a 4 bar @Exothermic10X , but you will need to adjust many of the values. The key is the ~100 point dead zone to help prevent the tweaking. It will take some trial and error to get the values right.
Use at your own risk if you don’t have a decent programmer on your team.
int liftValue = SensorValue[LiftPot];
int liftPower = 0;
if(liftValue < (armCurrent - 200)){
liftPower = 40;
}
else if(liftValue < (armCurrent - 50)){
liftPower = 20;
}
else if(liftValue > (armCurrent + 400)){
liftPower = -127;
}
else if(liftValue > (armCurrent + 200)){
liftPower = -80;
}
else if(liftValue > (armCurrent + 50)){
liftPower = -20;
}
else {
liftPower = 0;
}
motor[LiftA] = motor[LiftB] = motor[LiftC] = liftPower;
@creatorthomas where does this slot into your main code? That seems pretty confusing to me. How does that integrate with the controller?
Here’s a task I wrote just now using a PID controller; this way no matter what kind of load you pick up the lift will stay at the same height.
task liftControl(){
int PIDTargetValue;
//PID constants. Do research if you don't know what these are
float kp = 0.5;
float ki = 0.01;
float kd = 0.00001;
int error;
int integral = 0;
int derivative;
int lastError;
int PIDDrive;
while(true){
if(vexRT[Btn[6U] == 1{
//lift up
motor[liftRight] = 127;
motor[liftLeft] = 127;
PIDTargetValue = SensorValue[liftPot];
}
else if{vexRT[Btn[6D] == 1){
//lift down
motor[liftRight] = -127;
motor[liftLeft] = -127;
PIDTargetValue = SensorValue[liftPot];
}
else{
//PID to hold
error = PIDTargetValue - SensorValue[liftPot];
integral += error;
derivative = error - lastError;
PIDDrive = kp*error + ki*integral + kd*derivative;
motor[liftRight] = PIDDrive;
motor[liftLeft] = PIDDrive;
lastError = error;
}
wait1msec(15);//don't hog cpu
}
}
Ok. Thanks. I will test it out with the four-bar.