PageRenderTime 55ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/application/lineFollower/lineFollower.c

https://gitlab.com/BGCX261/zhonx3-git
C | 314 lines | 188 code | 41 blank | 85 comment | 19 complexity | cf644de2c5ae97879746cd0276e4a72d MD5 | raw file
  1. /**************************************************************************/
  2. /*!
  3. @file line_follower.c
  4. @author BM Pacabot.com
  5. @date 05 May 2015
  6. @version 0.01
  7. */
  8. /**************************************************************************/
  9. /* STM32 hal library declarations */
  10. #include "stm32f4xx_hal.h"
  11. /* General declarations */
  12. #include "config/basetypes.h"
  13. #include "config/config.h"
  14. #include "config/errors.h"
  15. #include "stdbool.h"
  16. #include <arm_math.h>
  17. #include <math.h>
  18. #include <string.h>
  19. #include <stdio.h>
  20. #include <stdint.h>
  21. /* Peripheral declarations */
  22. #include "peripherals/lineSensors/lineSensors.h"
  23. #include "peripherals/tone/tone.h"
  24. #include "peripherals/display/ssd1306.h"
  25. #include "peripherals/display/smallfonts.h"
  26. #include "peripherals/expander/pcf8574.h"
  27. #include "peripherals/motors/motors.h"
  28. #include "peripherals/encoders/ie512.h"
  29. #include "peripherals/multimeter/multimeter.h"
  30. #include "peripherals/telemeters/telemeters.h"
  31. #include "peripherals/bluetooth/bluetooth.h"
  32. /* Middleware declarations */
  33. #include "middleware/wall_sensors/wall_sensors.h"
  34. #include "middleware/controls/pidController/pidController.h"
  35. #include "middleware/controls/motionControl/positionControl.h"
  36. #include "middleware/controls/motionControl/speedControl.h"
  37. #include "middleware/controls/motionControl/transfertFunction.h"
  38. #include "middleware/controls/motionControl/mainControl.h"
  39. #include "middleware/controls/motionControl/wallFollowControl.h"
  40. /* Declarations for this module */
  41. #include "application/lineFollower/lineFollower.h"
  42. #include "application/statistiques/statistiques.h"
  43. line_follower_struct line_follower;
  44. ground_sensors_struct max_Floor; //global data to memorize maximum value of sensors
  45. ground_sensors_struct coef_Floor; //global data to memorize coeff value (0..1000]
  46. ground_sensors_struct min_Floor; //global data to memorize minimum value of sensors
  47. //__IO uint16_t ADC1ConvertedValues[2] = {0};
  48. //__IO uint16_t ADC3ConvertedValues[3] = {0};
  49. GPIO_InitTypeDef GPIO_InitStruct;
  50. //----------------------------------------------------------------
  51. // Initialize data sensor to memorize the max and min value for each 5 sensors
  52. void lineSensorsCalibration(void)
  53. {
  54. mainControlInit();
  55. telemetersStop();
  56. lineSensorsInit();
  57. lineSensorsStart();
  58. motorsInit();
  59. motorsSleepDriver(OFF);
  60. tone(a, 500);
  61. // HAL_Delay(1000);
  62. move(0, 100, 200, 0);
  63. // -------------------------------------------------------------
  64. // Init line Sensor
  65. max_Floor.left=(double)lineSensors.left.adc_value;
  66. max_Floor.front=(double)lineSensors.front.adc_value;
  67. max_Floor.right=(double)lineSensors.right.adc_value;
  68. max_Floor.leftExt=(double)lineSensors.left_ext.adc_value;
  69. max_Floor.rightExt=(double)lineSensors.right_ext.adc_value;
  70. memcpy(&min_Floor, &max_Floor, sizeof(ground_sensors_struct) );
  71. while(isEndMove() != TRUE)
  72. {
  73. if (lineSensors.left.adc_value < min_Floor.left) min_Floor.left = lineSensors.left.adc_value;
  74. if (lineSensors.front.adc_value < min_Floor.front) min_Floor.front = lineSensors.front.adc_value;
  75. if (lineSensors.right.adc_value < min_Floor.right) min_Floor.right = lineSensors.right.adc_value;
  76. if (lineSensors.left_ext.adc_value < min_Floor.leftExt) min_Floor.leftExt = lineSensors.left_ext.adc_value;
  77. if (lineSensors.right_ext.adc_value < min_Floor.rightExt) min_Floor.rightExt = lineSensors.right_ext.adc_value;
  78. if (lineSensors.left.adc_value > max_Floor.left) max_Floor.left = lineSensors.left.adc_value;
  79. if (lineSensors.front.adc_value > max_Floor.front) max_Floor.front = lineSensors.front.adc_value;
  80. if (lineSensors.right.adc_value > max_Floor.right) max_Floor.right = lineSensors.right.adc_value;
  81. if (lineSensors.left_ext.adc_value > max_Floor.leftExt) max_Floor.leftExt = lineSensors.left_ext.adc_value;
  82. if (lineSensors.right_ext.adc_value > max_Floor.rightExt) max_Floor.rightExt = lineSensors.right_ext.adc_value;
  83. }
  84. tone(b, 500);
  85. tone(c, 500);
  86. // desactivate PID
  87. pid_loop.start_state = FALSE;
  88. line_follower.active_state = FALSE;
  89. telemetersStop();
  90. motorsSleepDriver(ON);
  91. }
  92. //---------------------------------------------------------------------
  93. // Intelligent function to manage zhonx on the line path
  94. void lineFollower(void)
  95. {
  96. mainControlInit();
  97. telemetersStop();
  98. lineSensorsInit();
  99. lineSensorsStart();
  100. motorsInit();
  101. control_params.line_follow_state = TRUE;
  102. motorsSleepDriver(OFF);
  103. if (max_Floor.left-min_Floor.left< 100.0)
  104. {
  105. tone(a, 3000);
  106. max_Floor.left=2000.0;
  107. max_Floor.front=2000.0;
  108. max_Floor.right=2000.0;
  109. max_Floor.leftExt=2000.0;
  110. max_Floor.rightExt=2000.0;
  111. min_Floor.left=150.0;
  112. min_Floor.front=150.0;
  113. min_Floor.right=150.0;
  114. min_Floor.leftExt=150.0;
  115. min_Floor.rightExt=150.0;
  116. tone(b, 3000);
  117. // return;
  118. }
  119. tone(c, 100);
  120. coef_Floor.left=1000.0/(max_Floor.left-min_Floor.left); // 1000/(max_capteur-min_capteur)
  121. coef_Floor.front=1000.0/(max_Floor.front-min_Floor.front);
  122. coef_Floor.right=1000.0/(max_Floor.right-min_Floor.right);
  123. coef_Floor.leftExt=1000.0/(max_Floor.leftExt-min_Floor.leftExt);
  124. coef_Floor.rightExt=1000.0/(max_Floor.rightExt-min_Floor.rightExt);
  125. ssd1306ClearScreen();
  126. ssd1306PrintInt(10, 5, "LEFT_EXT = ", (uint16_t) min_Floor.leftExt, &Font_5x8);
  127. ssd1306PrintInt(10, 15, "LEFT = ", (uint16_t) min_Floor.left, &Font_5x8);
  128. ssd1306PrintInt(10, 25, "FRONT -- = ", (uint16_t) min_Floor.front, &Font_5x8);
  129. ssd1306PrintInt(10, 35, "RIGHT = ", (uint16_t) min_Floor.right, &Font_5x8);
  130. ssd1306PrintInt(10, 45, "RIGHT_EXT = ", (uint16_t) min_Floor.rightExt, &Font_5x8);
  131. ssd1306Refresh();
  132. // HAL_Delay(900);
  133. tone(c, 100);
  134. ssd1306ClearScreen();
  135. ssd1306PrintInt(10, 5, "LEFT_EXT = ", (uint16_t) max_Floor.leftExt, &Font_5x8);
  136. ssd1306PrintInt(10, 15, "LEFT = ", (uint16_t) max_Floor.left, &Font_5x8);
  137. ssd1306PrintInt(10, 25, "FRONT -- = ", (uint16_t) max_Floor.front, &Font_5x8);
  138. ssd1306PrintInt(10, 35, "RIGHT = ", (uint16_t) max_Floor.right, &Font_5x8);
  139. ssd1306PrintInt(10, 45, "RIGHT_EXT = ", (uint16_t) max_Floor.rightExt, &Font_5x8);
  140. ssd1306Refresh();
  141. // HAL_Delay(900);
  142. // HAL_Delay(500);
  143. line_follower.active_state = TRUE;
  144. move(0, 10000, MAXSPEED, 0);
  145. // while(isEndMove() != TRUE);
  146. char foreward = TRUE;
  147. char cpt=0;
  148. int error;
  149. while(expanderJoyFiltered()!=JOY_LEFT && foreward)
  150. {
  151. //error=follow_control.follow_error*10;
  152. int left=((double)lineSensors.left.adc_value - min_Floor.left) * coef_Floor.left ;
  153. int front=((double)lineSensors.front.adc_value- min_Floor.front) * coef_Floor.front ;
  154. int right=((double)lineSensors.right.adc_value- min_Floor.right) * coef_Floor.right ;
  155. error=line_follower.position*200;
  156. ssd1306ClearScreen();
  157. // ssd1306PrintInt(10, 5, "LEFT_EXT = ", (uint16_t) lineSensors.left_ext.adc_value, &Font_5x8);
  158. // ssd1306PrintInt(10, 15, "LEFT = ", (uint16_t) lineSensors.left.adc_value, &Font_5x8);
  159. // ssd1306PrintInt(10, 25, "FRONT -- = ", (uint16_t) lineSensors.front.adc_value, &Font_5x8);
  160. // ssd1306PrintInt(10, 35, "RIGHT = ", (uint16_t) lineSensors.right.adc_value, &Font_5x8);
  161. // ssd1306PrintInt(10, 45, "RIGHT_EXT = ", (uint16_t) lineSensors.right_ext.adc_value, &Font_5x8);
  162. ssd1306PrintInt(10, 15, "LEFT = ", left, &Font_5x8);
  163. ssd1306PrintInt(10, 25, "FRONT -- = ", front, &Font_5x8);
  164. ssd1306PrintInt(10, 35, "RIGHT = ", right, &Font_5x8);
  165. ssd1306PrintInt(10, 54, "Error = ", error, &Font_5x8);
  166. ssd1306Refresh();
  167. // -----------------------------------------------------------------------
  168. // Condition to stop zhonx if no line
  169. // -----------------------------------------------------------------------
  170. if ((double)lineSensors.front.adc_value < min_Floor.front *1.2 &&
  171. (double)lineSensors.left.adc_value < min_Floor.left *1.2 &&
  172. (double)lineSensors.right.adc_value < min_Floor.right *1.2 &&
  173. (double)lineSensors.left_ext.adc_value < min_Floor.leftExt *1.2 &&
  174. (double)lineSensors.right_ext.adc_value < min_Floor.rightExt *1.2)
  175. {
  176. cpt++;
  177. if (cpt>5)
  178. {
  179. foreward = FALSE;
  180. move(0, 150, 250, 0);
  181. tone(c, 500);tone(d, 500);
  182. }
  183. }
  184. // -----------------------------------------------------------------------
  185. // Condition to stop if right priority
  186. // -----------------------------------------------------------------------
  187. // if (((double)lineSensors.left_ext.adc_value*1.2) > max_Floor.leftExt )
  188. // {
  189. // move(0, 30, 30, 0);
  190. // tone(c, 500);
  191. // // capteur telemeter ON
  192. // move(0, 10000, MAXSPEED, 0);
  193. // }
  194. }
  195. pid_loop.start_state = FALSE;
  196. line_follower.active_state = FALSE;
  197. telemetersStop();
  198. motorsSleepDriver(ON);
  199. }
  200. //----------------------------------------------------------------------
  201. // fonction pour asservir zhonx sur la ligne
  202. //
  203. void controlLoop(void)
  204. {
  205. static int maxfront=0; // memorize the max level of front sensors line
  206. int left=(lineSensors.left.adc_value - min_Floor.left) * coef_Floor.left ;
  207. int front=(lineSensors.front.adc_value- min_Floor.front) * coef_Floor.front ;
  208. int right=(lineSensors.right.adc_value- min_Floor.right) * coef_Floor.right ;
  209. int rightExt=(lineSensors.right_ext.adc_value - min_Floor.rightExt) * coef_Floor.rightExt;
  210. int leftExt=(lineSensors.left_ext.adc_value - min_Floor.leftExt)* coef_Floor.leftExt;
  211. int midle=0; // take account if the center sensor line is out the line
  212. int inside=right-left; //take account the sensor just right and left of front
  213. int outside=0; // take account the external sensor line
  214. if (inside>20)
  215. {
  216. midle=(maxfront-front);
  217. }
  218. else if (inside<-20)
  219. {
  220. midle=-(maxfront-front);
  221. }else
  222. {
  223. maxfront=front;
  224. }
  225. // check if we are for the center out of the line to take account the gaucheExt and droiteExt
  226. // if (devant<100)
  227. // {
  228. // exterieur = droiteExt - gaucheExt;
  229. // }
  230. line_follower.position = (double)(right - left + midle + outside) * 0.004;
  231. }
  232. void lineFollower_IT(void)
  233. {
  234. // Rapide
  235. // static int vitesse=0;
  236. controlLoop();
  237. // if (follow_control.follow_error > 3.0 && vitesse==0)
  238. // {
  239. // // deceleration
  240. // move(0, 30, MAXSPEED, MINSPEED);
  241. // vitesse=-1;
  242. // }
  243. // else if (follow_control.follow_error < 3.0 && vitesse==0)
  244. // {
  245. // // acceleration
  246. // move(0, 30, MINSPEED, MAXSPEED);
  247. // vitesse=1;
  248. // }
  249. //
  250. // if (isEndMove() == TRUE)
  251. // {
  252. // if (vitesse<0)
  253. // {
  254. // move(0, 10000, MINSPEED, MINSPEED);
  255. // }
  256. // else if (vitesse>0)
  257. // {
  258. // move(0, 10000, MAXSPEED, MAXSPEED);
  259. // }
  260. // vitesse=0;
  261. // }
  262. // -----------------------------------------------------------------------
  263. // Condition to stop zhonx if no line
  264. // -----------------------------------------------------------------------
  265. if ((double)lineSensors.front.adc_value < min_Floor.front *1.2 &&
  266. (double)lineSensors.left.adc_value < min_Floor.left *1.2 &&
  267. (double)lineSensors.right.adc_value < min_Floor.right *1.2 &&
  268. (double)lineSensors.left_ext.adc_value < min_Floor.leftExt *1.2 &&
  269. (double)lineSensors.right_ext.adc_value < min_Floor.rightExt *1.2)
  270. {
  271. move(0, 150, 250, 0);
  272. }
  273. }