文章目录

  • 00-灵感篇
  • 01-设计篇
  • 02-硬件篇
  • 03-原理篇
  • 04-软件篇
  • 05-3D打印篇
  • 06-测试篇
  • 网盘链接

  对某个篇章感兴趣的,请直接跳转


00-灵感篇

  小型自平衡机器人EVA的制作灵感,来源于2018年的STM峰会的一次work shop活动。

  work shop上的这位大神,格子(别称,因为他穿着高深程序员的标志-格子衬衫)被邀请到峰会上介绍STM的有关产品,格子当时大四,能被邀请到STM32峰会的大学生想必不用多做介绍。

  在演讲中可知,格子是个综合能力极强的人,只要有想法,就能从0做起,构思-设计-原理图-电路图-外观-组装-测试等全部自己完成,而且十分痴迷“小”的东西,自制了非常多有趣的物品。小白也钟爱“小”的玩物,被其中一个吸引,就是他自制的迷你自平衡机器人nano

  第一次接触Arduino、第一次接触PID、第一次接触姿态解算……,很是忧愁,何以解忧,唯有动手。

01-设计篇

   首先是确定功能,核心功能是自平衡,为了比较好玩,外加的功能有:OLED(显示)、蓝牙(手机控制)、超声波(跟随物体)、红外阵列传感器(识别感应火焰),以下是思维导图(红外阵列删了的原因是不小心用烙铁头把镜片焊坏了…):

然后是外观,看到nano后,马上想到了电影《机器人总动员》中的瓦力。

既然想到了瓦力,就顺便模仿一下EVA,但是要给EVA加上轮子,于是最初的外观图纸如下

瓦力是方形的,想到三维画图可能比较容易,于是外观选择是瓦力,那么名字就取EVA,两者结合就是我最终的小玩物。


02-硬件篇

  根据思维导图,可以得出材料清单:

名称 型号/驱动 用途 简述
Arduino MCU nano 主控芯片 建议买贵一点的,有质量保证
6轴陀螺仪 GY-521 MPU6050 姿态解算,获得x轴偏移角度(pitch) 需要用到加速度计和角速度计
减速电机 GA12N20 带动轮子转动 可以不用减速,但是一定要自带码盘进行测速
电机驱动 TB6612 驱动电机,控制正反转和速度 TB6612比较小型,推荐
OLED液晶屏 SSD1306 自检信息显示、图片显示 IIC或者SPI都可以,最好IIC,能节省MCU端口
蓝牙 HC05-V13 手机端控制 主从一体或者只有从模式都可以
超声波 HC-SR04 跟随物品移动 只能直线行驶,超声波不能判断方向
红外阵列传感器 GY-AMG8833 在一个矩阵范围内识别火焰位置 这个传感器非常贵,注意资金


  还有一些硬件比如蜂鸣器、LED和按键等等,就随意购买了。


03-原理篇

  两轮自平衡的数学模型是倒立摆,与单摆相似的运动。

   对于倒立摆(轴是可转动的),在不施加外力的情况下,由于重力作用,上方的物体会向左或者向右摆,而我们的期望是让上方的物体保持在垂直位置(平衡位置),所以需要添加外力让倒立摆保持平衡。

   添加外力的控制算法一般是PID(比例-积分-微分),一个短小精悍的算法,要使用PID,系统中需要有回环,回环简单理解为一个单元发出的信号需要被反馈回来
   举个例子,拿出自己的手机,一边说话一边测分贝,你发出的声音被手机上的分贝反馈回来让自己知道,这个过程就是回环,然后用反馈回来的分贝调整自己的声音停留在某一个分贝值附近,这个过程就是PID。

  两轮平衡的回环由电机的转速和重心的偏移角度构成,PID算法使用3个参数去控制平衡,分别是P(比例)、I(积分)和D(微分),假设传感器对重心偏移角度的历史采样序列为:X1,X2, ······ ,Xk-1,Xk,而平衡位置的目标值为Sv(一般为0,意思是没有偏移)

  比例P控制,基本思想是关心当前偏差,用目标值减去最近的一次测量,得到Pk = Sv - Xk
  Pk>0; 当前控制未达标(输出信号要升高)
  Pk=0; 当前控制达标(不控制)
  Pk<0; 当前控制超标(输出信号要降低)
  得到 Pout = P * Pk + Pm(Pm是常数,用于抵消机器阻力)

  积分I控制,基本思想是关心历史偏差, 把历史采样点数据序列逐个与Sv比较,得到历史偏差序列:P1,P2, ······ Pk-1,Pk,然后对历史偏差序列积分:Ik = P1+P2+······+Pk-1+Pk (每一项都可正可负)
  Ik>0; 所有偏差之和为正,控制总体偏低,未达标(输出信号要升高)
  Ik=0; 所有偏差之和为零,控制总体正常,达标(不输出信号)
  Ik<0; 所有偏差之和为负,控制总体偏高,超标(输出信号要降低)
  得到 Iout = I * Ik + Im(Im是常数,用于抵消机器阻力)

  微分D控制,基本思想是关心近期偏差, 把最近的两次偏差相减得到Dk = Pk - Pk-1
  Dk>0; 这一次的偏差值大于上一次,越来越偏离我们的目标,偏差有增大趋势
  Dk=0; 这一次采样和后一次采样之间的变化没有产生变化
  Dk<0; 这一次的偏差值小于上一次,越来越偏离我们的目标,偏差有减小趋势
  得到 Dout = D * Dk + Dm(Dm是常数,用于抵消机器阻力)

  最后的PID控制输出 OUT = Pout + Iout + Dout,可以看出,如果要编写PID,只有几行的代码,就可以控制平衡。

  以上是MCU的运算,直观而言,可以简单粗暴理解为,当检测到机器人身体向前倾,就让轮子猛一下往前转,利用惯性让身体往后摆动,同理,当检测机器人身体往后倾,就让轮子猛一下往后转,由此不断重复,进而保持平衡。


04-软件篇

  接下来就是每个模块的驱动程序编写,MCU平台为Arduino,开发非常快捷,为了方便移植,在编程中小白尽量自己写库或者引用一些已经非常完善的平台无关库。

  MPU6050姿态结算后使用一阶互补滤波算法得到pitch的偏移角,因为Arduino计算处理能力并不是很强,也不需要太精准的滤波,用一阶互补滤波算法足矣,但是小白在源码中还是编写了卡尔曼滤波,可以比较精准得到当前角度,移植到STM的时候可以使用

/*** @brief 一阶互补滤波函数,得到偏移角度*/
float MPU6050::one_filter(float angle_m,float gyro_m,float dt)
{float K1 =0.07; //Weight of accelerometer float one_filter_angle = K1 * angle_m+ (1-K1) * (one_filter_angle + gyro_m * dt);return one_filter_angle;
}/*** @brief   卡尔曼滤波函数,得到具体角度*/
float MPU6050::Kalman_filter(float newAngle, float newRate, float dt)
{rate = newRate - bias;angle += dt * rate;// Update estimation error covariance - Project the error covariance ahead/* Step 2 */P[0][0] += dt * (dt*P[1][1] - P[0][1] - P[1][0] + Q_angle);P[0][1] -= dt * P[1][1];P[1][0] -= dt * P[1][1];P[1][1] += Q_bias * dt;// Discrete Kalman filter measurement update equations - Measurement Update ("Correct")// Calculate Kalman gain - Compute the Kalman gain/* Step 4 */float S = P[0][0] + R_measure; // Estimate error/* Step 5 */float K[2]; // Kalman gain - This is a 2x1 vectorK[0] = P[0][0] / S;K[1] = P[1][0] / S;// Calculate angle and bias - Update estimate with measurement zk (newAngle)/* Step 3 */float y = newAngle - angle; // Angle difference/* Step 6 */angle += K[0] * y;bias += K[1] * y;// Calculate estimation error covariance - Update the error covariance/* Step 7 */float P00_temp = P[0][0];float P01_temp = P[0][1];P[0][0] -= K[0] * P00_temp;P[0][1] -= K[0] * P01_temp;P[1][0] -= K[1] * P00_temp;P[1][1] -= K[1] * P01_temp;return angle;
}

  开启蓝牙模式后,EVA一直保持平衡,同时解析手机发送的数据开始行走,手机连接蓝牙的APP使用一个两轮自平衡机器人开源网站提供的APP-Balanduino,本来小白想自己写,但是发现了这个宝物后就懒得动手了,可以从Balanduino源程序中或者官方说明中得到数据协议。

  其中一个模拟摇杆的数据协议是:(CJ,x,y ),其中摇杆的坐标是单位坐标,上下左右坐标轴长度都为1,只要根据x,y判断哪个现象后,再赋予两个轮子不同的速度,就可以进行转弯、前进和后退,速度的大小需要自己去调试,每个机器人都不一样。

#ifdef HC05_DEBUGif((micros() - hc05_time) > 200000){data = hc05.recv();char str[32];if(!data.equals(AT_ERROR)){/* CJ,x,y */data.toCharArray(str, data.length());strtok(str, ",");float x = atof(strtok(NULL, ","));float y = atof(strtok(NULL, ","));speed_setpoint = x * 15;if(x >0  && y >0)                               //第一象限{int x_speed = x * 15;int y_speed = y * 30;tb6612_A.set_rotate_dir(TB6612_LEFT);  tb6612_A.set_speed(x_speed);tb6612_B.set_rotate_dir(TB6612_LEFT);  tb6612_B.set_speed(y_speed);}  if(x < 0 && y > 0)                                //第二象限{     int x_speed = x * 15;int y_speed = y * 60;tb6612_A.set_rotate_dir(TB6612_LEFT);  tb6612_A.set_speed(x_speed);tb6612_B.set_rotate_dir(TB6612_LEFT);  tb6612_B.set_speed(y_speed);              }if(x < 0 && y < 0)                               //第三象限{     int x_speed = x * 30;int y_speed = y * 15;tb6612_A.set_rotate_dir(TB6612_LEFT);  tb6612_A.set_speed(x_speed);tb6612_B.set_rotate_dir(TB6612_LEFT);  tb6612_B.set_speed(y_speed);                  }if(x > 0 && y < 0)                               //第四象限{int x_speed = x * 60;int y_speed = y * 15;tb6612_A.set_rotate_dir(TB6612_LEFT);  tb6612_A.set_speed(x_speed);tb6612_B.set_rotate_dir(TB6612_LEFT);  tb6612_B.set_speed(y_speed);                   }}PID_speed_compute();}
#endif


  超声波的跟随控制就比较直观了,只要检测到物体在跟随范围内,就赋予一个特定的速度,让EVA前进,同时保持与物体的距离,让EVA后退,当物体不在跟随范围的时候,就停止。

#ifdef HC_SR04_DEBUGif((micros() - hcsr_time) > 200000){hcsr_distance = hcsr.get_distance();if(hcsr_distance > 10.0 && hcsr_distance < 15.0)       //向前跟{speed_setpoint = 25;}else if(hcsr_distance > 2.0 && hcsr_distance < 10.0)  //往后退{speed_setpoint = -25;}else {speed_setpoint = SPEED_DEFAULT;                     //停止}hcsr_time = micros();PID_speed_compute();}
#endif


  其它模块的驱动都比较简单,可以在文件末尾链接得到,这里贴出PID的控制算法代码,PID应用在两个环上,分别是速度环和角度环,角度环令EVA平衡,速度环令EVA行走

/* out = (P * P_err) + (I * I_err) */
static void PID_speed_compute(void)
{if(micros() - PID_speed_timer > 10000){P_speed_err = (count_L + count_R ) * 1.25 - speed_setpoint ;I_speed_err += P_speed_err;pitch_setpoint = P_speed * P_speed_err + I_speed * I_speed_err;PID_speed_timer = micros();     }
}/* out = (P * P_err) + (I * I_err) + (D * D_err) */
static void PID_angle_compute(void)
{if(micros() - PID_angle_timer > 10000){float pitch_current = accelgyro.get_filter_pitch();         //当前的pitchfloat P_angle_err = pitch_setpoint - pitch_current;          //获得偏差I_angle_err += P_angle_err;                                 //积分,累计微小变化量D_angle_err = P_angle_err - P_angle_err_last;               //微分,偏差的变化趋势P_angle_err_last = P_angle_err;                             //记录当前误差float angle_output = P_angle*P_angle_err + I_angle*I_angle_err + D_angle*D_angle_err;int speed;if(angle_output > 255.0)speed = 255;else if(angle_output < -255.0)speed = -255;elsespeed = (int)angle_output;do_motor(speed);PID_angle_timer = micros();}}

05-3D打印篇

  三维建模工具是CAD,三维建模而言,CAD并没有像Solidworks这样方便快捷,不过头一次建模也够用了,到CAD官网认证学生后有3年的免费试用!!不用烦破解安装。

  CAD只是建模工具,实际的模型还是需要图纸的,和最初图纸有一定的差别,因为小白不想把外壳做得复杂,然后用纸皮做了模具,头、身体、连接、电池夹和底座:

然后用CAD三维建模,适当渲染后得到如下模型:

最后打印出来,实物图如下(后面其实经过修改,把身体的两个照明灯取消,因为电压不够):

06-测试篇

3D打印好零件后,进行连线和组装:

如果自己有轮子的,尽量不要用打印,因为打印出来的轮子很光滑,不能使用的,小白给它套了橡胶圈才能正常使用

组装完成后,首先进行平衡测试,第一次调PID,真的是非常难调,调了大概3天时间才调出比较好的参数。

  怕轮子打滑厉害,因为橡胶圈磨损得比较薄了,放了件衣服增加摩擦测试平衡,EVA平衡的摆动幅度不大,已经可以自平衡了。

   其实文章是EVA一边开发一边编写的,本来这个时候要编写蓝牙连接控制的,但是由于参数调的过高,在测试蓝牙控制的时候EVA突然过冲撞向对面的桌子,跌倒在地,本来焊接好的线很多都断了,难以重新连接,还发现电机编码器的电路板被刮破了,一个电机已经不能使用,下面是大型翻车现场…


  上图还是小白补救后的图,摔倒在地后其实身体和基座都断开了,电机驱动的线基本全部断,重新焊接后才得到上面的图,非常心疼EVA,还有超声波跟随测试和蓝牙控制测试没有进行,只能重新买模块组装,不过条件有限,EVA只能暂时到此,等小白有条件后再回来……

   核心功能已经完成,其实后面的超声波和蓝牙代码已经写好,只欠测试,另外还有很多【买多/买错/凑单】的零件,可能后面拿来做有趣的东西。

  • 自平衡
  • 超声波跟随
  • 蓝牙控制

网盘链接

最后分享所有的硬件资料+Arduino源代码+3D文件:百度网盘 密码:zn9e

【project】Adruino小型自平衡机器人EVA(+硬件+源代码+3D文件)相关推荐

  1. 循迹的光电搬运小车含PID(硬件+源代码+3D文件)

    循迹的光电搬运小车(硬件+源代码+CAD文件) 一. 设计思路 1. 比赛规则 2. 设计思路 二. 硬件需求 三. 算法设计 1.循迹部分 (1)读取灰度传感器数值 (2)前进后退算法 (3)循迹算 ...

  2. 基于STM32开源项目:球上自平衡机器人

    关注+星标公众号,不错过精彩内容 来源 | 达尔闻说 作者 | Jumping润 本次毕业设计过程中,Jumping润受到过许多人的帮助,收获良多,在此将机器人整体开源,同时总结一下机器人搭建过程中遇 ...

  3. 使用Arduino的DIY自平衡机器人

    原文地址:https://circuitdigest.com/microcontroller-projects/arduino-based-self-balancing-robot 使用Arduino ...

  4. 建造一个自平衡机器人

    index 第1部分:简介 1.1 简要概述 1.2 所需组件 必要: 可选的: 第2部分:加速度计和陀螺仪传感器 2.1 确定要使用的陀螺仪模块 2.2 Accel-Gyro模块入门 2.3 标记 ...

  5. MATLAB/Simulink模型开发乐高EV3 双足平衡机器人

    MATLAB/Simulink 2018a 模型开发乐高EV3 双足平衡机器人(含视频) 之前只是用Matlab做一些算法的仿真,数据的计算分析处理,知道MATLAB中包含有Simulink,只知道S ...

  6. 毕业设计--球上自平衡机器人

    目录 前言 一.机器人原理分析 二.控制器设计 三.程序部分 四.硬件清单 五.电路设计 六.结构设计 七.总结与展望 总结 展望 2021 8.18更新: 看到评论区很多人对这个机器人比较感兴趣,把 ...

  7. 《单足自平衡机器人》(转)

    中山大学南方学院 这个机器人的走路方式很有创意.所以就转了,以后应用应该会非常广. 前言      传统机器人的移动平台,基本上都由三个以上的车轮或履带实现的,在静止状态下,他们有很好的稳定性,但是这 ...

  8. 两轮平衡机器人送披萨,旋转跳跃!

    在过去几个月,国外的街头陆续涌现各式各样的外卖机器人,其中一款神似波士顿动力Handle会旋转会弹跳的机器人成功引起了小编的注意,这波披萨送得666~ 送完一单,开心到飞起~~~ 这是苏黎世团队研发的 ...

  9. 两轮自平衡机器人(一)---Simscape物理建模

    我们将建立和控制一个两轮自平衡机器人的3d模型.我们使用一个PID控制器来实现机器人的直立姿态,并使用两种方法来调整PID控制器:手动和自动调整. 1.通过在命令中键入smnew来进行项目 重心设置为 ...

最新文章

  1. 公众号管理01-基本架构
  2. iTween基础之功能简介
  3. php运行环境largon,环境配置(一)
  4. Java使用预定格式获取时间字符串
  5. 每日两道前端面试题20190221
  6. Python rfind()方法
  7. 单一职责在.NET中
  8. 杭州师范大学计算机与科学,杭州师范大学信息科学与工程学院
  9. 基于stm32的太阳跟踪装置设计与制作
  10. 我(和谐)草(和谐)尼(和谐)玛
  11. Asio驱动开发学习笔记(1)
  12. C# 淘宝商品微信返利助手开发-(一)返利助手原理
  13. 关于电子科技大学学生用餐情况的一些调查
  14. 【基础知识①】计算机网络知识
  15. GWAS生物学相关名词解释
  16. 微信小程序开发手账从入门到部署【持续更新】
  17. 完美解决 w10 设置 个性化 wifi 无法打开的问题
  18. 用 Word2016 编辑花体和空心字母
  19. Java基础——Day23——Lock和TCP传输
  20. 图解IFRS9 金融工具(7)减值损失披露

热门文章

  1. php 字符串替换中文,PHP中文字符串替换其中为*的方法
  2. ACRUSH 楼教主的回忆录
  3. 【windows】window10打开图片显示黑屏,一直打不开
  4. #榜样的力量#航班管家全球大交通出行疫情追踪服务系统丨数据猿新冠战“疫”公益策划...
  5. 网络环路检测定位技术的发展过程
  6. mysql配置kodi16.1_kodi中文包|kodi 16.1中文语言包下载 附插件使用教程 - 121下载站...
  7. LPC1768用官方库中用寄存器开启两个硬件PWM
  8. 图片横向滚动 01-兼容IE8和Chrome浏览器
  9. 国外问卷调查详细讲解
  10. 《只为遇见你》硬生生把爱情片拍成了把妹宝典,真人出镜演绎直男转型