卷 I · 成环CH 02深度 2/24

会照做的,和会看着办的

同一台加热器,两种控制方式。一种是「照着说明书算出该开多大,然后开着不管」,另一种是「不管说明书,看着温度调」。在一切如你所料的时候,它们的表现完全一样——这正是第一种方式的陷阱。

开环 vs 闭环模型误差反馈买来了什么

▷ 先拧一下

一台加热器,你想把它稳在某个温度(记作 1.0)。你查了说明书,算出功率应该开到 1.0,于是把旋钮拧到 1.0,走人。这叫开环

结果两件事同时发生了: 这台机器实际上比说明书说的猛 30%; 半路有人开了窗,进来一份你完全不知道的热量(相当于 0.3)。

问:最后温度会停在多少?而如果换成一个会看着温度调的闭环控制器(它同样不知道①和②),它会停在多少?

A 开环 1.3,闭环 1.0——开窗的热量会自己散掉 B 开环 1.3,闭环 1.3——两个都不知道真相,所以一样错 C 开环大约 1.69,闭环大约 1.0 D 开环大约 1.69,闭环大约 1.15——闭环能修一半

这一题的重点不在算术,在于「不知道」这件事对两种做法意味着什么

两种活法

面对「我想让某个量等于某个值」这件事,天底下只有两条路。

第一条路:算。建一个模型——「开 x 的功率,温度会到 Kx」——反解出 x,拧到那个位置,收工。这条路的英文名是 open loop,开环,意思是那条把结果送回来的线没接

第二条路:看。不管模型,测当前温度,和目标比,低了就加、高了就减,一直这么干下去。这条路叫 closed loop,闭环。

# 开环:一条直线,走完就完了

  目标 ──▶ [ 反解模型 ] ──▶ [ 设备 ] ──▶ 实际
                                            (没人再看它一眼)

# 闭环:一个圈,永远转下去

  目标 ──▶ ⊕ ──▶ [ 控制器 ] ──▶ [ 设备 ] ──┬──▶ 实际
           ▲(−)                             │
           └───────────── 测量 ◀────────────┘

# 差别只有那一条线。但它买来的东西,比它看起来贵重得多。

开环不是「原始」或「错误」的做法。它有闭环没有的优点:它不可能失稳(没有环,就没有绕圈放大这回事),它不需要传感器(省钱、省地方、少一个故障点),它反应可以极快(不用等误差出现)。微波炉加热三分钟、红绿灯按固定时长切换、你按配方放两勺盐——全是开环,而且非常合理。

开环的问题只有一个,但这个问题是致命的

◆ 这一章的主线

开环的精度,完全等于你那个模型的精度。模型错多少,结果就错多少;模型没考虑到的东西,结果就一分不差地承担多少。

而闭环不需要模型是对的。它甚至不需要知道发生了什么。它只知道一件事:「现在比目标低了一点」,然后往上顶。反馈的全部价值,就是对付你不知道的事。

四种情况,同一台机器

下面这个 demo 把四种情况摆在一起。灰色虚线是开环,绿色实线是闭环。它们面对的是同一台设备

逐条看:

情况开环停在开环偏了闭环停在闭环偏了
一切如你所料1.00000.0%0.999650.03%
设备比你以为的猛 30%1.299930.0%0.999750.02%
半路有人开了窗1.297929.8%1.002310.23%
两样一起来1.687368.7%1.002330.23%

第一行是这张表里最重要的一行,而它看起来最无聊:两种做法表现得一模一样

这就是开环的陷阱。它在实验室里、在验收时、在「一切正常」的那一天,和闭环看不出任何区别。它的脆弱只在世界偏离模型的那一刻才暴露出来——而世界一定会偏离模型:设备会老化,室温会变,负载会变,供电电压会变,有人会开窗。

再看最后一行的对比:68.7% 对 0.23%,相差约 300 倍。而闭环控制器没有被告知设备变猛了,也没有被告知有人开窗。它甚至没有能力知道这些事——它的输入只有一个数:当前温度。

∑ 算一遍

为什么闭环能把误差压到那么小?这里有一条一行的算术,第 5 章会正式推它,现在先看结论。

设你的控制器增益是 Kp,设备增益是 K,两者相乘叫回路增益 KpK。那么开环和闭环面对同一份「模型错误 + 未知扰动」,误差之比是:

   闭环误差 / 开环误差 = 1 / (1 + Kp K)

回路增益 9,误差变成十分之一;回路增益 99,变成百分之一。反馈不是「消除」了误差,它是把误差除以了一个数,而这个数就是你在这个环上愿意用多大力气。

这自然引出一个问题:那把 Kp 拧到一万不就完事了?——这正是这本书接下来二十章的全部内容。剧透:不行,而且拦住你的东西不是功耗、不是成本、不是执行器上限。

一个不太舒服的推论

如果反馈这么好,为什么不是所有地方都用反馈?

因为反馈要付四笔钱,而且每一笔都不小:

  1. 你得有一个传感器。而且它测的必须真是你想要的那个量。这一条比听起来难得多——第 23 章会给出一个例子:传感器测的东西只占你真正想要的四成,于是那个环把指标顶上去 90%,同时把你真正想要的东西压下去 24%。
  2. 你得等误差先发生。反馈是事后的:它必须先看见偏差,才能动手。第 18 章讲怎么用前馈补上这一刀。
  3. 你引入了失稳的可能。开环再差也只是不准,它不会自己抖起来。闭环可以。这是卷 III 和卷 IV 的全部主题。
  4. 你把传感器的毛病也接进了环里。传感器上的噪声会被控制器放大成执行器的动作——第 7 章那个 demo 里,加一点微分项,执行器的抖动会涨 11 倍。

所以现实中最常见、也最好的做法,往往是两条路一起走:用开环(前馈)拿到速度和大方向,用闭环兜住模型的错。你的巡航定速就是这么干的——它知道油门开度和车速的大致关系(前馈),也在实时比对当前车速(反馈)。第 18 章会把这个组合拆开给你看:前馈模型哪怕错 50%,配上反馈之后,峰值偏差仍然比纯反馈小一半。

▸ 在现实里

烤箱 vs 电饭煲。普通烤箱基本是开环的:你设 180°C,它按一个粗糙的温控开开关关,实际温度可以差 20 度,所以每个人的烤箱都得「摸脾气」。而电饭煲是闭环的:它盯着锅底温度,水一烧干温度就会突然上蹿,它据此判断「饭好了」——它不需要知道你放了多少米多少水。这就是为什么烤箱要你有经验,而电饭煲不用。

预算 vs 实时竞价。「这个月投放预算 100 万,按去年的转化率分配」是开环——去年的转化率就是那个模型。「按小时看实际 ROI 调整出价」是闭环。前者在市场稳定时更省事,后者在市场变化时不会整月错下去。

固定重试次数 vs 自适应限流。「失败重试 3 次」是开环:不管系统现在是空闲还是快挂了,都重试 3 次。而基于实时延迟调整并发上限(比如 Netflix 的 concurrency-limits、TCP 的拥塞控制)是闭环:它不需要知道下游有多少台机器、跑的什么代码。

✗ 这个直觉是错的
闭环控制器之所以准,是因为它「知道」发生了什么——它某种意义上推断出了扰动。 闭环控制器什么都不知道。它唯一的输入是「当前值和目标差多少」。它不区分「设备变猛了」和「有人开窗了」,因为它不需要区分。

这一点值得多想一分钟,因为它是反馈最反直觉、也最强大的地方:一个只会做减法的装置,能对付无穷多种它从未被告知的干扰。

这也解释了反馈的一个重要局限:既然它不区分原因,它就不会告诉你哪里出了问题。一个整定良好的闭环,会安安静静地补偿掉一台正在老化的设备,直到有一天它补不动了——那时候故障是突然出现的。反馈会掩盖问题,直到它掩盖不住。所以监控要盯的不只是被控量,还得盯控制量:阀门开度悄悄从 40% 爬到 85%,是比温度更早的告警。(这一条在第 15、24 章还会再出现。)

◈ 回读

C开环停在 1.6873(偏了 68.7%),闭环停在 1.00233(偏了 0.23%)。

开环那个 1.69 是这么来的:你按模型算出功率 1.0,但设备实际增益是 1.3,所以它自己就到了 1.3;再加上开窗那份 0.3 乘以 1.3,又多出 0.39。两笔直接相加,一分不少——这就是开环的定义。

A 「开窗的热量会自己散掉」——不会。稳态就是稳态:加进来的热量必须有个去处,而这个去处只能是更高的温度。开环里没有任何机制去抵消它。 B 「两个都不知道真相,所以一样错」——这是本章要打的靶子。闭环不需要知道真相;它只需要看得见结果。这句话值得记住:看得见结果,比知道原因更有用。 D 「闭环能修一半」——方向对了,量级差远了。修多少不是「一半」这种定性的事,它等于 1/(1+KpK)。这个 demo 里回路增益不小,加上积分项之后稳态误差在数学上就是 0(第 6 章会讲为什么),剩下的 0.23% 只是仿真还没跑完的余量。

这一章的一句话

开环的精度上限是你对世界的了解,闭环的精度上限是你的传感器——而后者通常便宜得多。

下一章把那个环拆开,数一数里面到底有几个零件。答案是五个,其中只有三个是你写的代码;而根据我的经验,生产事故有一大半出在剩下那两个上。