四轮全向轮底盘运动学推导
符号定义
X ˙ \dot{X} X˙:底盘绝对坐标系下X方向速度
Y ˙ \dot{Y} Y˙:底盘绝对坐标系下Y方向速度
u u u:底盘在自身坐标系下x方向运动速度
v v v:底盘在自身坐标系下y方向运动速度
θ \theta θ:底盘自身坐标系x轴与绝对坐标系X轴的夹角
ω \omega ω:自转角速度
L L L:轮子到中心的距离
v 1 v_1 v1 ~ v 4 v_4 v4:四个轮子的速度
公式推导
V ⃗ = u ⃗ + v ⃗ = X ˙ ⃗ + Y ˙ ⃗ \vec{V}=\vec{u}+\vec{v}=\vec{\dot{X}}+\vec{\dot{Y}} V=u+v=X˙+Y˙
{ X ˙ cos θ + Y ˙ sin θ = u Y ˙ cos θ − X ˙ sin θ = v θ ˙ = ω \left\{\begin{array}{c} \dot{X} \cos \theta+\dot{Y} \sin \theta=u \\ \dot{Y} \cos \theta-\dot{X} \sin \theta=v \\ \dot{\theta}=\omega \end{array}\right. ⎩ ⎨ ⎧X˙cosθ+Y˙sinθ=uY˙cosθ−X˙sinθ=vθ˙=ω
[ u v ω ] = [ cos θ sin θ 0 − sin θ cos θ 0 0 0 1 ] [ X ˙ Y ˙ θ ˙ ] \left[\begin{array}{l} \mathrm{u} \\ \mathrm{v} \\ \omega \end{array}\right]=\left[\begin{array}{ccc} \cos \theta & \sin \theta & 0 \\ -\sin \theta & \cos \theta & 0 \\ 0 & 0 & 1 \end{array}\right]\left[\begin{array}{c} \dot{X} \\ \dot{Y} \\ \dot{\theta} \end{array}\right] uvω = cosθ−sinθ0sinθcosθ0001 X˙Y˙θ˙
{ v 1 = 2 2 v − 2 2 u + ω L v 2 = − 2 2 v − 2 2 u + ω L v 3 = − 2 2 v + 2 2 u + ω L v 4 = 2 2 v + 2 2 u + ω L \left\{\begin{array}{l} v_1=\frac{\sqrt{2}}{2} v-\frac{\sqrt{2}}{2} u+\omega L \\ v_2=-\frac{\sqrt{2}}{2} v-\frac{\sqrt{2}}{2} u+\omega L \\ v_3=-\frac{\sqrt{2}}{2} v+\frac{\sqrt{2}}{2} u+\omega L \\ v_4=\frac{\sqrt{2}}{2} v+\frac{\sqrt{2}}{2} u+\omega L \end{array}\right. ⎩ ⎨ ⎧v1=22v−22u+ωLv2=−22v−22u+ωLv3=−22v+22u+ωLv4=22v+22u+ωL
[ v 1 v 2 v 3 v 4 ] = [ − 2 2 2 2 L − 2 2 − 2 2 L 2 2 − 2 2 L 2 2 2 2 L ] [ u v ω ] \left[\begin{array}{l} \mathrm{v}_1 \\ \mathrm{v}_2 \\ \mathrm{v}_3 \\ \mathrm{v}_4 \end{array}\right]=\left[\begin{array}{ccc} -\frac{\sqrt{2}}{2} & \frac{\sqrt{2}}{2} & L \\ -\frac{\sqrt{2}}{2} & -\frac{\sqrt{2}}{2} & L \\ \frac{\sqrt{2}}{2} & -\frac{\sqrt{2}}{2} & L \\ \frac{\sqrt{2}}{2} & \frac{\sqrt{2}}{2} & L \end{array}\right]\left[\begin{array}{l} u \\ v \\ \omega \end{array}\right] v1v2v3v4 = −22−22222222−22−2222LLLL uvω
= 2 2 [ − 1 1 L − 1 − 1 L 1 − 1 L 1 1 L ] [ u v ω ] =\frac{\sqrt{2}}{2}\left[\begin{array}{ccc} -1 & 1 & L \\ -1 & -1 & L \\ 1 & -1 & L \\ 1 & 1 & L \end{array}\right]\left[\begin{array}{l} u \\ v \\ \omega \end{array}\right] =22 −1−1111−1−11LLLL uvω
= 2 2 [ − 1 1 L − 1 − 1 L 1 − 1 L 1 1 L ] [ cos θ sin θ 0 − sin θ cos θ 0 0 0 1 ] [ X ˙ Y ˙ θ ˙ ] =\frac{\sqrt{2}}{2}\left[\begin{array}{ccc} -1 & 1 & L \\ -1 & -1 & L \\ 1 & -1 & L \\ 1 & 1 & L \end{array}\right]\left[\begin{array}{ccc} \cos \theta & \sin \theta & 0 \\ -\sin \theta & \cos \theta & 0 \\ 0 & 0 & 1 \end{array}\right]\left[\begin{array}{c} \dot{X} \\ \dot{Y} \\ \dot{\theta} \end{array}\right] =22 −1−1111−1−11LLLL cosθ−sinθ0sinθcosθ0001 X˙Y˙θ˙
= 2 2 [ − cos θ − sin θ − sin θ + cos θ L − cos θ + sin θ − sin θ − cos θ L cos θ + sin θ sin θ − cos θ L − cos θ − sin θ sin θ + cos θ L ] [ X ˙ Y ˙ θ ˙ ] =\frac{\sqrt{2}}{2}\left[\begin{array}{ccc} -\cos \theta-\sin \theta & -\sin \theta+\cos \theta & L \\ -\cos \theta+\sin \theta & -\sin \theta-\cos \theta & L \\ \cos \theta+\sin \theta & \sin \theta-\cos \theta & L \\ -\cos \theta-\sin \theta & \sin \theta+\cos \theta & L \end{array}\right]\left[\begin{array}{c} \dot{X} \\ \dot{Y} \\ \dot{\theta} \end{array}\right] =22 −cosθ−sinθ−cosθ+sinθcosθ+sinθ−cosθ−sinθ−sinθ+cosθ−sinθ−cosθsinθ−cosθsinθ+cosθLLLL X˙Y˙θ˙
参考程序
void chassis_move(float target_speed, float target_dir, float target_omega)
{
/********直接计算方法********/
float speed_cal[4];
float sin_ang = sin(chassis.angle);
float cos_ang = cos(chassis.angle);
float speed_X = target_speed * cos(target_dir);
float speed_Y = target_speed * sin(target_dir);
speed_cal[0] = ((-cos_ang - sin_ang) * speed_X + (-sin_ang + cos_ang) * speed_Y + chassis.Radius * target_omega) / sqrt(2);
speed_cal[1] = ((-cos_ang + sin_ang) * speed_X + (-sin_ang - cos_ang) * speed_Y + chassis.Radius * target_omega) / sqrt(2);
speed_cal[2] = ((cos_ang + sin_ang) * speed_X + (sin_ang - cos_ang) * speed_Y + chassis.Radius * target_omega) / sqrt(2);
speed_cal[3] = ((cos_ang - sin_ang) * speed_X + (sin_ang + cos_ang) * speed_Y + chassis.Radius * target_omega) / sqrt(2);
int speed_out[4] = {0, 0, 0, 0};
for (int i = 0; i < 4; i++)
{
speed_out[i] = (int)speed_cal[i];
}
chassis.SetMotorSpeed(speed_out);
}