Advertisement
Scifi_

Arducopter motor linearization for + quad

Jan 27th, 2012
170
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.23 KB | None | 0 0
  1. static void pow3(float base, float& base2, float& base3)
  2. {
  3.     base2 = base*base;
  4.     base3 = base2*base;
  5.  
  6. }
  7.  
  8. static float polynome(float base, float A, float B,  float C, float D)
  9. {
  10.     float base2 = 0, base3 = 0;
  11.     pow3(base, base2, base3);
  12.     return (  (A*base3) + (B*base2) + (C*base) + D);
  13. }
  14.  
  15. static int16_t linearize_thrust(const int& out_min, const int& out_max, const int& pwm_in)
  16. {
  17.     float scale =  1.1314;
  18.     int range = out_max - out_min;
  19.     float norm = (float)(pwm_in - out_min) / (float)range;
  20.  
  21.     float out = scale*polynome(norm, 1.94252312331125, -3.18980232442278, 2.15241011525948, -0.0212837690567283);
  22.  
  23.     return ((out*range)+out_min);
  24. }
  25.  
  26. static void output_motors_armed()
  27. {
  28.     int roll_out, pitch_out, radio3_out;
  29.     int out_min = g.rc_3.radio_min;
  30.     int out_max = g.rc_3.radio_max;
  31.  
  32.     // Throttle is 0 to 1000 only
  33.     g.rc_3.servo_out    = constrain(g.rc_3.servo_out, 0, 800);
  34.  
  35.     if(g.rc_3.servo_out > 0)
  36.         out_min = g.rc_3.radio_min + MINIMUM_THROTTLE;
  37.  
  38.     g.rc_1.calc_pwm();
  39.     g.rc_2.calc_pwm();
  40.     g.rc_3.calc_pwm();
  41.     g.rc_4.calc_pwm();
  42.  
  43.  
  44.     if(g.frame_orientation == X_FRAME){
  45.         roll_out        = g.rc_1.pwm_out * .707;
  46.         pitch_out       = g.rc_2.pwm_out * .707;
  47.  
  48.         // left
  49.         motor_out[MOT_3]        = g.rc_3.radio_out + roll_out + pitch_out;  // FRONT
  50.         motor_out[MOT_2]        = g.rc_3.radio_out + roll_out - pitch_out;  // BACK
  51.  
  52.         // right
  53.         motor_out[MOT_1]        = g.rc_3.radio_out - roll_out + pitch_out;  // FRONT
  54.         motor_out[MOT_4]    = g.rc_3.radio_out - roll_out - pitch_out;  // BACK
  55.  
  56.     }else{
  57.  
  58.         roll_out        = g.rc_1.pwm_out;
  59.         pitch_out       = g.rc_2.pwm_out;
  60.         radio3_out      = g.rc_3.radio_out;
  61.  
  62.  
  63.         /*// right motor
  64.         motor_out[MOT_1]        = g.rc_3.radio_out - roll_out;
  65.         // left motor
  66.         motor_out[MOT_2]        = g.rc_3.radio_out + roll_out;
  67.         // front motor
  68.         motor_out[MOT_3]        = g.rc_3.radio_out + pitch_out;
  69.         // back motor
  70.         motor_out[MOT_4]    = g.rc_3.radio_out - pitch_out;*/
  71.  
  72.         // right motor
  73.         motor_out[MOT_1] = linearize_thrust(out_min, out_max, radio3_out - roll_out);
  74.         // left motor
  75.         motor_out[MOT_2] = linearize_thrust(out_min, out_max, radio3_out + roll_out);
  76.         // front motor
  77.         motor_out[MOT_3] = linearize_thrust(out_min, out_max, radio3_out + pitch_out);
  78.         // back motor
  79.         motor_out[MOT_4] = linearize_thrust(out_min, out_max, radio3_out - pitch_out);
  80.        
  81.     }
  82.  
  83.     // Yaw input
  84.     motor_out[MOT_1]        +=  g.rc_4.pwm_out;     // CCW
  85.     motor_out[MOT_2]        +=  g.rc_4.pwm_out;     // CCW
  86.     motor_out[MOT_3]        -=  g.rc_4.pwm_out;     // CW
  87.     motor_out[MOT_4]    -=  g.rc_4.pwm_out;     // CW
  88.  
  89.     /* We need to clip motor output at out_max. When cipping a motors
  90.      * output we also need to compensate for the instability by
  91.      * lowering the opposite motor by the same proportion. This
  92.      * ensures that we retain control when one or more of the motors
  93.      * is at its maximum output
  94.      */
  95.     for (int i=MOT_1; i<=MOT_4; i++) {
  96.         if (motor_out[i] > out_max) {
  97.             // note that i^1 is the opposite motor
  98.             motor_out[i^1] -= motor_out[i] - out_max;
  99.             motor_out[i] = out_max;
  100.         }
  101.     }
  102.  
  103.     // limit output so motors don't stop
  104.     motor_out[MOT_1]        = max(motor_out[MOT_1],     out_min);
  105.     motor_out[MOT_2]        = max(motor_out[MOT_2],     out_min);
  106.     motor_out[MOT_3]        = max(motor_out[MOT_3],     out_min);
  107.     motor_out[MOT_4]    = max(motor_out[MOT_4],     out_min);
  108.  
  109.     #if CUT_MOTORS == ENABLED
  110.     // if we are not sending a throttle output, we cut the motors
  111.     if(g.rc_3.servo_out == 0){
  112.         motor_out[MOT_1]        = g.rc_3.radio_min;
  113.         motor_out[MOT_2]        = g.rc_3.radio_min;
  114.         motor_out[MOT_3]        = g.rc_3.radio_min;
  115.         motor_out[MOT_4]    = g.rc_3.radio_min;
  116.     }
  117.     #endif
  118.  
  119.     // this filter slows the acceleration of motors vs the deceleration
  120.     // Idea by Denny Rowland to help with his Yaw issue
  121.     for(int8_t i=MOT_1; i <= MOT_4; i++ ) {
  122.         if(motor_filtered[i] < motor_out[i]){
  123.             motor_filtered[i] = (motor_out[i] + motor_filtered[i]) / 2;
  124.         }else{
  125.             // don't filter
  126.             motor_filtered[i] = motor_out[i];
  127.         }
  128.     }
  129.  
  130.  
  131.     APM_RC.OutputCh(MOT_1, motor_filtered[MOT_1]);
  132.     APM_RC.OutputCh(MOT_2, motor_filtered[MOT_2]);
  133.     APM_RC.OutputCh(MOT_3, motor_filtered[MOT_3]);
  134.     APM_RC.OutputCh(MOT_4, motor_filtered[MOT_4]);
  135.  
  136.  
  137.     #if INSTANT_PWM == 1
  138.     // InstantPWM
  139.     APM_RC.Force_Out0_Out1();
  140.     APM_RC.Force_Out2_Out3();
  141.     #endif
  142.  
  143.     //debug_motors();
  144. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement