DesignSpark Electrical Logolinkedin
菜单 搜寻
提问问题

给您的机器人装上真正的火星探测器所用的移动控制:第 2 部分

第 1 部分介绍了 PID 控制的理论依据。这是一种广泛使用的方法,用于确保执行器的机械输出(速度、位置等)与其控制程序要求的值相匹配。我已经展示了复杂的理论如何转化为能够在基本微控制器上运行的相对简单的算法。现在让我们看看为连续旋转伺服电动机所驱动的双轮越野机器人编写的一些真实代码。我使用了一个微芯片 16 位 dsPIC33 数字信号控制器(带有 DSP 扩展的 PIC24 微控制器),但是大多数实际问题都适用于基于其他微控制器的项目。

捕获车轮旋转数据

用于检测车轮转速的装置由两部分组成:车轮本身(带有 32 个径向槽)和反射式红外光束模块,后者固定在底盘上,并与径向槽对齐( 1)。其工作原理很简单。

传感器模块由红外 (IR) LED 和光电二极管组成,二者并排放置,指向车轮槽孔。当车轮转动时,光束穿过一个槽孔,因此无法被光电二极管看到;但是光束会被反射回槽孔之间的二极管。结果产生重复率与车轮转速成正比的脉冲序列。我们需要一种方法来测量这种转速,幸运的是,大多数现代微控制器都有用于此目的的称为“输入捕获”单元的内置硬件( 2)。

原则上,您可以使用由传感器直接计时的计数器来测量速度。以固定的时间间隔对计数器进行采样,并且每次都进行清除,这将得出速度值。问题是,在低速时,采样间隔肯定会相当长,以至于无法捕获大量计数。这可以通过改变采样方式来克服:用快速时钟增加计数器,并使用传感器脉冲采样或“捕获”其值。通过这种方式,我们得到了脉冲周期的测量值。dsPIC 输入捕获 (IC) 单元具有所有必要的硬件,只需要几行汇编代码即可工作。不幸的是,有一个复杂的问题:在我使用的特定芯片上有两个独立的 IC 单元,但是另一项功能需要使用其中一个计时器。有一个解决方案:IC 单元中存在其他一些硬件,因此可以共享剩余的计时器。在这种情况下,两个 IC 单元都被设置为使用计时器 3,计时器 3 从 0000 到 FFFF 连续计数,溢出到 0000 之后重复计数。这是折衷方案:计数器不能在每个采样周期开始时重新启动,因为两个单元将在不同的时间进行采样( 3)。

斜坡波形表示计时器计数从 0000 上升到 FFFF 并重复计数。来自旋转传感器的脉冲波形显示在“捕捉”每个上升沿的计时器计数时的下方。输入捕获硬件将此“快照”保存在其 FIFO 缓冲器中,同时为处理器产生中断。

计算速度

现在,中断服务代码获取从先前中断中存储的计数值,从最近的中断中减去该计数值,并获得表示传感器脉冲周期的数字。在图中,快照计数 C1、C2 在时间 T1、T2 获取,C2–C1 对应于时间间隔 T2–T1。这很容易。但是当车轮开始转动时会出现两个问题:

  • 当传感器第一次发生中断时,没有有效的“先前计数”值,因此第一次计算的速度将是错误的。
  • 存在最小速度限制,因为传感器脉冲周期不能长于计时器从 0000 计数到 FFFF 所用的时间。还有最大速度限制,但这不太可能成为问题!

这两方面意味着机器人开始移动后计算的前几个速度值可能无效。对此,除了启动电动机并让电动机在机器人静止到传感器数值进入有效范围这段估计时间内“开环”运行,以便让 PID 控制代码忽略前几个值之外,没有什么其他办法。回到 3,还有一个问题,但是可以解决。考虑在时间 T3 计算的速度。从 T2 到 T3 的时间间隔跨越了计数器的溢出点,因此 C3 – C2 将提供错误的答案。幸运的是,软件可以检测到这种情况(C3 小于 C2),并且应用了校正因数。通常,最新值大于较早值,如 C1 和 C2。

实际代码

我的 dsPIC 处理器的基本中断服务例程(在没有标度变换和 K 系数的情况下计算速度和三个“原始”P、I 和 D 值)见下面的列表 1

这是我自己的嵌入式控制编程语言 FORTHdsPIC 中针对两个旋转传感器通道之一的中断例程。尽管是在 dsPIC 汇编程序(“裸机”)代码中,但应该很容易看到原始的复杂 PID 方程是如何归结为一些加减运算的。该代码随每个传感器脉冲执行,计算出原始 PID 值并且将其保存在变量中,以便主程序处理。在本系列的第 3 部分中,我将介绍这个主程序,它采用这些变量来计算电动机控制值。中断例程还包含一条执行重要导航任务的代码行,它提供测距功能。

测距

车轮旋转传感器不仅仅提供速度信息(测速):通过脉冲计数,您可以得到行驶距离的测量值(测距)。这就是代码行“inc  ODOMTR”在列表 1中的作用。任何驾驶过汽车或摩托车的人都会认识里程表:它是仪表板上行驶里程的数字读数。在机器人上,它可以在移动系统中发挥重要作用。在这种情况下,ODOMTR 变量在每一次传感器中断时进行递增,这对应于一个槽孔在车轮上的旋转,每一次完整旋转共有 32 个槽孔。要找出在单个槽孔周期内行驶的距离,只需将车轮圆周 πD 除以 32,其中 D 是车轮直径。这些装有 Parallax 编码器的车轮直径为 66 mm,因此测距分辨率为 6.4 mm。我的机器人使用差速转向,需要来自每个车轮的速度数据来进行直行运动,并且需要行驶距离数据来进行精确的转弯操纵。第 3 部分将详细介绍这一方面的内容。

正交编码器

上述简单的旋转传感器有一个相当明显的局限性:它无法分辨车轮是朝哪个方向旋转的。通过添加另一个光电传感器,可以提取旋转方向信息。第二个传感器经过校准,使其输出脉冲波形与第一个传感器的( 4)波形精确地相差 90°。

只需一个简单的 D 型触发器即可解码这些信号。最新设计的用于控制电动机的微控制器通常有一对 QE 通道输入,并且带有必要的片上硬件。我的机器人不需要“倒车档”,所以简单的转速计就足够了,但是行星探测器需要能够倒退。

3 部分后期预告

我将讨论 PID 算法的电动机驱动端,以及机器人如何通过“航位推算”进行导航。最后是一些实际问题,在崎岖不平的地形上,如果电动机负载变化,会发生什么?了解好奇号火星探测器移动控制系统的设计缺陷是如何导致其车轮损坏的。即使火箭科学家也无法做到万无一失!

如果您暂时想不出做什么,可以关注我在 Twitter 上发布的文章。我会贴出关于新的电子产品和相关技术的文章链接,也会转发我读到的关于机器人、空间探索以及其它话题的文章。

Engineer, PhD, lecturer, freelance technical writer, blogger & tweeter interested in robots, AI, planetary explorers and all things electronic. STEM ambassador. Designed, built and programmed my first microcomputer in 1976. Still learning, still building, still coding today.

2 Oct 2018, 6:38