☰
ROS环境下无人机PID调参实战指南:从仿真到真机
2026/10/7 7:33:17 网站建设 项目流程

最近把我的无人机项目从纯仿真往真机方向推进,卡在PID调参上差不多两个星期。GPS装上、飞控固件烧好、MAVROS通信也通了,结果一解锁起飞就是各种抽风:要么原地抖成筛子,要么油门一推就翻。后来沉下心把ROS环境下无人机PID调参的整个流程详细过了一遍,从最基础的PID如何工作,到串级PID里内外环各自负责什么,再到真机试飞时怎么根据日志判断该加P还是该加D,总算是摸出了门道。这篇笔记就是那段时间的完整复盘,适合正在学ROS、刚接触无人机飞控、或者已经被PID参数折磨到想摔遥控器的同学参考。

先说一个我的总体感受:PID调参这东西,理论知识其实很少,但动手过程中会遇到大量“黑盒现象”,比如参数看起来没问题但飞机就是飞不稳,这类问题往往不是单纯调参能解决的,而是和传感器噪声、控制频率、机体结构都有关。这篇笔记会把原理、步骤和排查思路放在一起写,希望能帮你少走几个月的弯路。

1. 项目背景与整体设计思路

1.1 为什么无人机飞控绕不开PID

四旋翼本质上是一个开环不稳定的系统。四个电机产生升力和力矩,但如果没有反馈控制,机体会在几秒钟内翻滚坠地。姿态控制器需要实时读取IMU输出的角速度和姿态角,再计算四个电机对应的转速修正量。这个计算过程,绝大多数飞控用的都是PID控制。

PID三个字母分别对应比例项P、积分项I、微分项D。P根据当前误差大小输出修正量,误差越大修正越强;I把历史误差累积起来,用来消除那种持续存在的偏差;D则根据误差的变化趋势提前施加阻尼,抑制超调。用开手动挡的车来类比:P是看到方向盘偏了多少就回多少,D是感觉到方向正在越偏越快时提前往回带,I是车辆一直跑偏时慢慢把方向盘往中间顶住。

在无人机飞控里,PID的价值在于用三个可调系数,去匹配电机响应速度、机体转动惯量、传感器延迟等因素,让系统的响应速度和阻尼达到平衡点。这个过程没有解析解,只能靠实验去逼近。

注意:不同飞控固件的PID实现细节差异很大,PX4的姿态角速度环用的是PID,位置环则常用P控制器加前馈。ArduPilot的参数命名和PX4也完全不同。调参前先确认自己用的是哪套固件,别拿A固件的参数往B固件上套。

1.2 ROS环境下的调参整体方案与技术路线

在ROS框架下做无人机控制,主流有两条技术路线。一是使用PX4或ArduPilot这类成熟飞控,通过MAVROS将飞控和ROS通信打通,ROS负责上层感知、规划、避障,底层姿态控制交给飞控。二是完全在ROS里实现控制器,先在Gazebo里跑仿真,再迁移到自研飞行控制板。这篇笔记以PX4 + Gazebo + MAVROS这条路线为主,因为对初学者最友好,也最容易出效果。

我建议第一次接触无人机控制的同学,不要急着写控制器代码,先把PX4的官方仿真跑起来,用QGroundControl地面站观察姿态响应曲线,熟悉一下飞控的行为特征。等对“飞机在收到一个姿态指令后是怎么响应”有了直观认识,再考虑改参数或者写自己的控制器逻辑,会顺手得多。

ROS在这条链路里扮演的角色就是“大脑上层的通信总线”。MAVROS节点负责把PX4的无人机状态数据封装成ROS话题,比如/pose、/imu、/mavros/state;同时它接收来自ROS侧的指令,再转发给飞控。调参时,ROS侧能做的核心工作就是数据记录和可视化,rosbag把飞行数据完整录下来,plotjuggler或rqt_plot画出来分析,这比只看地面站里的曲线高效得多。

1.3 先理清控制器层次,再动手调参

在调任何参数之前,务必先把无人机的控制器分层结构弄清楚。飞控内部是一个级联结构,外环是位置环和速度环,内环是姿态角度环和姿态角速度环。以下面这个简化的级联结构为例:

  • 位置外环:输入是期望位置与实际位置的误差,输出期望速度。
  • 速度外环(部分飞控才有):输入期望速度与实际速度误差,输出期望姿态角。
  • 姿态角度环:输入期望姿态角与实际姿态角误差,输出期望角速度。
  • 角速度内环:输入期望角速度与实际角速度误差,输出电机油门修正量。

实际调试时这个框图不需要画得多精确,但必须明白:最内层是角速度环,它直接决定电机转速;最外层是位置环,它决定无人机往哪飞。调参顺序必须从内到外逐层进行,先保证角速度环能快速收敛,再让它上面的角度环稳定,最后才轮到位置环。

如果不按这个顺序来,典型表现就是“外环P调得很大,飞机仍然剧烈振荡”。因为外环输出的是内环的期望值,外环P越大,内环需要跟踪的角速度就越激进,如果内环本身响应跟不上,整个系统就会出现几赫兹的低频振荡,这时候你去减小外环P只能治标不治本。

2. PID控制原理拆解:位置式、增量式与串级结构

2.1 位置式PID和它的离散化写法

连续PID控制律是控制理论教科书里的标准形式。但在飞控和单片机里,所有量都是采样得到的离散值,所以要把积分和微分离散化。熟悉STM32单片机和嵌入式控制的人对“位置式PID用差分方程实现”这句话应该很有共鸣。

位置式PID的离散化表达式可以写成:

u(k) = Kp * e(k) + Ki * sum(e(j)) + Kd * (e(k) - e(k-1))

其中e(k)是当前周期的误差,e(k-1)是上一周期的误差,sum(e(j))是从启动到当前所有误差的累加和。积分项用累加代替,输出的u(k)是一个绝对的控制量,比如电机油门百分比、期望角速度等。飞控姿态环里,更多使用的正是这种位置式形式。

为什么姿态环偏爱位置式而非增量式?因为姿态环输出的期望角速度或者油门修正量,是一个需要落在绝对数值范围内的量,直接输出当前位置式的计算结果更直观。而增量式输出的是控制量的变化量,适合执行机构对绝对位置不敏感的场景,比如舵机,输入的是脉宽变化量而不是绝对脉宽值。

2.2 增量式PID到底用在哪儿

增量式PID的离散化写法是:

delta_u(k) = Kp * (e(k)-e(k-1)) + Ki * e(k) + Kd * (e(k) - 2*e(k-1) + e(k-2))

它的输出是当前控制量相对于上一时刻控制量的增量。增量式的一大好处是:控制输出不会发生突变,即使某个周期误差突然变大,最终执行器的变化量也只是在上一周期基础上小幅累加,这在小车电机调速、舵机云台等场景非常实用。

搜索“位置式PID用离散化差分方程”的人,多半是在MATLAB或者C代码里做仿真时,发现连续公式和离散实现出来的曲线对不上。问题通常出在采样周期不固定:如果控制周期不是固定的毫秒级节拍,Ki和Kd的系数必须除以或乘以采样时间T,而不是直接把连续时间的Ki拿来用。飞控系统一般用固定频率控制,例如250Hz、400Hz,所以算好一次的Ki在该频率下能直接用,但一旦改了控制频率,参数必须重新换算。

2.3 串级PID的内外环分工与运行频率

单级PID的问题在于:如果直接把位置误差送给姿态控制器,那位置环的延迟和姿态响应很难匹配,控制品质会很差。无人机对姿态响应速度要求极高,所以主流方案是串级PID。

内环是角速度环,响应要非常快,因为它是真正直接改变电机转速的环节。外环是角度环,需要的是把角度误差转换成期望角速度,它的响应可以慢一些。位置环或速度环在最外层,通常由GPS、光流或视觉定位提供数据,数据更新率较慢,因此频率要求最低。

控制频率的经验参考值大致如下:

控制环名称建议运行频率范围说明
角速度内环200Hz ~ 500Hz直接决定电机转速,频率越高越有利
姿态角度外环100Hz ~ 200Hz将角度误差转为角速度期望
速度/位置外环20Hz ~ 50Hz受定位数据更新率限制
GPS位置环10Hz ~ 20Hz受GPS模块输出频率限制

内环频率必须远高于外环,这点非常关键。如果两个环频率太接近,会形成控制环路之间的耦合,典型表现是系统产生一种听上去像“呜呜呜”的低频喘振。热词里有人搜“内外环的作用及时间间隔”,时间间隔指的就是上述控制周期差异。内环一般用周期2.5ms到5ms,外环周期20ms到50ms,这样内外环之间的相位差足够小,整个系统才不容易互相激励。

2.4 输出量纲:最容易忽略的坑

搜索词条里有个“pid量纲输出量”,这确实是新手最容易忽略的问题。PID每一项输出的量纲必须一致。比如角速度内环,输入是角速度误差,单位是rad/s,经过PID后输出的是油门百分比或者归一化力矩,那么Kp的量纲就是“油门百分比/(rad/s)”。

如果把一个用于角度环的P参数,直接挪到角速度环上,数值会差几个数量级。因为角度误差的单位是度或弧度,角速度误差的单位是度每秒或弧度每秒,同样的误差数值,经过不同环的Kp后,输出差异非常大。这也是为什么网上找的参数不能直接复用的核心原因:你根本不知道那些参数对应的是哪个环、什么量纲、什么机体。

调参前应该先搞清楚的三个问题:这个PID环的输入量是多少,单位是什么;输出量是多少,单位是什么;控制频率是多少。三个问题清楚了,再看别人的参数才有参考价值,否则就是在盲人摸象。

3. 实操过程记录:从仿真整定到真机微调

3.1 环境搭建:Ubuntu、ROS、PX4、MAVROS

我用的环境是Ubuntu 20.04 + ROS Noetic + PX4 + Gazebo。ROS环境的安装,这里多说一句:如果不想在软件源配置和依赖包上耗掉半天时间,可以直接用鱼香ROS的一键安装脚本,它会把ROS发行版、常用工具链、依赖一次性装好,实测比手动配置省一两个小时。新手不必迷信“必须手动敲命令”的说法,配置环境只是手段,控制算法才是重点。

之后安装MAVROS:

sudo apt install ros-noetic-mavros ros-noetic-mavros-extras

接着安装MAVROS需要的地理数据文件。这里要注意国内网络环境的实际情况,建议提前准备,否则MAVROS启动时会因为加载地理数据失败而报警。然后安装QGroundControl地面站,按官方文档下载对应AppImage并配置权限即可。

下面的基础检查流程比较重要:

# 启动PX4 SITL仿真 cd ~/PX4-Autopilot make px4_sitl gazebo # 新终端启动MAVROS roslaunch mavros px4.launch fcu_url:="udp://:14540@127.0.0.1:14557"

启动后可以用rostopic echo /mavros/state查看飞控连接状态,看到connected: True就说明通信打通了。这一步如果不通,后面所有调参都无从谈起。常见原因是端口号不匹配,仿真时MAVROS的udp端口要和PX4的配置文件对齐,真机则是/dev/ttyUSB0这类串口权限问题,记得把自己的用户加入dialout组。

3.2 仿真里怎么练手:阶跃响应与临界振荡法

仿真平台的价值在于可以大胆做破坏性实验。我推荐先在Gazebo中把PX4的iris模型跑起来,切换到Offboard模式,用MAVROS发送一个期望姿态角阶跃指令,比如期望roll角从0度阶跃到10度,然后观察实际roll角的响应曲线。

这个环节强烈建议用rosbag把数据录下来,配合plotjuggler或rqt_plot分析。只盯着QGroundControl里的实时曲线看,很难捕捉到细节。我一般录制以下话题:

  • /mavros/local_position/pose
  • /mavros/imu/data
  • /mavros/rc/out(遥控器输出)
  • /mavros/state

调参过程可以按照齐格勒-尼科尔斯临界振荡法的思路走。先把I和D全部置0,只保留P项,从小往大加。观察roll角跟踪情况,当P高到某个值时,机体开始以某个固定频率等幅振荡,这个点是临界点,记录此时的增益Ku和振荡周期Tu。然后根据经验,把P降回临界值的某个比例,加入D项抑制振荡,最后再加少量I消除稳态误差。

这里给一组我实测的记录,供参考:

参数组KpKiKd观察结果
A组0.300响应太慢,10度阶跃要5秒才接近目标
B组1.200响应变快,但出现约2Hz轻微抖动
C组0.80.010.4响应平稳,超调约5%,约1秒内收敛

从B组到C组的变化最能说明问题:单独加P到临界边缘后,靠D把振荡“压”下去,响应速度和阻尼可以达到一个相对平衡的状态。

3.3 从仿真参数到真机参数的三步转换

仿真和真机的差异主要集中在传感器噪声、电机响应延迟、机体刚度和重心位置。从仿真参数直接搬到真机是不现实的,我习惯按以下三步做转换:

第一步,把仿真里内环的P值乘以0.7左右作为真机初始值,D值可以稍微放大,因为真机电机和桨叶的阻尼通常比仿真模型小。第二步,暂时保持I值较小,甚至先置0,飞起来观察稳态误差,再逐步增加。第三步,每次只改一个参数,改完记录飞行日志,不要同时动两个以上参数,否则出了问题你根本不知道该找谁。

为什么P要缩放而D可以放大?因为仿真模型里的电机响应往往偏理想,P偏大会在真机上表现为高频抖动甚至噪声振荡;而D在仿真里过于保守,真机则能在一定程度上通过D提供必要的阻尼。

注意:真机首次试飞,务必先不装桨解锁,在地面上用手掰一下机体,观察电机是否产生反向修正力。方向反了就直接把电机转向或者对应参数取反,这一步能避免炸机。

3.4 真机试飞的完整流程与安全事项

真机试飞和仿真完全是两种体验。仿真里参数错了顶多模型翻倒重启,真机参数错了就是桨叶扫地。我在真机调试时的流程是:

第一次试飞只做自稳模式下的悬停,不上Offboard。解锁后缓慢推油门,让飞机离地30厘米左右,观察姿态角是否平稳,有没有高频抖动声。如果电机发出“嗡嗡”的高频异响,通常是D项过大,把噪声放大了。这时候优先减小D,而不是减P。

第二次试飞仍然悬停,但可以小幅打杆,观察滚转和俯仰响应是否回中。如果回中慢,或者有回弹,说明内环角度环P偏小或者D偏大;如果打杆后机身在到达目标角度后还左右晃动,说明内环的P偏大。

第三次试飞才考虑切换Offboard模式,先给一个很小的期望高度或者很小的期望姿态角,看控制是否平稳。真机上不建议第一次Offboard就做大机动,哪怕日志看起来很好。

整个试飞过程中,人是站在机体后方的,螺旋桨平面要与身体垂直,这是最基础的安全姿势。有条件就上绑线测试台,至少确保任何情况下飞机不会飞到人脸上来。

4. 常见问题与排查技巧实录

4.1 振荡、超调、偏航三大现象的排查思路

调试中遇到的绝大多数控制问题,都可以归结为振荡、超调、偏航三类现象。下面这个表格是我整理出来的排查思路,搭配飞行日志看会更有感觉。

现象表现可能原因排查与解决思路
低频大幅振荡,整个机体“喘”外环P过大,或内外环频率太接近降低外环P,确认内外环控制周期差足够大
高频轻微抖动,伴随着电机异响内环D过大放大传感器噪声降低内环D,检查陀螺仪原始数据是否有毛刺
悬停时始终朝一个方向漂重心偏移、传感器零偏、I不足校准加速度计陀螺仪,做水平校准,适当增加I
打杆后超调,姿态来回震荡几秒内环P偏大,D不足减小P,适量增加D,观察收敛时间
推油门机体先冲高再回落位置外环P过大,速度环阻尼不足降低位置外环P,检查速度环配置

排查原则是“先内后外、先P后D、最后I”。每次只改一个参数,改完必须重新采集日志对比。很多情况下问题真正来源不是某个参数,而是传感器数据本身,比如振动过大导致IMU饱和,这时候再怎么调PID都无济于事,先解决机械振动才是正道。

4.2 容易被忽略的细节坑

这块内容是我认为整篇笔记里最有价值的部分,因为这些问题几乎不会出现在教科书里。

第一个坑是改完参数忘记写回飞控。仿真模式下参数存在内存里,重启就恢复默认。真机模式下,如果使用的是QGroundControl在线修改参数,离线上电后又会回到上次保存的旧参数。建议每次调参后立刻用QGroundControl的“参数文件”功能导出存档,文件名带上日期和备注,比如params_20240901_hover_mini.param。

第二个坑是内外环D项用混。内环D的作用是抑制角速度变化率,提升阻尼;外环D的作用是抑制角度变化趋势。如果把外环D当成内环阻尼来用,噪声会被急剧放大,因为外环输入里包含了定位数据的跳变。正确的做法是各环的D各司其职,外环需要平滑时,优先降低外环带宽或增加滤波,而不是堆D。

第三个坑是日志时间戳不同步。在plotjuggler里看到姿态角已经平稳,但真机仍然乱晃,很可能是因为MAVROS与飞控的时间同步出了问题。调参前先检查HAL和MAVROS的时间同步状态,确认PX4参数里正确启用了硬件时间戳。时间戳不同步会导致控制指令滞后,系统表现就像P过大一样,但实际P值并不大。

第四个坑是想直接抄网上参数。不同机架大小对应不同转动惯量,机架越大P值通常越小;不同电机和电调响应速度不同,D的可调范围差异很大。网上参数可以参考的只有量级和调试思路,直接填进自己的飞控,大概率是要出问题的。

4.3 调参经验速查表

把这段时间的经验浓缩成一张表,给已经上手的同学直接参考:

环节主要目标参数调整习惯
角速度内环快速跟踪期望角速度且不抖先P后D,P从小到大,D用于压高频振荡
姿态角度外环姿态角准确回中且不超调P适当大一些,D不宜过大,I用于消除固定偏差
位置/速度环悬停位置保持、航线跟踪P值不能过大,优先保证阻尼,I值偏保守
传感器滤波提供干净的数据给控制器先看原始IMU数据,再决定滤波强度,滤波太强会引入延迟

实际调参时,建议每轮参数都记录这样一行:日期、机架型号、控制频率、P值、I值、D值、改动目的、观察结果。坚持一周之后,你会形成自己的参数库,调试效率会高很多。

还有一个很实用的小技巧:在Gazebo仿真里,可以用rqt_reconfigure这个ROS工具在运行中动态调整ROS侧节点的参数,不用重启就能看到响应变化。但要注意,如果参数是写在飞控固件里的,动态调参工具是不生效的,必须通过地面站或MAVROS服务写入飞控参数系统。

最后再分享一个我在实操中的体会:PID调参不是一次性的任务,它会伴随无人机项目的整个生命周期。换了桨叶、改了机架、换了电池,参数都可能需要重新微调。每次飞完带着日志回来分析,比在起飞现场瞎试要高效太多。培养“改一个参数、飞一次、看一段日志”的工作习惯,比追求所谓“万能参数”重要得多。希望这篇笔记能帮你在无人机控制这条路上少摔几架飞机。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询