micrmouse
Dependencies: AVEncoder mbed-src-AV
Diff: main.cpp
- Revision:
- 0:394261695392
diff -r 000000000000 -r 394261695392 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Fri Mar 18 07:42:11 2016 +0000 @@ -0,0 +1,328 @@ +//ADJUST VARIABLES SECTION + +const int preRunLength = 1600; +const int postRunLength = 0; +const int turnLength = 850; +const float leftAngleTurnThreshhold = -.045; +const float rightAngleTurnThreshhold = -.06; +const float baseSpeed = 0.25; + +#include "PinDefinitions.h" + +//PROTOTYPES +void motorCorrections(); +float getLSreading(); +float getLAreading(); +float getRAreading(); +float getRSreading(); +float pidCorrection(int error); +float proportion(int error); +int derivative(int error); +float integral(int error); +void setRightPwm(float speed); +void setLeftPwm(float speed); +void postTurnRun(); +void preTurnRun(); + +Serial pc(PA_11, PA_12); //SERIAL TX/RX +DigitalOut myled(LED1); + +Ticker PIDcorrectionTicker; +Ticker gyroOffsetCalc; + +float baselineRS; +float baselineLS; +float baselineLA; +float baselineRA; + + +bool safeToRunSystick; +int rightPulses; +int leftPulses; +float currentAngle = 0; +float refreshTimeSeconds = 0.05; //How fast the systicker is going +const int flashTime = 20; //The amount of time sensors are on before we take measurment (millisecond) + +int prevError; +int integrator = 0; +int decayFactor = 1.1; +float Kp = 0.001; +//Kd = +float Ki = 0.002; + +//FOR THE SENSORS RUN WHEN DARK TO FIND AMBIENT LIGHT +//HOW LONG DO I NEED TO TURN ON SENSORS TO GET A READING? 1MS? NO TIME AT ALL? + + + +void motorCorrections() //Three things, I should probably break into three functions!! +{ + if(safeToRunSystick) { + int rightPulses = RENC.getPulses(); + int leftPulses = LENC.getPulses(); + //we want the difference which is the error + int errorEncoder = rightPulses - leftPulses; + float correction = pidCorrection(errorEncoder); + if(correction > 0.5) + correction = 0.5; + else if(correction < -0.5) + correction = -0.5; + setRightPwm(baseSpeed-correction); + setLeftPwm(baseSpeed+correction); + //pc.printf("Error:%.6f \r\i", correction); + //pc.printf("Gyro Raw: %.6f \r\n", currentAngle); + RENC.reset(); + LENC.reset(); + myled = !myled; + } +} + + +float getLSreading() +{ + int ambient = IRSensorLS.read(); //Ambient Reading + IRledLS.write(1); + wait_ms(flashTime); //Maybe we can decrease this amount + float sensorReading = IRSensorLS.read(); //Will get the reading + IRledLS.write(0); + return sensorReading - ambient; //Ideally we will get pure IR reading + +} + +float getLAreading() +{ + int ambient = IRSensorLA.read(); //Ambient Reading + IRledLA.write(1); + wait_ms(flashTime); //Maybe we can decrease this amount + float sensorReading = IRSensorLA.read(); //Will get the reading + IRledLA.write(0); + return sensorReading - ambient; //Ideally we will get pure IR reading +} + +float getRAreading() +{ + int ambient = IRSensorRA.read(); //Ambient Reading + IRledRA.write(1); + wait_ms(flashTime); //Maybe we can decrease this amount + float sensorReading = IRSensorRA.read(); //Will get the reading + IRledRA.write(0); + return sensorReading - ambient; //Ideally we will get pure IR reading +} + +float getRSreading() +{ + int ambient = IRSensorRS.read(); //Ambient Reading + IRledRS.write(1); + wait_ms(flashTime); //Maybe we can decrease this amount + float sensorReading = IRSensorRS.read(); //Will get the reading + IRledRS.write(0); + return sensorReading - ambient; //Ideally we will get pure IR reading +} +//The correction will be given in difference that power should be writen to the motors. We will chose baseline speed for both +float pidCorrection(int error) +{ + return proportion(error) + integral(error); + // +derivative(error) +} + +float proportion(int error) +{ + return Kp*error; +} +/* +int derivative(int error){ + int dError = error - prevError; + int dt = timer.read_us(); + timer.reset(); + prevError = error; + int correctionD = -(Kd*dError)/dt; + return correctionD; +} +*/ +float integral(int error) +{ + integrator +=error; + integrator /= decayFactor; + return Ki*integrator; +} + + +void setRightPwm(float speed) +{ + if (speed == 0) { + RMOTORA = 1.0; + RMOTORB = 1.0; + } + + if (speed > 0) { + RMOTORA = speed; + RMOTORB = 0; + } else { + RMOTORA = 0; + RMOTORB = -speed; + } +} + +void setLeftPwm(float speed) +{ + if (speed == 0) { + LMOTORA = 1.0; + LMOTORB = 1.0; + } + + if (speed > 0) { + LMOTORA = speed; + LMOTORB = 0; + } else { + LMOTORA = 0; + LMOTORB = -speed; + } +} + +void setBaselines() +{ + baselineLS = getLSreading(); + baselineRS = getRSreading(); + baselineLA = getLAreading(); + baselineRA = getRAreading(); +} + + +void turnAround() +{ + safeToRunSystick = false; + RENC.reset(); + LENC.reset(); + setRightPwm(-.1); + setLeftPwm(.1); + myled = !myled; + while(RENC.getPulses() < 1700 && LENC.getPulses() < 1700) { + } + pc.printf("WE MADE IT OUT \r\n"); + myled = 0; + setRightPwm(0); + setLeftPwm(0); + wait(0.2); + RENC.reset(); + LENC.reset(); + safeToRunSystick = true; + +} + +void turnLeft() +{ + safeToRunSystick = false; + preTurnRun(); + //Now should be in position to turn + setRightPwm(.1); + setLeftPwm(-.1); + RENC.reset(); + LENC.reset(); + myled = !myled; + while(RENC.getPulses() < turnLength && LENC.getPulses() < turnLength) {} + setRightPwm(0); + setLeftPwm(0); + wait(0.2); + safeToRunSystick = true; + //At this point the car should be pivoted + postTurnRun(); +} + +void turnRight() +{ + safeToRunSystick = false; + preTurnRun(); + //Now should be in position to turn + setRightPwm(-.1); + setLeftPwm(+.1); + RENC.reset(); + LENC.reset(); + myled = !myled; + while(RENC.getPulses() < turnLength && LENC.getPulses() < turnLength) {} + setRightPwm(0); + setLeftPwm(0); + wait(0.2); + postTurnRun(); + safeToRunSystick = true; + //At this point the car should be pivoted +} + + + +void preTurnRun(){ //this code runs before and after every turn to ensure that the car is positioned at the right spot when it turns + RENC.reset(); + LENC.reset(); + int rightPulses = 0; + int leftPulses = 0; + //we want the difference which is the error + while(RENC.getPulses() < preRunLength && LENC.getPulses() < preRunLength) { + rightPulses = RENC.getPulses() - rightPulses; + leftPulses = LENC.getPulses() - leftPulses; + int errorEncoder = rightPulses - leftPulses; + float correction = proportion(errorEncoder); + if(correction > 0.5) + correction = 0.5; + else if(correction < -0.5) + correction = -0.5; + setRightPwm(baseSpeed-correction); + setLeftPwm(baseSpeed+correction); + } +} + +void postTurnRun(){ //this code runs before and after every turn to ensure that the car is positioned at the right spot when it turns + RENC.reset(); + LENC.reset(); + int rightPulses = 0; + int leftPulses = 0; + //we want the difference which is the error + while(RENC.getPulses() < postRunLength && LENC.getPulses() < postRunLength) { + rightPulses = RENC.getPulses() - rightPulses; + leftPulses = LENC.getPulses() - leftPulses; + int errorEncoder = rightPulses - leftPulses; + float correction = proportion(errorEncoder); + if(correction > 0.5) + correction = 0.5; + else if(correction < -0.5) + correction = -0.5; + setRightPwm(baseSpeed-correction); + setLeftPwm(baseSpeed+correction); + } +} + +int main() +{ + wait(0.2); + myled =1; + wait(0.5); + myled =0; + wait(0.2); + setBaselines(); + safeToRunSystick = true; + PIDcorrectionTicker.attach(&motorCorrections, refreshTimeSeconds); + while(1) { + //Turns if theres a wall infront of it + myled = !myled; + float leftSSensor = getLSreading(); + float rightSSensor = getRSreading(); + if((leftSSensor > 0.1 + baselineLS) || (rightSSensor > 0.1 + baselineRS)) { + // turnAround(); + } + float leftASensor = getLAreading(); + float rightASensor = getRAreading(); + + float leftAStrig = leftASensor- baselineLA; + float rightAStrig = rightASensor-baselineRA; + + if(rightAStrig < rightAngleTurnThreshhold) + turnRight(); + else if(leftAStrig < leftAngleTurnThreshhold) + turnLeft(); + + + //pc.printf("Left angle: %.6f \r\n", leftASensor); + // pc.printf("Right angle: %.6f Left angle: %.6f \r\n", rightAStrig, leftAStrig); + // pc.printf("Gyro accum: %.6f \r\n", accumGyro); + + + } +}