失败的格斗机器人-万向轮系统运动控制

        全向移动的机器有几个很有名的机器, 一个是这次参赛的蓝调(好好期待哦), 一个是国外的Alchoholic stepfather, 可能拼错了别介意。 这个stepfather可是曾经战胜过墓碑的机器, 很荣耀的一战。
常用的全向移动的方式有三种:

1, 三个万向轮, 120度角排布。 我的烈焰双星就是这样排布的。
 
2. 四个万向轮, 十字排布, 老船长就是这么设计的。
 
3. 四个麦克纳姆轮, 蓝调和stepfather都是这种。
 
斜对角的从动滚轮最好平行, 否则会降低效率。

优略来说的话, 万向轮的移动更平滑, 更顺,但是容易被推动。 比如我的机器, 即便通上了电, 蹬一脚, 就和滑板一样窜出去了。 相比万向轮, 麦克纳姆轮就不会这样, 与对手角力时不会太吃亏。
承重来说的话, 万向轮同等承重的轮子比麦克纳姆轮要贵些, 这在大重量级里面就会很吃亏了。 要是再给我一次机会, 我应该会选麦轮。 除了这个优点之外, 麦轮的结构相对更好设计, 可以设计的更加紧凑, 框架化。

对于很多玩模型的朋友, 如何控制这种轮子呢? 这就成了个难题, 像三个轮子的更是别说, 单一个遥控器想调混控达到控制效果真是很困难的。 我的做法是, 在接收机和电机信号之间加一层解算, 就能够达到想要的效果。 如何解算呢? 对于三轮的万向轮, 有:
 
右边变量为纵向速度, 横向速度, 自转速度, 左边为对应三个轮子分别速度。 利用这个公式, 就能解算出来了。 可以参考以下代码。

float get_wheel_speed1(float vx, float vy, float w) {
return vx * 0.8660 + vy * 0.5 + w * 0.15;
}

float get_wheel_speed2(float vx, float vy, float w) {
return -vx * 0.8660 + vy * 0.5 + w * 0.15;
}

float get_wheel_speed3(float vx, float vy, float w) {
return 0 + vy * -1 + w * 0.15;
}

int desire_speed = 80;
int desire_speed_y = 0;
void control() {
static long int distance_motor1 = 0;
int desire_speed1, desire_speed2, desire_speed3;
int x_speed, y_speed, w;
static float t = 0;
t = t+0.2;
desire_speed = 40*sin(t);
desire_speed_y = 40*cos(t);
distance_motor1 = distance_motor1 + counter1;
w = 10*(0-theta);
desire_speed1 = get_wheel_speed1(desire_speed, desire_speed_y, 0);
desire_speed2 = get_wheel_speed2(desire_speed, desire_speed_y, 0);
desire_speed3 = get_wheel_speed3(desire_speed, desire_speed_y, 0);run_motor1(speed_loop1(desire_speed1, counter1, 1, 0.9));
run_motor2(speed_loop2(desire_speed2, counter2, 1, 0.9));
run_motor3(speed_loop3(desire_speed3, counter3, 1, 0.9));

// Serial.print( );
//Serial.print(‘ ‘);
//if(Serial2.available()){
// Serial.println(Serial2.read());
// }
// Serial.println(counter1);

// Serial.print(counter2);
// Serial.print(‘ ‘);
// Serial.println(counter3);
// Serial.println (theta);
counter1 = 0;
counter2 = 0;
counter3 = 0;

}

对于四轮的万向轮, 其实调整混控即可。

对于麦克纳姆轮也一样, 混控即可完成控制要求。

万向轮其实也很难走直线, 所以辅助控制很有必要!

所以千万别以为装了万向轮就很溜, 其实不是的, 要面临这些问题, 如何解决?

2. 陀螺仪偏航修正
陀螺仪是什么, gyroscope? 这里面的门道可就多了, 说也说不完, 简单来说, 就是能够监测角速度的传感器。 角速度是什么概念, 转动起来了才有速度, 有速度就能监测出来, 不动的时候当然是没有速度的了。

陀螺仪偏航矫正的实现方式有两个, 1. 买个这种模块。 但是问题在于: 反过来以后就会疯狂旋转, 以及如果打偏了, 也会疯狂旋转。
 
除了购买这种产品, 也可以自己加装传感器编程实现, 避免已上问题那么具体是怎么做的呢? 如果不是要做个商业通用混控产品的话, 为自己的机器加装陀螺仪控制其实并不难, 而且成本只增加个100元不到。 当然, 前提是使用可编程的混控, 否则用遥控器接收机是没法直接做到这一点的。下面来展示实现方式:

readGyroScaled(gx, gy, gz);

gz = gz-0.525;
z = z+gz*0.03;
z就是角度, gz就是陀螺仪获取的偏航的角速度。  就这样? 就这样! 当然需要做一些滤波什么的处理, 这个就因传感器而异了。 理论上说, 角速度要获得角度很容易, 积分就可以了。 第二行为什么要减掉一个常数呢? 这是一个校准的偏值, 减去以后, 角度偏移会变得更慢。
这就是获得的角度, 来回扭一扭看到了正确的趋势, 这就可以控制了。 代码如下:
w = 10*(0-z) - 5*gz;
desire_speed1 = get_wheel_speed1(desire_speed, desire_speed_y, w);
desire_speed2 = get_wheel_speed2(desire_speed, desire_speed_y, w);
desire_speed3 = get_wheel_speed3(desire_speed, desire_speed_y, w);
run_motor1(speed_loop1(desire_speed1, counter1, 1, 0.9));
run_motor2(speed_loop2(desire_speed2, counter2, 1, 0.9));
run_motor3(speed_loop3(desire_speed3, counter3, 1, 0.9));
w是我们的期望偏航角速度, 走歪了当然想让头转回来了, 因此我们控制器的输出当然是角速度。 第一行w的计算就是一个pd控制器, 参数可以根据需求调教。 而第2-4行就是将w代入到混控算法里, 第5到最后行就是将期待轮速赋值给底层的电机调速接口, 由底层调速程序去控制电机的转速。
这是我的一个小模型角度反馈控制的效果。 大机器同样适用:
正是因为有了这项陀螺仪反馈的辅助控制, 我们的机器才能逃命打满3分钟啊。

 

2
说点什么

avatar
1 Comment threads
1 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
2 Comment authors
root郑舟恒 Recent comment authors
  Subscribe  
最新 最旧 得票最多
提醒
郑舟恒
游客
郑舟恒

所以叫疾风就是因为跑的快嘛。。。。

error: Content is protected !!