一文读懂麦克纳姆轮全向移动原理及剖析 |
您所在的位置:网站首页 › 为什么做4轮定位 › 一文读懂麦克纳姆轮全向移动原理及剖析 |
扣扣技术交流群:460189483
参考文章如下,计算过程小白可能看不懂,于是做进一步补充,写出该文 https://zhuanlan.zhihu.com/p/20282234?utm_source=qq&utm_medium=social
全向轮:
麦克纳姆轮:
全向轮与麦克纳姆轮的共同点在于他们都由两大部分组成:轮毂和辊子(roller)。轮毂是整个轮子的主体支架,辊子则是安装在轮毂上的鼓状物。全向轮的轮毂轴与辊子转轴相互垂直,而麦克纳姆轮的轮毂轴与辊子转轴呈 45° 角。理论上,这个夹角可以是任意值,根据不同的夹角可以制作出不同的轮子,但最常用的还是这两种。 全向轮与麦克纳姆轮(以下简称「麦轮」)在结构、力学特性、运动学特性上都有差异,其本质原因是轮毂轴与辊子转轴的角度不同。经过分析,二者的运动学和力学特性区别可以通过以下表格来体现。
计算过程如下,供参考,学霸可点开大图验算:
近年来,麦轮的应用逐渐增多,特别是在 Robocon、FRC 等机器人赛事上。这是因为麦克纳姆轮可以像传统轮子一样,安装在相互平行的轴上。而若想使用全向轮完成类似的功能,几个轮毂轴之间的角度就必须是 60°,90° 或 120° 等角度,这样的角度生产和制造起来比较麻烦。所以许多工业全向移动平台都是使用麦克纳姆轮而不是全向轮,比如这个国产的叉车: 全向移动平台 麦克纳姆轮叉车 美科斯叉车 另外一个原因,可能是麦轮的造型比全向轮要酷炫得多,看起来有一种不明觉厉的感觉…… 的确,第一次看到麦轮运转起来,不少人都会惊叹。以下视频直观地说明了麦轮底盘在平移和旋转时的轮子旋转方向。 麦克纳姆轮工作原理 【物理篇-力学专题】E03 S1小车为什么横着走?~滚动摩擦与麦克纳姆轮
【初中-物理】E08 速度解算?绕圆运动?麦克纳姆轮-进阶 麦轮的安装方法麦轮一般是四个一组使用,两个左旋轮,两个右旋轮。左旋轮和右旋轮呈手性对称,区别如下图。
安装方式有多种,主要分为:X-正方形(X-square)、X-长方形(X-rectangle)、O-正方形(O-square)、O-长方形(O-rectangle)。其中 X 和 O 表示的是与四个轮子地面接触的辊子所形成的图形;正方形与长方形指的是四个轮子与地面接触点所围成的形状。 以O-长方形的安装方式为例,四个轮子的着地点形成一个矩形。正运动学模型(forward kinematic model)将得到一系列公式,让我们可以通过四个轮子的速度,计算出底盘的运动状态;而逆运动学模型(inverse kinematic model)得到的公式则是可以根据底盘的运动状态解算出四个轮子的速度。需要注意的是,底盘的运动可以用三个独立变量来描述:X轴平动、Y轴平动、yaw 轴自转;而四个麦轮的速度也是由四个独立的电机提供的。所以四个麦轮的合理速度是存在某种约束关系的,逆运动学可以得到唯一解,而正运动学中不符合这个约束关系的方程将无解。 先试图构建逆运动学模型,由于麦轮底盘的数学模型比较复杂,我们在此分四步进行: ①将底盘的运动分解为三个独立变量来描述; ②根据第一步的结果,计算出每个轮子轴心位置的速度; ③根据第二步的结果,计算出每个轮子与地面接触的辊子的速度; ④根据第三部的结果,计算出轮子的真实转速。 一、底盘运动的分解 我们知道,刚体在平面内的运动可以分解为三个独立分量:X轴平动、Y轴平动、yaw 轴自转。如下图所示,底盘的运动也可以分解为三个量: 以上三个量一般都视为四个轮子的几何中心(矩形的对角线交点)的速度,也是底盘控制时设置的已知量
二、计算出轮子轴心位置的速度(以右上角轮子为例) 定义: 如下图所示: (手动绘制部分不喜勿喷,怕个别小白不理解,专门增加该部分讲解) 分别计算 几何中心X、Y 轴的分量为:
其中
同理可以算出其他三个轮子轴心的速度。 三、计算辊子的速度 根据轮子轴心的速度,可以分解出沿辊子方向的速度
向量几何知识了解参考 https://www.jianshu.com/p/6b37baa326ec
可以通过膜*单位方向向量实现,如下图所示,设X轴单位方向向量
所以最终求得沿辊子方向的速度数值大小 四、计算轮子的速度 从与地面接触的辊子速度到轮子线转速的计算比较简单:原因是辊子与轮子夹角是45°,
根据上面求出的 这样求出来的是轮子与地面接触的一点的线速度,如果要求轮子转速 根据上图定义,可知 由此计算获得四个轮子线速度如下 以上方程组就是O-长方形麦轮底盘的逆运动学模型,而正运动学模型可以直接根据逆运动学模型中的三个方程解出来,此处不再赘述。 另一种计算方式「传统」的推导过程虽然严谨,但还是比较繁琐的。这里介绍一种简单的逆运动学计算方式。 我们知道,全向移动底盘是一个纯线性系统,而刚体运动又可以线性分解为三个分量。那么只需要计算出麦轮底盘在「沿X轴平移」、「沿Y轴平移」、「绕几何中心自转」时,四个轮子的速度,就可以通过简单的加法,计算出这三种简单运动所合成的「平动+旋转」运动时所需要的四个轮子的转速。而这三种简单运动时,四个轮子的速度可以通过简单的测试,或是推动底盘观察现象得出。 当底盘沿着 X 轴平移时:
当底盘沿着 Y 轴平移时:
当底盘绕几何中心自转时: 将以上三个方程组相加,得到的恰好是根据「传统」方法计算出的结果。这种计算方式不仅适用于O-长方形的麦轮底盘,也适用于任何一种全向移动的机器人底盘。 Makeblock 麦轮底盘的组装理论分析完成,可以开始尝试将其付诸实践了。 第一步,组装矩形框架。 第二步,组装电机模块。 由于麦轮底盘的四个轮子速度有约束关系,必须精确地控制每个轮子的速度,否则将会导致辊子与地面发生滑动摩擦,不仅会让底盘运动异常,还会让麦轮的寿命减少。所以必须使用编码电机。
第三步,将电机模块安装到框架上。
第四步,将麦轮安装到框架上。
第五步,安装电路板并接线。 编码电机必须配上相应的驱动板才能正常工作。这里使用的 Makeblock 编码电机驱动板,每一块板可以驱动两个电机。接线顺序在下文中会提及,也可以随意接上,在代码中定义好对应的顺序即可。
第六步,装上电池。
至此,一个能独立运行的麦轮底盘就完成了。 控制程序 根据麦轮的底盘的运动学模型,要完全控制它的运动,需要有三个控制量:X轴速度、Y轴速度、自转角速度。要产生这三个控制量,有很多种方法,本文将使用一个 USB 游戏手柄,左边的摇杆产生平移速度,右边的摇杆产生角速度。 首先将一个 USB Host 模块连接到 Orion 主板的 3 口。 。
然后插上一个无线 USB 游戏手柄。
然后再添加其他细节,就大功告成啦!
其他细节: #include #include #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-128 MeEncoderMotor motor1(0x02, SLOT2); MeEncoderMotor motor2(0x02, SLOT1); MeEncoderMotor motor3(0x0A, SLOT2); MeEncoderMotor motor4(0x0A, SLOT1); // 底盘:a = 130mm, b = 120mm float 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); } Makeblock 麦克纳姆轮 全向移动机器人 PS:答疑 1. 这轮子这么灵活,为啥不都装成麦克纳姆轮呢,多方便啊 答:1. 如果上面的算法你掌握了,那么就明白所有的理论计算都是基于小车轮子在一个平面的,那么如果有悬挂的,或者地面不平坦的时候,很明显计算过程中的速度会有偏差,就会导致你的小车底盘跑的不准、不直,如果你因此计算里程计就更差了。2. 效率上不行,为啥呢?记得上面那个问题吗?棍子垂直方向的速度不考虑,为啥?因为这个速度主要用于棍子自转,对小车运行没有影响,那这就势必造成了能量浪费(相比普通轮子),所以效率就降低了 。3 .因为结构特性原因,不利于爬坡、越障,所以比较适合于平地使用,大大限制了应用场景 2. 程序中为啥有速度反向 因为电机运行方向的原因 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |