ROS(Robot Operating System,开源机器人操作系统)是目前较为火热的一个一个机器人开发者平台。依赖于强大的资源库和开发者社区,ROS可以说是风靡全球。
在机器人开发的领域,机械臂作为机器人的执行机构至关重要。同样在ROS的系统下面,Moveit和Gazebo对机械臂的开发有着强力的支持。接下来,我来阐述一下目前所设计的一款基于ROS Moveit的机械臂。
机械臂主体部分
Moveit仿真部分
rqt_graph通讯节点关系图
该机械臂是一款六自由度舵机驱动机械臂,各个关节可运动范围为0到180°,其中末端执行机构——机械爪可运动范围0-45°。六个关节使用MG996舵机(13Kg/CM)进行驱动,主控板使用Arduino Nano进行串口通讯控制。
驱动板PCB视图
驱动板实物图(换了个DC头)
机械臂的六个关节舵机分别接在Arduino的D3,D5,D6,D9,D10,D11六个具有PWM输出的IO口,D13预留的是其他数字型传感器接口,A0模拟口接了一个LM35温度传感器用于获得当前温度数值,CH预留的是A3模拟口,我们可以使用该口在ROS下实现一个类似示波器的Demo。串口也有留出,可以方便你连接一些无线模块,比如HC-05蓝牙模块。我所使用的无线模块如下。
无线串口收发模块
我们将该模块的一端插在驱动板,USB端插在电脑,即可进行无线通讯。默认通讯频率115200bps,8位数据位,1位停止位,无校验(8N1模式)。
机械臂的开发,我做了Windows下的上位机和Linux下的ROS功能包两部分,两套程序共用一套底层硬件程序——StandardFirmata。
Firmata是一个PC与MCU通讯的一个常用协议。其遵旨是能与任何主机PC软件包兼容。到目前为止,已经得到不少语言的支持,这样可方便地将对协议的支持加入软件系统中。Firmata起初是针对于PC与Arduino通讯的固件(Firmware),其目标是让开发者可以通过PC软件完全地控件Arduino。
我们打开Arduino IDE,在文件——示例——Firmata——StandardFirmata,该程序默认的波特率是57600,你可以进行修改。我使用了无线串口模块,所以波特率修改为115200。
StandardFirmata程序
在此按照需求修改波特率
至此,我们的底层代码设计到此结束,接下来的就是我们在ROS部分的开发。
我们在ROS下面玩机械臂需要些什么呢?很简单,模型和驱动。
ROS工作空间下的功能包
arm_driver是我们的一个驱动包,主要是把每个关节的角度值给机械臂执行;marm_description是古月老师在《ROS机械臂开发从入门到实战》课程里面提供的一个URDF模型,这个模型和机械臂很相似,可以直接使用;marm_moveit_config是Moveit配置生成的一个功能包。整套机械臂的开发,除了驱动文件是个人开发之外,模型功能包和Moveit功能包都是依靠古月老师的指导才能完工,在此感谢古月老师。
marm_description功能包目录
古月老师的模型文件是xacro的模型,有兴趣的同学可以自己下载研究一下,我主要给大家阐述下launch启动文件、CmakeList.txt和package.xml
首先是我们的launch启动文件,内容如下。
launch启动文件内容
古月老师的注释写的很详细,大家可以看到这个launch文件内容,依次顺序分别为加载机器人模型、显示关节控制插件、发布机器人关节状态、发布tf坐标系、启动RVIZ可视化界面。我们在终端执行roslaunch marm_description view_marm.launch启动代码。
marm_decription功能包下的view_marm.launch启动效果
可以看到,机械臂模型、关节控制插件、可视化界面都有了,那么机器人关节状态和tf这两个呢?先不要急,我们运行rostopic list查看下当前的话题都有哪些。
在view_marm.launch启动下的topic情况
可以看到,机器人关节状态话题joint_state和tf两个话题。欧克,接下来我们来看下rqt节点关系图是怎么样的,在终端下输入rqt_graph。
view_marm.launch运行下的节点关系图
可以看到,joint_state_publisher发布了一个joint_states的话题,被robot_state_publisher订阅到。然后robot_state_publisher发布了一个tf的话题,被rviz订阅到。那么joint_state和tf的内容是什么呢?我们现在来echo一下。在终端输入rostopic echo /joint_state,效果如下。
view_marm.launch运行下的joint_state内容
我这里给显示了两个数据,大家可以看一下。大家的重点要在name(名字)position(位置)两个参数。我们通常使用0-360°来表示角度,在ROS下面,使用则是圆周来表示角度,范围-3.14到3.14(对应0到180°)。那么此时的0.0则对应的就是180°,到这里为止,我们的在仿真的过程中的角度值也就由此得到。
那么在驱动文件下,我们就可以写一个代码,来订阅这个joint_state来获得角度,然后把这个角度数值传递给我们的Arduino,由此来控制舵机,从而实现控制机械臂。
接下来,我们来建立arm_driver功能包,目录如下。
arm_driver功能包目录
launch依旧是我们的启动文件,这个内容稍后再说;msg是消息,里面有一个我自己写的角度消息(当时不知道joint_state,自己傻傻的写了一个哈哈,没用,不要理);重点就是我们的script文件,joint_state_publisher.py是我做的测试文件,有兴趣的可以看一下(代码写的超级烂)。
driver.py是我订阅joint_state话题并向Arduino驱动舵机的功能包,内容如下。
功能包下的driver.py代码
rospy是Python和ROS通讯的接口,我们需要订阅的joint_state话题是在sensor_msgs功能包下,这里我们需要导入一下,我们的硬件通讯协议使用的是Firmata协议,Python对于Firmata有着很好的支持,这里可以直接导入。
然后就是声明我们的机械臂了,这里需要串口号和波特率。注意一下,我们需要给串口号最高权限才可以启动。(sudo chmod +777 串口号)。
callback()是回调函数,我们一会来聊。现在主要看driver()函数的内容,可以看到,我们先先初始化了一个节点,叫做Arm_Driver;然后订阅joint_state,数据格式是JointState,对应的执行函数是callback;最后就是spin。
现在来说下回调函数的概念,我们的driver.py是作为订阅者、接收者的方式来获得角度值,属于是被动处理,在我订阅到joint_state消息的时候,driver这里需要做出一个被动执行。所以在订阅收到joint_state消息的时候,我们就去调用callback()函数的内容,去做出对应的执行。
现在我们来看下callback()函数的内容,里面你的内容是六组重复的,对应的分别是Joint1到Joint6六个关节点。我们通过data.position[下标]获得对应关节的数值。没错,我们的虚拟和现实的联动就这样实现了!!!
值得注意的是joint_state的position角度数值是-3.14到3.14,为了适应我的舵机,我给做了一个计算处理,这个计算大家可以自己算一下,在这里我买个关子不做解释(可以遐想到减速比、减速带类机械臂开发)。
通过调用Firmata的函数servo_config()实现控制舵机。关于Python Firmata的内容,我会有专门的文档来介绍这一内容。对了,记得考虑自己的现实情况,给做个角度限位,别把舵机烧了哈哈哈。我的爪子位置只能转到45°,超过45°铁定烧舵机。
到这里,我们的RVIZ仿真和物理机械臂的联动介绍到此结束。关于Moveit的内容还在测试中,敬请期待!
2020-09-19 11:38:23举报