Massey 2017, Group 5, AGV control software.
Dependencies: Commands charQueue esp8266-driver
Drive/drive.cpp
- Committer:
- williampeers
- Date:
- 2017-08-23
- Revision:
- 1:87d8ac1a1e94
- Parent:
- 0:91703b1eb29e
File content as of revision 1:87d8ac1a1e94:
#include "driver.h" Driver::Driver(osPriority priority, int memory) : pidR(KP, KI, KD, 0.1, -1*PWMPERIOD, PWMPERIOD, AUTOMATIC, DIRECT), pidL(KP, KI, KD, PIDSAMPLERATE, -1*PWMPERIOD, PWMPERIOD, AUTOMATIC, REVERSE), l_encoder1(PB_4), l_encoder2(PB_5), r_encoder1(PA_0), r_encoder2(PA_1), left_motor(PB_10), left_motor_rev(PA_8), right_motor(PA_15), right_motor_rev(PB_7), my_led(LED1) { driver_thread(priority, memory); lSpeedGoal = 0;//Goal motor RPM rSpeedGoal = 0; l_RPM = 0;//Measured current speed r_RPM = 0; //my_led = DigitalOut(LED1); LoutA = 0x00; //Holds left output A of encoder signal LoutB = 0x00; //Holds left output B of encoder signal RoutA = 0x00; //Holds Right output A of encoder signal RoutB = 0x00; //Holds Right output B of encoder signal l_enc_val = 0x00; //Sequence that holds current and previous encoder combination values r_enc_val = 0x00; l_enc_direction = 1; r_enc_direction = 1; l_enc_count = 0; //Holds counter of encoder pulses r_enc_count = 0; //Holds counter of encoder pulses l_old_enc_count = 0x00; //Hold old encounter value for computation r_old_enc_count = 0x00; } void Driver::l_encode_trig() { static int8_t lookup_table[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0}; LoutA = l_encoder2.read(); LoutB = l_encoder1.read(); l_enc_val = l_enc_val << 2; LoutA = LoutA <<1; l_enc_val = l_enc_val | LoutA | LoutB; l_enc_count += lookup_table[l_enc_val & 0x0F]; } void Driver::r_encode_trig() { static int8_t lookup_table[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0}; RoutA = r_encoder2.read(); RoutB = r_encoder1.read(); r_enc_val = r_enc_val << 2; RoutA = RoutA <<1; r_enc_val = r_enc_val | RoutA | RoutB; r_enc_count += lookup_table[r_enc_val & 0x0F]; } void Driver::run() { float rSpeed, lSpeed; left_motor.period_us(PWMPERIOD); left_motor_rev.period_us(PWMPERIOD); right_motor.period_us(PWMPERIOD); right_motor_rev.period_us(PWMPERIOD); l_encoder1.rise(callback(this, &Driver::l_encode_trig)); //Out A of encoder rises l_encoder1.fall(callback(this, &Driver::l_encode_trig)); //Out A of encoder falls l_encoder2.rise(callback(this, &Driver::l_encode_trig)); //Out B of encoder rises l_encoder2.fall(callback(this, &Driver::l_encode_trig)); //Out B of encoder falls r_encoder1.rise(callback(this, &Driver::r_encode_trig)); //Out A of encoder rises r_encoder1.fall(callback(this, &Driver::r_encode_trig)); //Out A of encoder falls r_encoder2.rise(callback(this, &Driver::r_encode_trig)); //Out B of encoder rises r_encoder2.fall(callback(this, &Driver::r_encode_trig)); //Out B of encoder falls Timer timer; timer.start(); int timerOld = 0; while(true) { Thread::wait(100); if(timer.read_ms() > 100) { timer.reset(); /*right_motor.pulsewidth_us(2000); right_motor_rev.pulsewidth_us(0); left_motor.pulsewidth_us(2000); left_motor_rev.pulsewidth_us(0);*/ /*Calculate rpm from encoder counts*/ r_RPM = (r_enc_count - r_old_enc_count) * 5*60/(51.45*12); r_old_enc_count = r_enc_count; l_RPM = (l_enc_count - l_old_enc_count) * 5*60/(51.45*12); l_old_enc_count = l_enc_count; /*Give motor speeds to pid controller*/ pidR.PIDInputSet(r_RPM); pidL.PIDInputSet(l_RPM); pidR.PIDCompute(); pidL.PIDCompute(); /*Get new pwm output from PID controller and set pwm on motors*/ lock.lock(); rSpeed = pidR.PIDOutputGet(); lSpeed = pidL.PIDOutputGet(); printf("r_RPM: [%d] rSpeed: [%f]\n\r", r_RPM, rSpeed); printf("l_RPM: [%d] lSpeed: [%f]\n\r", l_RPM, lSpeed); if (rSpeed > 0) { right_motor_rev.pulsewidth_us(abs((long)rSpeed)); right_motor.pulsewidth_us(0); } else { right_motor_rev.pulsewidth_us(0); right_motor.pulsewidth_us(abs((long)rSpeed)); } if (lSpeed > 0) { left_motor_rev.pulsewidth_us(abs((long)lSpeed)); left_motor.pulsewidth_us(0); } else { left_motor_rev.pulsewidth_us(0); left_motor.pulsewidth_us(abs((long)lSpeed)); } lock.unlock(); } else { Thread::wait(1000); } } } void Driver::start() { driver_thread.start(callback(this, &Driver::run)); } void Driver::setVelocity(int lSpeed, int rSpeed) { lock.lock(); lSpeedGoal = lSpeed; //Goal motor speed NEEDS CONVERSION FROM ms-1 to RPM rSpeedGoal = rSpeed; pidR.PIDSetpointSet(rSpeedGoal); pidL.PIDSetpointSet(lSpeedGoal); lock.unlock(); }