task_communication(978).c 4.2 KB

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