摘要:巡线小车为什么总是摇头晃脑?P、I、D 这三个字母到底代表什么魔法?通过好玩的动态交互小游戏,带你直观感受如何驯服一台调皮的巡线小车。
大家在学机器人或者玩乐高 EV3 的时候,想必都遇到过「巡线小车」这个经典任务吧?小车车头装着颜色传感器(光电传感器),要沿着地上一条黑线跑,听起来很简单对不对?
但如果你只是写一个简单的程序:「看到白底就左转,看到黑线就右转」,你会发现小车就像喝醉了酒一样,在黑线上疯狂地「左拐右拐」,扭来扭去,根本跑不快。
这时候老师就会告诉你,要用 PID 算法 来控制转向模块。可是,到底什么是 P,什么是 I,什么是 D 呢?在 EV3 里这些参数该填多大?很多教程里都是一堆看不懂的公式,今天我们换个玩法。废话不多说,我们直接上「小游戏」,你自己动手调一调,一秒就能看懂。
P 的魔法:按比例来,不要太猛
P 代表「比例」。
想象一下,如果你蒙着眼睛,我让你沿着一条直线走。如果你发现自己往左偏了一点点,你会怎么做?你肯定会向右走一点点来纠正,对吧?
最笨的小车是没有「一点点」这个概念的。它只要发现自己偏了,就会把方向盘打死(猛拐)。这样一来,它马上就会偏向另一边,然后再猛拐回来,这就是小车疯狂摇头的原因。
有了 P 魔法,小车就聪明了:偏得多,就使劲拐;偏得少,就轻轻拐。 这就是「比例」的意思。
如果 P 太小,小车拐弯太慢,就会跑飞;如果 P 太大,小车就会用力过猛,不停地越过黑线左摇右晃。
💡 提示
对于 EV3,P 值(也就是 Kp)通常在 0.5 到 2.0 之间。你可以把 P 值调到最大(5.0)试试,看看小车是不是抖得很厉害?这种现象在控制学里叫做「震荡」。
D 的魔法:预测未来,提前踩刹车
D 代表「微分」。
只靠 P,小车虽然能巡线,但总是免不了会有一点晃悠。为什么呢?因为小车是有惯性的。当小车拼命转回黑线上的时候,它转得太快了,等它发现「哦,我回到线上了」的时候,由于惯性,它已经冲过头了。
这时候,我们需要 D 魔法,也就是「预测未来」。D 魔法会一直盯着小车靠近黑线的速度:「哎呀哎呀,你靠近黑线的速度太快了,马上要冲过头了,赶紧反打方向盘刹车。」
有了 D 的阻尼作用,小车在快要回到黑线时就会温柔地减速,稳稳地贴上去。快在下面的演示里加上 D 试试吧,看小车是不是丝滑了很多?
I 的魔法:记仇的小本本,专治顽固偏差
I 代表「积分」。
P 和 D 配合,其实已经能解决 90% 的问题了。但生活总是充满意外,假如你的小车天生左轮比右轮大一点,或者刚好有一阵强侧风一直吹着它。这时候,小车就会发现:我怎么总是偏离黑线一点点呢?
因为只偏了一点点,P 魔法觉得「小事一桩」,只给了一点点力;D 魔法发现小车没有在晃,也就不管了。结果就是:小车一直平行着黑线跑,死活靠不上去,这就叫「稳态误差」。
这时候就轮到 I 魔法出场了。I 就像一个爱记仇的小本本。只要小车没有完全在黑线上,它就会把误差一点一点记下来(积分)。「一秒钟偏一点点我不管,十秒钟你还偏一点点,我积攒的力量就很大了,非把你拽回去不可。」
💡 EV3 调参秘籍(必看)
如果你把滑块乱拉一通,小车肯定会像发疯一样乱跑。记住 EV3 巡线的 调参核心要领:
1. 先把 I 和 D 调到 0。慢慢调大 P(从 0.5 开始,每次加 0.1),直到小车能勉强跟着线走,但开始明显「左摇右晃」。
2. 保持 P 不变,慢慢调大 D。从 1.0 开始试,你会发现小车的摇晃被压制住了,变得越来越顺滑。
3. 一般不需要 I,除非你开启了侧风(发现小车总是偏离中心一点点),这时再加一点点 I(EV3 的 I 通常非常非常小,比如 0.01)把它拉回来。
4. 直线与弯道的参数权衡:在直线上小车应保持平稳,此时 P 和 D 值应尽量调小以避免「扭动画龙」或高频颤动;而在弯道上为了快速响应,P 和 D 值则需要适当调大以防脱线。如果为了在比赛中追求极致车速,可以使用「分段 PID」(不同路段切换参数)或「动态 PID」(让参数随误差大小自动改变)。
在下面这个完整的 PID 演示里,你可以勾选「一阵侧风」,看看 P 和 D 是怎么束手无策的,然后再把 I 值调大,看看小车是怎么顽强地被拉回黑线的。
动手前第一步:测光到底在测什么?
无论你是用单传感器还是双传感器,在写程序前,老师一定会让你「先去测一下场地的反射光线」。这是为什么呢?
其实,小车是没有「眼睛」的,它只能靠光电传感器感受到地面的反光亮度。比如你在自己家里测试,测出来全白区亮度是 33,纯黑线亮度是 6。这组数据对单/双传感器都有巨大的意义:
- 对于单传感器(骑着黑线边缘走):
你需要找一个「完美目标值」。你可以直接把小车传感器压在半黑半白的地方,读取端口数值(大概在 19 左右);不过最稳妥的做法还是分别测出全白(33)和全黑(6),然后计算它们的中间值:(33 + 6) / 2 = 19.5。之后小车就会通过 误差 = 19.5 - 当前读数 来算出自己偏了多少。 - 对于双传感器(把黑线夹在中间走):
两只眼睛平时都看着白区(都读到 33)。如果小车偏了,一只眼睛就会看到黑线(变成 6)。由于程序中会先将它们校准为 0 到 100 的百分比(白区 100,黑区 0),所以校准后的两只眼睛相减,算出来的最大极限差值(误差)就是 100 - 0 = 100。知道最大误差是 100,你就能用来推算 P 值该设多大了(比如你想让小车最大功率是 100,那 P 就设成 100 ÷ 100 = 1.0)。此外,测光也是为了检查两只眼睛在同样的白区读数是否一致,如果不一致还需要做校准。
⚠️ 比赛排雷指南
1. 现实世界的场地灯光、地图纸张材质都会影响反光。所以去参加比赛时,每次到了新场地,第一件事必须是把小车放地上,重新测一遍白区和黑区。只有误差和参数算准了,后面的 PID 魔法才能生效。
2. 别把「黑区值」设成了「中间值」:在双传感器校准公式中,我们需要将黑区映射为 0,白区映射为 100。因此公式中的最小值参数(如封装模块中的反射光参数)必须填黑区测得的原始值(如 6),千万不要误填成了中点值(如 19),否则校准计算会出错,导致误差范围失真、小车剧烈抖动。
实战演练:看看这串神秘的 EV3 代码
现在,我们来看看你一直在用的「双颜色传感器」在乐高 EV3 软件里到底长什么样。下面是一张真实的双传感器 PD 巡线代码截图:
别怕,我们把这串像「小火车」一样的积木拆开来看看,其实非常简单。这是一个只用了 P 和 D 魔法的程序(大多数比赛中大家只用 PD 就够了,因为 I 魔法有时比较难控制,干脆不用):
- 第一步(传感器校准/归一化):在算误差之前,程序会先用 (a-c)/(b-c)*100 这个数学公式,对左边和右边两个传感器的数值进行「光线校准」。这里的 b 填了 33(白),c 填了 6(黑)。它的作用是把读取到的环境光线原始数值,统一换算成 0 到 100 的百分比。千万别搞混了, 这个公式根本不是 PID 算法,它只是在给传感器做校准,处理完的百分比数值才会送往下一步。
- 第二步(找误差):前半部分,程序分别用左右两个传感器的校准值(即 0 到 100 的百分比)做了一个减法(a - b)。对于双传感器来说,只要两只眼睛看到的黑白比例一样(减出来是 0),就说明没偏;如果不为 0,就说明偏了。这个减出来的结果,就是传给后续数学公式的 a,也就是我们一直说的误差。(如果是单传感器,这里就会变成 50 - 传感器校准值,算出来的也是 a,因为 0 到 100 的中间值是 50)。
- 第三步(算 P 和 D):中间最长的那块红色高级数学积木,写着 a*b + (a-c)*d。这里的 a 是现在的误差,c 是一直存在小本本里(变量)的上次误差。b 就是我们前面学的 P 值,d 就是 D 值。
所以,前半段 a*b 就是在算 P 魔法(比例)。
后半段 (a-c)*d 就是在算现在的误差减去上次的误差,这就是在预测未来的速度,也就是 D 魔法(微分)。如果你现在正面对着真实的 EV3 软件里的这个公式却不知道填什么数字,这里给你一个基于双传感器的「无脑起步公式」:
🛠️ 假设你已在程序中校准了「白 33,黑 6」:
因为两个传感器的读数均已被校准为 0 到 100 的百分比,所以:最大极限误差 = 100 - 0 = 100。
- b(也就是 P 值):目标是让小车在最大误差(100)时打满方向盘(EV3 最大功率为 100)。所以初始 P 设为:100 ÷ 100 = 1.0。你可以从 1.0 开始试。
- c(也就是上次误差):注意,这个不需要你填固定数字。它是程序用一个黑箱(变量)自动从上一个循环存下来的,你只需要连线,不用填数字。
- d(也就是 D 值):EV3 每秒钟运行成百上千次,每次的误差变化 (a-c) 非常小。为了让 D 魔法显灵,D 通常要比 P 大很多。你可以从 P 的 3 到 5 倍起步,也就是
1.0 × 4 = 4。初始 D 可以填 4 左右。
- 第四步(打方向盘):把算出来的 P 和 D 加在一起,就得到了小车需要打多少方向盘。然后用加法和减法,把这个转向值分别加到(或减去)两个轮子的基础速度上,小车就会稳稳地顺着黑线跑啦。
- 最后一步(记在小本本上):最右边的小黑箱子,就是把这次的误差存进变量里,留给下一次循环当「上次误差」使用。
是不是一下子就看懂了?下次再看到复杂的机器人程序,只要认准真正算 P、I、D 魔法的那个积木,就不怕啦。
总结与实战调参口诀
现在大家应该对这三个字母有感觉了吧:
- P (比例 / b):负责让小车乖乖拐弯,值越大拐得越猛,但容易摇头晃脑。
- D (微分 / d):负责预测未来,在摇晃前提前踩刹车,让小车走得丝滑。
- I (积分):负责记仇,专门对付那种一直存在、挥之不去的微小误差。
平时玩乐高 EV3 或者写代码时,遇到要调这三个参数,记住一个经典老口诀:「先算 P,再加 D,最后不行加点 I」。 算出起步值后稍微在场地里微调一下,小车就能跑得非常棒了。
希望这个小小的互动能帮到正在学编程的你,有问题可以随时在评论区找我。
加载评论中……