编码器应用——测速、测距和闭环控制中的使用

📅 2026/8/8 11:06:22
编码器应用——测速、测距和闭环控制中的使用
上篇讲了编码器的原理——增量式和绝对式的区别、信号处理、机械安装、选型考虑。今天讲编码器在实际项目中的应用怎么用编码器测速、测距以及怎么在闭环控制中使用编码器数据。面试时候被问编码器怎么用很多人会说计数脉冲算角度。但面试官想听的是更工程化的内容怎么从脉冲算出速度和距离速度估计有哪些方法编码器数据怎么用在PID控制里里程计怎么和IMU融合从编码器到速度和距离编码器的基本输出是脉冲计数。从脉冲计数到物理量角度、角速度、线速度、距离的转换需要知道几个参数编码器分辨率counts per revolution, CPR、减速比gear ratio、轮子半径。import numpy as np class EncoderOdometry: 编码器里程计 def __init__(self, cpr, gear_ratio, wheel_radius, wheel_base): self.cpr cpr # 编码器分辨率counts/rev self.gear_ratio gear_ratio # 减速比电机转/轮子转 self.wheel_radius wheel_radius # 轮子半径m self.wheel_base wheel_base # 左右轮间距m # 每个脉冲对应的轮子转角rad self.rad_per_count (2 * np.pi) / (cpr * gear_ratio) self.left_count 0 self.right_count 0 self.x 0.0 # 机器人位置 self.y 0.0 self.theta 0.0 # 机器人朝向 def update(self, left_delta, right_delta, dt): 更新里程计 left_delta, right_delta: 左右轮编码器增量counts dt: 时间间隔s # 转换为轮子转角 dtheta_left left_delta * self.rad_per_count dtheta_right right_delta * self.rad_per_count # 转换为轮子线位移 dl dtheta_left * self.wheel_radius dr dtheta_right * self.wheel_radius # 差速运动学 d_center (dl dr) / 2 d_theta (dr - dl) / self.wheel_base # 更新位姿用中心角度近似 self.theta d_theta self.x d_center * np.cos(self.theta - d_theta/2) self.y d_center * np.sin(self.theta - d_theta/2) return self.x, self.y, self.theta这段代码是差速机器人里程计的核心。每个控制周期比如10ms读取左右轮编码器的增量转换成线位移和角位移然后积分得到机器人的位姿。编码器参数的实际标定里程计代码看着简单但里面的参数——轮子半径、轮距、编码器分辨率——如果不准算出来的位姿就是错的。很多新人拿到编码器就直接写代码忽略了标定这一步结果里程计跑起来误差巨大。轮子半径的标定方法在地上画一条1米长的直线让机器人沿直线走编码器记录走过的距离。如果编码器显示走了1.05米说明轮子半径参数偏大需要按比例缩小。反复几次直到编码器距离和实际距离一致。这个方法简单但有效精度能到毫米级。轮距wheel_base的标定更关键因为它直接影响角度估计。方法很简单让机器人原地旋转360度比较编码器估计的旋转角度和实际角度。如果编码器说转了370度但实际只转了360度说明轮距参数偏小。调整轮距参数直到旋转角度匹配。def calibrate_wheel_radius(encoder_distance, actual_distance, initial_radius): 根据直线行走测试校准轮子半径 return initial_radius * (actual_distance / encoder_distance) def calibrate_wheel_base(encoder_angle, actual_angle, initial_base): 根据原地旋转测试校准轮距 return initial_base * (encoder_angle / actual_angle)还有一个容易忽略的问题编码器的零位对齐。增量式编码器上电后不知道当前位置需要找一个参考点。常见做法是用一个霍尔传感器或者光电开关作为归零信号。机器人每次启动时先慢速旋转到归零位置然后清零编码器计数。如果归零位置没对准后续的里程计数据全部会有偏差。实际项目中我一般会让机器人每次上电后执行一个初始化舞蹈——先左右各转一圈找到归零信号然后原地转几圈确认编码器读数一致性。这个过程大概需要10秒但能保证每次启动的初始状态是可靠的。编码器数据的滤波处理编码器数据虽然精度高但也不是完美的。实际使用中需要做适当的滤波。速度估计中的量化噪声是个常见问题。低速时编码器每个采样周期可能只有几个脉冲量化误差很大。前面提到的M法在低速时精度差T法在高速时精度差M/T法结合了两者优势但实现更复杂。实际项目中如果速度范围不大用M法加一个简单的滑动平均滤波就够了。另一个常见问题是编码器数据的突变。电磁干扰可能导致偶尔出现一个异常的脉冲计数导致速度估计出现尖峰。处理方法很简单设置一个速度变化率上限如果相邻两个周期的速度变化超过这个上限就认为是异常值用上一次的合法值替代。面试中怎么聊面试官问编码器应用按这个顺序回答先说从脉冲到物理量的转换角度、速度、距离再说速度估计方法M法、T法、M/T法然后说闭环控制中的使用PID反馈最后说里程计的局限性和多传感器融合。如果面试官追问编码器里程计和IMU里程计怎么融合你可以说用EKF状态量包括位置(x,y)、朝向θ、线速度v、角速度ω。编码器提供v和ω的观测通过差速运动学IMU提供ω的直接观测陀螺仪两者互补。编码器的短期精度好但长期漂移IMU的短期精度高但长期漂移陀螺仪零偏融合后可以得到短期和长期都可靠的位姿估计。如果面试官追问怎么处理轮子打滑你可以说轮子打滑时编码器数据不可靠可以通过检测编码器估计速度和IMU估计速度的差异来判断是否打滑。如果差异超过阈值降低编码器数据的权重在EKF中增大编码器的观测噪声协方差。更高级的方案是用滑模观测器或者自适应滤波来处理。如果面试官追问工业场景下编码器有什么特别的注意事项补充一点工业AGV对编码器的可靠性要求很高通常会用双编码器冗余设计——每个轮子装两个编码器互相校验。如果一个编码器数据异常比如和另一个差异过大系统自动切换到单编码器模式并报警。另外工业环境振动大编码器的机械安装要用防振联轴器信号线要用工业级的屏蔽线缆接头用M12航空插头而不是普通的杜邦线。这些细节在面试中说出来会让面试官觉得你有实际工程经验。再补充一个编码器里程计校准的实战技巧。很多团队在调里程计参数时只关注轮径和轮距忽略了编码器的计数方向。有一次我们新装了一台机器人发现里程计的朝向和实际相反——机器人往前走odom报告的yaw角在减小而不是增大。排查了半天最后发现是左轮编码器的A/B相序接反了导致计数方向反了。解决办法是在MCU的编码器配置里把计数模式从上升沿下降沿改成上升沿-下降沿。这种低级错误在新硬件调试时很常见建议每次装完编码器后先手动转一下轮子看计数方向是否正确再做后续标定。下一篇讲力/力矩传感器——机器人触觉的实现方案。从运动传感器转到力觉传感器这是机器人交互能力的关键。如果这篇文章对你有帮助欢迎点赞、在看、转发三连。 你的支持是我持续更新的最大动力。「机器人软件开发面试·从入门到精通」连载系列上一篇第159篇 编码器原理——增量式和绝对式的区别与选型 下一篇预告第161篇 力/力矩传感器——机器人触觉的实现方案有任何问题欢迎评论区留言我会尽量回复。