#include "task_communication.h" /* typedef -----------------------------------------------------------*/ comData s_comData = { .maxFeed = 60, .maxRunFeed = 0, }; // 下发的车时速控制 void Speed_Control(comData *p_comData, ec800Date *p_ec800Date){ if (p_comData == NULL || p_ec800Date == NULL) { // 错误处理:输入参数无效 return; } // 获取后台允许的最高车速 p_comData->maxFeed = s_param_boot.speed_limit; // 检查是否处于硬件更新状态 if(p_ec800Date->hardwareUpdate == 0x01){ p_comData->maxRunFeed = 0; return; } // 后台锁车 if(s_param_boot.car_lock_flag){ p_comData->maxRunFeed = (p_comData->maxRunFeed > 0) ? p_comData->maxRunFeed - 1 : 0; return; } // 检查围栏状态和驾驶状态 if(p_ec800Date->fenceRecSuccess == 0 || (p_comData->driveStatus == 1 && p_comData->fenceStatus == 1)){ p_comData->maxRunFeed = p_comData->maxFeed; return; } // 检查是否超出围栏且处于运行状态 if(p_comData->driveStatus == 3 && (BIT_CHECK(s_comData.Malfunction, fence))){ p_comData->maxRunFeed = (p_comData->maxRunFeed > p_comData->maxFeed) ? p_comData->maxRunFeed - 1 : p_comData->maxFeed; return; } // 如果在围栏内,设置最大速度为后台允许的最高车速 if(p_comData->fenceStatus == 0){ p_comData->maxRunFeed = p_comData->maxFeed; } } // 车运行状态切换 void vehicle_runState(rs485RecDate *p_rs485RecDate, comData *p_comData){ uint16_t vehSpeed; // 车速 static uint8_t status2_cnt, status3_cnt = 0; // 初始化还未完成,不进行行车状态判断 if(p_comData->driveStatus == 0){ return; } /* 尝试获取互斥量,等待无限长时间 */ if(osMutexAcquire(mutex_rs485RecDateHandle, 1000) == osOK) { vehSpeed = p_rs485RecDate->vehicleSpeed; /* 访问完成,释放互斥量 */ osMutexRelease(mutex_rs485RecDateHandle); } // 车速判断 判断车的运行状态 if(vehSpeed == 0){ status3_cnt = 0; if(status2_cnt < times_60s){ status2_cnt++; }else{ status2_cnt = times_60s; p_comData->driveStatus = 2; } } if(vehSpeed > 0){ status2_cnt = 0; if(status3_cnt < times_5s){ status3_cnt++; }else{ status3_cnt = times_5s; p_comData->driveStatus = 3; } } } // 电子围栏判断 void evaluateGeofenceBoundary(comData *p_comData, double PolygonLat[], double PolygonLng[]) { double point1Lat = 34.155896; double point1Lng = 108.978638; /* 尝试获取互斥量,等待无限长时间 */ if(osMutexAcquire(s_messageDate_locationHandle, 100) == osOK) { /* 安全地访问s_rs485RecDate结构体 */ point1Lat = (double)s_messageDate.latitude / 100000; point1Lng = (double)s_messageDate.longitude / 100000; // point1Lat = 34.15792; // point1Lng = 108.97439; /* 访问完成,释放互斥量 */ osMutexRelease(s_messageDate_locationHandle); } // 测试点在多边形内部的情况 bool result1 = isPointInPolygon(point1Lat, point1Lng, PolygonLat, PolygonLng, REC_COORDINATE_DEPTH); // printf("Test case 1: Point (%f, %f) is%s inside the polygon.\n", point1Lat, point1Lng, result1 ? "" : " not"); if(result1){ // 处于围栏内 p_comData->fenceStatus = 0; }else{ // 处于围栏外 p_comData->fenceStatus = 1; } } // 测试用 void readFaultRecord(void){ char storeFaultData[100] = {0}; // 读数据 norflash_read((uint8_t *)storeFaultData, 0, 56); HAL_UART_Transmit(&huart1, (uint8_t*)&storeFaultData ,56,1000); } /* USER CODE BEGIN Header_Task_communication */ /** * @brief Function implementing the communication thread. * @param argument: Not used * @retval None */ /* USER CODE END Header_Task_communication */ void task_communication_content(void) { // unsigned long times = 0; comData *p_comData = &s_comData; LED0_TOGGLE(); // 灯翻转 faultDetection(&s_global_par); // 故障监测 handleOTAUpgradeFault(); // OTA升级故障处理 EC800_FTP_OTA_Upgrade(); // OTA升级 // 固件升级时不做其他操作,保证固件更新的完成,发送限制车速为0,锁定车辆 if(s_ec800Date.hardwareUpdate != 0){ // HAL_NVIC_DisableIRQ(USART3_IRQn); // 避免被中斷 // HAL_NVIC_DisableIRQ(USART1_IRQn); // 写限制车速为0 modbus_write_holding_registers(0x01, 0x0001, 1, 0); osDelay(200); }else{ if(s_ec800Date.fenceRecSuccess == 1){ // 围栏数据接收完成 执行围栏判断 evaluateGeofenceBoundary(&s_comData, polygonLat, polygonLng); // 电子围栏 // 从无状态转为初始态 if(p_comData->driveStatus == 0){ p_comData->driveStatus = 1; } } #ifdef NO_CAR_STATIC_INFO fun(); uint32_t accTotalMileage = (s_rs485RecDate.accTotalMileage_h << 16) | s_rs485RecDate.accTotalMileage_l; calculate_driving_distance(accTotalMileage); // 车辆行驶里程计算 calculateDriveTime(); // 车辆行驶时长计算 vehStateDataMig(s_param_boot.date); // 车辆状态参数数据迁移 #endif storeFaultRecord(); // 历史故障存储 refreshSavedTime(); // 更新保存的时间信息 Speed_Control(&s_comData, &s_ec800Date); // 速度控制 vehicle_runState(&s_rs485RecDate, &s_comData); // 行车状态判断 rs485_poll_sendReceive(s_comData.maxRunFeed); // 与车进行通信 osDelay(1000); } // times = getRunTimeCounterValue(); // printf("test_isPointInPolygon:%ld\r\n", times); }