两轮平衡机器人DIY图解

电子说

1.3w人已加入

描述

步骤1:硬件

Arduino

Arduino

Arduino

我尝试了多种IMU,电机,电动机驱动器,车轮和电源。

原型视频中显示的内容包括:

MPU6050

Pololu低功率直流电动机(2282:590 rpm,9.68:1,17 oz-in)

霍尔编码器464.64 cpr(齿轮后为48 cpr)

Pololu轮120 x 60 mm(通行节拍器)

Arduino UNO

Seeed Studio 4A电机罩

大沽蓝牙模块(HC06)

Raspberry Pi 2B +

2x UltraBorg板,用于读取Raspberry上的超声波传感器

2x DFRobot LiPo 7.4 V电池

HOBBYWING 3A开关模式UBEC 5V 6V

惯性测量单元(IMU)

视频中的机器人使用基于InvenSense MPU6050芯片的基本且成本非常低的模块。我还尝试了基于MPU9150和MPU9250的多个SeeedStudio模块和版本。后者的芯片名为10DOF(自由度),因为它在陀螺仪(3轴),加速度计(3轴)和磁力计(3轴)上增加了气压计(单轴)。

所有3种芯片上都装有数字运动处理器(DMP)。使用此处理器有很大的优势。它在计算垂直角度(传感器融合和滤波)时节省了大量代码。其次,它具有内置的校准程序。最后但并非最不重要的一点是:它节省了Arduino的CPU和内存的使用。

如果您想将DMP与Arduino结合使用,即使在“开发人员专区”中,InvenSense文档也无济于事。 Jeff Rowberg在这里发布了有关MPU6050寄存器的出色技巧。该库仅适用于MPU6050和MPU9150。 MPU9250的寄存器配置不同。在使用MPU9150芯片进行测试时,DMP偶尔会停止工作(可能是该芯片)。最后,MPU6050给出了最佳结果。 (其他优点:这些模块是最小,最薄且价格非常低的模块。)

如果MPU6050产生错误的数据,则可能需要校准传感器的x,y,z偏移量。可以在此处找到用于校准偏移量的Arduino草图

我经历过,调整偏移量可以提高小角度的精度,但也会降低大角度的精度。到最后,芯片默认偏移量在大多数情况下效果最好。

电动机,编码器,电动机驱动器和车轮

我使用的电动机(全部为Pololu):

大功率Micro no 1101,990 rpm,齿轮:100.37:1,失速扭矩:30 oz/in

大功率Micro no 2271,990 rpm,齿轮:9.68:1,失速扭矩: 39 oz/in

大功率no 2274,210 rpm,齿轮:100:1,失速转矩:80 oz/in

小功率no 2282,590 rpm,齿轮:9.68 :1,失速转矩:17 oz/in

除微型版本外,所有电机均随附霍尔编码器。它们产生易于操作的分辨率,取决于齿轮比,分辨率为464至2248节拍。对于微型马达,我使用了产生48个刻度的光学编码器。

在我看来,在室内使用扭矩不太重要。我也经历了高功率版本,因为调音更难。它们具有更大的静摩擦力(“死功率区” =开始移动所需的功率),因此,我发现很难以很小的平衡差(即小的垂直角度)来调节功率。转速与最大速度直接相关。在我看来,对于首次建立平衡器也不太重要。但是,极低的转速几乎不可能达到稳定的平衡。我的建议:使用普通电动机,最好以600 rpm左右的速度运转。

总体而言,尽管来自相同系列的直流电动机显示出不同且不一致的静摩擦力。内置差动控制被证明是必不可少的。也许步进电机将减少此问题(它们移动直到到达某个位置或角度)。步进电机也消除了对编码器的需求。

我已经使用L298N双(2A)电动机控制器板和Seeed Studio 4A电动机控制器护罩进行了测试。我更喜欢后者,因为它是盾牌。易于安装,占用空间少。此外:我发现屏蔽罩4Amp可以更好地缓冲大功率电机的堵转电流。 (注意:请注意我的Arduino草图中的引脚排列。我体验到的屏蔽线与Seeed示例不同。)

轮子 您的生活轻松。我使用的直径分别为4.2、9和12厘米。大轮毂带来更大的稳定性。这也适用于表面上的抓地力。我的最爱:“野生ump击器”车轮(12x6厘米)。

身高和体重 对机器人的行为也很重要。较大的重量会使机器人保持惰性:反应缓慢,因此一开始会显示较大的过冲。当然也需要大功率的电动机。重心(COG)较高将使机器人更加稳定,但也可能会导致后果。高度加上顶部的重量也会使机器人保持惰性。因此,这完全是调整的问题。当机器人保持稳定平衡时,如果发现它在向前或向后移动时反应缓慢,请尝试减轻重量和/或减轻重量。

电源

该机器人由两节LiPo电池供电。一种用于为Arduino和电机供电。一种用于为Raspberry供电,并通过它与HC-SR04超声波传感器配合使用。我从所有组件的一个来源开始。当电动机处于“重载”状态时,它们吸收了太多电流,以至于超声波读数变得错误,甚至RPi有时也会复位。为RPi和Ultraborgs使用单独的LiPo解决了这一问题,但我必须添加UBEC才能获得5V 3A的稳定电流。

步骤2:逻辑和编码

Arduino

网上有很多有关平衡机器人和/或倒立摆的信息。但是,我使用了一个非常简化的逻辑,并具有以下假设:

1-电机轴应该旋转的角度(至少)与机器人掉落的角度相同。因此,请尝试控制电动机轴的角度,而不是距离和/或速度。 (如前所述,使用步进电机可能更容易实现。)

2-为了平衡,需要控制角度及其导数,即电机轴的角速度。这可以通过使用PD控制回路来完成。它不像PID回路那样常见,但是由于运动方向会迅速变化,因此使用积分因子几乎没有用处。

3 –要保持位置,必须控制水平移动和速度。这可以通过将传感器(编码器)输出转换为补偿角度来完成。出于与垂直控制相同的原因,所需的控制循环也是PD循环。

可以简单地将2和3的结果相加,但是最好在水平方向使用嵌套(级联)控制循环控制回路为垂直控制回路产生目标角度。

按照这些假设进行操作可以节省机器人的高度和质量(甚至是线速度)的计算负担(如上所述:这些是重要因素,但可以轻松调整)。这样,在不更改(大部分)编码参数的情况下调整机器人的高度和COG相对容易。

保持机器人直面是通过差动控制(转弯)完成的,并且可以独立于机器人水平和垂直控制。输入可以来自编码器(即滴答声数量的差异)或来自IMU(即偏航数据)。后者所需的编码要少得多。

要对其进行总结,为了平衡,需要:

1将水平位移转换为垂直位移角度

2补偿该角度与测得的角度之差

3将电机轴移动此补偿角度

要翻译成代码,需要机器人的某些功能:

最大电动机速度以编码器刻度表示。这是编码器可以在特定电机上产生的最大滴答声。在公式中: RPM/60 *每转刻度数

编码器刻度数和度之间的关系。在公式中: 360/每转刻度数

使用这两个公式,我们可以推论度数与电动机功率之间的关系(PWM值0-255)。

Arduino草图作为具有以下功能的机器人“固件”运行:

根据车轮编码器的输入进行水平控制

垂直和差分基于IMU输入(俯仰和偏航)的控制

用于调整,输出监视和运动测试的蓝牙通信

与Raspberry Pi的串行通信

草图在这里。用于远程控制和调整的android应用程序是使用MIT App Inventor开发的,可以在此处找到这些块。用于在Raspberry和Arduino之间进行通信和控制的Python脚本位于同一存储库中。我不会在此赘述,因为该帖子仅用于平衡基本面。

有关Arduino草图的注释很好。因此,我将只介绍一下其功能。

初始化

UNO的插针已被占用,没有将传感器连接到Arduino的空间很大(pwm,中断和模拟引脚已售罄)。

一些机器人/电机常数进行计算(如上所述)。

松弛或静摩擦常数。通过试用和测试收集。我从草图开始,以获取空载条件下的平均值。您会在这里找到它。在实践中,我在测试平衡和运动的同时根据观察结果对它们进行了重大调整。这些常数就足够了,但是在很大程度上取决于电动机的性能。跳过这些功率量会使机器人在(很小)小角度时反应更快。但是将这些值设置得太高会在调整控制循环时带来一些挑战!

maxAngle

假设无法进行补偿的角度。用于确定机器人是站立还是躺下。

间隔

稳定的间隔对于控制回路至关重要。在Arduino站点上有一个“ TimedAction”库,但是一个计时器的直接编码非常简单,并且节省了一些内存。

pitchOffset

通过调整IMU获得。最简单的方法是将机器人固定在绝对90度的位置(由顶部的数字水平仪测量)并读取IMU值。

cogOffset

没有此常数,控制回路也将获得平衡。第一个原型机带有8个超声波传感器,这使它的前部有点沉重。正如您在视频中看到的那样,控制循环通过让机器人稍微向后倾斜来进行调整。使用 cogOffset 可以补偿倾斜,并使机器人前进时更加灵活。

序列。 begin()和Bluetooth.begin()

与RPi的通信通过USB串行进行。 SoftwareSerial接线库用于与Android应用进行蓝牙通信。

wdt_enable(WDTO_500MS)

初始化IMU错误时,设置了Averdude看门狗定时器,这将强制Arduino复位。

resetRobot()

每次运行时都会初始化所有变量(并停止电动机)机器人放下。这对拾起机器人很有帮助。

loop()

只要机器人站立时,将检查所有输入。当间隔过去后,将执行控制循环。我尝试了不同的时间间隔。最佳选择取决于传感器和所用电机的类型。超过100Hz(《0.01秒)时,我遇到了错误的编码器数据,并且机器人的动作也太“辣”了。在50Hz时,机器人变得“笨拙”。在大多数情况下,100Hz环路效果最佳。

horizontalControl()

检查是否已经确定了目标距离,并向目标刻度添加了速度偏移。速度偏移是在间隔内以特定速度进行的滴答声数量。如果未设置距离和速度目标,则在机器人上升时设置目标刻度数。这使机器人可以返回其位置(如果命令移动一定距离,则可以返回新位置)。

differentialControl()

这对于IMU的偏航输出有点特殊在这里使用。 IMU返回-π《=偏航《=π(弧度)。

getAngles() 例程将读数转换为以度为单位的角度0-360范围。

resetRobot() 例程将机器人上升时的偏航角设置为yawTarget(基本上是360度刻度上的角度偏移量) )。

最后一个角度读数和偏移之间的差被视为错误。

冒充360度的刻度(例如在指南针上)可以轻松确定最小角度(=旋转方向)。可以根据向机器人补偿的方向(左/右)以及机器人必须移动的方向(向前/向后),简单地将结果添加到发送到各个电动机的功率中或从中减去。

仅当在 getMessage() 例程中通过蓝牙或从Raspberry接收命令时,才会执行以下3个例程。

setSpeed()

取一个电机一次可产生的最大滴答声的百分比( = RPM/60 *每转刻度数*时间间隔(秒)。)

setDistance()

将以米为单位的行驶距离乘以每米的刻度数( =每转刻度数/以米为单位的车轮周长)

setTurn()

为偏航偏移量添加所需的度数,将新目标调整为360度并重置转弯命令以防止连续转弯。

传感器和电机例程非常简单。 resetEncoders() 例程可防止由于编码器“翻转”(编码器输出为整数)而引起的事故。

交互例程检查串行和蓝牙队列中是否有新命令,如果有,则通过通用的案例结构对其进行处理。

第3步:调整控制循环

出于明显的原因,PID调整有时被称为“黑手艺”。这个过程可能非常繁琐和令人沮丧。尽管有许多获取控制器值的半结构化方法,但为获得机器人平衡,几乎总是不可避免地要进行手动调整。

一些注意事项将在这里有所帮助:

此过程需要耐心和观察:如果更改增益值,可以观察到哪种行为?

比例收益代表补偿的 P 下位。即所供应的电动机功率。

微分增益代表 D 放大所供电功率的效果。

请记住,这一切都与加速度有关。所提供的动力很快就会加速。

从两个增益都为零开始,然后以小步长开始增加 P (向下)。当漫游器自行停留或多或少时停止。也许太“摇晃”或“摇摆”,但它应该使自己保持几秒钟。 (通常称为“ 稳定振荡”。)

如果您真的无法获得稳定振荡,则可能是物理原因造成的。某些可能的信号是:振幅不均匀(可能表示齿轮,质量或高度问题)或仅沿一个方向移动(可能是缺乏电机动力)

机器人在剧烈振动时(机器人向前和向后移动),并且移动变得越来越野,加速度太大,因为已经提供了太多的动力。

当机器人开始越来越快地运行时,在一个方向上以崩溃告终,由于电力供应不足,机器人无法充分加速。

稳定振荡意味着不断的超调,就像坐在秋千上一样。添加 D (放大)后,过冲将减少(并最终消失)。

使用小步长,将值保持尽可能小,并彻底观察效果。

当可以从外部调整增益时,生活会变得不那么艰难。草图(否则必须一遍又一遍地编辑,重新编译和重建草图)。我从2个微调电位器开始调整增益。我发现它们很难使用。因为我一开始对增益值一无所知,所以我不得不多次编辑草图以进行新的缩放(?。????:1024),并且在没有直接视觉反馈的情况下,我不知道这些更改我是通过转动花盆来做的。

Android应用最适合我:几乎所有常量都可以通过输入一个值来更改。屏幕顶部概述了所有当前值。在屏幕底部,可以得到误差或角度本身的图形显示。请注意,这样的显示只是一个延迟的指示(串行和Wifi),而不是真实的实时反馈。该应用程序还可以用于测试一些命令(距离,速度,转弯)。

一旦我达到了球场标准,我就需要一些半自动化的测试工具,因为几乎所有更改机器人或其代码或多或少需要重新调整。特别是在水平控制回路上工作需要多次。

我编写了一个Python脚本,该脚本使用了通常称为“旋转”算法的协调上升算法。可以在这里找到Sebastian Thrun(Udacity,Google,Stanford)对算法的解释

可以在此处找到脚本:twiddleVert.py

我尝试在其中构建算法Arduino草图。尽管它只是安装在可用的32K内存中,但它使整体周期延迟太多。因此,该脚本旨在在Raspberry上运行,并使用其他一些Python脚本:

control.py,用于向Arduino和与UltraBorgs的I2C通信发送命令。如果未附加Ultraborg,则最好将导入和初始化注释掉。否则,还需要UltraBorg.py。

messaging.py是用于与Arduino进行实际通信的线程类

linkingStorage.py,它充当主脚本与主脚本之间的共享内存。线程脚本

measurements.py,用于收集,显示和保存所有测试数据。

注意:

Python脚本将根据进一步的实验而更改。如果您想避免更改,请克隆存储库。

我认为现在已经涵盖了所有基本知识,并有望帮助您构建自己的平衡器。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分