1. 项目概述
去年夏天,我在实验室里调试一台四轮驱动的小车时,突然意识到一个问题:为什么市面上那么多智能小车项目,真正能实现精准轨迹控制的却寥寥无几?这个问题促使我开始了为期三个月的智能小车建模与轨迹控制研究。今天要分享的就是这段从理论推导到实际落地的完整历程。
智能小车作为移动机器人中最基础的形态,其运动控制问题看似简单,实则包含了动力学建模、传感器融合、控制算法设计等多个技术难点。一个完整的智能小车控制系统需要解决三个核心问题:如何准确描述小车的运动状态(建模)、如何规划期望的运动路径(轨迹生成)、以及如何让小车实际跟随这个路径(轨迹跟踪)。
2. 系统架构设计
2.1 硬件平台选型
在开始建模前,首先要确定硬件平台。经过多次对比测试,我最终选择了以下配置方案:
- 底盘:四轮差速驱动结构,使用直流减速电机(减速比1:30)
- 主控:STM32F407(168MHz主频,带FPU)
- 传感器:MPU6050(加速度计+陀螺仪)+ 光电编码器(每转500脉冲)
- 通信:NRF24L01无线模块(用于上位机监控)
这个配置的考虑在于:四轮差速结构比两轮更稳定,适合初学者;STM32F407的性能足够处理控制算法;传感器组合既能获取姿态也能测量位移;无线模块方便调试。
注意:电机减速比不宜过小,否则会影响低速控制性能。实测1:30的减速比在PWM分辨率10bit时,最小可控速度约0.05m/s。
2.2 软件架构设计
软件部分采用分层架构:
- 底层驱动层:电机PWM控制、编码器计数、IMU数据读取
- 中间件层:传感器数据融合(扩展卡尔曼滤波)、电机闭环控制(PID)
- 应用层:轨迹规划、轨迹跟踪控制算法
- 监控层:通过无线模块上传数据到上位机显示
这种架构的优势在于各层解耦,便于单独调试和功能扩展。例如更换不同的轨迹跟踪算法时,只需修改应用层代码。
3. 运动学建模
3.1 差速驱动模型
对于四轮差速驱动的小车,可以简化为两轮模型进行分析。建立如图所示的坐标系:
code复制 Y
^
|
|
X<------O
其中:
- (x,y)表示小车中心位置
- θ表示车体朝向角
- v表示线速度
- ω表示角速度
- L表示轮距(两驱动轮间距)
运动学方程为:
code复制dx/dt = v * cosθ
dy/dt = v * sinθ
dθ/dt = ω = (v_r - v_l)/L
v = (v_r + v_l)/2
其中v_r和v_l分别是右轮和左轮的线速度。
3.2 模型离散化
为了在微控制器上实现控制,需要将连续模型离散化。采用前向欧拉法,采样周期为T:
code复制x(k+1) = x(k) + T*v(k)*cosθ(k)
y(k+1) = y(k) + T*v(k)*sinθ(k)
θ(k+1) = θ(k) + T*ω(k)
这个离散模型将成为后续控制算法设计的基础。
实测发现:当采样周期T>20ms时,离散误差会明显影响控制精度。建议控制在10ms以内。
4. 轨迹规划
4.1 直线轨迹
最简单的轨迹是两点间的直线。给定起点(x0,y0)和终点(x1,y1),参数方程为:
code复制x(t) = x0 + (x1-x0)*t
y(t) = y0 + (y1-y0)*t
t∈[0,1]
对应的期望速度和角度为:
code复制v_d(t) = sqrt((x1-x0)^2 + (y1-y0)^2)/T_total
θ_d(t) = atan2(y1-y0, x1-x0)
4.2 圆弧轨迹
对于圆弧轨迹,给定圆心(xc,yc)、半径R、起始角α和终止角β,参数方程为:
code复制x(t) = xc + R*cos(α + (β-α)*t)
y(t) = yc + R*sin(α + (β-α)*t)
t∈[0,1]
期望速度和角度:
code复制v_d(t) = R*(β-α)/T_total
θ_d(t) = α + (β-α)*t + π/2
4.3 多项式轨迹
更复杂的轨迹可以使用五次多项式插值,满足位置、速度、加速度的边界条件:
code复制x(t) = a0 + a1*t + a2*t^2 + a3*t^3 + a4*t^4 + a5*t^5
y(t) = b0 + b1*t + b2*t^2 + b3*t^3 + b4*t^4 + b5*t^5
系数可以通过解线性方程组得到。这种轨迹平滑,适合需要连续加速度的场景。
5. 轨迹跟踪控制
5.1 PID控制
最基础的跟踪方法是分别对x、y、θ三个变量设计PID控制器。以x方向为例:
code复制e_x = x_d - x
u_x = Kp*e_x + Ki*∫e_x dt + Kd*de_x/dt
然后将u_x转换为左右轮速:
code复制v_l = u_x - L/2 * u_θ
v_r = u_x + L/2 * u_θ
这种方法简单但存在耦合问题,三个PID控制器会相互干扰。
5.2 反步法控制
更高级的方法是反步法(Backstepping),设计Lyapunov函数保证稳定性。控制律为:
code复制v = v_d * cos(θ_e) + K1 * x_e
ω = ω_d + K2 * v_d * y_e + K3 * v_d * sin(θ_e)
其中(x_e, y_e, θ_e)是跟踪误差,K1,K2,K3>0是控制参数。
5.3 模型预测控制
MPC通过在线优化未来一段时间的控制序列来实现跟踪。在每个采样时刻求解:
code复制min Σ(||x(k+i)-x_d(k+i)||^2 + λ||u(k+i)||^2)
s.t. x(k+i+1) = f(x(k+i),u(k+i))
虽然计算量大,但在STM32F407上简化后的MPC仍能实现20Hz的控制频率。
6. 系统实现
6.1 硬件搭建
- 组装底盘,确保四个轮子在同一平面
- 安装电机和编码器,注意接线正确性
- 固定IMU模块,尽量靠近重心
- 连接主控板和电源,测试各部件供电
常见问题:电机接线反相会导致正反馈震荡。可以通过观察开环响应来判断。
6.2 软件实现
核心控制循环伪代码:
code复制void control_loop() {
read_sensors();
ekf_update(); // 状态估计
get_reference(); // 获取期望轨迹
compute_control(); // 计算控制量
set_motor_speed(); // 输出到电机
send_telemetry(); // 上传数据
}
关键参数配置示例(STM32 HAL库):
c复制// PID参数
pid_x.Kp = 0.5; pid_x.Ki = 0.01; pid_x.Kd = 0.1;
// 电机PWM配置
htim1.Instance->ARR = 999; // 1kHz PWM
htim1.Instance->CCR1 = 500; // 50% duty
6.3 调试技巧
- 先调单个电机的速度闭环
- 再测试开环直线运动
- 最后调试轨迹跟踪
- 使用上位机实时绘图分析误差
7. 实测结果与分析
7.1 直线跟踪
参数:速度0.3m/s,距离2m
| 控制方法 | 最大误差(m) | 稳态误差(m) |
|---|---|---|
| PID | 0.12 | 0.05 |
| 反步法 | 0.08 | 0.02 |
| MPC | 0.05 | 0.01 |
7.2 圆形跟踪
参数:半径1m,速度0.5m/s
| 控制方法 | 最大径向误差(m) |
|---|---|
| PID | 0.15 |
| 反步法 | 0.10 |
| MPC | 0.06 |
从结果看,MPC表现最好但计算量大,PID最简单但精度有限,反步法在性能和复杂度间取得了平衡。
8. 常见问题与解决
8.1 电机响应迟缓
可能原因:
- PWM频率过低(建议8-10kHz)
- PID参数不合适(先调P,再调D,最后I)
- 电机扭矩不足(检查电源电压)
8.2 轨迹跟踪震荡
解决方案:
- 降低控制增益
- 增加速度前馈
- 检查编码器噪声(可加低通滤波)
8.3 姿态估计漂移
处理方法:
- 校准IMU零偏
- 调整EKF参数
- 融合编码器数据
9. 进阶优化方向
- 加入动态障碍物避碰
- 实现SLAM建图与定位
- 移植到ROS系统
- 尝试强化学习控制
经过三个月的迭代,这个小车系统最终实现了厘米级的轨迹跟踪精度。最大的收获是认识到理论建模与实际系统的差距,以及如何通过实验不断调整模型参数。
