I’m using 2 IME’s, one on each side of the drivetrain. I made a PID function to move forward, back, turn right and left. But I’m not sure if the code is right. I haven’t tuned the Kp, Ki, and Kd values yet, so don’t worry about that.
#pragma config(I2C_Usage, I2C1, i2cSensors)
#pragma config(Sensor, I2C_1, , sensorQuadEncoderOnI2CPort, , AutoAssign )
#pragma config(Sensor, I2C_2, , sensorQuadEncoderOnI2CPort, , AutoAssign )
#pragma config(Motor, port1, , tmotorVex393_HBridge, openLoop)
#pragma config(Motor, port3, , tmotorVex393_MC29, openLoop)
#pragma config(Motor, port4, , tmotorVex393_MC29, PIDControl, encoderPort, I2C_1)//right
#pragma config(Motor, port5, , tmotorVex393_MC29, PIDControl, encoderPort, I2C_2)//left
#pragma config(Motor, port6, , tmotorVex393_MC29, openLoop)
#pragma config(Motor, port7, , tmotorVex393_MC29, openLoop)
#pragma config(Motor, port8, , tmotorVex393_MC29, openLoop, reversed)
#pragma config(Motor, port10, , tmotorVex393_HBridge, openLoop, reversed)
// This code is for the VEX cortex platform
#pragma platform(VEX2)
// Select Download method as "competition"
#pragma competitionControl(Competition)
//Main competition background code...do not modify!
#include "Vex_Competition_Includes.c"
float Kp = 0.01;
float Ki = 0;
float Kd = 0;
void moveForward(float distance)
{
slaveMotor(port7,port5);
slaveMotor(port5,port3);//left
slaveMotor(port6,port4);
slaveMotor(port4,port1); //right
slaveMotor(port10, port2); //flywheel
float errorLeft;
float errorRight;
float errorTotalLeft;
float errorTotalRight;
float lastErrorLeft;
float lastErrorRight;
float proportionLeft;
float proportionRight;
float integralLeft;
float integralRight;
float integralActiveZone = 57;
float derivativeLeft;
float derivativeRight;
float speedLeft;
float speedRight;
//convert distance in inches to raw values
errorLeft = distance * 57.2967795;
errorRight = distance * 57.2967795;
//calculates new error based on distance left from objective
errorLeft = errorLeft - nMotorEncoder[I2C_1];
errorRight = errorRight - nMotorEncoder[I2C_2];
//add hard stop/limit to integral, otherwise motors will keep running
if(errorLeft < integralActiveZone && errorLeft != 0)
{
errorTotalLeft += errorLeft;
}
else
{
errorTotalLeft = 0;
}
if(errorRight < integralActiveZone && errorRight != 0)
{
errorTotalRight += errorRight;
}
else
{
errorTotalRight = 0;
}
//proportion values
proportionLeft = errorLeft * Kp;
proportionRight = errorRight * Kp;
//integral values
integralLeft = errorTotalLeft * Ki;
integralRight = errorTotalRight * Ki;
//derivative values
derivativeLeft = (errorLeft - lastErrorLeft) * Kd;
derivativeRight = (errorRight - lastErrorRight) * Kd;
//add P, I, and D to get motor speed
speedLeft = (proportionLeft + integralLeft + derivativeLeft);
speedRight = (proportionRight + integralRight + derivativeRight);
//round speeds to whole numbers
round(speedLeft);
round(speedRight);
//motors move at speed found
motor(port3) = speedLeft;
motor(port1) = speedRight;
//make error into lastError after loop
lastErrorLeft = errorLeft;
lastErrorRight = errorRight;
wait1Msec(25); //let motors and cortex catch up
}
void moveBackward(float distance)
{
slaveMotor(port7,port5);
slaveMotor(port5,port3);//left
slaveMotor(port6,port4);
slaveMotor(port4,port1); //right
slaveMotor(port10, port2); //flywheel
float errorLeft;
float errorRight;
float errorTotalLeft;
float errorTotalRight;
float lastErrorLeft;
float lastErrorRight;
float proportionLeft;
float proportionRight;
float integralLeft;
float integralRight;
float integralActiveZone = -57;
float derivativeLeft;
float derivativeRight;
float speedLeft;
float speedRight;
//convert distance in inches to raw values
errorLeft = distance * -57.2967795;
errorRight = distance * -57.2967795;
//calculates new error based on distance left from objective
errorLeft = errorLeft - nMotorEncoder[I2C_1];
errorRight = errorRight - nMotorEncoder[I2C_2];
//hard stop/limit for integral, otherwise integral will keep motors running
if(errorLeft > integralActiveZone && errorLeft != 0)
{
errorTotalLeft += errorLeft;
}
else
{
errorTotalLeft = 0;
}
if(errorRight > integralActiveZone && errorRight != 0)
{
errorTotalRight += errorRight;
}
else
{
errorTotalRight = 0;
}
//proportion values
proportionLeft = errorLeft * Kp;
proportionRight = errorRight * Kp;
//integral values
integralLeft = errorTotalLeft * Ki;
integralRight = errorTotalRight * Ki;
//derivative values
derivativeLeft = (errorLeft - lastErrorLeft) * Kd;
derivativeRight = (errorRight - lastErrorRight) * Kd;
//add P, I, and D to get motor speed
speedLeft = (proportionLeft + integralLeft + derivativeLeft);
speedRight = (proportionRight + integralRight + derivativeRight);
//round speeds to whole number
round(speedLeft);
round(speedRight);
//motors move at speed found
motor(port3) = speedLeft;
motor(port1) = speedRight;
//make error into lastError after loop
lastErrorLeft = errorLeft;
lastErrorRight = errorRight;
wait1Msec(25); //let motors and cortex catch up
}
void turnRight(float degrees)
{
slaveMotor(port7,port5);
slaveMotor(port5,port3);//left
slaveMotor(port6,port4);
slaveMotor(port4,port1); //right
slaveMotor(port10, port2); //flywheel
float errorLeft;
float errorRight;
float errorTotalLeft;
float errorTotalRight;
float lastErrorLeft;
float lastErrorRight;
float proportionLeft;
float proportionRight;
float integralLeft;
float integralRight;
float integralActiveZone = -57;
float derivativeLeft;
float derivativeRight;
float speedLeft;
float speedRight;
//right side back, left side front
//627.2 ticks per revolution
//how many ticks is in 1 degree
errorLeft = (degrees/360) * 4582.131913;
errorRight = (degrees/360) * -4582.131913;
//calculates new error based on distance left from objective
errorLeft = errorLeft - nMotorEncoder[I2C_1];
errorRight = errorRight - nMotorEncoder[I2C_2];
//add hard stop/limit to integral, otherwise motors will keep running
if(errorLeft < integralActiveZone && errorLeft != 0)
{
errorTotalLeft += errorLeft;
}
else
{
errorTotalLeft = 0;
}
if(errorRight > integralActiveZone && errorRight != 0)
{
errorTotalRight += errorRight;
}
else
{
errorTotalRight = 0;
}
//proportion values
proportionLeft = errorLeft * Kp;
proportionRight = errorRight * Kp;
//integral values
integralLeft = errorTotalLeft * Ki;
integralRight = errorTotalRight * Ki;
//derivative values
derivativeLeft = (errorLeft - lastErrorLeft) * Kd;
derivativeRight = (errorRight - lastErrorRight) * Kd;
//add P, I, and D to get motor speed
speedLeft = (proportionLeft + integralLeft + derivativeLeft);
speedRight = (proportionRight + integralRight + derivativeRight);
//round speeds to whole number
round(speedLeft);
round(speedRight);
//motors move at speed found
motor(port3) = speedLeft;
motor(port1) = speedRight;
//make error into lastError after loop
lastErrorLeft = errorLeft;
lastErrorRight = errorRight;
wait1Msec(25); //let motors and cortex catch up
}
void turnLeft(float degrees)
{
slaveMotor(port7,port5);
slaveMotor(port5,port3);//left
slaveMotor(port6,port4);
slaveMotor(port4,port1); //right
slaveMotor(port10, port2); //flywheel
float errorLeft;
float errorRight;
float errorTotalLeft;
float errorTotalRight;
float lastErrorLeft;
float lastErrorRight;
float proportionLeft;
float proportionRight;
float integralLeft;
float integralRight;
float integralActiveZone = -57;
float derivativeLeft;
float derivativeRight;
float speedLeft;
float speedRight;
//left side back, right side front
//627.2 ticks per revolution
//how many ticks is in 1 degree
errorLeft = (degrees/360) * -4582.131913;
errorRight = (degrees/360) * 4582.131913;
//calculates new error based on distance left from objective
errorLeft = errorLeft - nMotorEncoder[I2C_1];
errorRight = errorRight - nMotorEncoder[I2C_2];
//add hard stop/limit to integral, otherwise it will keep motors running
if(errorLeft > integralActiveZone && errorLeft != 0)
{
errorTotalLeft += errorLeft;
}
else
{
errorTotalLeft = 0;
}
//add hard stop/limit to integral otherwise motors will keep running
if(errorRight < integralActiveZone && errorRight != 0)
{
errorTotalRight += errorRight;
}
else
{
errorTotalRight = 0;
}
//proportion values
proportionLeft = errorLeft * Kp;
proportionRight = errorRight * Kp;
//integral values
integralLeft = errorTotalLeft * Ki;
integralRight = errorTotalRight * Ki;
//derivative values
derivativeLeft = (errorLeft - lastErrorLeft) * Kd;
derivativeRight = (errorRight - lastErrorRight) * Kd;
//add P, I, and D to get motor speed
speedLeft = (proportionLeft + integralLeft + derivativeLeft);
speedRight = (proportionRight + integralRight + derivativeRight);
//round speeds to whole number
round(speedLeft);
round(speedRight);
//motors move at speed found
motor(port3) = speedLeft;
motor(port1) = speedRight;
//make error into lastError after loop
lastErrorLeft = errorLeft;
lastErrorRight = errorRight;
wait1Msec(25); //let motors and cortex catch up
}
void pre_auton()
{
bStopTasksBetweenModes = true;
//reset shaft encoders
nMotorEncoder[I2C_1] = 0;
nMotorEncoder[I2C_2] = 0;
task autonomous()
{
moveForward(20);
moveBackward(13);
turnRight(90);
}