Guest User

FC_EASY

a guest
Mar 19th, 2017
296
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.10 KB | None | 0 0
  1. #include <Wire.h>
  2. #include <Servo.h>
  3. #include "RadioController.h"
  4.  
  5. RadioController rc;
  6.  
  7. // Bardzo dziwne zachowanie PITCH - wysoki wzrost
  8.  
  9. #define GSCALE ((70.f / 1000.f))
  10. #define ASCALE ((0.244f / 1000.f))
  11.  
  12. #define ACC_SCALE(x) ((float)x * ASCALE)
  13. #define GYRO_SCALE(x) ((float)x * GSCALE)
  14.  
  15. unsigned long integration = 0, sensor = 0, update_start = 0;
  16.  
  17. long gx, gy, gz, ax, ay, az;
  18.  
  19. float gxc, gyc, gzc;
  20.  
  21. double pitch, roll, yaw,
  22. angle_pitch, angle_roll, angle_yaw;
  23.  
  24. bool cal = false;
  25.  
  26. const float P_ROLL = 1.3f, I_ROLL = 0.03f, D_ROLL = 15.f;
  27. float pid_roll, last_pid_roll_error, i_pid_roll;
  28.  
  29. const float P_PITCH = P_ROLL, I_PITCH = I_ROLL, D_PITCH = D_ROLL;
  30. float pid_pitch, last_pid_pitch_error, i_pid_pitch;
  31.  
  32. const float P_YAW = 4.f, I_YAW = 0.02f, D_YAW = 0.f;
  33. float pid_yaw, last_pid_yaw_error, i_pid_yaw;
  34.  
  35. const short PID_MAX = 400, // +-
  36. ANGLE_CORRECTION_SENS = 15;
  37.  
  38.  
  39. float cal_pitch = 0.0f, cal_roll = 0.0f;
  40.  
  41. Servo NCCW, NCW, SCW, SCCW;
  42.  
  43. void setup()
  44. {
  45. Serial.begin(9600);
  46. while(Serial.read() != 'g');
  47.  
  48. NCCW.attach(2);
  49. NCCW.writeMicroseconds(1000);
  50.  
  51. NCW.attach(3);
  52. NCW.writeMicroseconds(1000);
  53.  
  54. // SCW.attach(4);
  55. // SCW.writeMicroseconds(1000);
  56.  
  57. SCCW.attach(5);
  58. SCCW.writeMicroseconds(1000);
  59.  
  60.  
  61. rc.Setup();
  62.  
  63. Wire.begin();
  64. Wire.setClock(400000L);
  65.  
  66. WriteReg(0x10, 0b01101100); // 208Hz refresh rate, +-8g anti-aliasing 200Hz
  67. WriteReg(0x11, 0b01101100); // 208Hz refresh rate, +- 2k dps, full-scale at 125dps off
  68. WriteReg(0x12, 0b00000100);
  69.  
  70. Serial.println("Calibration: ");
  71. delay(4);
  72.  
  73. for(int i = 0; i < 1000; i++)
  74. {
  75. Read();
  76.  
  77. if(i % 50 == 0) Serial.print(".");
  78. gxc += gx;
  79. gyc += gy;
  80. gzc += gz;
  81.  
  82. delay(4);
  83. }
  84.  
  85. gxc /= 1000;
  86. gyc /= 1000;
  87. gzc /= 1000;
  88.  
  89. cal = true;
  90. Serial.println("Done!");
  91.  
  92.  
  93. // while(rc.
  94.  
  95. integration = update_start = millis();
  96. }
  97.  
  98. ISR(PCINT0_vect)
  99. {
  100. rc.HandleInterrupt();
  101. }
  102.  
  103.  
  104. void WriteReg(uint8_t reg, uint8_t val)
  105. {
  106. Wire.beginTransmission(0b1101011);
  107. Wire.write(reg);
  108. Wire.write(val);
  109. Wire.endTransmission();
  110. }
  111. bool Read()
  112. {
  113. unsigned long current_timer = millis();
  114.  
  115. if(current_timer - sensor < 4)
  116. return false;
  117.  
  118. sensor = current_timer;
  119.  
  120. Wire.beginTransmission(0b1101011);
  121. Wire.write(0x28); // OUTX_L_XL
  122. Wire.endTransmission();
  123. Wire.requestFrom(0b1101011, (uint8_t) 6);
  124.  
  125. uint8_t axl = Wire.read(), axh = Wire.read(),
  126. ayl = Wire.read(), ayh = Wire.read(),
  127. azl = Wire.read(), azh = Wire.read();
  128.  
  129. ax = -(long)(axh << 8 | axl); // mg
  130. ay = -(long)(ayh << 8 | ayl); // mg
  131. az = -(long)(azh << 8 | azl); // mg
  132.  
  133. Wire.beginTransmission(0b1101011);
  134. Wire.write(0x22); // OUTX_L_G
  135. Wire.endTransmission();
  136. Wire.requestFrom(0b1101011, (uint8_t) 6);
  137.  
  138. uint8_t gxl = Wire.read(), gxh = Wire.read(),
  139. gyl = Wire.read(), gyh = Wire.read(),
  140. gzl = Wire.read(), gzh = Wire.read();
  141.  
  142. gx = (long)(gxh << 8 | gxl);
  143. gy = (long)(gyh << 8 | gyl);
  144. gz = (long)(gzh << 8 | gzl);
  145.  
  146. if(cal)
  147. {
  148. gx -= gxc;
  149. gy -= gyc;
  150. gz -= gzc;
  151. }
  152.  
  153. return true;
  154. }
  155.  
  156. bool startup = false;
  157.  
  158. void loop()
  159. {
  160.  
  161. rc.Normalize();
  162.  
  163. // rc.DEBUG_PrintAngles();
  164. //if(!rc.CheckConnection())
  165. // {
  166. // Serial.print("RC ERROR");
  167. // rc.DEBUG_PrintValues();
  168. // return;
  169. // }
  170. // while(abs(rc.GetChannel(1)) > 500) { Serial.println("NO RADIO SIGNAL"); }
  171.  
  172. // unsigned long start = micros();
  173. Read();
  174.  
  175. pitch = pitch * 0.75 + (gy * GSCALE) * 0.25;
  176. roll = roll * 0.75 + (gx * GSCALE) * 0.25;
  177. yaw = yaw * 0.75 + (gz * GSCALE) * 0.25;
  178.  
  179. float dt = (millis() - update_start) / 1000.f;
  180.  
  181. angle_pitch += gy * GSCALE * dt;
  182. angle_roll += gx * GSCALE * dt;
  183. float sin_yaw = sin(gz * GSCALE * dt * DEG_TO_RAD);
  184.  
  185. update_start = millis();
  186.  
  187. angle_pitch -= angle_roll * sin_yaw;
  188. angle_roll += angle_pitch * sin_yaw;
  189.  
  190. float acc_vector = sqrt(ax * ax + ay * ay + az * az),
  191. a_pitch = 0.0, a_roll = 0.0;
  192.  
  193. if(abs(ay) < acc_vector)
  194. a_pitch = asin((float)ay / acc_vector) * RAD_TO_DEG;
  195.  
  196. if(abs(ax) < acc_vector)
  197. a_roll = asin((float)ax / acc_vector) * -RAD_TO_DEG;
  198.  
  199. a_pitch -= -4.10;
  200. a_roll -= -2.30;
  201.  
  202. angle_pitch = angle_pitch * 0.9996 + 0.0004 * a_pitch;
  203. angle_roll = angle_roll * 0.9996 + 0.0004 * a_roll;
  204.  
  205. if(!startup)
  206. {
  207. angle_pitch = a_pitch;
  208. angle_roll = a_roll;
  209. startup = true;
  210.  
  211. i_pid_roll = 0;
  212. last_pid_roll_error = 0;
  213. i_pid_pitch = 0;
  214. last_pid_pitch_error = 0;
  215. i_pid_yaw = 0;
  216. last_pid_yaw_error = 0;
  217. }
  218.  
  219.  
  220. calculate_pid();
  221.  
  222. // rc.DEBUG_PrintValues();
  223. // Serial.println(micros() - start);
  224. Serial.print(angle_pitch);// Serial.print(" "); Serial.print(pitch); Serial.print(" "); Serial.println(a_pitch);
  225. Serial.print(" "); Serial.println(angle_roll);// Serial.print(" "); Serial.print(roll); Serial.print(" "); Serial.println(a_roll);
  226. // Serial.print(ax); Serial.print(" "); Serial.print(ay); Serial.print(" "); Serial.println(az);
  227. //Serial.print(angle_pitch); Serial.print(" "); Serial.println(angle_roll);
  228. // delay(100);
  229.  
  230.  
  231. // CommandMotors
  232. long throttle = (rc.GetChannel(3) > 1800) ? 1800 : rc.GetChannel(3),
  233. esc_nccw = throttle - pid_pitch + pid_roll - pid_yaw,
  234. esc_ncw = throttle + pid_pitch + pid_roll + pid_yaw,
  235. esc_sccw = throttle + pid_pitch - pid_roll - pid_yaw,
  236. esc_scw = throttle - pid_pitch - pid_roll + pid_yaw;
  237.  
  238. if(esc_nccw < 1000) esc_nccw = 1000;
  239. else if(esc_nccw > 2000) esc_nccw = 2000;
  240.  
  241. if(esc_ncw < 1000) esc_ncw = 1000;
  242. else if(esc_ncw > 2000) esc_ncw = 2000;
  243.  
  244. if(esc_sccw < 1000) esc_sccw = 1000;
  245. else if(esc_sccw > 2000) esc_sccw = 2000;
  246.  
  247. if(esc_scw < 1000) esc_scw = 1000;
  248. else if(esc_scw > 2000) esc_scw = 2000;
  249.  
  250. Serial.print("THR: "); Serial.print(throttle); Serial.print(" PIT: "); Serial.print(pid_pitch); Serial.print(" ROL: "); Serial.print(pid_roll); Serial.print(" YAW: "); Serial.println(pid_yaw);
  251. // Serial.print("ESC_NCCW: "); Serial.print(esc_nccw); Serial.print(" ESC_NCW: "); Serial.print(esc_ncw); Serial.print(" ESC_SCW: "); Serial.print(esc_scw); Serial.print(" ESC_SCCW: "); Serial.println(esc_sccw);
  252.  
  253. NCCW.writeMicroseconds(esc_nccw);
  254. NCW.writeMicroseconds(esc_ncw);
  255. SCCW.writeMicroseconds(esc_sccw);
  256. // SCW.writeMicroseconds(esc_scw);
  257.  
  258. while(millis() - integration < 4);
  259. integration = millis();
  260. }
  261.  
  262. void calculate_pid()
  263. {
  264. float error_temp = roll - (rc.GetChannelDeg(1) - angle_roll * ANGLE_CORRECTION_SENS);
  265.  
  266. // Serial.print("ROLL: "); Serial.print(rc.GetChannelDeg(1)); Serial.print(angle_roll * ANGLE_CORRECTION_SENS); Serial.print( " " ); Serial.println(roll);
  267. i_pid_roll += I_ROLL * error_temp;
  268.  
  269. if(i_pid_roll > PID_MAX) i_pid_roll = PID_MAX;
  270. else if(i_pid_roll < -PID_MAX) i_pid_roll = -PID_MAX;
  271.  
  272. pid_roll = P_ROLL * error_temp + i_pid_roll + D_ROLL * (error_temp - last_pid_roll_error);
  273. if(pid_roll > PID_MAX) pid_roll = PID_MAX;
  274. else if(pid_roll < -PID_MAX) pid_roll = -PID_MAX;
  275.  
  276. last_pid_roll_error = error_temp;
  277.  
  278. error_temp = pitch - (rc.GetChannelDeg(2) - angle_pitch * ANGLE_CORRECTION_SENS);
  279. // Serial.print("PITCH: "); Serial.print(rc.GetChannelDeg(2)); Serial.print(angle_pitch * ANGLE_CORRECTION_SENS); Serial.print( " " ); Serial.println(pitch);
  280. i_pid_pitch += I_PITCH * error_temp;
  281.  
  282. if(i_pid_pitch > PID_MAX) i_pid_pitch = PID_MAX;
  283. else if(i_pid_pitch < -PID_MAX) i_pid_pitch = -PID_MAX;
  284.  
  285. pid_pitch = P_PITCH * error_temp + i_pid_pitch + D_PITCH * (error_temp - last_pid_pitch_error);
  286. if(pid_pitch > PID_MAX) pid_pitch = PID_MAX;
  287. else if(pid_pitch < -PID_MAX) pid_pitch = -PID_MAX;
  288.  
  289. last_pid_pitch_error = error_temp;
  290.  
  291.  
  292. error_temp = yaw - rc.GetChannelDeg(4);
  293. i_pid_yaw += I_YAW * error_temp;
  294.  
  295. if(i_pid_yaw > PID_MAX) i_pid_yaw = PID_MAX;
  296. else if(i_pid_yaw < -PID_MAX) i_pid_yaw = -PID_MAX;
  297.  
  298. pid_yaw = P_YAW * error_temp + i_pid_yaw + D_YAW * (error_temp - last_pid_yaw_error);
  299. if(pid_yaw > PID_MAX) pid_yaw = PID_MAX;
  300. else if(pid_yaw < -PID_MAX) pid_yaw = -PID_MAX;
  301.  
  302. last_pid_yaw_error = error_temp;
  303. }
Add Comment
Please, Sign In to add comment