导数:局部线性近似Derivatives as Local Linear Approximation
用显微镜看一条光滑曲线,放大得足够多,它就变成一条直线。这条直线的斜率就是导数。机器人里几乎所有"线性化"都是这一句话:在工作点附近,把复杂的函数换成一条直线,算起来便宜得多,误差也有明确的上界。 Put a smooth curve under a microscope and zoom in far enough: it becomes a straight line. The slope of that line is the derivative. Nearly every "linearization" in robotics is that one sentence: near an operating point, swap a complicated function for a line, which is cheap to compute and has an error you can bound.
1为什么机器人需要它Why robots need this
轮子上的编码器只会告诉你"现在转到了哪个角度"。可控制器要的是转速,规划器要的是加速度。从位置到速度,中间隔着一次求导。
另一件事更普遍:机器人的世界几乎全是非线性的。关节角到末端位置有 \(\sin\)、\(\cos\),相机投影要除以深度。非线性函数很难直接分析,直线却很好对付。导数就是把曲线在一点附近换成直线的方法:EKF 的线性化、逆运动学的每一步迭代、Newton 法、反向传播,全靠它。
这一节只做三件事:看清导数是什么(一条放大后的直线),知道这个近似好到什么程度(误差随距离的平方缩小),再看一个它会咬人的地方(对带噪声的数据求导)。
A wheel encoder only tells you "the wheel is at this angle right now". The controller wants the speed, and the planner wants the acceleration. Between position and speed sits one derivative.
Something even more pervasive: the robot's world is almost entirely nonlinear. Joint angles reach the end effector through \(\sin\) and \(\cos\); a camera divides by depth. Nonlinear functions are hard to analyze directly, while lines are easy. The derivative is the recipe for replacing a curve with a line near one point: EKF linearization, every step of inverse kinematics, Newton's method and backpropagation all run on it.
This lesson does three things: shows what the derivative is (a line seen under magnification), tells you how good that approximation is (the error shrinks with the square of the distance), and then visits a place where it bites (differentiating noisy data).
2直觉:显微镜下的曲线是直线Intuition: under a microscope, a curve is a line
地球是圆的,可站在操场上它是平的。曲线上任何一点附近都是这样:放得够大,弯曲就看不出来了。放大后看到的那条直线,斜率就是导数 \(f'(x_0)\)。
下面是一台"显微镜"。拖动黄点选位置,拖动滑块放大。先在平滑的曲线上试,再换成 \(|x|\),看看会发生什么。
The Earth is round, yet a playground looks flat. Near any point on a curve the same thing happens: zoom in enough and the bend disappears. The slope of the line you are left with is the derivative \(f'(x_0)\).
Below is a "microscope". Drag the amber point to pick a location and drag the slider to magnify. Try a smooth curve first, then switch to \(|x|\) and see what happens.
- 在光滑曲线上放大到 ×200 以上,直到曲线几乎变成直线。On a smooth curve, zoom to ×200 or more until it is nearly a straight line.
- 切换到 |x|,把黄点拖到尖角 x = 0,放大到 ×50 以上:曲线始终不变直。Switch to |x|, drag the point to the corner x = 0 and zoom past ×50: the curve never straightens.
"可导"的意思是:放大后能看到一条直线。导数 \(f'(x_0)\) 就是这条直线的斜率,它回答的问题是"输入动一点点,输出会动多少倍"。\(|x|\) 在尖角处没有这条直线,所以不可导。
"Differentiable" means: zooming in reveals a line. The derivative \(f'(x_0)\) is that line's slope, answering "if the input moves a tiny bit, by what factor does the output move?" At its corner \(|x|\) has no such line, so it is not differentiable there.
3动手玩:从割线到切线Play: from secant to tangent
放大镜给了直觉,现在把它变成公式。过曲线上两点 A、B 画一条直线,叫割线,斜率是"纵向增量 / 横向增量"。让 B 向 A 靠近,割线就转成切线。右图画出割线斜率随 \(h\)(B 到 A 的水平距离)的变化:\(h\to 0\) 时它趋向的那个数,就是导数。
The magnifier gave the picture; now turn it into a formula. Draw a line through two points A and B on the curve: a secant, with slope "rise over run". Slide B toward A and the secant rotates into the tangent. The right panel plots the secant slope against \(h\), the horizontal distance from A to B. The number it approaches as \(h\to 0\) is the derivative.
- 让 |h| 小于 0.01:割线与切线重合,右图上的点贴到虚线上。Get |h| below 0.01: secant and tangent coincide and the dot on the right lands on the dashed line.
- 切到 |x|,把 A 放在 x = 0,分别从左边和右边把 |h| 压到 0.05 以下:两侧斜率不同。Switch to |x|, put A at x = 0 and squeeze |h| below 0.05 from both the left and the right: the two slopes differ.
这个直线近似有多准?How good is the line approximation?
在 \(x_0\) 处用切线代替曲线,在距离 \(\delta\) 处的误差是多少?下面拖动 \(\delta\) 看看。右图是误差随 \(|\delta|\) 变化的双对数图:直线的斜率就是"误差随距离的几次方缩小"。
Replace the curve by its tangent at \(x_0\): how large is the error at distance \(\delta\)? Drag \(\delta\) below. The right panel is a log–log plot of the error against \(|\delta|\); the slope of the straight line there says "the error shrinks like the distance to the power …".
- 在光滑曲线上,找一个位置使得"δ 减半,误差约变成 1/4"(读数栏里的比值接近 4)。On a smooth curve, find a spot where "halving δ cuts the error to about 1/4" (the ratio in the readout is near 4).
- 切到 |x|,把 x₀ 放在 0:比值变成 2,不再是 4。Switch to |x| and put x₀ at 0: the ratio becomes 2, no longer 4.
导数本身也是一个函数The derivative is itself a function
每个 \(x\) 都对应一个斜率,把所有斜率画出来就得到导函数 \(f'\)。左边拖动黄点,右边的点会沿 \(f'\) 的图像一起走。
Every \(x\) has a slope; plot all the slopes and you get the derivative function \(f'\). Drag the amber point on the left and the dot on the right slides along the graph of \(f'\).
- 在 sin 或三次曲线上,把黄点拖到 f′ = 0 的位置(峰或谷)。On sin or the cubic, drag the point to where f′ = 0 (a peak or valley).
4再看数学The math
提示:把鼠标悬停在公式中带底色的符号上,FIG 2 中对应的线段会被高亮。Tip: hover the highlighted symbols in the formulas; the matching segment in FIG 2 lights up.
定义Definition
函数 \(f\) 在 \(a\) 处的导数是割线斜率当 \(h\to 0\) 时的极限:
The derivative of \(f\) at \(a\) is the limit of the secant slope as \(h\to 0\):
极限存在,等价于从左、右两侧趋近得到同一个数。这正是 \(|x|\) 在 0 处失败的原因。
The limit exists exactly when approaching from the left and from the right gives the same number. That is precisely where \(|x|\) fails at 0.
局部线性近似Local linear approximation
把上式移项,就是机器人里最常用的一句话:
Rearranging gives the sentence robotics uses most:
误差项里最先出现的是 \(\delta^2\):\(\delta\) 缩小为原来的 1/10,误差缩小为 1/100。\(f''\)(导数的导数,描述曲线弯得多厉害)越大,线性近似失效得越快。完整的展开见 2.4 泰勒展开。
The first term in the error is \(\delta^2\): shrink \(\delta\) tenfold and the error shrinks a hundredfold. The bigger \(f''\) (the derivative of the derivative, how sharply the curve bends), the faster the approximation fails. The full expansion is in Lesson 2.4 (Taylor).
放大镜读法:\(f'(a)\) 是放大后那条直线的斜率。放大倍率读法:输入的一点点变化 \(\Delta x\) 被乘以 \(f'(a)\) 变成输出变化 \(\Delta f\approx f'(a)\,\Delta x\)。第二种读法在多元函数里变成"矩阵乘向量",那就是 3.3 节的雅可比。
Magnifier reading: \(f'(a)\) is the slope of the line you see after zooming. Gain reading: a small input change \(\Delta x\) is multiplied by \(f'(a)\) to give the output change \(\Delta f\approx f'(a)\,\Delta x\). With several variables the gain becomes "matrix times vector": the Jacobian of Lesson 3.3.
常用求导规则The rules you will use
| 规则Rule | 公式Formula | 来源Where from |
|---|---|---|
| 线性Linearity | \((c f + g)' = c f' + g'\) | 极限保持加法和数乘limits preserve sums and scaling |
| 乘积Product | \((f g)' = f' g + f g'\) | 展开 \((f+\Delta f)(g+\Delta g)\),丢掉 \(\Delta f\,\Delta g\)expand \((f+\Delta f)(g+\Delta g)\), drop \(\Delta f\,\Delta g\) |
| 幂Power | \((x^n)' = n x^{n-1}\) | \((x+h)^2 - x^2 = 2xh + h^2\),除以 \(h\) 再令 \(h\to0\)\((x+h)^2 - x^2 = 2xh + h^2\); divide by \(h\), let \(h\to0\) |
| \(\sin,\cos\) | \((\sin x)' = \cos x,\ (\cos x)' = -\sin x\) | 小角度 \(\sin h\approx h\)(2.4)small angle \(\sin h\approx h\) (2.4) |
| \(e^x,\ \ln x\) | \((e^x)' = e^x,\ (\ln x)' = 1/x\) | 指数函数是"变化率等于自身"的函数\(e^x\) is the function whose rate equals itself |
| 复合Composition | \((f\circ g)' = f'(g)\,g'\) | 下一节next lesson (2.2) |
数值求导:步长不能太大,也不能太小Numerical differentiation: not too big a step, not too small
用计算机估计导数,最直接的是差商。前向差分 \(\frac{f(x+h)-f(x)}{h}\) 的截断误差约为 \(\tfrac12 f''\,h\),中心差分 \(\frac{f(x+h)-f(x-h)}{2h}\) 的误差约为 \(\tfrac16 f'''\,h^2\),所以中心差分更准。但 \(h\) 也不能太小:两个几乎相等的数相减,舍入误差(双精度约 \(10^{-16}\))被 \(1/h\) 放大。因此双精度下前向差分的最佳 \(h\) 约是 \(10^{-8}\),中心差分约是 \(10^{-5}\)。3.3 节有一个可以拖动步长观察这一现象的实验。
The most direct way to estimate a derivative on a computer is a difference quotient. The forward difference \(\frac{f(x+h)-f(x)}{h}\) has truncation error about \(\tfrac12 f''\,h\), while the central difference \(\frac{f(x+h)-f(x-h)}{2h}\) has error about \(\tfrac16 f'''\,h^2\), so central is more accurate. But \(h\) cannot be too small either: subtracting two nearly equal numbers lets round-off (about \(10^{-16}\) in double precision) get amplified by \(1/h\). In double precision the best \(h\) is about \(10^{-8}\) for forward and \(10^{-5}\) for central differences. Lesson 3.3 has a lab where you drag the step size and watch this happen.
5机器人中的它:从编码器估计转速In robotics: estimating wheel speed from an encoder
编码器每转一圈输出 \(N\) 个脉冲,位置只能被量化到 \(q = 2\pi/N\)。要得到转速,最直接的是对位置求差:\(\hat\omega_n = \dfrac{\theta_n-\theta_{n-k}}{k\,\Delta t}\)。
这里有一个两难。窗口 \(k\) 取得小,响应快,但量化误差 \(\sim q/(k\Delta t)\) 被放大;窗口取得大,噪声小了,估计却滞后(约 \(k\Delta t/2\) 秒)。下面是一个真实的权衡:真实角度 \(\theta(t)=2\sin(0.9t)+0.5t\),采样 100 Hz,编码器把它量化后再求差。
An encoder outputs \(N\) pulses per revolution, so position is quantized to \(q = 2\pi/N\). The most direct way to get speed is to difference positions: \(\hat\omega_n = \dfrac{\theta_n-\theta_{n-k}}{k\,\Delta t}\).
That creates a dilemma. A small window \(k\) responds quickly but amplifies the quantization error \(\sim q/(k\Delta t)\); a large window is quiet but lags (by about \(k\Delta t/2\) seconds). Here is the real trade-off: true angle \(\theta(t)=2\sin(0.9t)+0.5t\), sampled at 100 Hz, quantized by the encoder and then differenced.
- 设窗口 k = 1:估计乱得不能用(RMS 误差大于 0.2 rad/s)。Set window k = 1: the estimate is unusable (RMS error above 0.2 rad/s).
- 用"因果"模式、分辨率 ≤ 1024,把 RMS 误差压到 0.065 rad/s 以下。你会发现再怎么调也有一个最低点。In "causal" mode with resolution ≤ 1024, push the RMS error below 0.065 rad/s. You will find a floor no setting beats.
电机驱动器常常同时用两种办法:高速时数脉冲(M 法),低速时测相邻脉冲的间隔(T 法)。想要既无滞后又低噪声,办法是把"求导"改成"估计":用位置、加速度模型加传感器噪声模型,做卡尔曼滤波(4.8 节)。不要对原始数据硬求导,这是机器人里最老的教训之一。
Motor drives often combine two tricks: count pulses at high speed (M-method) and time the gap between pulses at low speed (T-method). To get no lag and low noise together, replace "differentiate" by "estimate": use a position/acceleration model plus a sensor-noise model in a Kalman filter (Lesson 4.8). Never differentiate raw data blindly: it is one of robotics' oldest lessons.
6常见误区Common pitfalls
它只在工作点附近好用,误差按 \(\delta^2\) 增长。关节角偏离线性化点 30° 时,\(\sin\theta\approx\theta\) 的误差已经有 5%;EKF 里若状态变化太大,线性化会让滤波器发散。
It works near the operating point only, and the error grows like \(\delta^2\). At 30° off the linearization point, \(\sin\theta\approx\theta\) is already 5% off; in an EKF, a large state change can make the linearization mislead the filter into divergence.
求导是"高通"操作:它放大高频成分,噪声基本都在高频。位置噪声 \(\sigma\) 进了差分后变成 \(\sqrt2\sigma/\Delta t\),采样越快反而越糟。要么平滑后再差分,要么用滤波器。
Differentiation is a high-pass operation: it amplifies high frequencies, and noise lives there. Position noise \(\sigma\) becomes \(\sqrt2\sigma/\Delta t\) after differencing, so sampling faster makes it worse. Either smooth first or use a filter.
\(|x|\) 连续,但在尖角不可导。机器人里的尖角很多:接触瞬间的力、\(\max/\min\)、ReLU、限幅、静摩擦。基于梯度的方法碰到它们要小心,必要时用平滑版本或"次梯度"。
\(|x|\) is continuous but not differentiable at its corner. Robotics is full of corners: contact forces at touchdown, \(\max/\min\), ReLU, saturation, static friction. Gradient-based methods need care around them; use smoothed versions or "subgradients" where necessary.
\((\sin x)'=\cos x\) 只在 \(x\) 以弧度为单位时成立。若 \(x\) 以度为单位,导数里会多出一个 \(\pi/180\)。代码里统一用弧度,只在输入输出的边界做换算。
\((\sin x)'=\cos x\) holds only when \(x\) is in radians. In degrees an extra factor \(\pi/180\) appears. Use radians throughout the code and convert only at the input/output boundary.
7小练习Check yourself
8延伸阅读Further reading
- 3Blue1Brown, Essence of Calculus — 第 2 章(导数的悖论)与第 3 章(求导公式的几何直觉)Ch. 2 (the paradox of the derivative) and Ch. 3 (geometric intuition for derivative formulas)
- G. Strang, Calculus (MIT OpenCourseWare) — 第 2 章:导数Ch. 2: derivatives
- K. Lynch & F. Park, Modern Robotics, 附录:速度与线性化appendices on velocity and linearization
- T. Barfoot, State Estimation for Robotics, Ch. 2 — 线性化与估计Linearization and estimation