![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
UCR Robosub manual control / PID tuning interface
main.cpp
- Committer:
- roger_wee
- Date:
- 2017-07-22
- Revision:
- 0:048a74dd7c3a
- Child:
- 1:3f291f2f80d3
File content as of revision 0:048a74dd7c3a:
//Robosub Control Interface #include "mbed.h" #include "IMU.h" #include "PID.h" #include "HMC5883L.h" //------------Declare Objects------------------// PwmOut m1(D3); PwmOut m2(D4); PwmOut m3(D5); PwmOut m4(D6); // Declare mpu6050 and compass object MPU6050 mpu1; HMC5883L compass; // Serial communication between Arduino NANO RawSerial device(PA_11, PA_12); //TX RX //-----------Global Variables------------------// char command = 0; Timer calibrate; int pwmMax = 1100; // Reversed due to motor orientation int pwmMin = 1500; // PWM output variable for each motor int m1pwm = pwmMin; int m2pwm = pwmMin; int m3pwm = pwmMin; int m4pwm = pwmMin; // Individual pid parameters double myYaw, yawPoint, yawOut; double myPitch, pitchPoint, pitchOut; double myRoll, rollPoint, rollOut; double myDepth, depthPoint, depthOut; int depth = 1; double kpVal = 0; //-----------End Global Variables--------------// //----PID objects------// // Input, Output, SetPoint, kp, ki, kd, Controller Direction PID pidy(&myYaw, &yawOut, &yawPoint, 1, 1, 1, DIRECT); PID pidp(&myPitch, &pitchOut, &pitchPoint, 1, 1, 1, DIRECT); PID pidr(&myRoll, &rollOut, &rollPoint, 1, 1, 1, DIRECT); PID pidd(&myDepth, &depthOut, &depthPoint, 1, 1, 1, DIRECT); //----End PID objects--// //-----------Helper functions------------------// void calibrateFilter() { calibrate.start(); while(calibrate.read() < 10) { IMUPrintData(mpu1, compass); char text[90]; sprintf(text, "%f,%f,%f \n", yaw, pitch, roll); pc.printf("%s", text); } calibrate.stop(); } void updateMotors() { m1.pulsewidth_us(m1pwm); m2.pulsewidth_us(m2pwm); m3.pulsewidth_us(m3pwm); m4.pulsewidth_us(m4pwm); } void neutralizeMotors() { m1pwm = pwmMin; m2pwm = pwmMin; m3pwm = pwmMin; m4pwm = pwmMin; updateMotors(); } void readUserInput() { if(pc.readable()) { command = pc.getc(); } } void initializePIDs() { pidy.SetMode(AUTOMATIC); // Yaw PID pidy.SetOutputLimits(pwmMin, pwmMax); pidp.SetMode(AUTOMATIC); // Pitch PID pidp.SetOutputLimits(pwmMin, pwmMax); pidr.SetMode(AUTOMATIC); // Roll PID pidr.SetOutputLimits(pwmMin, pwmMax); pidd.SetMode(AUTOMATIC); // Depth PID pidd.SetOutputLimits(pwmMin, pwmMax); depthPoint = 0; } void readDepth() { // Read pressure sensor data if available if (device.readable()) { // Receive depth in inches as an integer depth = device.getc(); // Convert to feet } } void displayTelemetry() { char text[90]; sprintf(text, "%f,%f,%f,%d \n", yaw, pitch, roll, depth); pc.printf("%s", text); } //-----------End Helper functions--------------// //-----------Interface States------------------// enum controlStates { init, idle, manual, preparePid, beginTune } controlState; void controlInterface(){ switch(controlState) //Actions { case init: pc.printf("Initialize sensors \n"); IMUinit(mpu1); compass.init(); pc.printf("Initialize motors \n"); neutralizeMotors(); pc.printf("Initialize PID objects \n"); initializePIDs(); pc.printf("Calibrate MARG Filter \n"); calibrateFilter(); break; case idle: IMUPrintData(mpu1, compass); readDepth(); displayTelemetry(); break; case manual: //pc.printf("Manual Control \n"); switch(command) { case 'N': //pc.printf("Neutralize motors\n"); neutralizeMotors(); break; case 'R': //pc.printf("Reduce Thrust\n"); if (m1pwm < pwmMin) { m1pwm++; m2pwm++; m3pwm++; m4pwm++; } break; case 'I': //pc.printf("Increase Thrust\n"); if (m1pwm > pwmMax) { m1pwm--; m2pwm--; m3pwm--; m4pwm--; } break; default: break; } updateMotors(); break; case preparePid: // pc.printf("Prepare PID \n"); switch(command) { case 'I': // Increase Kp gain kpVal += .1; break; case 'R': if (kpVal > 0 ) // Decreae Kp gain { kpVal -= .1; } break; case 'S': // Increase depth depthPoint++; case 's': // Decrease setpoint if(depthPoint > 0) { depthPoint--; } break; default: break; } // Set tunings pidd.SetTunings(kpVal,0,0); //Set Ki Kd = 0 // Print Set parameters pc.printf("DepthPoint: %d \n", depthPoint); pc.printf("Kp gain: %d \n", pidd.GetKp()); break; case beginTune: //pc.printf("Tuning process begins.. \n"); // Sense inertial / depth data IMUPrintData(mpu1, compass); readDepth(); // Assign feedback variables myDepth = depth; // Compute PID pidd.Compute(); // Output pwm to motors // FIXME : account for pitch, roll and maybe yaw depending on motor configuration m1pwm = m2pwm = m3pwm = m4pwm = depthOut; updateMotors(); // Display telemetry displayTelemetry(); break; default: pc.printf("Error! \n"); break; } switch(controlState) //Transitions { case init: controlState = idle; break; case idle: controlState = (command == 'm') ? manual : ((command == 'p') ? preparePid : idle); break; case manual: controlState = (command == 'p') ? preparePid : manual; if (controlState == preparePid) { //pc.printf("Neutralize Motors \n"); neutralizeMotors(); } break; case preparePid: controlState = (command == 'g') ? beginTune : preparePid; break; case beginTune: controlState = (command == 't') ? preparePid : beginTune; if (controlState == preparePid) { //pc.printf("Neutralize Motors \n"); neutralizeMotors(); } break; default: break; } } //-----------End Interface---------------------// int main() { // Initialize control state controlState = init; while(1) { // Read user input readUserInput(); // Begin Interface controlInterface(); } }