赞
踩
运动特性为两轮差速驱动,其底部后方两个同构驱动轮的转动为其提供动力,前方的随动轮起支撑作用并不推动其运动,如图两轮差速驱动示意图所示。
定义其左右驱动轮的中心分别为
W
l
W_l
Wl和
W
r
W_r
Wr,且车体坐标系中这两点在惯性坐标系下移动的线速度为
v
l
v_l
vl和
v
r
v_r
vr ,理想情况下即为左右轮转动时做圆周运动的线速度。该值可以通过电机驱动接口输出的角转速
ϕ
l
\phi_l
ϕl 、
ϕ
r
\phi_r
ϕr和驱动轮半径
r
r
r求得,即:
v
l
=
r
⋅
ϕ
l
v_l = r \cdot \phi_l
vl=r⋅ϕl
令两驱动轮中心连线的中点为机器的基点
C
C
C,
C
C
C 点在大地坐标系
X
O
Y
XOY
XOY 下坐标为
(
x
,
y
)
(x,y)
(x,y),机器的瞬时线速度为
v
c
v_c
vc ,瞬时角速度
ω
c
\omega_c
ωc ,姿态角
θ
\theta
θ 即为
v
c
v_c
vc
与X 轴夹角。此时,机器位姿信息可用矢量
P
=
[
x
,
y
,
θ
]
T
P=[x,y,\theta]^T
P=[x,y,θ]T 表示。机器人瞬时线速度为
v
c
v_c
vc可以表示为:
v
c
=
v
r
+
v
l
2
v_c = \frac{v_r + v_l}{2}
vc=2vr+vl
令左右轮间距为
l
l
l,且机器瞬时旋转中心(ICR)为
O
c
O_c
Oc,转动半径即为
C
C
C到
O
c
O_c
Oc的距离
R
R
R。机器在做同轴(轴为左右轮到ICR连线)圆周(圆心为ICR)运动时,左右轮及基点所处位置在该圆周运动中的角速度相同
ω
l
=
ω
r
=
ω
c
\omega_l=\omega_r=\omega_c
ωl=ωr=ωc,到旋转中心的半径不同,有
l
=
v
r
ω
r
−
v
l
ω
l
l=\frac{v_r}{\omega_r}-\frac{v_l}{\omega_l}
l=ωrvr−ωlvl。则机器的瞬时角速度
ω
c
\omega_c
ωc可以表示为:
ω
c
=
v
r
−
v
l
l
\omega_c = \frac{v_r - v_l}{l}
ωc=lvr−vl
联立两式,利用
v
r
v_r
vr和
v
l
v_l
vl求出机器转动半径:
R
=
v
c
ω
c
=
l
2
⋅
v
r
+
v
l
v
r
−
v
l
R = \frac{v_c}{\omega_c} = \frac{l}{2} \cdot \frac{v_r + v_l}{v_r - v_l}
R=ωcvc=2l⋅vr−vlvr+vl
差速驱动方式,即 V 1 V_1 V1和 V 2 V_2 V2间存在的速度差关系决定了其具备不同的三种运动状态,如图:
通过上述两节的运动分析,在驱动轮与地面接触运动为纯滚动无滑动情况下,机器的运动学模型可以表示为:
[
x
˙
y
˙
θ
˙
]
=
[
v
x
v
y
ω
]
=
[
v
⋅
c
o
s
θ
v
⋅
s
i
n
θ
ω
]
=
[
v
r
+
v
l
2
⋅
c
o
s
θ
v
r
+
v
l
2
⋅
s
i
n
θ
v
r
−
v
l
L
]
=
[
c
o
s
θ
2
c
o
s
θ
2
s
i
n
θ
2
s
i
n
θ
2
1
L
−
1
L
]
=
[
c
o
s
θ
0
s
i
n
θ
0
0
1
]
[
1
2
1
2
1
L
−
1
L
]
[
v
r
v
l
]
双轮差速移动机器人直观的控制量是上述建模中所述的左右轮转速,为了更一般的描述机器人的运动以及与ROS(Robot Operation System,机器人操作系统)的对接,控制量选机器人线速度 v c v_c vc与角速度 ω c \omega_c ωc,左右轮转速可由模型反求取。
方法一
根据机器人的线速度 v c v_c vc 和角速度 ω c \omega_c ωc,以及公式 v = ω ∗ r v=\omega*r v=ω∗r 可计算出机器人的实时转弯半径 r c r_c rc(即 O c C O_cC OcC):
r c = v c w c r_c = \frac{v_c}{w_c} rc=wcvc
已知机器人左右轮
W
1
W
2
W_1W_2
W1W2 距离
L
L
L,
W
1
W_1
W1
W
2
W_2
W2 与
C
C
C 同轴,所以左右轮以
O
c
O_c
Oc为旋转中心的旋转角速度
ω
l
=
ω
r
=
ω
c
\omega_l=\omega_r=\omega_c
ωl=ωr=ωc,可计算两轮线速度:(注意:以各自的轮子中心为旋转中心的旋转速度在此称为转速)
v
l
=
ω
l
∗
r
l
=
ω
c
∗
(
r
c
−
L
2
)
=
v
c
−
L
2
∗
ω
c
v
r
=
ω
r
∗
r
r
=
ω
c
∗
(
r
c
+
L
2
)
=
v
c
+
L
2
∗
ω
c
v_l = \omega_l * r_l = \omega_c*(r_c-\frac{L}{2}) = v_c - \frac{L}{2}*\omega_c \\ v_r = \omega_r * r_r = \omega_c*(r_c+\frac{L}{2}) = v_c + \frac{L}{2}*\omega_c
vl=ωl∗rl=ωc∗(rc−2L)=vc−2L∗ωcvr=ωr∗rr=ωc∗(rc+2L)=vc+2L∗ωc
已知轮子半径是
r
r
r,计算控制量左右轮转速:
ϕ
l
=
v
l
r
=
1
r
∗
(
v
c
−
L
2
∗
ω
c
)
ϕ
r
=
v
r
r
=
1
r
∗
(
v
c
+
L
2
∗
ω
c
)
\phi_l = \frac{v_l}{r} = \frac{1}{r}*(v_c - \frac{L}{2}*\omega_c) \\ \phi_r = \frac{v_r}{r} = \frac{1}{r}*(v_c + \frac{L}{2}*\omega_c)
ϕl=rvl=r1∗(vc−2L∗ωc)ϕr=rvr=r1∗(vc+2L∗ωc)
方法二
根据第一部分中推导的两个公式直接联立
v c = v l + v r 2 ω c = v r − v l L v_c = \frac{v_l + v_r}{2} \\ \omega_c = \frac{v_r - v_l}{L} vc=2vl+vrωc=Lvr−vl
计算左右轮速度以及转速
v
l
=
v
c
−
L
2
∗
ω
c
v
r
=
v
c
+
L
2
∗
ω
c
ϕ
l
=
v
l
r
=
1
r
∗
(
v
c
−
L
2
∗
ω
c
)
ϕ
r
=
v
r
r
=
1
r
∗
(
v
c
+
L
2
∗
ω
c
)
v_l = v_c - \frac{L}{2}*\omega_c \\ v_r = v_c + \frac{L}{2}*\omega_c \\ \phi_l = \frac{v_l}{r} = \frac{1}{r}*(v_c - \frac{L}{2}*\omega_c) \\ \phi_r = \frac{v_r}{r} = \frac{1}{r}*(v_c + \frac{L}{2}*\omega_c)
vl=vc−2L∗ωcvr=vc+2L∗ωcϕl=rvl=r1∗(vc−2L∗ωc)ϕr=rvr=r1∗(vc+2L∗ωc)
两种方法都是一个结果的,至于计算左右轮速度时是 v c − L 2 ∗ ω c v_c-\frac{L}{2}*\omega_c vc−2L∗ωc 还 是 v c + L 2 ∗ ω c v_c+\frac{L}{2}*\omega_c vc+2L∗ωc ,这与机器人坐标系的定义以及角速度矢量的定义有关,逆时针为正,顺时针为负。
此部分搭建了基于ROS的CoppeliaSim仿真环境,环境搭建可参考我的博客,在环境中实现了ROS端发布 geometry_msgs/Twist
类型的话题 /cmd_vel
,CoppeliaSim端订阅此话题,控制电机转动从而控制机器人的移动。Twist.msg
中包括机器人控制量线速度linear.x
和角速度angular.z
。
#Twist.msg
# This expresses velocity in free space broken into its linear and angular parts.
Vector3 linear
Vector3 angular
---
# Vector3.msg
# This represents a vector in free space.
# It is only meant to represent a direction. Therefore, it does not
# make sense to apply a translation to it (e.g., when applying a
# generic rigid transformation to a Vector3, tf2 will only apply the
# rotation). If you want your data to be translatable too, use the
# geometry_msgs/Point message instead.
float64 x
float64 y
float64 z
场景下载链接:controlledViaRos.ttt 提取码: c96d
function sysCall_init()
leftMotor=sim.getObjectHandle("rosInterfaceControlledBubbleRobLeftMotor") -- Handle of the left motor
rightMotor=sim.getObjectHandle("rosInterfaceControlledBubbleRobRightMotor") -- Handle of the right motor
-- Launch the ROS client application:
if simROS then
sim.addLog(sim.verbosity_scriptinfos,"ROS interface was found.")
cmdVelSub = simROS.subscribe('/cmd_vel','geometry_msgs/Twist','cmd_vel_callback')
else
sim.addLog(sim.verbosity_scripterrors,"ROS interface was not found. Cannot run.")
end
end
function cmd_vel_callback(msg)
-- This is the sub_velocity callback function
local L = 0.2 -- wheel_tread
local r = 0.04 -- wheel_radius
phi_l = (1.0/r)*(msg.linear.x - L/2.0*msg.angular.z)
phi_r = (1.0/r)*(msg.linear.x + L/2.0*msg.angular.z)
sim.setJointTargetVelocity(leftMotor, phi_l)
sim.setJointTargetVelocity(rightMotor,phi_r)
end
function sysCall_cleanup()
if simROS then
simROS.shutdownSubscriber(cmdVelSub)
end
end
发布话题
rostopic pub /cmd_vel geometry_msgs/Twist "linear:
x: 0.2
y: 0.0
z: 0.0
angular:
x: 0.0
y: 0.0
z: 1.0" -r 15
效果图:
部分参考 两轮差速移动机器人运动分析、建模和控制
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。