上篇讲了IMU数据预处理的完整流程——零偏补偿、温度补偿、低通滤波、时间对齐、坐标系变换。从这篇开始,我们聊编码器。编码器是机器人运动控制的基础传感器,不管是差速底盘的里程计还是机械臂的关节控制,都离不开它。

面试时候被问"你用过什么编码器",很多人会说"增量式编码器"。但面试官想听的是:你理解增量式和绝对式的区别吗?知道编码器的分辨率、精度、响应频率这些参数怎么选吗?知道编码器信号怎么处理吗?

编码器的工作原理

编码器的核心功能是测量旋转角度。根据输出方式的不同,分为增量式和绝对式两大类。

增量式编码器输出的是脉冲信号。编码器每转过一个固定的角度增量,就输出一个脉冲。通过计数脉冲的数量,可以知道转过了多少角度。通过检测脉冲的频率,可以知道转速。

增量式编码器通常有两个通道(A相和B相),两个通道的脉冲相位差90度(正交编码)。通过判断A相领先还是B相领先,可以确定旋转方向。有些编码器还有第三个通道(Z相),每转一圈输出一个脉冲,用作参考零点。

正交编码的分辨率可以四倍细分——在每个脉冲的上升沿和下降沿都计数,一个周期可以计4个数。所以如果一个编码器的标称分辨率是1000线(每转1000个脉冲),四倍细分后实际分辨率是4000 counts/rev。

# 正交编码器读数示例(通过GPIO中断)
class QuadratureEncoder:
    def __init__(self, counts_per_rev=4000):
        self.counts_per_rev = counts_per_rev
        self.count = 0
        self.direction = 1
    
    def on_pulse(self, channel_a, channel_b):
        """脉冲中断回调"""
        if channel_a ^ channel_b:  # 异或为真,正转
            self.count += 1
        else:
            self.count -= 1
    
    def get_angle(self):
        """获取当前角度(弧度)"""
        return (self.count / self.counts_per_rev) * 2 * np.pi
    
    def get_velocity(self, dt):
        """获取角速度(rad/s),需要记录上次的count"""
        delta_count = self.count - self.last_count
        self.last_count = self.count
        return (delta_count / self.counts_per_rev) * 2 * np.pi / dt

绝对式编码器输出的是当前位置的绝对角度值。每个位置都有一个唯一的数字编码,不需要计数。即使断电后重新上电,也能立即知道当前位置。

绝对式编码器有多种通信接口:SSI(同步串行接口)、BiSS、CANopen、EtherCAT等。分辨率通常用位数表示,比如17位编码器分辨率为2^17 = 131072个位置/转,对应角度分辨率约0.0027度。

编码器的机械安装和误差来源

编码器不是装上就能用的,机械安装质量直接影响测量精度。

同轴度误差:编码器的旋转轴和被测轴的轴线如果不重合,就会产生偏心误差。偏心会导致编码器测量的角度和真实角度之间有周期性偏差——每转一圈,误差呈现正弦变化。偏心越大,误差越大。解决方法是用柔性联轴器(比如梅花联轴器)来补偿微小的同轴度偏差。

轴向窜动和径向跳动:如果被测轴在旋转时有轴向移动(窜动)或者径向摆动(跳动),编码器的测量也会受影响。高端编码器自带轴承,可以容忍一定的轴向和径向偏差。低端编码器对被测轴的机械精度要求很高。

齿轮间隙(Backlash):如果编码器不是直接安装在被测轴上,而是通过齿轮传动,齿轮之间的间隙会导致反向时的测量误差。比如机械臂关节反转时,齿轮间隙会让编码器继续计数但关节实际还没动。解决方法是消除齿轮间隙(用预紧齿轮)或者在控制算法中补偿间隙。

温度影响:编码器的机械结构也会随温度变化。金属的热胀冷缩会导致间隙变化,影响测量精度。对于高精度应用,需要选择温度特性好的编码器,或者在工作温度范围内做标定补偿。

总的来说,编码器的精度不仅取决于传感器本身的分辨率,更取决于机械安装的质量。在实际项目中,花时间在机械安装上对中、联轴器选型、间隙消除上,往往比换一个更高分辨率的编码器收益更大。

增量式 vs 绝对式:怎么选

选型时核心考虑四个维度:精度需求、断电恢复、成本、通信接口。

精度要求高(关节角度误差<0.01度)且不允许断电后重新回零的场景(比如机械臂、手术机器人),必须用绝对式编码器。精度要求一般(<0.1度)、成本敏感、断电后可以回零的场景(比如差速底盘、AGV),增量式编码器就够了。

通信接口方面,增量式编码器输出脉冲,接口最简单,MCU的定时器直接做正交解码。绝对式编码器常用SSI或BiSS-C接口,传输速率高、抗干扰能力强。高端伺服电机用的EtherCAT接口编码器,可以实现多编码器级联和纳秒级时间同步。

成本上,一个普通的增量式编码器模块几十块钱,17位单圈绝对式编码器几百块,多圈绝对式(带电池或齿轮计数)要上千。选型时不要盲目追求高分辨率——分辨率超出系统机械精度太多的话,多出来的位数全是噪声。

还有一点值得注意:编码器的信号质量。增量式编码器的脉冲信号在长距离传输时容易受电磁干扰,导致脉冲丢失或多计。解决方法是用差分信号(RS422电平)代替单端信号(TTL电平),差分信号的抗干扰能力强很多。高端编码器的线缆还会带屏蔽层,进一步减少干扰。在工业环境中,编码器线缆要远离动力线和变频器,走线时保持至少20cm的间距。

面试中怎么聊

面试官问编码器原理,按这个顺序回答:先说增量式和绝对式的工作原理和区别,再说选型考虑(精度、断电恢复、成本、转速),然后说编码器信号的处理方式(正交解码、细分),最后结合项目说你用过什么编码器、怎么用的。

如果面试官追问"增量式编码器的累计误差怎么解决",你可以说:增量式编码器的主要误差来源是脉冲丢失(电磁干扰导致)和机械传动误差(齿轮间隙、皮带打滑)。解决方法是定期用外部传感器(比如激光雷达SLAM的位置估计)做校正,或者用绝对式编码器替代。

如果面试官追问"编码器的分辨率和精度有什么区别",你可以说:分辨率是编码器能区分的最小角度变化,精度是测量值和真实值之间的偏差。分辨率高不代表精度高——一个17位的绝对式编码器分辨率是0.0027度,但如果安装偏心或者轴承有间隙,实际精度可能只有0.1度。

如果面试官追问"编码器在ROS2中怎么使用",你可以说:在ROS2中,编码器数据通常通过nav_msgs/Odometry消息发布。差速底盘的两个轮子各接一个增量式编码器,通过运动学模型(差速运动学)把左右轮的速度和位移转换成机器人的线速度和角速度,再积分得到里程计。编码器驱动一般跑在MCU上(比如STM32),通过串口或CAN总线把数据传给上位机。上位机的ROS2节点接收数据,发布odom topic供导航和SLAM使用。

分享一个我在项目中排查编码器问题的经历。当时做一台差速机器人的里程计校准,发现机器人走直线时odom报告的位移比实际偏小约5%。一开始以为是轮径参数设错了,但用卷尺量了轮子直径和参数值一致。后来用示波器看编码器的输出波形,发现高速运行时偶尔会丢脉冲——原因是编码器的信号线和电机的电源线走在一起,电机的电磁干扰导致编码器信号出现毛刺,MCU的计数器偶尔误判。解决办法是给编码器信号线加屏蔽层,并且和电源线分开走线。改完之后丢脉冲的问题消失了,里程计精度提升了5%。这个经历说明编码器的精度不只是编码器本身的问题,信号传输的抗干扰设计同样重要。面试时候能讲出这种系统级的排查思路,比单纯说编码器原理更有说服力。

下一篇讲编码器应用——测速、测距和闭环控制中的使用。把编码器的原理搞清楚之后,看看它在实际机器人系统中怎么用。


如果这篇文章对你有帮助,欢迎点赞、在看、转发三连。 你的支持是我持续更新的最大动力。

「机器人软件开发面试·从入门到精通」连载系列 

上一篇:第158篇 IMU数据预处理——滤波、补偿和对齐

下一篇预告:第160篇 编码器应用——测速、测距和闭环控制中的使用

有任何问题欢迎评论区留言,我会尽量回复。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐