task_communication(7964).c 4.5 KB

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