Answers:
看一下PID基本示例,我认为您只需要实例化PID控制器的两个副本,每个车轮,编码器和pwm一个:
PID leftPID(&InputLeft, &OutputLeft, &SetpointLeft,2,5,1, DIRECT);
PID rightPID(&InputRight, &OutputRight, &SetpointRight,2,5,1, DIRECT);
然后,loop()
等效地,您只需读取两个编码器,将每个编码器值传递给相关的值PID
,最后写出两个PWM值。
目前SetpointLeft
,SetpointRight
它实际上可以指向相同的值,但是像这样单独定义它们可以使您添加以后转弯的功能。
虽然这可能适用于基本情况,但是否足够,实际上取决于您需要直线的精度。
假设每个车轮上都有编码器,如果您运行两个PID回路并比较每个车轮的跟随误差,则可以假设车轮不打滑,从而有可能计算出整个距离上的最大阿贝误差。如果该错误小于您的要求,那么就需要推算。
但是,如果车轮容易打滑,则可能是隐藏了控制系统无法检测到的跟随误差,您将需要某种方法来检测打滑或独立于车轮编码器计算位置,然后使用高级软件进行校正要求车轮位置/速度保持直线。
正如John所建议的那样,您也许可以使用加速度计来确定位置,但是鉴于其准确性以及随着时间的推移累积的误差的影响,您最好使用加速度计数据来检测和校正车轮打滑。
在移动机器人中,卡尔曼滤波技术通常用于融合来自多个源的数据,例如加速度计和车轮编码器,以更好地确定当前位置。
但是,无论您如何确定相对位置,随着时间的流逝,您认为自己所处的位置都会偏离实际身体位置。
解决此问题的唯一方法是使参考点位于车辆参考系之外。
例如,Roomba通常使用航位推算在房间内移动,但是每当需要停靠时,它都会寻找充电基座发出的一束红外光。当Roomba随机移动通过该光束时,它会检测到它,锁定在光束上,然后将其返回到其源头。结合其碰撞传感器,它可以将自己准确地定位在充电触点上。
对于您的机器人,它可能有一个原始位置,可以回到原始位置并检测到它在该已知位置。那时,它确切地知道它在哪里,并且可以报告其计算位置与实际位置的距离。
另一个选择是,如果您需要机器人沿直线走几百米,那就是改用另一种技术,例如添加Arduino GPS护罩。
最终,取决于您的准确性要求,您可能需要结合使用这些技术。
如果可以使用导向梁,则可以使用隐形线跟随技术非常简单地完成所需的操作。如果您需要在约束区域内以任意直线移动,那么像Roomba一样,您可以使用一对导向梁(彼此成直角)来校正一个直角坐标轴上的合成位置每次机器人通过其中一根光束时。
这里有很多选项,您选择哪种取决于您的需求。
如果您不是使用单个轴来驱动两个车轮,那么我看到的唯一解决方案是添加一个3轴加速度计或另一个传感器来检测机器人的方向,并相应地调整每个电机的信号。