#include "task_communication.h" /* typedef -----------------------------------------------------------*/ comData s_comData = { .maxFeed = 60, .maxRunFeed = 0, }; // 定义测试函数 void test_isPointInPolygon(comData *p_comData) { // 定义多边形的经纬度坐标集合 double polygonLat[] = {34.34934, 34.25916, 34.36221, 34.21619}; double polygonLng[] = {108.84569, 108.80257, 109.03829, 109.05611}; // 测试点在多边形内部的情况 double point1Lat = 34.33312; double point1Lng = 108.8531; /* 尝试获取互斥量,等待无限长时间 */ if(osMutexAcquire(s_messageDate_locationHandle, osWaitForever) == osOK) { /* 安全地访问s_rs485RecDate结构体 */ point1Lat = s_messageDate.latitude / 100000; point1Lng = s_messageDate.longitude / 100000; /* 访问完成,释放互斥量 */ osMutexRelease(s_messageDate_locationHandle); } bool result1 = isPointInPolygon(point1Lat, point1Lng, polygonLat, polygonLng); printf("Test case 1: Point (%f, %f) is%s inside the polygon.\n", point1Lat, point1Lng, result1 ? "" : " not"); if(result1){ // 处于围栏内 p_comData->fenceStatus = 0; GPIO_BEEP(GPIO_PIN_RESET); }else{ // 处于围栏外 p_comData->fenceStatus = 1; GPIO_BEEP(GPIO_PIN_SET); // 蜂鸣器响 只有在超出围栏时响 } // 从初始态转为中间静止态 if(p_comData->driveStatus == 0){ p_comData->driveStatus = 1; } } // 下发的车时速控制,运行状态的切换 // 初始化时 // 时速为0的情况 :1. MQTT通信超时 2. 围栏未初始化时 3. 允许更新固件,并启动更新时 // 时速为max的情况:在围栏内行驶 // 运行中超出围栏 以每秒减1km/h的速度下调直至超出围栏 void Speed_Control(comData *p_comData, ec800Date *p_ec800Date){ // 1. 判断时速为0的情况 if((p_ec800Date->fenceRecSuccess == 0) || (p_ec800Date->hardwareUpdate == 0x01)){ // 围栏未初始化时 p_comData->maxRunFeed = 0; }else{ // 2. 时速为max的情况 // 如果初始态超出围栏 if((p_comData->driveStatus == 1) && (p_comData->fenceStatus == 1)){ p_comData->maxRunFeed = 0; return; } // 如果运行态超出围栏或者出现故障 if(((p_comData->driveStatus == 3) && (p_comData->fenceStatus == 1)) || ((p_comData->Malfunction != 0)){ if(p_comData->maxRunFeed > 0){ p_comData->maxRunFeed = p_comData->maxRunFeed - 1; }else{ p_comData->maxRunFeed = 0; } 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, osWaitForever) == osOK) { vehSpeed = p_rs485RecDate->vehicleSpeed; /* 访问完成,释放互斥量 */ osMutexRelease(mutex_rs485RecDateHandle); } // 车速判断 判断车的运行状态 if(vehSpeed == 0){ status3_cnt = 0; if(status2_cnt < times_3s){ status2_cnt++; }else{ status2_cnt = times_3s; p_comData->driveStatus = 2; } } if(vehSpeed > 0){ status2_cnt = 0; if(status3_cnt < times_3s){ status3_cnt++; }else{ status3_cnt = times_3s; p_comData->driveStatus = 3; } } } // 电池故障判断 void fault_bat(rs485RecDate *p_rs485RecDate, comData *p_comData){ uint16_t errorLevel = 0; /* 尝试获取互斥量,等待无限长时间 */ if(osMutexAcquire(mutex_rs485RecDateHandle, osWaitForever) == osOK) { errorLevel = p_rs485RecDate->alarmLevel; /* 访问完成,释放互斥量 */ osMutexRelease(mutex_rs485RecDateHandle); } // 存在电池故障 if(errorLevel != 0){ BIT_SET(s_comData.Malfunction, batError); // 置位电池故障 }else{ BIT_CLEAR(s_comData.Malfunction, batError); // 清除电池故障 } } /* 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; LED0_TOGGLE(); // 灯翻转 EC800_FTP_OTA_Upgrade(); // OTA升级 // 固件升级时不做其他操作,保证固件更新的完成 if(s_ec800Date.hardwareUpdate != 0){ HAL_NVIC_DisableIRQ(USART3_IRQn); // 避免被中斷 // HAL_NVIC_DisableIRQ(USART1_IRQn); vTaskSuspend(ec800_dataUploaHandle); // 挂起任务 osDelay(200); }else{ if(s_ec800Date.fenceRecSuccess == 1){ // 围栏数据接收完成 执行围栏判断 test_isPointInPolygon(&s_comData); // 电子围栏 } fault_bat(&s_rs485RecDate, &s_comData); // 电池故障判断 vehicle_runState(&s_rs485RecDate, &s_comData); // 行车状态判断 Speed_Control(&s_comData, &s_ec800Date); // 速度控制 rs485_poll_sendReceive(s_comData.maxRunFeed); // 与车进行通信 osDelay(1000); } // times = getRunTimeCounterValue(); // printf("test_isPointInPolygon:%ld\r\n", times); }