Advertisement
Advertisement

More Related Content

Advertisement
Advertisement

Embedded Programming for Quadcopters

  1. Embedded Programming Quadcopters for
  2. I’m Ryan Boland Web Developer @ Tanooki Labs @bolandrm (github, twitter)
  3. 1. Components 2. Quadcopter physics 3. Sensor Inputs 4. Motor Outputs 5. Safety
  4. Frame
  5. Electronic Speed Controllers (ESCs) & Motors
  6. Lithium Polymer (LiPo) Battery
  7. Remote Control Transmitter + Receiver
  8. Flight Controller Microprocessor & Inertial measurement Unit (IMU)
  9. My Project - Custom Flight Controller Arduino Mega 2560 & Prototyping Shield 8-bit AVR 16 MHz clock 256K Flash 8K Ram Arduino Nano Clone 8-bit AVR 16 MHz clock 32K Flash 2K Ram Teensy 3.1 32-bit ARM 96 MHz clock 256K Flash 64K Ram $5$55 $20
  10. My Project - Inertial Measurement Unit MPU6050 - 3 axis gyroscope, 3 axis accelerometer HMC5883L - 3 axis magnetometer BMP180 Barometer 3.3V or 5V GY-87 $8
  11. Sourcing Components/Parts
  12. Configuration - + vs X
  13. Orientation - Angles x axis == roll y axis == pitch z axis == yaw
  14. Maneuvering
  15. The Code
  16. Control Loop void loop() { while(!imu_read()); rc_read_values(); fc_process(); }
  17. Control Loop void loop() { while(!imu_read()); rc_read_values(); fc_process(); }
  18. Orientation (IMU) • rotational rates (x, y, z) (degrees per second) • angles (x, y) (degrees)
  19. IMU - Gyroscope measures rotational rate in °/sec
  20. IMU - Gyroscope average = -2.599 (°/s)
  21. Orientation (IMU) • rotational rates (x, y, z) (degrees per second) • angles (x, y) (degrees)
  22. Gyroscope - Angles Rotational Rate Duration Total Movement Quad Angle 0 0 0 0 ° 5 °/s 2 s 10 ° 10 ° -10 °/s 2 s -20 ° -10 ° -5 °/s 1 s -5 ° -15 °
  23. Gyroscope - Angles uint32_t gyro_last_update = micros(); void compute_gyro_angles() { mpu6050_read_gyro(&gyro_rates); rates.x = gyro_rates.x + GYRO_X_OFFSET; delta_t = (micros() - gyro_last_update) / 1000000; gyro_angles.x += rates.x * delta_t; gyro_last_update = micros(); }
  24. Gyroscope - Angles uint32_t gyro_last_update = micros(); void compute_gyro_angles() { mpu6050_read_gyro(&gyro_rates); rates.x = gyro_rates.x + GYRO_X_OFFSET; delta_t = (micros() - gyro_last_update) / 1000000; gyro_angles.x += rates.x * delta_t; gyro_last_update = micros(); }
  25. Gyroscope - Angles uint32_t gyro_last_update = micros(); void compute_gyro_angles() { mpu6050_read_gyro(&gyro_rates); rates.x = gyro_rates.x + GYRO_X_OFFSET; delta_t = (micros() - gyro_last_update) / 1000000; gyro_angles.x += rates.x * delta_t; gyro_last_update = micros(); }
  26. Gyroscope - Angles uint32_t gyro_last_update = micros(); void compute_gyro_angles() { mpu6050_read_gyro(&gyro_rates); rates.x = gyro_rates.x + GYRO_X_OFFSET; delta_t = (micros() - gyro_last_update) / 1000000; gyro_angles.x += rates.x * delta_t; gyro_last_update = micros(); }
  27. Gyroscope - Angles How is our estimation?
  28. Gyro Drift Occurs when gyroscope data changes between samples
  29. Orientation (IMU) • rotational rates (x, y, z) (degrees per second) • angles (x, y) (degrees) ?
  30. IMU - Accelerometer • measures acceleration in terms of g-force (g) • requires offset calibration, similar to gyroscope data • z axis should be calibrated to 1G!
  31. IMU - Accelerometer http://www.freescale.com/files/sensors/doc/app_note/ AN3461.pdf (y, pitch) (x, roll) x = accel_filtered.x; y = accel_filtered.y; z = accel_filtered.z; accel_angles.x = atan2(y, z) * RAD_TO_DEG; accel_angles.y = atan2(-1 * x, sqrt(y*y + z*z)) * RAD_TO_DEG;
  32. IMU - Accelerometer http://www.freescale.com/files/sensors/doc/app_note/ AN3461.pdf (y, pitch) (x, roll) x = accel_filtered.x; y = accel_filtered.y; z = accel_filtered.z; accel_angles.x = atan2(y, z) * RAD_TO_DEG; accel_angles.y = atan2(-1 * x, sqrt(y*y + z*z)) * RAD_TO_DEG; (median filters)
  33. IMU - Accelerometer http://www.freescale.com/files/sensors/doc/app_note/ AN3461.pdf (y, pitch) (x, roll) x = accel_filtered.x; y = accel_filtered.y; z = accel_filtered.z; accel_angles.x = atan2(y, z) * RAD_TO_DEG; accel_angles.y = atan2(-1 * x, sqrt(y*y + z*z)) * RAD_TO_DEG;
  34. IMU - Accelerometer
  35. IMU - Accelerometer Susceptible to vibrations
  36. Combining Approaches Gyroscope - Good for short durations Accelerometer - Good for long durations Complementary Filter! #define GYRO_PART 0.995 #define ACC_PART 0.005 dt = <time since last update>; angles.x = GYRO_PART * (angles.x + (rates.x * dt)) + ACC_PART * accel_angles.x;
  37. Combining Approaches Gyroscope - Good for short durations Accelerometer - Good for long durations Complementary Filter! #define GYRO_PART 0.995 #define ACC_PART 0.005 dt = <time since last update>; angles.x = GYRO_PART * (angles.x + (rates.x * dt)) + ACC_PART * accel_angles.x;
  38. Combining Approaches Gyroscope - Good for short durations Accelerometer - Good for long durations Complementary Filter! #define GYRO_PART 0.995 #define ACC_PART 0.005 dt = <time since last update>; angles.x = GYRO_PART * (angles.x + (rates.x * dt)) + ACC_PART * accel_angles.x;
  39. Combining Approaches Gyroscope - Good for short durations Accelerometer - Good for long durations Complementary Filter! #define GYRO_PART 0.995 #define ACC_PART 0.005 dt = <time since last update>; angles.x = GYRO_PART * (angles.x + (rates.x * dt)) + ACC_PART * accel_angles.x;
  40. complementary filter vs previous approaches
  41. Orientation (IMU) • rotational rates (x, y, z) (degrees per second) • angles (x, y) (degrees)
  42. Control Loop void loop() { while(!imu_read()); rc_read_values(); fc_process(); }
  43. Remote Control http://rcarduino.blogspot.com/2012/01/how-to-read-rc- receiver-with.html Channel Function Min/Max Mapped Min/Max 1 Roll (1000μs, 2000μs) (-25, 25) 2 Pitch (1000μs, 2000μs) (-25, 25) 3 Throttle (1000μs, 2000μs) (1000, 2000) 4 Yaw (1000μs, 2000μs) (-50, 50)
  44. Control Loop void loop() { while(!imu_read()); rc_read_values(); fc_process(); }
  45. Controlling Motors (ESCs) Made to work with the remote control. Motor Max - 2000μs Motor Min - 1000μs
  46. Rate Mode
  47. 3 problems to correct Flight Controller Code
  48. Flight Controller Code motor1 = rc_throttle - roll_adjust - pitch_adjust - yaw_adjust; motor2 = rc_throttle + roll_adjust + pitch_adjust - yaw_adjust; motor3 = rc_throttle - roll_adjust + pitch_adjust + yaw_adjust; motor4 = rc_throttle + roll_adjust - pitch_adjust + yaw_adjust; correcting roll, pitch, yaw
  49. Flight Controller Code motor1 = rc_throttle - roll_adjust - pitch_adjust - yaw_adjust; motor2 = rc_throttle + roll_adjust + pitch_adjust - yaw_adjust; motor3 = rc_throttle - roll_adjust + pitch_adjust + yaw_adjust; motor4 = rc_throttle + roll_adjust - pitch_adjust + yaw_adjust; correcting roll, pitch, yaw
  50. Flight Controller Code motor1 = rc_throttle - roll_adjust - pitch_adjust - yaw_adjust; motor2 = rc_throttle + roll_adjust + pitch_adjust - yaw_adjust; motor3 = rc_throttle - roll_adjust + pitch_adjust + yaw_adjust; motor4 = rc_throttle + roll_adjust - pitch_adjust + yaw_adjust; correcting roll, pitch, yaw
  51. Flight Controller Code motor1 = rc_throttle - roll_adjust - pitch_adjust - yaw_adjust; motor2 = rc_throttle + roll_adjust + pitch_adjust - yaw_adjust; motor3 = rc_throttle - roll_adjust + pitch_adjust + yaw_adjust; motor4 = rc_throttle + roll_adjust - pitch_adjust + yaw_adjust; correcting roll, pitch, yaw
  52. Flight Controller Code motor1 = rc_throttle - roll_adjust - pitch_adjust - yaw_adjust;
  53. The PI Controller (Proportional-Integral) • Calculates error based on difference between sensor reading and pilot command • Proportional term depends on present error • Integral term depends on accumulation of past errors
  54. The PI Controller (Proportional-Integral) #define KP 2.0 # ??? #define KI 2.0 # ??? float error = desired_pitch - current_pitch; proportional = KP * error; integral += KI * error * dt; output = proportional + integral;
  55. The PI Controller (Proportional-Integral) #define KP 2.0 # ??? #define KI 2.0 # ??? float error = desired_pitch - current_pitch; proportional = KP * error; integral += KI * error * dt; output = proportional + integral;
  56. The PI Controller (Proportional-Integral) #define KP 2.0 # ??? #define KI 2.0 # ??? float error = desired_pitch - current_pitch; proportional = KP * error; integral += KI * error * dt; output = proportional + integral;
  57. The PI Controller (Proportional-Integral) #define KP 2.0 # ??? #define KI 2.0 # ??? float error = desired_pitch - current_pitch; proportional = KP * error; integral += KI * error * dt; output = proportional + integral;
  58. Flight Controller Code motor1 = rc_throttle - roll_adjust - pitch_adjust - yaw_adjust; motor2 = rc_throttle + roll_adjust + pitch_adjust - yaw_adjust; motor3 = rc_throttle - roll_adjust + pitch_adjust + yaw_adjust; motor4 = rc_throttle + roll_adjust - pitch_adjust + yaw_adjust; correcting roll, pitch, yaw
  59. Stabilize Mode 3 new PI controllers!
  60. Ready to fly! (??)
  61. Ready to fly! (??) Tuning is hard!
  62. Tuning
  63. Safety & Handling Failure
  64. Safety & Handling Failure • Stale IMU values • Stale remote control values • Angles too high? • Motor outputs too high? (indoor safe mode)
  65. Some Takeaways • Be Safe • Start small (balancing robot?) • Break things down into subcomponents
  66. Resources How-to Guide: https://ghowen.me/build-your-own-quadcopter-autopilot/ Similar Projects: https://github.com/cTn-dev/Phoenix-FlightController https://github.com/baselsw/BlueCopter My Code: https://github.com/bolandrm/rmb_multicopter https://github.com/bolandrm/arduino-quadcopter (old)
  67. Thanks! @bolandrm
Advertisement