![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Leader Robot
Dependencies: Motor PID Servo mbed-rtos mbed
main.cpp
- Committer:
- mpereira30
- Date:
- 2016-12-11
- Revision:
- 0:35cf52223527
File content as of revision 0:35cf52223527:
#include "mbed.h" #include "Servo.h" #include "Motor.h" #include "PID.h" #include "rtos.h" #include <stdlib.h> #define PI 3.1415926 #define threshold 27 //objects Motor rightMotor(p24, p28, p27); // pwm, fwd(in1), rev(in2) Motor B (right wheel) Motor leftMotor(p22, p29, p30); // pwm, fwd(in1), rev(in2) Motor A (left wheel) Timer timer; AnalogIn ain(p20); AnalogIn ainL(p18); AnalogIn ainR(p19); Servo myservo(p26); Serial pc(USBTX, USBRX); Serial xbee1(p13, p14); Mutex wheelMutex; //globals float max_angle = 0.0; int leftPrevPulses = 0; int leftActPulses=0; //pulses from left motor float leftVelocity = 0.0; //The velocity of the left wheel in pulses per second int rightPrevPulses = 0; int rightActPulses=0; //pulses from right motor float rightVelocity = 0.0; //The velocity of the right wheel in pulses per second int turnDistance = 0; //Number of pulses to travel. int distanceR = 0; // in mm int distanceL = 0; // in mm int distanceRold = 0; // in mm int distanceLold = 0; // in mm float X = 0.0; float Y = 0.0; float inc_X = 1.0; float inc_Y = 0.0; float cur_dir = 0.0; bool go; int DistancesR[4]; int DistancesL[4]; //functions void lookaround(void); void go_fwd(void); void turn_R(float); void turn_L(float); void stop(void); void distR(int); void distL(int); int distTransform(float input); void tunePID(void); float find_avg(float a[5]); float to_Rad(float); void go_fwd_thread(void const *argument); void grab_init_direct(void); class Counter { //interrupt driven rotation counter to be used with the feedback control public: Counter(PinName pin) : _interrupt(pin) { // create the InterruptIn on the pin specified to Counter _interrupt.rise(this, &Counter::increment); // attach increment function of this counter instance } void increment() { _count++; } int read() { return _count; } private: InterruptIn _interrupt; volatile int _count; }; Counter leftPulses(p9), rightPulses (p10); //PID leftPid(0.4620, 0.1, 0.0, 0.01); //Kc, Ti, Td //PID rightPid(0.4620, 0.1, 0.0, 0.01); //Kc, Ti, Td PID leftPid(0.462, 0.1, 0.2, 0.01); //Kc, Ti, Td PID rightPid(0.462, 0.1, 0.1, 0.01); //Kc, Ti, Td int main() { tunePID(); xbee1.baud(115200); myservo = 0.65; leftPid.setSetPoint(975); //set velocity goals for PID rightPid.setSetPoint(990); Thread fwdThread(go_fwd_thread); grab_init_direct(); go = true; float middle[5]; float left[5]; float right[5]; while(1){ float mid_avg = 0.0; float left_avg = 0.0; float right_avg = 0.0; timer.start(); while (mid_avg <0.4 && left_avg <0.7 && right_avg <0.4) { middle[0] = ain; middle[1] = ain; middle[2] = ain; middle[3] = ain; middle[4] = ain; mid_avg = find_avg(middle); left[0] = ainL; left[1] = ainL; left[2] = ainL; left[3] = ainL; left[4] = ainL; left_avg = find_avg(left); right[0] = ainR; right[1] = ainR; right[2] = ainR; right[3] = ainR; right[4] = ainR; right_avg = find_avg(right); X = X + inc_X; Y = Y + inc_Y; xbee1.printf("+\n"); xbee1.printf("%.2f\n%.2f\n" ,X ,Y); } go = false; stop(); xbee1.printf("*\n"); xbee1.printf("%4d",timer.read_ms()); timer.stop(); timer.reset(); lookaround(); //fwdThread.signal_set(0x1); if (max_angle >= 45.0) { turn_R((max_angle - 45.0)); cur_dir = cur_dir - (max_angle - 45.0); inc_X = cos(to_Rad(cur_dir)); inc_Y = sin(to_Rad(cur_dir)); xbee1.printf("R\n"); xbee1.printf("%2.1f",(max_angle - 45.0)); } else if (max_angle < 45.0) { turn_L((45.0 - max_angle)); cur_dir = cur_dir + (45.0 - max_angle); inc_X = cos(to_Rad(cur_dir)); inc_Y = sin(to_Rad(cur_dir)); xbee1.printf("L\n"); xbee1.printf("%2.1f",(45.0 - max_angle)); } myservo = 0.65; stop(); wait(0.1); go = true; } // End of while(1)loop - main thread }// End of main() void grab_init_direct(void) { char initdirect[4]; int Count = 0; initdirect[Count] = xbee1.getc(); while(initdirect[Count] != '+') { Count++; initdirect[Count] = xbee1.getc(); } char initdirect2[Count]; for(int i=0; i<Count; i++) { initdirect2[i] = initdirect[i]; } float init_turn = atof(initdirect2); cur_dir = init_turn; turn_R(init_turn); } float find_avg(float a[5]) { return ((a[0] + a[1] + a[2] + a[3] + a[4])/5.0); } void tunePID(void){ leftPid.setInputLimits(0, 3000); leftPid.setOutputLimits(0.0, 0.5); leftPid.setMode(AUTO_MODE); rightPid.setInputLimits(0, 3000); //rightPid.setOutputLimits(0.0, 0.465); rightPid.setOutputLimits(0.0, 0.48); rightPid.setMode(AUTO_MODE); } void stop(void) { wheelMutex.lock(); leftMotor.speed(0.0); rightMotor.speed(0.0); wheelMutex.unlock(); } void turn_R(float deg) { wheelMutex.lock(); leftActPulses=leftPulses.read(); rightActPulses=rightPulses.read(); turnDistance=rightActPulses+(int)deg; while (rightActPulses<turnDistance) { //turn approximately half a revolution leftMotor.speed(0.4); //rotate to the right rightMotor.speed(-0.4); //open loop, because the PID class can't handle negative values leftActPulses=leftPulses.read(); rightActPulses=rightPulses.read(); wait(0.005); } wheelMutex.unlock(); } void turn_L(float deg) { wheelMutex.lock(); leftActPulses=leftPulses.read(); rightActPulses=rightPulses.read(); turnDistance=leftActPulses+(int)deg; while (leftActPulses<turnDistance) { //turn approximately half a revolution leftMotor.speed(-0.4); //rotate to the right rightMotor.speed(0.4); //open loop, because the PID class can't handle negative values leftActPulses=leftPulses.read(); rightActPulses=rightPulses.read(); wait(0.005); } wheelMutex.unlock(); } void lookaround(void) //returns a value between 0 and 90 that represents the best path in the cone of observation { float max; max_angle = 0.0; max = ain; for(float p=0; p<1.0; p += 0.05) { myservo = p; if (max > ain) { max = ain; max_angle = p; } //wait(0.25); wait(0.1); } if (max>0.45){ turn_L(180.0); myservo = 0.65; wait(0.5); } else{ myservo = max_angle; wait(0.5); max_angle = max_angle*90.0 - 13.5; //max_angle = max_angle*90.0; } } float to_Rad(float deg) { return deg * ((PI)/180); } void go_fwd_thread(void const *argument) { while(1){ if(!go) {Thread::yield();} while (go) { wheelMutex.lock(); leftActPulses=leftPulses.read(); leftVelocity = (leftActPulses - leftPrevPulses) / 0.01; leftPrevPulses = leftActPulses; rightActPulses=rightPulses.read(); rightVelocity = (rightActPulses - rightPrevPulses) / 0.01; rightPrevPulses = rightActPulses; leftPid.setProcessValue(fabs(leftVelocity)); leftMotor.speed(leftPid.compute()+0.0075); rightPid.setProcessValue(fabs(rightVelocity)); rightMotor.speed(rightPid.compute()); wheelMutex.unlock(); } } }