2nd draft
Dependencies: HIDScope MODSERIAL QEI biquadFilter mbed Servo
Fork of robot_mockup by
Diff: main.cpp
- Revision:
- 50:54f71544964c
- Parent:
- 49:6515c045cfd6
- Child:
- 51:e4a0ce7ff4b8
--- a/main.cpp Fri Oct 23 21:09:32 2015 +0000 +++ b/main.cpp Tue Oct 27 08:44:29 2015 +0000 @@ -112,10 +112,10 @@ //PID variables double u1; double u2; //Output of PID controller (PWM value for motor 1 and 2) double m1_error=0; double m1_e_int=0; double m1_e_prev=0; //Error, integrated error, previous error motor 1 -const double m1_kp=8; const double m1_ki=0.125; const double m1_kd=0.5; //Proportional, integral and derivative gains. +const double m1_kp=10; const double m1_ki=0.25; const double m1_kd=0.5; //Proportional, integral and derivative gains. double m2_error=0; double m2_e_int=0; double m2_e_prev=0; //Error, integrated error, previous error motor 2 -const double m2_kp=8; const double m2_ki=0.125; const double m2_kd=0.5; //Proportional, integral and derivative gains. +const double m2_kp=5; const double m2_ki=0.125; const double m2_kd=0.25; //Proportional, integral and derivative gains. //Calibration bools, checks if elbow/shoulder limits are hit volatile bool done1 = false; @@ -279,15 +279,15 @@ pc.baud(115200); //serial baudrate red=1; green=1; blue=1; //Make sure debug LEDs are off - theta1_cal = floor(theta1_lower * (4200/(2*PI))); - Encoder1.setPulses(theta1_cal); //edited QEI library: added setPulses() + //theta1_cal = floor(theta1_lower * (4200/(2*PI))); + //Encoder1.setPulses(theta1_cal); //edited QEI library: added setPulses() //Mechanical limit 43 degrees -> 43*(4200/360) = 350 - theta2_cal = floor(theta2_lower * (4200/(2*PI))); - Encoder2.setPulses(theta2_cal); + //theta2_cal = floor(theta2_lower * (4200/(2*PI))); + //Encoder2.setPulses(theta2_cal); - x = 0.2220; - y = 0.4088; + //x = 0.2220; + //y = 0.4088; //Set PwmOut frequency to 10k Hz pwm_motor1.period(0.001); @@ -431,8 +431,24 @@ controlMenu(); char c=0; while(c != 'Q' && c != 'q') { + //Debugging values: + if(c!='q' && c!='Q'){ + pc.printf("Reference position: %f and %f \r\n",x,y); + pc.printf("Current position: %f and %f \r\n",current_x,current_y); + pc.printf("Pos Error: %f and %f \r\n",x_error,y_error); + pc.printf("Current angles: %f and %f \r\n",theta1,theta2); + pc.printf("DLS1: %f and DLS2 %f and DLS3 %f and DLS4: %f \r\n",dls1,dls2,dls3,dls4); + pc.printf("Error in angles: %f and %f \r\n",q1_error,q2_error); + pc.printf("PID output: %f and %f \r\n",u1,u2); + pc.printf("----------------------------------------\r\n\n"); + pc.printf("Buffer 1: %f \r\n",biceps_avg); + pc.printf("Buffer 2: %f \r\n",triceps_avg); + pc.printf("Buffer 3: %f \r\n",flexor_avg); + pc.printf("Buffer 4: %f \r\n",extens_avg); + wait(1); + }//end if - if( pc.readable() ){ + /*if( pc.readable() ){ c = pc.getc(); switch (c) { @@ -470,18 +486,10 @@ break; }//end switch - if(c!='q' && c!='Q'){ - pc.printf("Reference position: %f and %f \r\n",x,y); - pc.printf("Current position: %f and %f \r\n",current_x,current_y); - pc.printf("Pos Error: %f and %f \r\n",x_error,y_error); - pc.printf("Current angles: %f and %f \r\n",theta1,theta2); - pc.printf("DLS1: %f and DLS2 %f and DLS3 %f and DLS4: %f \r\n",dls1,dls2,dls3,dls4); - pc.printf("Error in angles: %f and %f \r\n",q1_error,q2_error); - pc.printf("PID output: %f and %f \r\n",u1,u2); - pc.printf("----------------------------------------\r\n\n"); - }//end if } //end if pc readable + */ + } //end of while loop } @@ -503,11 +511,11 @@ biceps_power = lowpass.step(biceps_power); triceps_power = lowpass2.step(triceps_power); flexor_power = lowpass3.step(flexor_power); extens_power = lowpass4.step(extens_power); - scope.set(0,biceps_power); - scope.set(1,triceps_power); + //scope.set(0,biceps_power); + //scope.set(1,triceps_power); //scope.set(2,flexor_power); //scope.set(3,extens_power); - scope.send(); + //scope.send(); } @@ -536,12 +544,12 @@ //Run motors slowly clockwise to mechanical limit. Attached to 100Hz ticker void calibrate(void){ if(done1==false){ //if motor 1 limit has not been hit yet - pwm_motor1=0.1; //move upper arm slowly cw + pwm_motor1=0.3; //move upper arm slowly cw pc.printf("Motor 1 running %f \r\n"); } if(done1==true && done2==false){ //if limit motor 1 has been hit pwm_motor1=0; //stop motor1 - pwm_motor2=0.1; //start moving forearm slowly cw + pwm_motor2=0.3; //start moving forearm slowly cw pc.printf("Motor 2 running %f \r\n"); } // if(done1==true && done2==true) //if both limits are hit @@ -832,13 +840,11 @@ //Analyze filtered EMG, calculate reference position from EMG, compare reference position with current position,convert to angles, send error through pid(), send PWM and DIR to motors void control() -{ - - +{ /********************* START OF EMG REFERENCE CALCULATION ***************************/ if(emg_control==true){ - //TODO some idle time with static reference before EMG kicks in + //TODO some idle time with static reference before EMG kicks in. or go to reference in the first 5 seconds. emg_control_time += CONTROL_RATE; //if(emg_control_time < 5){ // x=BLA; y=BLA; starting position maybe @@ -856,13 +862,15 @@ keep_in_range(&extens,0,1); //send normalized emg to scope to compare with just filtered emg. - scope.set(2,biceps); - scope.set(3,triceps); + scope.set(0,biceps); + scope.set(1,triceps); + scope.set(2,flexor); + scope.set(3,extens); scope.send(); //threshold detection! buffer or two thresholds? If average of 100 samples > threshold, then muscle considered on. - /* + movavg1[i]=biceps; //fill array with 100 normalized samples movavg2[i]=triceps; movavg3[i]=flexor; @@ -872,18 +880,22 @@ i=0; } - for(int j = 0; j < window; j++){ // sum all values in the array - sum1 += movavg1[j]; - sum2 += movavg2[j]; - sum3 += movavg3[j]; - sum4 += movavg4[j]; + + //Sum all values in the array. The sum needs to be overwritten or it will continue to sum the next 100 samples on top it + //and will grow out of control. + //So the variable name for the sum in the for loop is not really correct since the average is calculated after the loop. + for(int j = 0; j < window; j++){ + biceps_avg += movavg1[j]; + triceps_avg += movavg2[j]; + flexor_avg += movavg3[j]; + extens_avg += movavg4[j]; } - biceps_avg = sum1/window; //divide sum by number of samples -> average - triceps_avg = sum2/window; - flexor_avg = sum3/window; - extens_avg = sum4/window; + biceps_avg = biceps_avg/window; //divide sum by number of samples -> average + triceps_avg = triceps_avg/window; + flexor_avg = flexor_avg/window; + extens_avg = extens_avg/window; - */ + //Compare muscle amplitudes and determine their influence on x and y reference position. if (biceps>triceps && biceps > 0.2){ @@ -939,13 +951,13 @@ x_error = x - current_x; y_error = y - current_y; - /******************************** START OF TRIG INVERSE KINEMATICS ****************************************/ if (control_method==1){ //inverse kinematics (refpos to refangle) costheta2 = (pow(x,2) + pow(y,2) - pow(l1,2) - pow(l2,2)) / (2*l1*l2) ; - sintheta2 = sqrt( abs( 1 - pow(costheta2,2) ) ); //absolute to avoid imaginary numbers -> bigger steady state error + //absolute in sqrt to avoid imaginary numbers -> bigger steady state error when reference out of workspace + sintheta2 = sqrt( abs( 1 - pow(costheta2,2) ) ); //Reference angle 2 dtheta2 = atan2(sintheta2,costheta2);