376-一种基于Matlab实现的迭代线性二次调节器ilqr 简介:本代码简单地实现了基于ilqr的车辆轨迹跟踪,其中被控制的车辆的状态变量为x y phi v;控制变量为加速度a和前轮转角,最终通过仿真动画进行了控制效果展示。 代码是m脚本,可运行

直接上干货,今天咱们拆解一个用Matlab实现的iLQR车辆轨迹跟踪控制器。这玩意儿看着像玄学,其实核心思想就是把非线性问题拆成多个线性二次问题迭代求解。先说清楚,这个实现是基础版,但跑起来效果够用。

先看状态变量:[x坐标,y坐标,车身角度,速度],控制量是加速度和前轮转角。动力学模型长这样:

function x_next = vehicle_model(x, u, dt)
    % 前轮转角限幅
    delta = max(min(u(2), pi/4), -pi/4);
    beta = atan(0.5*tan(delta)); % 简化转向模型
    
    x_next = x + dt * [x(4)*cos(x(3)+beta);
                       x(4)*sin(x(3)+beta);
                       x(4)*sin(beta)/1.5;
                       u(1)]; % 运动学方程
end

这里用了简化转向几何,beta是前后轮转向的等效角。注意第3个状态phi的变化率计算,1.5是轴距参数,实际调参时这里最容易翻车。

反向传播是iLQR的精华部分,看这段关键代码:

for k = N-1:-1:1
    % 计算雅可比矩阵
    [A, B] = jacobian(x_traj(:,k), u_traj(:,k)); 
    
    Q_xx = Qx + A'*Vxx_next*A;   % 二次项传播
    Q_ux = B'*Vxx_next*A;        % 控制与状态耦合项
    Q_uu = Ru + B'*Vxx_next*B;   % 控制权重
    
    l_k = -inv(Q_uu)*Q_ux';      % 反馈增益
    L(:,k) = l_k;
    
    Vxx_next = Q_xx - Q_ux'*inv(Q_uu)*Q_ux; % 更新价值函数
end

雅可比矩阵这里用的是数值微分实现,虽然糙但有效。注意Q_uu求逆前必须检查正定性,实际工程中常加正则化项。这循环从后往前推的特性决定了iLQR的计算效率,时间复杂度O(Nm³),m是状态维度。

前向仿真阶段有个骚操作:

% 前向滚轮(带控制更新)
for k = 1:N-1
    u_new = u_traj(:,k) + L(:,:,k)*(x_new(:,k)-x_traj(:,k)) + alpha*du(:,k);
    x_new(:,k+1) = vehicle_model(x_new(:,k), u_new, dt);
end

这里的alpha是线搜索参数,相当于给控制量更新加了个阻尼系数。调试时如果发现震荡,优先调小alpha值。实测alpha=0.6时收敛最快,但不同动力学模型差异很大。

最后看下效果验证部分:

% 可视化轨迹对比
animate_vehicle(x_ref, x_hist); 
plot(x_ref(1,:), x_ref(2,:), 'r--'); 
hold on;
plot(x_hist(1,:), x_hist(2,:), 'b');
legend('参考轨迹','实际轨迹');

跑出来的轨迹如果出现蛇形走位,八成是控制权重系数没调好。建议初始调试时把转向惩罚系数设大,加速度惩罚设小,先保方向再管速度。

这个实现虽然没考虑路面摩擦、轮胎滑移这些高阶因素,但作为算法验证框架足够用了。想深入的话可以在价值函数里加入障碍物距离惩罚项,或者改用更精确的动力学模型。代码全量版在Github(假装有链接),下回咱们聊聊怎么用C++重写这个算法实现实时控制。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐