Eurobot2012_Primary
Dependencies: mbed Eurobot_2012_Primary
main.cpp
- Committer:
- narshu
- Date:
- 2012-04-20
- Revision:
- 0:f3bf6c7e2283
- Child:
- 1:bbabbd997d21
File content as of revision 0:f3bf6c7e2283:
#include "mbed.h" #include "rtos.h" #include "TSH.h" #include "Kalman.h" #include "globals.h" #include "motors.h" #include "math.h" #include "system.h" //#include <iostream> //Interface declaration //I2C i2c(p28, p27); // sda, scl TSI2C i2c(p28, p27); Serial pc(USBTX, USBRX); // tx, rx Serial IRturret(p13, p14); DigitalOut OLED1(LED1); DigitalOut OLED2(LED2); DigitalOut OLED3(LED3); DigitalOut OLED4(LED4); int16_t face; Motors motors; Kalman kalman(motors); float targetX = 1000, targetY = 1000, targetTheta = 0; // bytes packing for IR turret serial comm union IRValue_t { float IR_floats[6]; int IR_ints[6]; unsigned char IR_chars[24]; } IRValues; //TODO mutex on kalman state, and on motor commands (i.e. on the i2c bus) //NOTE! Recieving data with RF12B now DISABLED due to interferance with rtos! void vMotorThread(void const *argument); void vPrintState(void const *argument); void ai_thread (void const *argument); void motion_thread(void const *argument); void vIRValueISR (void); void motorSpeedThread(void const *argument); float getAngle (float x, float y); void getIRValue(void const *argument); //Thread thr_AI(ai_thread); //Thread thr_motion(motion_thread); //Thread thr_getIRValue(getIRValue); Mutex targetlock; bool flag_terminate = false; float temp = 0; //Main loop int main() { motors.stop(); pc.baud(115200); IRturret.baud(9600); IRturret.format(8,Serial::Odd,1); //Thread thread(motorSpeedThread, NULL, osPriorityAboveNormal); //PID controller task. run at 50ms //IRturret.attach(&vIRValueISR); //Thread tMotorThread(vMotorThread,NULL,osPriorityNormal,256); Thread tUpdateState(vPrintState,NULL,osPriorityNormal,1024); pc.printf("We got to main! ;D\r\n"); //REMEMBERT TO PUT PULL UP RESISTORS ON I2C!!!!!!!!!!!!!! while (1) { // do nothing Thread::wait(osWaitForever); } } void motorSpeedThread(void const *argument) { while (1) { motors.speedRegulatorTask(); Thread::wait(10); } } void vMotorThread(void const *argument) { motors.resetEncoders(); while (1) { motors.setSpeed(20,-20); Thread::wait(2000); motors.stop(); Thread::wait(5000); motors.setSpeed(-20,20); Thread::wait(2000); motors.stop(); Thread::wait(5000); } } void vPrintState(void const *argument) { float state[3]; float sonardist[3]; //float x,y; //float d = beaconpos[2].y - beaconpos[1].y; //float i = beaconpos[0].y; //float j = beaconpos[0].x; while (1) { kalman.statelock.lock(); state[0] = kalman.X(0); state[1] = kalman.X(1); state[2] = kalman.X(2); sonardist[0] = kalman.SonarMeasures[0]*1000.0f; sonardist[1] = kalman.SonarMeasures[1]*1000.0f; sonardist[2] = kalman.SonarMeasures[2]*1000.0f; kalman.statelock.unlock(); // trilateration algorithm //y = ((sonardist[1]*sonardist[1]) - (sonardist[2]*sonardist[2]) + d*d) / (2*d); //x = ((sonardist[1]*sonardist[1]) - (sonardist[0]*sonardist[0]) + i*i + j*j) / (2*j) - (i/j)*y; //kalman.statelock.lock(); pc.printf("\r\n"); //printf("Position X: %0.1f Y: %0.1f \r\n", x,y); pc.printf("current: %0.4f %0.4f %0.4f \r\n", state[0], state[1],state[2]); //targetlock.lock(); //pc.printf("target : %0.4f %0.4f %0.4f \r\n", targetX/1000, targetY/1000,targetTheta); //targetlock.unlock(); printf("Sonar Dist: %0.4f, %0.4f, %0.4f \r\n", sonardist[0],sonardist[1],sonardist[2]); //printf("Distance is %0.1f, %0.1f \r\n", motors.encoderToDistance(motors.getEncoder1()), motors.encoderToDistance(motors.getEncoder2())); //pc.printf("IR ang : %f \n",temp * 180/3.14); //kalman.statelock.unlock(); Thread::wait(200); } } // AI thread ------------------------------------ void ai_thread (void const *argument) { // goes to the mid Thread::signal_wait(0x01); targetlock.lock(); targetX = 1500; targetY = 1000; targetTheta = PI/2; targetlock.unlock(); // left roll Thread::signal_wait(0x01); targetlock.lock(); targetX = 500; targetY = 1700; targetTheta = PI/2; targetlock.unlock(); // mid Thread::signal_wait(0x01); targetlock.lock(); targetX = 1500; targetY = 1000; targetTheta = PI/2; targetlock.unlock(); // map Thread::signal_wait(0x01); targetlock.lock(); targetX = 1500; targetY = 1700; targetTheta = PI/2; targetlock.unlock(); // mid Thread::signal_wait(0x01); targetlock.lock(); targetX = 1500; targetY = 1000; targetTheta = -PI; targetlock.unlock(); // home Thread::signal_wait(0x01); targetlock.lock(); targetX = 500; targetY = 500; targetTheta = 0; targetlock.unlock(); Thread::signal_wait(0x01); flag_terminate = true; //OLED3 = true; while (true) { Thread::wait(osWaitForever); } } // motion control thread ------------------------ void motion_thread(void const *argument) { motors.resetEncoders(); motors.setSpeed(20,20); Thread::wait(2000); motors.stop(); //thr_AI.signal_set(0x01); float currX, currY,currTheta; float speedL,speedR; float diffDir,diffSpeed; float lastdiffSpeed = 0; while (1) { if (flag_terminate) { terminate(); } // get kalman localization estimate ------------------------ kalman.statelock.lock(); currX = kalman.X(0)*1000.0f; currY = kalman.X(1)*1000.0f; currTheta = kalman.X(2); kalman.statelock.unlock(); // get IR turret angle -------------------------------------- /* float angEst = getAngle(currX, currY); // check this if (angEst != 1000){ // here the value should be a valid estimate // so update kalman state } */ //!!! add code here to update kalman angle state !!! // check if target reached ---------------------------------- if ( ( abs(currX - targetX) < POSITION_TOR ) &&( abs(currY - targetY) < POSITION_TOR ) ) { diffDir = rectifyAng(currTheta - targetTheta); diffSpeed = diffDir / PI; //pc.printf("%f \n",diffDir); if (abs(diffDir) > ANGLE_TOR) { if (abs(diffSpeed) < 0.5) { diffSpeed = 0.5*diffSpeed/abs(diffSpeed); } motors.setSpeed( int(diffSpeed*MOVE_SPEED), -int(diffSpeed*MOVE_SPEED)); } else { motors.stop(); Thread::wait(4000); //thr_AI.signal_set(0x01); } } // adjust motion to reach target ---------------------------- else { // calc direction to target float targetDir = atan2(targetY - currY, targetX - currX); diffDir = rectifyAng(currTheta - targetDir); diffSpeed = diffDir / PI; if (abs(diffDir) > ANGLE_TOR*2) { if (abs(diffSpeed) < 0.5) { diffSpeed = 0.5*diffSpeed/abs(diffSpeed); } motors.setSpeed( int(diffSpeed*MOVE_SPEED), -int(diffSpeed*MOVE_SPEED)); } else { if (abs(diffSpeed-lastdiffSpeed) > MAX_STEP_RATIO ) { if (diffSpeed-lastdiffSpeed >= 0) { diffSpeed = lastdiffSpeed + MAX_STEP_RATIO; } else { diffSpeed = lastdiffSpeed - MAX_STEP_RATIO; } } lastdiffSpeed = diffSpeed; // calculte the motor speeds if (diffSpeed <= 0) { speedL = (1-2*abs(diffSpeed))*MOVE_SPEED; speedR = MOVE_SPEED; } else { speedR = (1-2*abs(diffSpeed))*MOVE_SPEED; speedL = MOVE_SPEED; } motors.setSpeed( int(speedL), int(speedR)); } } // wait Thread::wait(MOTION_UPDATE_PERIOD); } } void getIRValue(void const *argument) { Thread::signal_wait(0x01); if (IRturret.readable() >= 24) { for (int i=0; i < 24; i++) { IRValues.IR_chars[i] = IRturret.getc(); } } } void vIRValueISR (void) { //thr_getIRValue.signal_set(0x01); } float getAngle (float x, float y) { /* function that returns current robot orientation input: x, y coords in mm output: orientation in rad note: the angle readings from IR is read in here must be called faster than IR turret frequency (few Hz - currently 3Hz) */ // variables float ang0 = 0, ang1 = 0, ang2 = 0; int sc0 = 0, sc1 = 0, sc2 = 0; // read serial port if (IRturret.readable()) { IRturret.scanf("%f;%f;%f;%d;%d;%d;",&ang0,&ang1,&ang2,&sc0,&sc1,sc2); } // if none sampled if (!sc0 && !sc1 && ! sc2) { return 1000; } // else { float est0 = 0, est1 = 0, est2 = 0; // calc if ((sc0 > RELI_BOUND_LOW)||(sc0 < RELI_BOUND_HIGH)) { est0 = atan2(1000 - y, 3000-x) - ang0; } if ((sc1 > RELI_BOUND_LOW)||(sc1 < RELI_BOUND_HIGH)) { est1 = atan2( -y, -x) - ang1; } if ((sc2 > RELI_BOUND_LOW)||(sc2 < RELI_BOUND_HIGH)) { est2 = atan2(2000 - y, -x) - ang2; } // weighted avg return rectifyAng( ((est0 * RELI_BOUND_HIGH-sc0) + (est1 * RELI_BOUND_HIGH-sc1) + (est2 * RELI_BOUND_HIGH-sc2)) / (3*RELI_BOUND_HIGH - sc0 - sc1 - sc2) ); } }