目录
一、前言
前段时间帮师弟做了一个“无人搜救小车”的项目,时间比较仓促,做的也比较简陋,毕竟是毕设嘛,比起外观,更注重功能的完整性。他是自动化专业,之前学过一些电子电路、微机原理、C语言的课程,但是没有相关项目的开发经验,要求我手把手教他完成这个项目,一方面能顺利毕业,另一方面也为今后找工作做铺垫,整个项目前后花了将近6个月的时间。下面我把整个开发过程做了一个详细的记录,有相关需求的小伙伴可以做个借鉴或私信我进行交流,有不对的地方欢迎大家批评并指正。(这里要特别感谢正点原子、小马哥以及匿名科创团队,整个项目得以顺利完成,是因为我站在了巨人的肩膀上。)
二、背景
项目的背景是做一个无人搜救小车,该小车搭载有GPS、电子罗盘和人体传感器(生命探测仪),在发生地震或者火灾后,小车可通过手机(或PC)终端获取目的地的GPS坐标信息,小车一方面可以按地图上规划好的既定路线到达目的地,也可以通过自主规划路径的方式到达救灾现场进行施救。前往目的地的过程中,如果遇到物体,可自行越过障碍物继续前行。
到达目的地后,通过生命探测仪对附近的废墟进行探测,一旦检测到废墟中存在幸存者,小车将发出报警信息,给救援人员提供幸存者位置,帮助救援人员进行施救,同时可将小车的位置信息回传到手机终端或应急指挥大厅。
本项目基于STM32微控制器打造智能GPS导航小车,融合PID精确控制算法,实现高精度自主导航。系统集成多源传感器数据,通过超声波、红外与激光测距模块构建全方位环境感知体系,配合改进型路径规划算法,确保小车能够智能避障并动态优化行驶路线。借助ESP8266无线通信模块,实时传输定位数据至云端,在电子地图上精准呈现小车位置与轨迹,实现远程可视化监控,展现智能移动平台的技术优势与应用潜力。

第一代

第二代
三、硬件设计
1、STM32控制器
2、电机驱动
3、智能小车底盘
4、GPS模组
5、电子罗盘
6、无线WIFI模组
7、超声波模块
三、软件设计
软件采用FreeRTOS操作系统和裸机两种方式开发,提供了:①PID控制、LPF、滑动窗口滤波等多种无人车相关飞行控制算法;②电子罗盘、超声波、定时器PWM、GPS、WiFi等多种传感器的驱动;③导航地面站应用终端、导航APP等多种遥控遥测协议的数据解析,尤其适合初学者。
1、main函数
const x = R * lng * radians
const y = R * Math.log(Math.tan((Math.PI*0.25) + (0.5 * lat * radians)))
int main(void)
{
FilterPram JD_FilterPram;
FilterPram WD_FilterPram;
extern struct PID YAW_PID;
extern struct PID DIS_PID;
void (*JD_Filter)(FilterPram*,double,double*,u8,u8);
void (*WD_Filter)(FilterPram*,double,double*,u8,u8);
JD_Filter=SortAver_Filter_fp;
WD_Filter=SortAver_Filter;
KEY_Init();
LED_Init();
TIM4_PWM_Init(100-1,84-1);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
delay_ms(3000); //初始化延时函数
uart_init(115200); //初始化串口波特率为115200
usart2_init(38400); //串口3初始化为115200
usart3_init(115200); //初始化串口3波特率为384200
usart6_init(921600);
LED0=1;
LED1=1;
PID_Init(&YAW_PID,0.036,0.00001,0.0044,20,-20); //(0.04/0.045,0.00,0.004,20,-20)
PID_Init(&DIS_PID,4.5,2.5,0,0,-100); //0.5,0.015,0.008
Compass_Init();
WiFi_Init();
GPS_Init();
Ultrasonic_Init();
while(1)
{
Heading_Update();
GPS_Analysis((u8*)USART1_TX_BUF);
WIFI_SendDate((char *)WIFI_Tx_StrBuff);
Get_Data_From_WIFI(&ucRxFinish6);
#if 1
if((timer_printf%50)==0)
{
sprintf((char *)WIFI_Tx_StrBuff,"CV
jd:%.5lf,wd:%.5lf,yaw:%.2lf\r\n",GPS_JD_L,GPS_WD_L,YAW_L);
ESP8266_SendDate((char *)WIFI_Tx_StrBuff);
printf("CV jd:%.5lf,wd:%.5lf,yaw:%.2lf\r\n",GPS_JD_L,GPS_WD_L,YAW_L);
delay_ms(1000);
sprintf((char *)WIFI_Tx_StrBuff,"SV jd:%.5lfwd:
%.5lf\r\n\r\n",WIFI_JD,WIFI_WD);
ESP8266_SendDate((char *)WIFI_Tx_StrBuff);
printf("SV jd:%.5lf,wd:%.5lf\r\n\r\n",WIFI_JD,WIFI_WD);
timer_printf=0;
}
timer_printf++;
#endif
Get_CurrentVal();
Calculate_PID();
Navigation_of_Car();
}
}
2、PID控制器
float PID_Controller(float target_angle, float current_angle) {
float error = target_angle - current_angle;
if (error > 180.0f) error -= 360.0f;
if (error < -180.0f) error += 360.0f;
integral += error;
float derivative = error - error_prev;
error_prev = error;
return KP * error + KI * integral + KD * derivative;
}
3、电机驱动
void Motor_SetSpeed(int left_speed, int right_speed) {
if (left_speed > 100) left_speed = 100;
if (left_speed < -100) left_speed = -100;
if (right_speed > 100) right_speed = 100;
if (right_speed < -100) right_speed = -100;
TIM2->CCR1 = (uint32_t)(left_speed * 10); // 左电机PWM
TIM3->CCR1 = (uint32_t)(right_speed * 10); // 右电机PWM
}
4、小车位置动态更新
void Car_Position_Update(void) {
current_latitude = Read_GPS_Latitude();
current_longitude = Read_GPS_Longitude();
target_angle = get_bearing();
current_angle = Get_Current_Angle();
float pid_output = PID_Controller(target_angle, current_angle);
Motor_SetSpeed(left_speed, right_speed);
}
四、效果演示
哔哩哔哩视频效果演示(一):
GPS导航小车,自主导航,避障,路径规划,stm32,esp8266,pid。GPS导航小车,小车可自主到达目的地,具有一定的避障和路径规划能力。_哔哩哔哩_bilibili
哔哩哔哩视频效果演示(二):
毕设之基于STM32的GPS导航小车,运用PID跟踪控制算法,具备自主导航、智能避障与动态路径规划功能,可通过地图规划小车路径,并在地图上显示小车位置_哔哩哔哩_bilibili
五、总结
创作不易,希望大家多多支持,感兴趣的朋友可以扫码进群,互相交流,共同进步。

STM32无人机/导航小车学习交流QQ群