I’m using 2 rotation sensors to code an autonomous PID loop, but I’ve just now realized that the sensors give a value between 360 and 0, which is not ideal. Is there a way to get rotation sensors to give continuous degree readings, going beyond 360? Or is there a way I can do that in the code, to keep track of the rotation sensors degree resets and add it up?
I am not 100% sure. But you may want to change the unit.
just use the position() function
I should’ve specified or posted my code, sorry, I am using rightRotationSensor.position(degrees); and the code gets stuck in an infinite loop above 360 degrees. I’ve tried it with the drive motor encoders and it works fine, but we wanted to at least try using the rotation sensors we have.
well, position() does not roll over at 360, it just keeps counting in the same way a motor encoder would, must be something else in your code, can you post the relevant section.
(assuming vexos is up to date)
Yeah, I’ve looked over this code quite a few times in the last few days, but up until 2 weeks ago, my team was using time based autonomous code, so I am very new to PID loops, or in this case just a P loop, I think. Where I’m pulling the rotation sensor values, if I replace it with the average of both the left motors or both the right motors it works just fine, but when I replace it with the rotation sensors (also left and right), it gets stuck in a loop somewhere. I am resetting the rotation sensors position at the start of autonomous and as a under the pre_auton.
int velCap;
int targetLeft;
int targetRight;
int drivePIDFn() {
int errorLeft;
int errorRight;
float kp = .05;
float kpTurn = .2;
int acc = 1;
int voltageLeft = 0;
int voltageRight = 0;
int signLeft;
int signRight;
task::sleep(20);
while(Competition.isAutonomous()) {
errorLeft = targetLeft - LRotationSens.position(degrees);
errorRight = targetRight - RRotationSens.position(degrees);
signLeft = (errorLeft > 0) - (errorLeft < 0);
signRight = (errorRight > 0) - (errorRight < 0);
if (signLeft == signRight) {
voltageLeft = errorLeft * kp;
voltageRight = errorRight * kp;
} else {
voltageLeft = errorLeft * kpTurn;
voltageRight = errorRight * kpTurn;
}
velCap = velCap + acc;
if (velCap > 100) {
velCap = 100;
}
if (abs(voltageLeft) > velCap) {
voltageLeft = velCap * signLeft;
}
if (abs(voltageRight) > velCap) {
voltageRight = velCap * signRight;
}
FLDrive.spin(forward, voltageLeft, voltageUnits::volt);
FRDrive.spin(forward, voltageRight, voltageUnits::volt);
BLDrive.spin(forward, voltageLeft, voltageUnits::volt);
BRDrive.spin(forward, voltageRight, voltageUnits::volt);
task::sleep(40);
}
return(1);
}
void drivePID(int left, int right) {
targetLeft = targetLeft + left;
targetRight = targetRight + right;
velCap = 0;
}
edit: mods fixed the code tags
Start adding some debug statements, perhaps
Brain.Screen.printAt(10,20, "pos L: %.2f ", LRotationSens.position(degrees) );
Brain.Screen.printAt(10,40, "pos R: %.2f ", RRotationSens.position(degrees) );
at the point you use those values.
also, be aware that 12 volts is max value the motors can handle, seems like you clip at 100
Thanks, I’ll try this tomorrow. And yeah, I was wondering why it was speeding up so quickly, this code is kind of an amalgamation of a bunch of online PID guides, personal experience, and asking other teams, so that 100 might’ve gotten in there accidentally.
The values are printing to the brain and are correct, they don’t cap at 360, but any time I put my acceleration value (now a float to account for the voltage cap being 12 not 100) below 1, it doesn’t move. When I put it back at 1 it works, it’s just insanely fast, so idk if thats just me tuning the proportional values incorrectly or if the tuning changed, because the rotation sensors are no longer the problem I think.
Try changing:
int voltageLeft = 0;
int voltageRight = 0;
To
double voltageLeft = 0;
double voltageRight = 0;
At best, if you are capping voltage to 12, you’ll only get 12 different “speeds”. Alternatively, multiple everything by 1000 and change the voltageUnits
from volt to millivolt.
Oh shoot thats why, I didn’t even think about that. I started doing some different equations to make it work, but changing that to a double works a lot better, thanks.