Course Project · Robot Motion Control

智能小车控制系统设计

在《机器人运动控制实验》中完成的智能小车控制项目,围绕树莓派上位机、STM32 下位机、摄像头视觉巡线、PID 控制和串口联调,打通从环境感知、控制决策到电机执行的闭环流程。

STM32 下位机外设初始化、速度闭环与电机输出
Raspberry Pi 摄像头采集、OpenCV 巡线和串口下发
14 / 24 速度控制帧输入 / 传感器状态帧输出
年级第一 期末巡线测试结果

Overview

项目概览

项目采用“上位机感知与决策、下位机实时控制”的结构。树莓派端通过摄像头获取赛道图像,使用 HSV 阈值、形态学处理、连通域筛选和分段质心计算得到车道线角度误差,再通过 PID 计算目标线速度与角速度。STM32 端接收速度指令后,结合编码器速度反馈进行运动学逆解和增量 PI 控制,最终输出电机 PWM 与阿克曼舵机角度。

STM32F10x Raspberry Pi OpenCV PID / PI UART Encoder MPU6050

System Flow

系统流程

视觉采集与预处理

follow_line.py 使用 V4L2 摄像头采集画面,截取底部 ROI,基于 HSV 黑线阈值生成掩膜,并通过开运算与膨胀降低噪声影响。

车道线误差计算

ROI 被划分为多个横向切片,程序筛选面积合理的连通域,计算质心相对画面底部中心的角度,得到带方向的平均角度误差。

PID 巡线控制

上位机将角度误差输入 PID 控制器,输出角速度并限幅;检测不到线时保持上一帧转向方向继续搜索,退出时主动发送零速度帧。

串口速度指令

速度控制帧采用 0x7B 帧头、三个小端浮点速度 vx / vy / vz0x7D 帧尾,共 14 字节,默认波特率 115200。

下位机运动控制

STM32 解析速度帧后写入 Move_XMove_Z,在 5ms 定时中断中读取编码器,完成运动学逆解、增量 PI 调速和 PWM / 舵机输出。

状态回传与调试

下位机以 24 字节状态帧回传速度、IMU 加速度/角速度、电池电压和校验位,read.py 可解析并彩色打印关键运行状态。

Modules

模块拆解

上位机视觉巡线

基于 Python、OpenCV 和 pyserial 完成摄像头读取、黑线检测、角度误差估计、PID 输出和串口速度帧发送。

串口联调工具

send.py 用于按固定频率发送速度帧,read.py 用于解析 STM32 状态帧,便于分阶段调试通信协议。

STM32 控制核心

下位机工程包含外设初始化、USART1 接收中断、编码器测速、运动学逆解、增量 PI 速度控制和电机 PWM 输出。

传感器与执行机构

工程中接触 OLED、电压 ADC、编码器、MPU6050、蜂鸣器、舵机、电机驱动,并保留 CCD、电磁巡线与雷达接口代码。

安全与异常处理

下位机包含低电压关断、按键停止、PWM 限幅和平滑滤波;上位机在异常退出时发送零速度,降低失控风险。

实验验证路径

通过串口单独收发、视觉巡线参数调整、PID 参数微调和实车巡线测试,逐步验证感知、决策与执行链路。

Code Highlights

算法、框架与亮点

这一部分从 follow_line.pyusartx.ccontrol.cpid.c 等代码中提炼,尽量展示可复盘的函数、参数、帧格式和容错策略。

视觉巡线算法

算法入口:compute_angle_error(frame)
ROI_RATIO=0.35:只取画面底部赛道区域
NUM_SLICES=5:分层计算,降低单点误检影响
HSV=[0,0,0]~[180,255,60]:提取黑色巡线路径
5x5 KERNEL:开运算 + 膨胀处理噪声
VALID_AREA=3000 / MAX_AREA=20000:过滤异常连通域
arctan2(dx,dy):质心偏移转为带方向角度误差

上 / 下位机控制框架

上位机:CONTROL_FPS=15
摄像头 -> OpenCV 巡线 -> 角度误差
PIDController(kp,ki,kd) 输出角速度
VX_CONST=0.5MAX_VZ=3.5 限幅

下位机:TIMING_TIM_Init(7199,49)
Get_Velocity_From_Encoder() 读取轮速
Get_TaEn() 做运动学逆解
Get_Motor_PWM() 生成电机 PWM

通信与调试协议

控制帧:14 bytes
0x7B + vx/vy/vz 三个 little-endian float + 0x7D
Python 端使用 struct.pack('<f')
STM32 端写入 Move_X / Move_Y / Move_Z

状态帧:24 bytes
速度 + IMU 加速度/角速度 + 电池电压
Check_Sum(22,1) 异或校验
read.py 解析帧头、帧尾、电压和校验位

优化与创新亮点

无检测保持转弯:count==0 时沿 last_sign 搜索线路
零速度退出:SIGINT / SIGTERM / 异常退出前发送停车帧
阿克曼映射:Vz_to_Akm_Angle() 将角速度转前轮角
角度限幅:前轮转角限制在 -0.32~0.32 rad
滑动滤波:Mean_Filter_Left/Right 平滑起步与停车
状态回传:速度、IMU、电压闭环辅助定位问题

Implementation

关键实现内容

  • 视觉算法 使用 ROI、HSV 阈值、连通域面积约束和多切片角度平均,提升黑线检测对噪声与局部丢线的容错性。
  • 控制策略 上位机将角度误差转换为角速度,下位机将目标速度映射到轮速/舵机角度,再由编码器反馈形成速度闭环。
  • 通信协议 控制帧与状态帧都使用明确帧头帧尾,状态帧增加异或校验,方便在串口噪声和半帧场景下定位问题。
  • 调试方法 先用固定速度帧验证下位机执行,再读取回传帧确认速度、IMU 与电压,最后接入视觉巡线脚本做整车联调。

Result

实验结果与收获

课程项目最终完成了智能小车巡线控制的闭环实验,覆盖从摄像头识别、PID 控制、串口通信到电机执行的完整链路。根据整理资料,期末巡线测试获得年级第一。

这个项目的价值不只在于跑通小车,更重要的是把机器人课程中的传感器采集、控制决策、执行机构驱动和上/下位机联调放到同一个系统里实践了一遍。

当前页面已基于文件夹内代码资料整理。后续若要继续增强展示效果,可以补充巡线测试视频、赛道记录、成绩证明、个人具体负责部分和关键调参过程;本次按要求暂不添加图片。