最近在知乎上看到一个问题:在ROS环境下,怎么使用moveit!来驱动真实的六轴机械臂?
很多小伙伴在使用ROS的时候,都会产生类似的疑问,程序写过那么多,仿真也跑过不少,但是如何控制真实机械臂/机器人呢?
今天古月君就来尝试破个题。
首先,解决这个问题的关键词是“接口”。所谓接口,即数据传输的通道,如何将ROS功能包计算得到的数据发给真实机器人并使之运动是问题的关键。
机械臂有点复杂,我们先以简单一些的ROS小车为例,看看ROS是如何让真实小车动起来的。
大家在某宝上搜索“ROS移动机器人”,会出现一系列的小车,看来看去,无非都是类似下图的零部件组成的:
做个分类,大家应该会更清晰一些:
这就是从控制角度看到的机器人四大组成部分,ROS并不是机器人的全部,主要运行于控制系统当中。
以小车的导航为例,从复杂的算法到小车的运动具体经过了哪些步骤呢?
1.使用者在rviz中使用鼠标选择一个导航目标点
2.全局规划器开始路径规划,得到一条从A到B的最优路径
3.本地规划器开始计算机器人每个周期的最佳速度,尽量靠近最优路径并躲避动态障碍物
OK,划重点啦,此时以上还都是ROS功能包完成的工作,我们进一步简化以上步骤,所有功能看成黑盒,输入是目标位置,输出是周期速度,这个周期速度就是“接口”。
接下来我们要做的事情就是让小车的硬件匹配这个周期速度的接口,怎么匹配呢?
小车的运动最后由电机执行,电机要转起来就需要一个电压信号,要产生电压信号就需要将控制信号(PWM)放大,要产生控制信号就需要有一个微控制器(MCU),微控制器的输入指令哪里来,一条电缆(网线或串口线)连接PC和MCU,接口就连上了。
当然,接口连上只是“肉体连接”,要做到“精神连接”还需要完成控制器里的驱动控制,也就是我们常说的PID闭环控制。
至此,我们成功的让小车动起来了,总结一下,我们怎么让小车动起来的:
1.ROS功能包跑起来
2.控制数据传输给小车的控制器
3.控制器里完成底层控制
4.控制信号变成电信号,电机转起来
似乎有点偏题,我们回到机械臂的场景,原理依然是上边的四个步骤,根据不同的硬件条件,并不是每个步骤都需要我们自己来实现。
在ROS环境下,不管是移动小车的move_base,还是机械臂的MoveIt!,都是解决第一个步骤的功能算法问题。ROS最大的好处就是:我们可以先不关注功能算法的内部实现,通过接口的拼接快速实现系统的原型。所以这里我们需要关注的一个问题是MoveIt!的输入输出接口是什么?
在下边这张图中,我们可以看到MoveIt!核心节点的接口:
输入:编程API(C++、Python)、GUI(Rviz中的Motion Planning)
输出:关节轨迹(Trajectory)
先不纠结MoveIt!里边干了啥,反正当我们通过程序或者界面指定一个目标位置后,它会规划得到一条运动到目标位置的轨迹,这条轨迹由一系列关节空间的位置组成。
和ROS小车一样,接下来,我们要把这条轨迹发给机械臂的控制器,如果你使用的是类似UR、ABB这种工业机械臂的话,控制器都是配套的,只需要在示教器上做一些TCP端口的配置,就可以接收轨迹数据了,后续的底层控制算法和电机驱动就不需要我们关心了,完善的控制器都会帮我们实现。
换一个场景,如果是我们自己做机械臂,控制器需要自己开发,又该如何做呢?
还是上边ROS小车的思路,机械臂控制器里也需要实现这些基础功能:
1.接收控制数据(运动轨迹)
2.完成底层运动控制
3.控制信号变成电信号,电机转起来
不管你用的控制器是MCU、树莓派还是PC,总会有和外界通信的方法,比如常见的串口、网络等,所以第一个接收控制数据的方法就是通过任一媒介,将轨迹数据发送到控制器上,具体实现可以参考ros_serial、ROS-I Simple Message功能包或串口、 socket通信的编程方法。
收到数据之后呢?MoveIt!规划得到的关节轨迹由一系列轨迹点组成,每两个点之间的时间间隔不定,基本是0.1~1秒之间,这个时间间隔对于底层控制来讲,是非常大的,很容易造成轨迹运动不圆滑、速度不均匀的现象,需要进一步细分到和控制周期匹配的间隔,也就是你可能常听说的“轨迹插补”,具体实现可以参考ros_control。
比如初始轨迹的运动总时间是5s,按照10ms插补,那么我们将得到一条由500个点组成的轨迹,每个点包含此刻各关节的位置信息。
接下来就是把这些位置信息变成电信号,让电机转动带动机械臂运动,这就是我们常说的电机驱动。如果你用的是步进电机,你可能需要一个可以接收脉冲位置的步进驱动器,如果你用的是伺服电机,可能需要一个可以接收位置指令的伺服驱动器,如果你使用的是舵机,直接发送位置指令即可,如果你要自己做驱动器,请Google“如何实现电机驱动器”。
按照周期依次完成所有点后,轨迹运动完成,真实机械臂就按照MoveIt!的规划完成运动了。
古月君洋洋洒洒写了这么多,你可能已经从入门到放弃了。。。
好吧,忽略上边的所有内容,直接看图:
ROS MoveIt!控制真实机械臂的一般框架:
1.通过程序或界面设置机械臂运动目标
2.MoveIt!完成运动规划并输出关节轨迹
3.通过socket接口和控制器连接,将关节轨迹发送给控制器
4.控制器进行插补运算,并周期发送给电机驱动器
5.驱动器完成闭环控制,让电机多、快、好、爽的跟随输入指令
6.控制器反馈实时状态到MoveIt!,Rviz动态显示当前状态
以上内容古月君偏向于系统原理的介绍,具体实现的手段和硬件相关,各位还需要在原理的基础上完成开发。愿大家都拥有一段美好的机器人开发之旅~