本文从零开始介绍如何使用ROS来操控真实的机械臂,其中包括创建机械臂的xacro模型,为机械臂创建仿真环境以及路径规划环境,使用了包括rviz,gazebo的使用。在ROS上订阅关节数据节点来操控真实的机械臂。本文在文末有完整的开源代码,只要在~/arm_ws/src/arm-robot下,在次目录下运行https://blog.csdn.net/m0_/article/details/start.sh,就能直接实现所有功能。
本文采用的硬件包括:arduino mega2560,pca9685多舵机控制模块,USB转TTL调试模块,测试用的舵机或直接是自己做的机械臂,杜邦线若干。
PC端上的ROS-Noetic,操作系统是Ubuntu20.04。调试用的有串口调试助手,在Ubuntu上安装的Arduino IDE。
这部分的配置可以去参考作者写的一篇详细文章,里面详细写了从Ubuntu安装到ROS-Noetic的详细过程,里面也有Arduino的安装教程,本文就不详细叙述了。
要注意的是,作者那篇文章使用的是PC端虚拟机和树莓派的分布式通信,本文目前并未使用到树莓派,如果读者使用的是树莓派来驱动Arduino的话,也可以按照作者那篇文章的来设置。如果不是,就要在 3.3.1 修改.bashrc的那一步, 将ROS_MASTER_URI这个的IP地址改回你自己虚拟机Ubuntu上的IP地址,因为目前主机和从机都是你自己的虚拟机。
讯享网
这步会创建一个文件夹,进入到arm_ws里面后执行catkin_make,执行完之后就会多出两个文件夹,一个是build,一个是devel,src是我们的源代码目录,build是编译过程中的中间文件存放的目录,devel是开发环境目录,编译后的目标文件和开发环境变量。
在src目录下创建一个arm-robot来存放该项目相关的文件夹。
讯享网
在arm-robot下创建一个用来放URDF文件。std_msgs rospy roscpp tf urdf xacro为该ros包的依赖项。
创建存放各个功能包的文件夹。
讯享网
config:存放配置文件,通常用于参数设置,比如机器人模型的参数、传感器配置等。文件通常为 YAML 格式。
launch:存放启动文件(.launch),用于启动一个或多个节点及其参数。这些文件定义了如何配置和启动你的 ROS 系统。
meshes:存放三维模型文件,通常为 STL 或 DAE 格式,用于可视化和仿真中表示机器人的物理形状。
scripts:存放可执行的 Python 脚本或其他脚本文件。这些脚本可以是 ROS 节点,也可以是辅助工具。
urdf:存放机器人的 URDF 文件,描述机器人的结构和关节信息。URDF 文件定义了机器人的几何形状、关节类型、连杆等。
此步骤如果是会建模的读者,或是已经有建模文件的读者,就可以跳过此步骤了,由于读者对机械臂的仿真要求不是很高,所以这里就直接使用圆柱体来代替了。如果是有建模文件的同学,就直接用solidwork来导出ros的urdf文件,具体的操作步骤请读者自行去搜索。
小鱼ros一键安装已经在安装的过程中帮我们把必要的rviz等依赖都安装好了,所以我们不需要另外再去安装什么东西了。
在urdf文件夹下创建一个arm.xacro文件
该文件的完整内容如下:
讯享网
接下来解析代码。
颜色定义,定义了不同的颜色,用于机器人部件的视觉表示。每种颜色都有一个名称和 RGBA 值。

链接属性,定义了不同链接的宽度和长度属性,便于在后续使用。

惯性矩阵宏,定义了一个宏,用于创建惯性矩阵,接受一个质量参数。这样可以在多个链接中复用这一部分代码。

链接定义,定义了链接(link)的视觉和碰撞特性,并设置了质量。每个链接都有视觉(visual)和碰撞(collision)部分。

关节定义,定义了一个可转动关节joint1,其父链接和子链接分别是base_link 和link。还定义了关节的原点、旋转轴、限制和动态特性。
type为revolute时,表示这是一个可转动的关节,type的类型有以下这几种:
那个lower和upper代表的是弧度制的0到Π(3.),转换为角度大概就是0到180°,作者使用的是180°舵机,所以就使用了这个弧度作为限制。如果读者使用的是360°舵机,那请自行修改,计算的公式如下:
度 = 弧度 × 180/Π
geometry的就是你定义的几何体形状,几何体的类型有:
讯享网

夹爪定义,定义了一个用于抓取的链接,包括视觉和碰撞特性,表明它的形状和材料。

Gazebo 相关定义,为 Gazebo 中的链接定义了材料属性,用于在仿真中显示的外观。

传动系统宏,定义了传动系统的宏,接受关节名称作为参数,用于简化多个关节的传动系统定义。

ros_control 插件, 为 Gazebo 添加了 ROS 控制插件,允许 ROS 控制机器人并与 Gazebo 进行交互。


由于作者的xarco不能直接检查,只能将其转化为urdf文件后再进行检查,所以作者直接就写了一个脚本来执行这个过程,在读者写了xacro,如果想要检查一下自己写的是否有错误,也可以进行这个操作。
报错的内容如下

检查格式的脚本,先创建一个check.sh文件,sudo nano check.sh,将以下内容填进去。
如果出现下面的这个的话,就说明你的xacro文件没错了,下面的这些child是你的关节的父子类。
在这步会创建一个启动文件,会发布机械臂的关节状态,并使用rviz加载出来。在marm_description/launch目录下:
讯享网
写入节点,在这个启动文件里,启动了一个gui节点,读者可以使用此gui,使用滑块来控制机械臂,在滑动机械臂运动之后,机械臂可能会一直不断的抽搐,也就是在不断的往返往返运动,这个是正常现象,无需担心。
随后在工作空间下执行
讯享网

执行后的效果如下图:

在弄完rviz之后,就可以开始弄moveit运动规划了。在终端输入
要注意:你的电脑网络最好是连你自己的热点,如果是连公网的话,你的主机请求可能会被防火墙拦截,导致启动不了moveit。
先启动ros节点
讯享网
再开另外一个终端来运行moveit配置(打开终端的快捷方式ctrl alt t)。
开始界面如下,新建一个Package,导入刚刚我们写的那个urdf文件, /home/pi/arm_ws/src/arm-robot/marm_description/urdf/arm.urdf

首先点Self-Collisions,点Generate Collision Matrix生成碰撞矩阵,用于自动生成和管理机器人各个部分之间的碰撞检测信息。使用默认的配置就行。

Virtual Joints本文是没有用到虚拟关节的,所以就不需要管他了。
然后是Planning Groups,规划组是将机器人的的关节或链接组合在一起,以便于进行运动规划和控制。点击Add Group,为组别起名字,机械臂运动是符合运动学规律的,所以要给机械臂添加kdl kinematics plugin/KDLKinematicsPlugin,机器人运动学计算。

点击Add Kin.chain,为机械臂添加和配置运动学链(kinematic chain)。运动学链是指机器人的关节和链接的集合,描述了从基座到末端执行器的运动关系。通过添加运动学链,用户可以明确机器人模型的各个部分如何相互连接和运动。配置运动学链后,MoveIt可以进行逆向运动学和正向运动学的计算,帮助确定关节位置。

再添加一个gripper组,这个组不需要添加运动学配置,这个组需要添加关节和链接。点击Add Joints,添加夹爪

保存完之后,再次点击gripper组的Links,添加链接。

Robot Pose是我们用来定义机械臂的姿态,用来表示当前机械臂的状态。Robot Pose用于表示机器人的当前状态,便于在运动规划和控制过程中跟踪机器人的位置和方向。这里作者就只定义一个初始化的姿态。读者可以根据自己的需求设置到想要的姿态。

然后是填写Author Information,这个一定要填,随便填也要填一个进去,不然他是会导出失败的。
最后是Configuration Files,我们先去arm-robot下创建一个存放Moveit配置文件的文件夹。
讯享网
![]()
在Configuration 中选择该保存路径。
如果生成成功应该会出现下面这些东西。

在launch文件夹下,会有一个示例文件demo.launch,我们可以试着启动他一下。

启动之后,就可以进行路径规划了。你可以通过移动那个球(Goal Pose)来将机械臂移动到指定的位置,也可以选择你之前在Moveit上设置的Goal State,弄完之后点Plan & Execute就会开始路径规划了。

这时候你再开启另外一个终端,用来获取此时的关节数据,首先先输入 rostopic list获取此时在运行的节点,发现有一个节点名字叫做/joint_states,这个就是驱动你机械臂运动的关节数据,我们可以看一下这个关节数据的内容

下面这些就是我们关节的数据,这个/joint_states提供的数据非常重要,在我们后续用gazebo来驱动真实的机械臂上起的至关重要的作用。
在moveit的配置文件当中,在launch中也有一个文件是叫做gazebo的文件的,我们将其运行一下就会进入到gazebo当中了。
讯享网
这个就是我们的gazebo界面了,接下来我们要试着来写一个逻辑控制节点来控制此机械臂。
在marm_description的script目录下创建一个simple_mover.py的运动控制节点,写入以下代码。
此代码通过sin函数,产生一个关节控制数据,通过/arm/joint1_position_controller/command节点来控制各个关节的运动。这个路径名字是取决于你在urdf中所定义的名字。
讯享网
这时候你就可以看见你的机械臂在一直不断的运动了,懂得了如何操控机械臂之后,接下来就是自己编写ros节点来控制机械臂运动了,控制机械臂运动可以用逻辑节点来控制,也就是你自己编写一个逻辑代码,使机械臂自主决策来运动,本文这里没有采用这种方式,而是采用一个gui界面来手动控制机械臂运动。

在上面我们使用一个gui节点来控制rviz的机械臂运动,在gazebo中我们也可以采用一个gui节点调出这个界面,从而用这个界面来控制gazebo的机械臂。
我们首先先启动gazebo
在另外一个终端启动gui界面
讯享网
这时候我们滑动这个滑块,是不是不能控制我们的gazebo,这是当然的,在上面作者也说了,gazebo的关节控制是通过/arm/joint1_position_controller/command节点来控制的,所以我们还需要一个转换节点来将/joint_states中的关节数据订阅,然后发布到command上。
在marm_description的script目录中创建一个joint_states_to_command.py文件,这个节点文件将帮助我们订阅/joint_states节点然后发布给command。
再另外开一个终端,将节点激活并开始运行。
讯享网
这时候你再滑动gui的滑块就发现能够成功控制到机械臂的运作了。

弄了这么多软件方面的东西,终于也是回到了我们的硬件环节了,ros和arduino的通讯方式主要有两种,一种是直接用串口来通讯,但是直接用串口来通讯的话,处理的时候可能会比较麻烦,所以本文这里直接就选择了第二种方法,也就是直接使用rosserial来通讯,在使用这个之前,我们首先要在Ubuntu上安装rosserial的依赖。版本名字依据你自己的ros版本来更改。
然后在arduino上,安装rosserial的库,如果你是和参考我的这篇文章安装的arduino的话,那你就完全跟着我的步骤走,但是步骤其实都差不多的。
点击左边导航栏的第三个库管理,然后搜索rosserial,点击安装。如果没有左边的导航栏的话,就在工具——>库管理,也是可以下载这个rosserial库的。


安装完毕之后,接下来我们就可以测试一下这个库了。
我们可以打开示例中的 hello world来测试我们的rosserial,如果有读者发现打不开,这是正常的,因为那个hello world的后缀名还是旧版的ide格式,我们现在的arduino已经是ino后缀了,所以我们只需要去arduino的库里面把那个示例的后缀名改一下就行了。
在arduino内点击文件——>首选项,在那里可以看见项目的文件夹地址,点击浏览,进入arduino的库。

选择Rosserial_Arduino_Library库,找到examples里面的hello world示例,将ide改成ino,再返回arduino,就发现这个示例能够打开了。如果有想看看其他示例的,也可以去一个个更改那个文件的格式。
如果有懒得去修改的,这里也粘贴出完整的测试代码。
讯享网
将你的arduino接到虚拟机上,把程序烧录进去,烧进去之后,按一下arduino的复位,返回Ros上,打开rosserial。USB根据你自己的实际来修改。在arduino上可以看见Arduino连接到了哪个USB上。
如果运行之后发现没有权限操控ttyUSB0,那就要把ttyUSB0添加到dialout用户组当中。
讯享网
运行完上面的命令后,需要重新登录你的用户账户,以使组权限更改生效。你可以注销并重新登录,或者重启虚拟机。
重启后,通过以下命令来检查/dev/ttyUSB0的权限。
输出中应该显示设备属于dialout组,并且拥有读取和写入权限(通常为crw-rw----)。
这时再运行一次rosrun rosserial_python serial_node.py /dev/ttyUSB0应该就没有报错了。
没报错之后我们就可以来订阅arduino发布的/chatter节点了。
讯享网
这时候我们就可以看见来自arduino发布的消息了。
解决完ros与arduino的通讯之后,接下来的问题就是如何驱动机械臂了,这里作者采用了PCA9685的模块来驱动机械臂,PCA9685是一款可以驱动多路舵机的模块,使用的是IIC通讯,在arduino上是有pca9685的相关库的。
在arduino上搜索Adafruit PwM Servo Driver Library,随后可以使用一个舵机来测试这个库。
测试代码如下,是在该库的servo示例上:
编译后烧录到arduino上,就可以驱动舵机运动了,接下来就可以使用该库来驱动我们的机械臂了。
在ros上,我们还需要编写一个节点,用来订阅/joint_states的消息和将该消息转换为我们舵机的PWM驱动值,作者使用的舵机是180°舵机(标准180°舵机的信号脉冲宽度范围为600微秒到2400微秒),所以限幅SERVOMIN和SERVOMAX是150到600,作者对精度的要求目前不是很高,所以就直接使用了pwm.setPWM来编写,如果读者的精度的要求较高的话,也可以使用pwm.writeMicroseconds编写。
转换的公式为:SERVOMIN = (脉冲长度/)*频率*4096
所以SERVOMIN = (600/20000)*4096 = 150 (50hz约为20毫秒)
在marm_description/script下创建一个states_to_positions.py节点文件,写入以下内容:
讯享网
在这个节点上,也顺便把关节数据映射为角度了,因为弧度转换为角度是浮点数运算,所以为了避免arduino端算力不足,还可以加快运算的速度,就直接在ros端直接把要做的全做了。
启动这个节点之后,我们也可以再写一个订阅节点,来查看states_to_positions节点运作是否正常。也可以直接rostopic echo /joint_positions
创建joint_positions_listener.py文件。
移动gui的滑块界面,如果数据的范围都是在你设定的范围内,那就是成功订阅到/joint_states并成功转换了。
回到arduino端,现在到arduino端来订阅/joint_positios的数据了,arduino端的代码建议使用serial1串口一来作为调试串口来输出你订阅到的数据,因为你不知道会不会出现什么问题,然后又找不到问题所在,arduino端的代码如下:
讯享网
这里串口一是作为我的调试串口来使用的,要特别注意:arduino订阅的数据长度是有限的,例如作者之前使用的是Float64的数组,所以导致回调函数根本就没有触发,因为他数据溢出了,所以要注意你数据的类型,如果你数据太多的话,建议将数据类型缩小,不然就会导致空空如也的情况,使用Float64经过作者一个个的测试之后,发现最多只能容纳5个Float64的数据,多了都会导致回调函数不能正常被触发,所以作者这里将数据类型改成了Float32,如果读者的关节数据没有那么多的话,就可以直接不用管这个了。
现在有了这么多的节点需要启动,一个个启动实在是太麻烦了,所以作者直接就将要启动的东西写成了一个脚本,直接运行就能实现想要运作的节点。
选择一个你喜欢的位置来安放你的脚本,作者这里选择的是arm-robot的目录下。
写入要启动的东西。
讯享网
sleep是为了等待进程启动完毕,作者的电脑是比较卡的,所以启动时间就放得长一点了,读者可根据自己的需求来更改。
在arm-robot下直接执行https://blog.csdn.net/m0_/article/details/start,启动所有的东西,移动你的滑块,就能驱动你的机械臂了。
本**的gazebo驱动真实机械臂还只是一个很粗略很粗略的东西,如果是想要完全在gazebo中驱动的结果和你在真实驱动的机械臂做到完全一样,那就需要读者自己的画3d模型,然后在states_to_positions.py中,发送数据的时候为每个关节都添加PID控制,这样应该就能做到大致一样了。
附录:
本文的Gitee开源如下:
arm_ws: 在Ubuntu的ros-noetic上,使用gazebo来控制真实的机械臂运作
也可以直接在你的Ubuntu上运行,这样就能获取到完整的ros工作空间了

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/164334.html