什么是麦克纳姆轮

在竞赛机器人和特殊工种机器人中,全向移动经常是一个必需的功能。「全向移动」意味着可以在平面内做出任意方向平移同时自转的动作。为了实现全向移动,一般机器人会使用「全向轮」(Omni Wheel)或「麦克纳姆轮」(Mecanum Wheel)这两种特殊轮子。

全向轮与麦克纳姆轮的共同点在于他们都由两大部分组成:轮毂和辊子(roller)。轮毂是整个轮子的主体支架,辊子则是安装在轮毂上的鼓状物。全向轮的轮毂轴与辊子转轴相互垂直,而麦克纳姆轮的轮毂轴与辊子转轴呈 45° 角。理论上,这个夹角可以是任意值,根据不同的夹角可以制作出不同的轮子,但最常用的还是这两种。

全向轮与麦克纳姆轮(以下简称「麦轮」)在结构、力学特性、运动学特性上都有差异,其本质原因是轮毂轴与辊子转轴的角度不同。经过分析,二者的运动学和力学特性区别可以通过以下表格来体现。

计算过程如下,供参考,学霸可点开大图验算:

近年来,麦轮的应用逐渐增多,特别是在 Robocon、FRC 等机器人赛事上。这是因为麦克纳姆轮可以像传统轮子一样,安装在相互平行的轴上。而若想使用全向轮完成类似的功能,几个轮毂轴之间的角度就必须是 60°,90° 或 120° 等角度,这样的角度生产和制造起来比较麻烦。所以许多工业全向移动平台都是使用麦克纳姆轮而不是全向轮,比如这个国产的叉车: 全向移动平台 麦克纳姆轮叉车 美科斯叉车

另外一个原因,可能是麦轮的造型比全向轮要酷炫得多,看起来有一种不明觉厉的感觉……

的确,第一次看到麦轮运转起来,不少人都会惊叹。以下视频直观地说明了麦轮底盘在平移和旋转时的轮子旋转方向。


麦克纳姆轮工作原理—在线播放—优酷网,视频高清在线观看

视频

麦轮的安装方法

麦轮一般是四个一组使用,两个左旋轮,两个右旋轮。左旋轮和右旋轮呈手性对称,区别如下图。

安装方式有多种,主要分为:X-正方形(X-square)、X-长方形(X-rectangle)、O-正方形(O-square)、O-长方形(O-rectangle)。其中 X 和 O 表示的是与四个轮子地面接触的辊子所形成的图形;正方形与长方形指的是四个轮子与地面接触点所围成的形状。

  • X-正方形:轮子转动产生的力矩会经过同一个点,所以 yaw 轴无法主动旋转,也无法主动保持 yaw 轴的角度。一般几乎不会使用这种安装方式。
  • X-长方形:轮子转动可以产生 yaw 轴转动力矩,但转动力矩的力臂一般会比较短。这种安装方式也不多见。
  • O-正方形:四个轮子位于正方形的四个顶点,平移和旋转都没有任何问题。受限于机器人底盘的形状、尺寸等因素,这种安装方式虽然理想,但可遇而不可求。
  • O-长方形:轮子转动可以产生 yaw 轴转动力矩,而且转动力矩的力臂也比较长。是最常见的安装方式。

麦轮底盘的正逆运动学模型

以O-长方形的安装方式为例,四个轮子的着地点形成一个矩形。

正运动学模型(forward kinematic model)将得到一系列公式,让我们可以通过四个轮子的速度,计算出底盘的运动状态;逆运动学模型(inverse kinematic model)得到的公式则是可以根据底盘的运动状态解算出四个轮子的速度

需要注意的是,底盘的运动可以用三个独立变量来描述:X轴平动、Y轴平动、yaw 轴自转;而四个麦轮的速度也是由四个独立的电机提供的。所以四个麦轮的合理速度是存在某种约束关系的,逆运动学可以得到唯一解,而正运动学中不符合这个约束关系的方程将无解。

先试图构建逆运动学模型,由于麦轮底盘的数学模型比较复杂,我们在此分四步进行:

①将底盘的运动分解为三个独立状态变量来描述;

②根据第一步的结果,计算出每个轮子轴心位置的速度;

③根据第二步的结果,计算出每个轮子与地面接触的辊子的速度;

④根据第三步的结果,计算出轮子的真实转速。

一、底盘运动分解

刚体在平面内的运动可以分解为三个独立分量:X轴平动、Y轴平动、yaw 轴自转。如下图所示,底盘的运动也可以分解为三个量:

以上三个量一般都视为四个轮子的几何中心(小车矩形底盘的对角线交点)的速度。

二、计算出轮子轴心位置的速度

定义:

同理可以算出其他三个轮子轴心的速度。

三、计算辊子的速度

四、计算轮子的速度

从麦轮的辊子速度变换到轮子转速的计算比较简单:

另一种计算方式

「传统」的推导过程虽然严谨,但还是比较繁琐的。这里介绍一种简单的逆运动学计算方式。

我们知道,全向移动底盘是一个纯线性系统,而刚体运动又可以线性分解为三个分量。那么只需要计算出麦轮底盘在「沿X轴平移」、「沿Y轴平移」、「绕几何中心自转」时,四个轮子的速度,就可以通过简单的加法,计算出这三种简单运动所合成的「平动+旋转」运动时所需要的四个轮子的转速。而这三种简单运动时,四个轮子的速度可以通过简单的测试,或是推动底盘观察现象得出。

将以上三个方程组相加,得到的恰好是根据「传统」方法计算出的结果。这种计算方式不仅适用于O-长方形的麦轮底盘,也适用于任何一种全向移动的机器人底盘。


Makeblock 麦轮底盘的组装

理论分析完成,可以开始尝试将其付诸实践了。

第一步,组装矩形框架。

第二步,组装电机模块。

由于麦轮底盘的四个轮子速度有约束关系,必须精确地控制每个轮子的速度,否则将会导致辊子与地面发生滑动摩擦,不仅会让底盘运动异常,还会让麦轮的寿命减少。所以必须使用编码电机。

第三步,将电机模块安装到框架上。

第四步,将麦轮安装到框架上。

第五步,安装电路板并接线。

编码电机必须配上相应的驱动板才能正常工作。这里使用的 Makeblock 编码电机驱动板,每一块板可以驱动两个电机。接线顺序在下文中会提及,也可以随意接上,在代码中定义好对应的顺序即可。

第六步,装上电池。

至此,一个能独立运行的麦轮底盘就完成了。


控制程序

根据麦轮的底盘的运动学模型,要完全控制它的运动,需要有三个控制量:X轴速度、Y轴速度、自转角速度。要产生这三个控制量,有很多种方法,本文将使用一个 USB 游戏手柄,左边的摇杆产生平移速度,右边的摇杆产生角速度。

首先将一个 USB Host 模块连接到 Orion 主板的 3 口。

然后插上一个无线 USB 游戏手柄。

然后再添加其他细节,就大功告成啦!

其他细节:

#include <Wire.h>
#include <SoftwareSerial.h>
#include "MeOrion.h"MeUSBHost joypad(PORT_3);
//  手柄代码(红灯亮模式)
//  默认:128-127-128-127-15-0-0-128
//  左一:128-127-128-127-15-1-0-128
//  右一:128-127-128-127-15-2-0-128
//  左二:128-127-128-127-15-4-0-128
//  右二:128-127-128-127-15-8-0-128
//  三角:128-127-128-127-31-0-0-128 (0001 1111)
//  方形:128-127-128-127-143-0-0-128 (1000 1111)
//  叉号:128-127-128-127-79-0-0-128 (0100 1111)
//  圆圈:128-127-128-127-47-0-0-128 (0010 1111)
//  向上:128-127-128-127-0-0-0-128 (0000 0000)
//  向下:128-127-128-127-4-0-0-128 (0000 0100)
//  向左:128-127-128-127-6-0-0-128 (0000 0110)
//  向右:128-127-128-127-2-0-0-128 (0000 0010)
//  左上:128-127-128-127-7-0-0-128 (0000 0111)
//  左下:128-127-128-127-5-0-0-128 (0000 0101)
//  右上:128-127-128-127-1-0-0-128 (0000 0001)
//  右下:128-127-128-127-3-0-0-128 (0000 0011)
//  选择:128-127-128-127-15-16-0-128
//  开始:128-127-128-127-15-32-0-128
//  摇杆:右X-右Y-左X-左Y-15-0-0-128MeEncoderMotor motor1(0x02, SLOT2);
MeEncoderMotor motor2(0x02, SLOT1);
MeEncoderMotor motor3(0x0A, SLOT2);
MeEncoderMotor motor4(0x0A, SLOT1);//  底盘:a = 130mm, b = 120mmfloat linearSpeed = 100;
float angularSpeed = 100;
float maxLinearSpeed = 200;
float maxAngularSpeed = 200;
float minLinearSpeed = 30;
float minAngularSpeed = 30;void setup()
{//  要上电才能工作,不能只是插上 USB 线来调试。motor1.begin();motor2.begin();motor3.begin();motor4.begin();Serial.begin(57600);joypad.init(USB1_0);
}void loop()
{Serial.println("loop:");//setEachMotorSpeed(100, 50, 50, 100);if(!joypad.device_online){//  若一直输出离线状态,重新拔插 USB Host 的 RJ25 线试一下。Serial.println("Device offline.");joypad.probeDevice();delay(1000);}else{int len = joypad.host_recv();parseJoystick(joypad.RECV_BUFFER);delay(5);}//delay(500);
}void setEachMotorSpeed(float speed1, float speed2, float speed3, float speed4)
{motor1.runSpeed(speed1);motor2.runSpeed(-speed2);motor3.runSpeed(-speed3);motor4.runSpeed(-speed4);
}void parseJoystick(unsigned char *buf)   //Analytic function, print 8 bytes from USB Host
{//  输出手柄的数据,调试用// int i = 0;// for(i = 0; i < 7; i++)// {//     Serial.print(buf[i]);  //It won't work if you connect to the Makeblock Orion.//     Serial.print('-');// }// Serial.println(buf[7]);// delay(10);//  速度增减switch (buf[5]){case 1:linearSpeed += 5;if (linearSpeed > maxLinearSpeed){linearSpeed = maxLinearSpeed;}break;case 2:angularSpeed += 5;if (angularSpeed > maxAngularSpeed){angularSpeed = maxAngularSpeed;}break;case 4:linearSpeed -= 5;if (linearSpeed < minLinearSpeed){linearSpeed = minLinearSpeed;}break;case 8:angularSpeed -= 5;if (angularSpeed < minAngularSpeed){angularSpeed = minAngularSpeed;}break;default:break;}if ((128 != buf[0]) || (127 != buf[1]) || (128 != buf[2]) || (127 != buf[3])){//  处理摇杆float x = ((float)(buf[2]) - 127) / 128;float y = (127 - (float)(buf[3])) / 128;float a = (127 - (float)(buf[0])) / 128;mecanumRun(x * linearSpeed, y * linearSpeed, a * angularSpeed);}else{switch (buf[4]){case 0:mecanumRun(0, linearSpeed, 0);break;case 4:mecanumRun(0, -linearSpeed, 0);break;case 6:mecanumRun(-linearSpeed, 0, 0);break;case 2:mecanumRun(linearSpeed, 0, 0);break;case 7:mecanumRun(-linearSpeed/2, linearSpeed/2, 0);break;case 5:mecanumRun(-linearSpeed/2, -linearSpeed/2, 0);break;case 1:mecanumRun(linearSpeed/2, linearSpeed/2, 0);break;case 3:mecanumRun(linearSpeed/2,  -linearSpeed/2, 0);break;default:mecanumRun(0, 0, 0);break;}}
}void mecanumRun(float xSpeed, float ySpeed, float aSpeed)
{float speed1 = ySpeed - xSpeed + aSpeed; float speed2 = ySpeed + xSpeed - aSpeed;float speed3 = ySpeed - xSpeed - aSpeed;float speed4 = ySpeed + xSpeed + aSpeed;float max = speed1;if (max < speed2)   max = speed2;if (max < speed3)   max = speed3;if (max < speed4)   max = speed4;if (max > maxLinearSpeed){speed1 = speed1 / max * maxLinearSpeed;speed2 = speed2 / max * maxLinearSpeed;speed3 = speed3 / max * maxLinearSpeed;speed4 = speed4 / max * maxLinearSpeed;}setEachMotorSpeed(speed1, speed2, speed3, speed4);
}

移动机器人技术(8) 麦克纳姆轮全向移动机器人相关推荐

  1. 麦克纳姆轮全向移动机器人运动模型规律分析

    关注同名微信公众号"混沌无形",有趣好文! 原文链接:https://mp.weixin.qq.com/s/GWhlXsuY6QYyoZydaSYpjQ(包含原文PDF百度云下载链 ...

  2. 麦克纳姆轮全向移动机器人的特性

    关注同名微信公众号"混沌无形",有趣好文! 原文链接:https://mp.weixin.qq.com/s/GWhlXsuY6QYyoZydaSYpjQ(包含原文PDF百度云下载链 ...

  3. 麦克纳姆轮全向移动机器人运动效率分析

    关注同名微信公众号"混沌无形",有趣好文! 原文链接:https://mp.weixin.qq.com/s/GWhlXsuY6QYyoZydaSYpjQ(包含原文PDF百度云下载链 ...

  4. 麦克纳姆轮全向移动机器人速度空间分析

    关注同名微信公众号"混沌无形",有趣好文! 原文链接:https://mp.weixin.qq.com/s/GWhlXsuY6QYyoZydaSYpjQ(包含原文PDF百度云下载链 ...

  5. 麦克纳姆轮全向移动机器人运动学模型应用

    关注同名微信公众号"混沌无形",有趣好文! 原文链接:https://mp.weixin.qq.com/s/GWhlXsuY6QYyoZydaSYpjQ(包含原文PDF百度云下载链 ...

  6. 麦克纳姆轮全向移动机器人速度分解

    关注同名微信公众号"混沌无形",有趣好文! 原文链接:https://mp.weixin.qq.com/s/GWhlXsuY6QYyoZydaSYpjQ(包含原文PDF百度云下载链 ...

  7. 麦克纳姆轮全向移动机器人自旋转运动分析

    关注同名微信公众号"混沌无形",有趣好文! 原文链接:https://mp.weixin.qq.com/s/GWhlXsuY6QYyoZydaSYpjQ(包含原文PDF百度云下载链 ...

  8. 麦克纳姆轮全向移动机器人纵向直线运动分析

    关注同名微信公众号"混沌无形",有趣好文! 原文链接:https://mp.weixin.qq.com/s/GWhlXsuY6QYyoZydaSYpjQ(包含原文PDF百度云下载链 ...

  9. 麦克纳姆轮全向移动机器人横向直线运动分析

    关注同名微信公众号"混沌无形",有趣好文! 原文链接:https://mp.weixin.qq.com/s/GWhlXsuY6QYyoZydaSYpjQ(包含原文PDF百度云下载链 ...

最新文章

  1. C语言记录元音字母的位置,算法训练 确定元音字母位置
  2. android 时间差 秒_Android进阶之使用时间戳计算时间差
  3. palindromic java_Longest Palindromic Substring leetcode java
  4. 微信出拳:狠起来,连自己人都不放过!
  5. 使用openssh的登录的三种方法
  6. 力扣-1128 等价多米诺骨牌对的数量
  7. 阿里云VPC和企业网络互通配置
  8. M3U8下载,直播源下载,FLASH下载(二)-ffmpeg安装手册(linux)
  9. 网页内容变化监控提醒
  10. 2019年网络工程师考试大纲
  11. 如何政治正确地黑咪蒙?!
  12. 英语拼音怎么在计算机上拼出来的,英语拼音怎么写
  13. 网页动画的12原则,帮你做出漂亮的动画效果
  14. 无法和 SFTP 服务器建立 FTP 连接,请选择合适的协议。
  15. 一个屌丝程序猿的人生(七十九)
  16. APM32F103 RTC内部时钟源报警中断例程测试
  17. Hive Table 操作命令汇总
  18. 2020-11-23 PTA算法_贪心算法部分习题及代码
  19. MBA案例分析(人员培训五)
  20. 分享Node.js + Koa2 + MySQL + Vue.js 实战开发一套完整个人博客项目网站

热门文章

  1. git更新pull不下来代码_git pull更新错误解决办法
  2. 自学java的网站,怎样自学java
  3. 【项目实战】Python实现多元线性回归模型(statsmodels OLS算法)项目实战
  4. oracle 正数变负数
  5. openlayers地图旋转_Openlayers实现地图的基本操作
  6. 数学分析教程(科大)——3.1笔记+习题
  7. 远程实习的实习证明上会注明是远程实习么?
  8. Unity背景音乐控制
  9. struts2之token,类型转换和数据校验
  10. CentOS 7安装LMD杀毒软件