Nico van Duijn
/
AwkwardSegway
Robot that balances on two wheels
Fork of EpilepticSegway by
Diff: main.cpp
- Revision:
- 3:89e4ed1324bb
- Parent:
- 2:89ada0b0b923
- Child:
- 4:51ea148fc592
--- a/main.cpp Tue Apr 28 02:18:55 2015 +0000 +++ b/main.cpp Wed Apr 29 20:10:33 2015 +0000 @@ -29,7 +29,7 @@ // Constants #define LSM9DS0_XM_ADDR 0x1D // Would be 0x1E if SDO_XM is LOW #define LSM9DS0_G_ADDR 0x6B // Would be 0x6A if SDO_G is LOW -//#define DEBUG // Comment this out for final version +//#define DEBUG // Comment this out for final version ////////////////////////////////////////////////////////////////// // I/O and object instatiation @@ -41,22 +41,19 @@ DigitalOut NmotorDirRight(p25); // Usually inverse of motorDirRight LSM9DS0 imu(p9, p10, LSM9DS0_G_ADDR, LSM9DS0_XM_ADDR); // Creates on object for IMU Ticker start; // Initialize ticker to call control function -Ticker GUI; -//Serial xbee(p13, p14); // Creates virtual serial for xbee -Serial pc(USBTX,USBRX);// later only use xbee -Timer t; //debugging only -DigitalOut led1(LED1); // debug only -DigitalOut led2(LED2); // debug only -DigitalOut led3(LED3); // debug only -typedef union _data { // maybe there is a better way? +Ticker GUI; // Ticker that calls the updateGUI +DigitalOut led1(LED1); // Use LED1 to provide some runtime info +Serial xbee(p13,p14); // Create serial port for Xbee + +typedef union _data { // Typedef so we can jump from chars to floats float f; char chars[4]; - int i; // added to receive integers + int i; } myData; - ////////////////////////////////////////////////////////////////// // Globals // double battery, lab floor: 67/100/600/160 cutoff ..35 +// positive turns float kp = 59; //98 // 145 Proportional gain kU 400-500 float kd = 105; //200 // Derivative gain float ki = 670; //985 // Integrative gain @@ -70,33 +67,32 @@ float dAngle = 0; // Derivative value for angle, angular velocity, how fast angle is changing float pAngle = 0; // Proportional value for angle, current angle (best measurement) float desiredAngle=0; // Setpoint. Set unequal zero to drive -float turnspeed=0; // positive turns -myData bytes; +float turnspeed=0; // Makes the robot turn +myData bytes; // Used to convert received/sent chars to ints and floats + ////////////////////////////////////////////////////////////////// // Function Prototypes void drive(float); // Function declaration for driving the motors void calibrate(); // Function to calibrate gyro and accelerometer void control(); // Function implementing PID control -void callback(); // Interrupt triggered function for serial communication -void sendFloatAsBytes(); void updateGUI(); +void checkValues(); + ////////////////////////////////////////////////////////////////// // Main function int main() { - - led1=0;//debug only + led1=0; // Turn led off uint16_t status = imu.begin(); // Use the begin() function to initialize the LSM9DS0 library. - pc.baud(115200);//pretty high, check if lower possible - pc.attach(&callback); // Attach interrupt to serial communication + xbee.baud(115200); // Baudrate. Pretty high, check if lower possible calibrate(); // Calibrate gyro and accelerometer start.attach(&control, 0.01); // Looptime 10ms ca. 100Hz - GUI.attach(&updateGUI, 0.5); // update GUI twice a second + GUI.attach(&updateGUI, 0.5); // Update GUI twice a second - while(1) { // Stay in this loop forever - led1=!led1; - wait_ms(500); // blink twice a second + while(1) { // Stay in this loop forever + led1=!led1; // Blink led1 to make sure the loop is running + wait_ms(500); // Looptime 500ms } } @@ -119,6 +115,7 @@ else if(speed>1) speed=1; // Cap if overshoot } else speed=0; // If we've fallen over or are steady on top drive(speed); // Write speed to the motors + checkValues(); // Checks if we need to update some values } @@ -180,86 +177,85 @@ gyroBias=gyroBias/100; // Convert sum to average } -///////////////////////////////////////////////////////////////// -// Callback function to change values/gains -void callback() + +/////////////////////////////////////////////////////////////////// +// updateGUI(), triggered by ticker GUI ever 0.5s, sends data to xbee +void updateGUI() { - led2=!led2; // Blink led2 so we know what's happening - char buffer[24]; //create a buffer - int i=0; - while(pc.readable()) { // read the whole damn thing - buffer[i]=pc.getc(); - i++; - } -// update kp - bytes.chars[0]=buffer[0]; - bytes.chars[1]=buffer[1]; - bytes.chars[2]=buffer[2]; - bytes.chars[3]=buffer[3]; - kp=bytes.i; -// update ki - bytes.chars[0]=buffer[4]; - bytes.chars[1]=buffer[5]; - bytes.chars[2]=buffer[6]; - bytes.chars[3]=buffer[7]; - ki=bytes.i; -// update kd - bytes.chars[0]=buffer[8]; - bytes.chars[1]=buffer[9]; - bytes.chars[2]=buffer[10]; - bytes.chars[3]=buffer[11]; - kd=bytes.i; -// update OVERALL_SCALAR - bytes.chars[0]=buffer[12]; - bytes.chars[1]=buffer[13]; - bytes.chars[2]=buffer[14]; - bytes.chars[3]=buffer[15]; - OVERALL_SCALAR=bytes.i; -// update turnspeed - bytes.chars[0]=buffer[16]; - bytes.chars[1]=buffer[17]; - bytes.chars[2]=buffer[18]; - bytes.chars[3]=buffer[19]; - turnspeed=bytes.i; -// update desiredAngle - bytes.chars[0]=buffer[20]; - bytes.chars[1]=buffer[21]; - bytes.chars[2]=buffer[22]; - bytes.chars[3]=buffer[23]; - desiredAngle=bytes.i; - - - // Update kp min: 0 max: 3000 - // Update kd min: 0 max: 3000 - // Update ki min: 0 max: 3000 - // Update OVERALL_SCALAR min: 0 max: 3000 - // Update turnspeed min: -0.5 max: 0.5 - // Update desiredAngle min: -3 max: 3 - // Send pAngle BETTER: kp*pAngle - // Send dAngle BETTER: kd*dAngle - // Send iAngle BETTER: kd*dAngle + xbee.putc('*'); // Send data validity value + bytes.f = accBias; // Send accBias + xbee.printf("%c%c%c%c", bytes.chars[0], bytes.chars[1], bytes.chars[2], bytes.chars[3]); + bytes.f = gyroBias; // Send gyroBias + xbee.printf("%c%c%c%c", bytes.chars[0], bytes.chars[1], bytes.chars[2], bytes.chars[3]); + bytes.f = pAngle; // Send P Angle + xbee.printf("%c%c%c%c", bytes.chars[0], bytes.chars[1], bytes.chars[2], bytes.chars[3]); + bytes.f = imu.gx; // Send current angular velocity + xbee.printf("%c%c%c%c", bytes.chars[0], bytes.chars[1], bytes.chars[2], bytes.chars[3]); + bytes.f = turnspeed; // Send turn speed + xbee.printf("%c%c%c%c", bytes.chars[0], bytes.chars[1], bytes.chars[2], bytes.chars[3]); + bytes.f = pAngle * kp; // Send P Value + xbee.printf("%c%c%c%c", bytes.chars[0], bytes.chars[1], bytes.chars[2], bytes.chars[3]); + bytes.f = iAngle * ki; // Send I Value + xbee.printf("%c%c%c%c", bytes.chars[0], bytes.chars[1], bytes.chars[2], bytes.chars[3]); + bytes.f = dAngle * kd; // Send D Value + xbee.printf("%c%c%c%c", bytes.chars[0], bytes.chars[1], bytes.chars[2], bytes.chars[3]); + xbee.putc('\n'); // Send delimiting character } ////////////////////////////////////////////////////////////////// -// maybe get rid of this function and put it into updateGUI to run faster -void sendFloatAsBytes() -{ - pc.printf("%c%c%c%c", bytes.chars[0], bytes.chars[1], bytes.chars[2], bytes.chars[3]); -} - -/////////////////////////////////////////////////////////////////// -// triggered by ticker GUI ever 0.5s, sends data to PC -void updateGUI() +// checkValues() updates globals received from xbee +void checkValues() { - led3=!led3; // blink so we know what's going on - pc.putc('6'); // 6 is for pTerm - bytes.f=pAngle; // later kp*pAngle - sendFloatAsBytes(); - wait_us(10); // waiting a little bit is key - pc.putc('7'); - bytes.f=iAngle; - sendFloatAsBytes(); - wait_us(10); - pc.putc('8'); - bytes.f=dAngle; - sendFloatAsBytes(); + int i=0; // Integer needed for looping through input buffer + char buffer[6]; // Buffer to hold all the received data + + while(xbee.readable()) { // As long as there is stuff in the buffer + buffer[i++]=xbee.getc(); // Read from serial + } + + if(buffer[0]== '*') { // Check for 'start' character + switch(buffer[1]) { // Switch depending on what value we update + case '1': // Updating kp + bytes.chars[0] = buffer[2]; + bytes.chars[1] = buffer[3]; + bytes.chars[2] = buffer[4]; + bytes.chars[3] = buffer[5]; + kp=bytes.f; + break; + case '2': // Updating kd + bytes.chars[0] = buffer[2]; + bytes.chars[1] = buffer[3]; + bytes.chars[2] = buffer[4]; + bytes.chars[3] = buffer[5]; + kd=bytes.f; + break; + case '3': // Updating ki + bytes.chars[0] = buffer[2]; + bytes.chars[1] = buffer[3]; + bytes.chars[2] = buffer[4]; + bytes.chars[3] = buffer[5]; + ki=bytes.f; + break; + case '4': // Updating OVERALL_SCALAR + bytes.chars[0] = buffer[2]; + bytes.chars[1] = buffer[3]; + bytes.chars[2] = buffer[4]; + bytes.chars[3] = buffer[5]; + OVERALL_SCALAR=bytes.f; + break; + case '5': // Updating desiredAngle + bytes.chars[0] = buffer[2]; + bytes.chars[1] = buffer[3]; + bytes.chars[2] = buffer[4]; + bytes.chars[3] = buffer[5]; + desiredAngle=bytes.f; + break; + case '6': // Updating turnspeed + bytes.chars[0] = buffer[2]; + bytes.chars[1] = buffer[3]; + bytes.chars[2] = buffer[4]; + bytes.chars[3] = buffer[5]; + turnspeed=bytes.f; + } + } + } \ No newline at end of file