0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何使用Arduino制造一个自动平衡机器人

科技观察员 来源:八色木 作者:八色木 2022-04-02 17:28 次阅读

本文将介绍如何使用Arduino来制造一个自动平衡机器人,并介绍其控制原理。

自平衡机器人的控制原理

poYBAGJIFzSAS9J1AAaQZ19FzRM458.png

自平衡机器人

自平衡机器人听名字比较高大上,但实际生活中其中已经可以看到很多成品了,像比较早期高端的赛格威,满大街跑的小米平衡车等,都属于自平衡机器人的范畴。那他是如何工作的呢?首先我们要知道,自平衡机器人为了让机器人保持平衡,电机的运动必须要能抵消机器人的自然重力导致的姿态变化,比如倾倒、后仰等。要实现这个抵消的动作平衡机器人就需要能反馈并纠正这些变化的因素。在本项目中,反馈元件是MPU6050及其内置的陀螺仪和加速度计,它在三个轴上都提供加速度和旋转反馈功能。

Arduino控制器通过它来知道机器人当前的姿态信息,从而通过这些信息控制电机和车轮的运动,使机器人能够保持平衡。

poYBAGJIFzuACRU9AAHtK3wB4mw293.png

感知到机器人的倾斜,通过驱动车轮来保持机器人直立。

自平衡机器人的电路原理

pYYBAGJIFz-AV4cVAAK9G8-2pQo425.png

自平衡机器人的电路原理图

在电路连接方面, 首先我们要将MPU6050连接到Arduino,可查阅:Arduino如何使用MPU6050,然后参照上图所示连接其余的组件。L298N模块可以为Arduino提供所需的+5V(详情见: Arduino直流电机控制教程 中的相关内容 )。本文中,我们选择了单独的电源为电机和电路供电。请注意,如果您计划为L298N模块使用大于+12V的电源电压,您需要移除刚好位于+12V输入上方的跳线。

构建机器人

pYYBAGJIF0aAUZJOAAV28BIL43Y475.png

机器人框架

机器人框架采用一些简单的材料黏贴完成,如果有3D打印机也可以尝试设计一款适合自己风格外壳框架。具体可参阅:设计自平衡机器人。

poYBAGJIF0yAcUJoAAev6fyVosI763.png

机器人主电路板

主电路板主要包括Arduino Nano和MPU6050和一块L298N电机驱动板。

自平衡机器人本质上是一个倒立钟摆。如果质量中心相对于轮轴较高,则可以更好地平衡。较高的质心意味着较高的质量惯性矩,这对应于较低的角加速度(下降较慢)。这就是为什么我把电池组放在上面。然而,机器人的高度是根据材料的可用性来选择的。 制作时不必过分强求。

PID控制原理

在控制中,保持某个变量(机器人的位置)的稳定需要一个称为PID(比例积分导数)的特殊控制器。这些参数都存在“增益”的问题,通常称为Kp、Ki和Kd。PID需要在期望值(输入值)和实际值(输出值)之间进行校正。输入和输出之间的差异称为“误差”。PID控制器通过不断调整输出将误差减小到最小值。在本文的Arduino自平衡机器人中,这些值的设置遵循以下原则:

使Kp Ki Kd等于0。

Kp的调整:Kp值太低会使机器人摔倒,因为没有足够的校正值。太大的Kp会使机器人疯狂地来回移动。一个合适的Kp值会使机器人稍微来回移动或者稍微摆动即可。

设定好Kp值后,需要调整Kd值。适当的Kd值可以减小振动,直到机器人基本稳定。同时,即使它被推动,适当的Kd值也能让机器人始终保持站立。

最后就是设置Ki值。因为我们即使设定了Kp和Kd值,机器人在打开电源时也会发生振动,但它会在一定的时间后稳定下来。正确的Ki值可以缩短机器人稳定的时间。

Arduino自平衡机器人代码

要成功实现代码安装,需要四个外部库文件来让Arduino自平衡机器人正常工作。PID库的引入使得计算P、I和D值变得相对容易。LMotorController库文件用于L298N模块驱动两个电机,I2Cdev库和MPU6050_6_Axis_MotionApps20库用于从MPU6050读取数据。你可以在这里下载包含这些库文件的代码。

#include

#include

#include "I2Cdev.h"

#include "MPU6050_6Axis_MotionApps20.h"

#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE

#include "Wire.h"

#endif

#define MIN_ABS_SPEED 20

MPU6050 mpu;

// MPU control/status vars

bool dmpReady = false; // set true if DMP init was successful

uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU

uint8_t devStatus; // return status after each device operation (0 = success, !0 = error)

uint16_t packetSize; // expected DMP packet size (default is 42 bytes)

uint16_t fifoCount; // count of all bytes currently in FIFO

uint8_t fifoBuffer[64]; // FIFO storage buffer

// orientation/motion vars

Quaternion q; // [w, x, y, z] quaternion container

VectorFloat gravity; // [x, y, z] gravity vector

float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container and gravity vector

//PID

double originalSetpoint = 173;

double setpoint = originalSetpoint;

double movingAngleOffset = 0.1;

double input, output;

//adjust these values to fit your own design

double Kp = 50;

double Kd = 1.4;

double Ki = 60;

PID pid(&input, &output, &setpoint, Kp, Ki, Kd, DIRECT);

double motorSpeedFactorLeft = 0.6;

double motorSpeedFactorRight = 0.5;

//MOTOR CONTROLLER

int ENA = 5;

int IN1 = 6;

int IN2 = 7;

int IN3 = 8;

int IN4 = 9;

int ENB = 10;

LMotorController motorController(ENA, IN1, IN2, ENB, IN3, IN4, motorSpeedFactorLeft, motorSpeedFactorRight);

volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high

void dmpDataReady()

{

mpuInterrupt = true;

}

void setup()

{

// join I2C bus (I2Cdev library doesn't do this automatically)

#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE

Wire.begin();

TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)

#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE

Fastwire::setup(400, true);

#endif

mpu.initialize();

devStatus = mpu.dmpInitialize();

// supply your own gyro offsets here, scaled for min sensitivity

mpu.setXGyroOffset(220);

mpu.setYGyroOffset(76);

mpu.setZGyroOffset(-85);

mpu.setZAccelOffset(1788); // 1688 factory default for my test chip

// make sure it worked (returns 0 if so)

if (devStatus == 0)

{

// turn on the DMP, now that it's ready

mpu.setDMPEnabled(true);

// enable Arduino interrupt detection

attachInterrupt(0, dmpDataReady, RISING);

mpuIntStatus = mpu.getIntStatus();

// set our DMP Ready flag so the main loop() function knows it's okay to use it

dmpReady = true;

// get expected DMP packet size for later comparison

packetSize = mpu.dmpGetFIFOPacketSize();

//setup PID

pid.SetMode(AUTOMATIC);

pid.SetSampleTime(10);

pid.SetOutputLimits(-255, 255);

}

else

{

// ERROR!

// 1 = initial memory load failed

// 2 = DMP configuration updates failed

// (if it's going to break, usually the code will be 1)

Serial.print(F("DMP Initialization failed (code "));

Serial.print(devStatus);

Serial.println(F(")"));

}

}

void loop()

{

// if programming failed, don't try to do anything

if (!dmpReady) return;

// wait for MPU interrupt or extra packet(s) available

while (!mpuInterrupt && fifoCount < packetSize)

{

//no mpu data - performing PID calculations and output to motors

pid.Compute();

motorController.move(output, MIN_ABS_SPEED);

}

// reset interrupt flag and get INT_STATUS byte

mpuInterrupt = false;

mpuIntStatus = mpu.getIntStatus();

// get current FIFO count

fifoCount = mpu.getFIFOCount();

// check for overflow (this should never happen unless our code is too inefficient)

if ((mpuIntStatus & 0x10) || fifoCount == 1024)

{

// reset so we can continue cleanly

mpu.resetFIFO();

Serial.println(F("FIFO overflow!"));

// otherwise, check for DMP data ready interrupt (this should happen frequently)

}

else if (mpuIntStatus & 0x02)

{

// wait for correct available data length, should be a VERY short wait

while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();

// read a packet from FIFO

mpu.getFIFOBytes(fifoBuffer, packetSize);

// track FIFO count here in case there is > 1 packet available

// (this lets us immediately read more without waiting for an interrupt)

fifoCount -= packetSize;

mpu.dmpGetQuaternion(&q, fifoBuffer);

mpu.dmpGetGravity(&gravity, &q);

mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);

input = ypr[1] * 180/M_PI + 180;

}

}

本文中的Kp、Ki、Kd的值可能适用也可能不适用你的机器人。如果不适用,那么按照上面PID控制原理中提到的方法来设当调整。注意,代码中的倾斜值设置为173度。如果有必要,你可以更改这个值,这是机器人必须保持的倾斜角度。此外,如果你的电机速度太快,你可以适当调整motorSpeedFactorLeft和motorSpeedFactorRight值,一个成功的DIY是需要不断调整的,重点是要有耐心,最后希望大家都能完成自己的自平衡机器人。

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

    关注

    210

    文章

    28180

    浏览量

    206334
  • Arduino
    +关注

    关注

    187

    文章

    6462

    浏览量

    186613
收藏 人收藏

    评论

    相关推荐

    关于两轮自平衡机器人载重问题

    现在流行的自平衡两轮机器人,有人接触过吗,小弟最近想DIY玩玩,现在碰到了难点,至今没想
    发表于 11-24 11:20

    怎样去制作种球上自平衡机器人

    毕业设计——球上平衡机器人前言本次毕业设计过程中,受到过许多人的帮助,收获良多,在此将机器人整体开源,同时总结一下机器人搭建过程中遇到的坑和未来的改进方向。
    发表于 08-17 08:44

    如何设计款球上自平衡机器人

    如何设计款球上自平衡机器人
    发表于 02-22 07:39

    制作迷你平衡机器人

    描述迷你平衡机器人大家好。我知道互联网上已经有很多平衡机器人项目,但我也想做一个。实际上,我想制作些特别的东西并制作
    发表于 07-07 07:17

    平衡机器人护盾的资料分享

    描述平衡机器人护盾
    发表于 09-05 06:11

    DIY:简简单单自制平衡机器人

    DIY:简简单单自制平衡机器人
    发表于 01-18 20:40 25次下载

    机器人掌握自动平衡术 未来可用于救灾

    来自中国广东工业大学自动化学院的研究人员开发出了种新型自动平衡机器人,开发代号为Jet-HR1,该机器人可用喷气动力引擎调整重心,未来双足机器人
    发表于 06-27 09:29 895次阅读

    如何利用超声波传感器制作轮式自平衡机器人

    这是轮式自平衡机器人。由 Arduino UNO 供电并由超声波传感器平衡,同时它能够自我保持垂直
    的头像 发表于 05-25 17:16 3097次阅读
    如何利用超声波传感器制作<b class='flag-5'>一</b><b class='flag-5'>个</b>轮式自<b class='flag-5'>平衡机器人</b>

    迷你平衡机器人

    电子发烧友网站提供《迷你平衡机器人.zip》资料免费下载
    发表于 07-08 09:34 16次下载
    迷你<b class='flag-5'>平衡机器人</b>

    Arduino平衡机器人盾牌代码

    电子发烧友网站提供《Arduino平衡机器人盾牌代码.zip》资料免费下载
    发表于 08-15 14:36 3次下载
    <b class='flag-5'>Arduino</b><b class='flag-5'>平衡机器人</b>盾牌代码

    Magicbit的自平衡机器人

    电子发烧友网站提供《Magicbit的自平衡机器人.zip》资料免费下载
    发表于 11-24 11:15 0次下载
    Magicbit的自<b class='flag-5'>平衡机器人</b>

    带有BT Web控制的Arduino平衡机器人

    电子发烧友网站提供《带有BT Web控制的Arduino平衡机器人.zip》资料免费下载
    发表于 11-29 10:27 0次下载
    带有BT Web控制的<b class='flag-5'>Arduino</b>自<b class='flag-5'>平衡机器人</b>

    基于Arduino UNO的自平衡机器人

    平衡机器人,使用带有 BluBug 和 Android 的车轮和 imu 6 轴传感器平衡机器人
    发表于 12-08 10:24 0次下载

    使用Arduino的自平衡机器人

    在这个项目中,我们将使用Arduino制造DIY自平衡机器人。在此,我们可以学习平衡概念以及
    发表于 01-05 16:40 0次下载

    平衡机器人的构建

    电子发烧友网站提供《自平衡机器人的构建.zip》资料免费下载
    发表于 02-09 11:54 0次下载
    自<b class='flag-5'>平衡机器人</b>的构建