Hello there, My friend and I have been trying to get this code working for about a week. I have spent more time on the forums then talking to my family, but I know something isn’t right. We are trying to get PID working for our double flywheel (3 standard torque motors on each side, 35:1 external gear ratio, and a IME on a motor on each side. I can send a picture if anyone wants one) a week ago we recreated the flywheel and for the first time all season it has shot WAYYYYY over the high goal, which is very exciting but now we have new problems like accuracy, which we didn’t have to worry about when our robot didn’t actually work. Anyway, after hearing something about PID on the forums we decided to take a look (we also read about TBH but it was after we had already worked on PID a bunch and didn’t want to switch over, plus we didn’t understand the code any more than we did with PID). So we watched a bunch of videos and borrowed some code (of course from people who said it was okay to borrow stuff) made some up ourselves and we think we have PID working fine (the constants aren’t calibrated yet, but we know how to do that) the main issue is getting the actual velocity of the flywheel and putting it into PID for it to calculate the error and stuff. We have a task getVelocity (I don’t know if it would be better as a function instead of a task, same with task shooterControl (which is PID) I’m thinking shooterControl would be better as a function that took in the desired power and the actual velocity like “void shooterControl (power, velocity)” or something but that’s not the main problem at the moment) the main problem is the getVelocity task. I don’t think it works properly. Just looking at the code it doesn’t seem like it actually gets the velocity of the flywheel. (and yes I realize that at the moment everything is set up for a single flywheel, but that isn’t much of a change we just have to double up on PID and the IME code).
Okay so that’s all probably very confusing, but I just wanted to know if there was anyone out there who could help me fix up this code. Specifically the getVelocity task and the parts of the shooterControl task that call the getVelocity task. Also anything else you see that could help us out would be very much appreciated. Thank you to anyone who decides to help.
#pragma config(I2C_Usage, I2C1, i2cSensors)
#pragma config(Sensor, I2C_1, , sensorQuadEncoderOnI2CPort, , AutoAssign )
#pragma config(Sensor, I2C_2, , sensorQuadEncoderOnI2CPort, , AutoAssign )
#pragma config(Motor, port1, IW1, tmotorVex393HighSpeed_HBridge, openLoop)
#pragma config(Motor, port2, DW1, tmotorVex393HighSpeed_MC29, openLoop)
#pragma config(Motor, port3, DW2, tmotorVex393HighSpeed_MC29, openLoop)
#pragma config(Motor, port4, DW3, tmotorVex393HighSpeed_MC29, openLoop)
#pragma config(Motor, port5, DW4, tmotorVex393HighSpeed_MC29, openLoop)
#pragma config(Motor, port6, flyWheelL1, tmotorVex393_MC29, openLoop, encoderPort, I2C_1)
#pragma config(Motor, port7, flyWheelL2, tmotorVex393_MC29, openLoop)
#pragma config(Motor, port8, flyWheelR1, tmotorVex393_MC29, openLoop, encoderPort, I2C_2)
#pragma config(Motor, port9, flyWheelR2, tmotorVex393_MC29, openLoop)
#pragma config(Motor, port10, IW2, tmotorVex393HighSpeed_HBridge, openLoop)
//*!!Code automatically generated by 'ROBOTC' configuration wizard !!*//
float power;
static float velocity;
float error;
task shooterControl; //defines shooterControl don't touch this
task getVelocity;
task main()
{
while(1 == 1)
{
//dummy text for flywheel
if(vexRT[BtnXX] == 1 ){
power = 65;
startTask (shooterControl);
}
//Intake
if(vexRT[Btn7L] == 1)
{
motor[IW1] = 127;
motor[IW2] = 127;
}
else
{
if(vexRT[Btn7D] == 1)
{
motor[IW1] = -127;
motor[IW2] = -127;
}
else
{
motor[IW1] = 0;
motor[IW2] = 0;
}
}
//drive control
if(vexRT[Btn6U] == 1 )
{
motor[DW1] = -75;
motor[DW2] = -75;
motor[DW3] = -75;
motor[DW4] = -75;
}
else if(vexRT[Btn5U] == 1)
{
motor[DW1] = 75;
motor[DW2] = 75;
motor[DW3] = 75;
motor[DW4] = 75;
}
else if(vexRT[Ch2] > 15) {
motor[DW1] = -100;
motor[DW2] = 100;
motor[DW3] = 100;
motor[DW4] = -100;
}
else if(vexRT[Ch2] < -15)
{
motor[DW1] = 100;
motor[DW2] = -100;
motor[DW3] = -100;
motor[DW4] = 100;
}
else
{
motor[DW1] = 0;
motor[DW2] = 0;
motor[DW3] = 0;
motor[DW4] = 0;
}
}
}
task shooterControl()
{
resetMotorEncoder(nMotor);
resetMotorEncoder(nMotor);
startTask(getVelocity);
float kp = 0.01; //proportional constant
float ki = 0.000000; //integral constant
float kd =0.00; //derivative constant
float current = 0; //starts with no power
float integralActiveZone = 2; //integral error accumulates
float errorT; //total error
float lastError; //last error recored
float proportion; //proportion term
float integral; //integral term
float derivative; //derivative term
while(true)
{
error = power - velocity; //difference between current vs target velocity
if(error<integralActiveZone && error !=0) //active integral zone
{
errorT += error; //adds error
}else
{
errorT = 0;
}
if(errorT>50/ki) //caps error at 50
{
errorT = 50/ki;
}
if(error == 0) //if error zero then derivative zero
{
derivative = 0;
}
proportion = error * kp; //setting proportion term
integral = errorT * ki; //setting integral term
derivative = (error - lastError)*kd;//setting derivative term
lastError = error; //last error becomes current error for next loop
current = proportion + derivative + integral; //setting power
motor[flyWheelL1] = motor[flyWheelL2] = motor[flyWheelR1] = motor[flyWheelR2] = current; //giving motors power
wait1Msec(20); //proventing hogging of CPU power
}
}
task getVelocity() {
while(1 == 1)
{
float gearRatio = 35.0;
float timeDelay = 20.0;
float ticks = 627.2;
float leftEncoderLast;
float rightEncoderLast;
float rightEncoder;
float leftEncoder;
float leftVelocity;
float rightVelocity;
float speedRPM;
leftEncoder = SensorValue[I2C_1];
rightEncoder = SensorValue[I2C_2];
leftVelocity = (leftEncoder - leftEncoderLast)/(timeDelay * 0.001);
rightVelocity = (rightEncoder - rightEncoderLast)/(timeDelay * 0.001);
velocity = (leftVelocity + rightVelocity)/2;
leftEncoderLast = leftEncoder;
rightEncoderLast = rightEncoder;
speedRPM = velocity * gearRatio * 60 * ticks;
wait1Msec(timeDelay);
}
}