task_communication(316).c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. #include "task_communication.h"
  2. /* typedef -----------------------------------------------------------*/
  3. comData s_comData = {
  4. .maxFeed = 60,
  5. .maxRunFeed = 0,
  6. };
  7. // 定义测试函数
  8. void test_isPointInPolygon(comData *p_comData) {
  9. // 定义多边形的经纬度坐标集合
  10. double polygonLat[] = {34.34934, 34.25916, 34.36221, 34.21619};
  11. double polygonLng[] = {108.84569, 108.80257, 109.03829, 109.05611};
  12. // 测试点在多边形内部的情况
  13. double point1Lat = 34.33312;
  14. double point1Lng = 108.8531;
  15. /* 尝试获取互斥量,等待无限长时间 */
  16. if(osMutexAcquire(s_messageDate_locationHandle, osWaitForever) == osOK)
  17. {
  18. /* 安全地访问s_rs485RecDate结构体 */
  19. point1Lat = s_messageDate.latitude / 100000;
  20. point1Lng = s_messageDate.longitude / 100000;
  21. /* 访问完成,释放互斥量 */
  22. osMutexRelease(s_messageDate_locationHandle);
  23. }
  24. bool result1 = isPointInPolygon(point1Lat, point1Lng, polygonLat, polygonLng);
  25. printf("Test case 1: Point (%f, %f) is%s inside the polygon.\n", point1Lat, point1Lng, result1 ? "" : " not");
  26. if(result1){ // 处于围栏内
  27. p_comData->fenceStatus = 0;
  28. GPIO_BEEP(GPIO_PIN_RESET);
  29. }else{ // 处于围栏外
  30. p_comData->fenceStatus = 1;
  31. GPIO_BEEP(GPIO_PIN_SET); // 蜂鸣器响 只有在超出围栏时响
  32. }
  33. // 从初始态转为中间静止态
  34. if(p_comData->driveStatus == 0){
  35. p_comData->driveStatus = 1;
  36. }
  37. }
  38. // 下发的车时速控制,运行状态的切换
  39. // 初始化时
  40. // 时速为0的情况 :1. MQTT通信超时 2. 围栏未初始化时 3. 允许更新固件,并启动更新时
  41. // 时速为max的情况:在围栏内行驶
  42. // 运行中超出围栏 以每秒减1km/h的速度下调直至超出围栏
  43. void Speed_Control(comData *p_comData, ec800Date *p_ec800Date){
  44. // 1. 判断时速为0的情况
  45. if((p_ec800Date->fenceRecSuccess == 0) || (p_ec800Date->hardwareUpdate == 0x01)){ // 围栏未初始化时
  46. p_comData->maxRunFeed = 0;
  47. }else{ // 2. 时速为max的情况
  48. // 如果初始态超出围栏
  49. if((p_comData->driveStatus == 1) && (p_comData->fenceStatus == 1)){
  50. if(p_ec800Date->vehSpeed > 0){ // 服务器下发的限制车速大于0
  51. p_comData->maxRunFeed = p_ec800Date->vehSpeed;
  52. }else{
  53. p_comData->maxRunFeed = 0;
  54. }
  55. return;
  56. }
  57. // 如果运行态超出围栏或者出现故障
  58. if(((p_comData->driveStatus == 3) && (p_comData->fenceStatus == 1))
  59. || (BIT_CLEAR(s_comData.Malfunction, fence))
  60. || (BIT_CLEAR(s_comData.Malfunction, batError))
  61. ){
  62. if(p_comData->maxRunFeed > 0){
  63. p_comData->maxRunFeed = p_comData->maxRunFeed - 1;
  64. }else{
  65. p_comData->maxRunFeed = 0;
  66. }
  67. return;
  68. }
  69. // 围栏内行驶
  70. if(p_comData->fenceStatus == 0){
  71. p_comData->maxRunFeed = p_comData->maxFeed;
  72. }
  73. }
  74. }
  75. // 车运行状态切换
  76. void vehicle_runState(rs485RecDate *p_rs485RecDate, comData *p_comData){
  77. uint16_t vehSpeed; // 车速
  78. static uint8_t status2_cnt, status3_cnt = 0;
  79. // 初始化还未完成,不进行行车状态判断
  80. if(p_comData->driveStatus == 0){
  81. return;
  82. }
  83. /* 尝试获取互斥量,等待无限长时间 */
  84. if(osMutexAcquire(mutex_rs485RecDateHandle, osWaitForever) == osOK)
  85. {
  86. vehSpeed = p_rs485RecDate->vehicleSpeed;
  87. /* 访问完成,释放互斥量 */
  88. osMutexRelease(mutex_rs485RecDateHandle);
  89. }
  90. // 车速判断 判断车的运行状态
  91. if(vehSpeed == 0){
  92. status3_cnt = 0;
  93. if(status2_cnt < times_3s){
  94. status2_cnt++;
  95. }else{
  96. status2_cnt = times_3s;
  97. p_comData->driveStatus = 2;
  98. }
  99. }
  100. if(vehSpeed > 0){
  101. status2_cnt = 0;
  102. if(status3_cnt < times_3s){
  103. status3_cnt++;
  104. }else{
  105. status3_cnt = times_3s;
  106. p_comData->driveStatus = 3;
  107. }
  108. }
  109. }
  110. // 电池故障判断
  111. void fault_bat(rs485RecDate *p_rs485RecDate, comData *p_comData){
  112. uint16_t errorLevel = 0;
  113. /* 尝试获取互斥量,等待无限长时间 */
  114. if(osMutexAcquire(mutex_rs485RecDateHandle, osWaitForever) == osOK)
  115. {
  116. errorLevel = p_rs485RecDate->alarmLevel;
  117. /* 访问完成,释放互斥量 */
  118. osMutexRelease(mutex_rs485RecDateHandle);
  119. }
  120. // 存在电池故障
  121. if(errorLevel != 0){
  122. BIT_SET(s_comData.Malfunction, batError); // 置位电池故障
  123. }else{
  124. BIT_CLEAR(s_comData.Malfunction, batError); // 清除电池故障
  125. }
  126. }
  127. /* USER CODE BEGIN Header_Task_communication */
  128. /**
  129. * @brief Function implementing the communication thread.
  130. * @param argument: Not used
  131. * @retval None
  132. */
  133. /* USER CODE END Header_Task_communication */
  134. void task_communication_content(void)
  135. {
  136. // unsigned long times = 0;
  137. LED0_TOGGLE(); // 灯翻转
  138. EC800_FTP_OTA_Upgrade(); // OTA升级
  139. // 固件升级时不做其他操作,保证固件更新的完成
  140. if(s_ec800Date.hardwareUpdate != 0){
  141. HAL_NVIC_DisableIRQ(USART3_IRQn); // 避免被中斷
  142. // HAL_NVIC_DisableIRQ(USART1_IRQn);
  143. vTaskSuspend(ec800_dataUploaHandle); // 挂起任务
  144. osDelay(200);
  145. }else{
  146. if(s_ec800Date.fenceRecSuccess == 1){ // 围栏数据接收完成 执行围栏判断
  147. test_isPointInPolygon(&s_comData); // 电子围栏
  148. }
  149. fault_bat(&s_rs485RecDate, &s_comData); // 电池故障判断
  150. vehicle_runState(&s_rs485RecDate, &s_comData); // 行车状态判断
  151. Speed_Control(&s_comData, &s_ec800Date); // 速度控制
  152. rs485_poll_sendReceive(s_comData.maxRunFeed); // 与车进行通信
  153. osDelay(1000);
  154. }
  155. // times = getRunTimeCounterValue();
  156. // printf("test_isPointInPolygon:%ld\r\n", times);
  157. }