ROS探索总结(六十五)—— 古月私房课 | MoveIt!编程驾驭机械臂运动控制

9516
52
2019年4月4日 22时49分

~欢迎关注~

微信公众号:古月居

新浪微博:古月春旭

知乎专栏:古月居

原文链接:古月私房课 | MoveIt!编程驾驭机械臂运动控制

 

古月居联合深蓝学院推出的“古月私房课”第一弹——《ROS机械臂开发:从入门到实战》已经上线啦,欢迎各位小伙伴前来围观,以下是第六讲《MoveIt!编程驾驭机械臂运动控制》的内容精要。

大家好,这里是《ROS机械臂开发:从入门到实战》的第六讲——MoveIt!编程驾驭机械臂运动控制,我是主讲人胡春旭。

幻灯片1

本讲我们将从以下四个部分进行讲解。

幻灯片2

首先来回顾下MoveIt!编程接口的框架。

幻灯片3

MoveIt!提供三种主要的交互方式:C++接口、Python接口以及上位机Rivz插件接口,无论哪种形式,底层都是和move_group核心节点交互,完成功能算法的调用。

幻灯片4

对比C++和Python两种编程方式,在流程上完全一致,API接口的名字也基本相同。

幻灯片5

完整的MoveIt!程序流程如下,不可或缺的步骤是:确定控制对象的规划组、设置目标位姿、进行运动规划、执行规划轨迹。

幻灯片6

API接口众多,而且有多态性,所以在开发过程中大家一定离不开官方的API文档,这里有最完整的接口介绍。

幻灯片7

接下来我们就来了解一下MoveIt!中的关键编程方法,第一种是关节空间运动。

幻灯片8

在关节空间运动中,机械臂各轴独立完成轨迹插补,终端轨迹是自由曲线,常用于码垛、搬运、分拣等对运动轨迹没有强制约束的场景,其中的关键就是对目标姿态的描述。

幻灯片9

可以在关节空间下直接通过各轴的位置描述目标姿态,这里需要调用MoveIt!提供的set_joint_value_target函数实现。

幻灯片10

也可以在工作空间下通过终端的位姿+姿态进行描述,需要调用set_pose_target函数进行设置。

幻灯片12

还有很多场景下对机械臂的终端轨迹有要求,那就需要用到笛卡尔空间下的运动规划功能了。

幻灯片14

比如让机械臂的终端走出一条直线。

幻灯片15

我们可以对比笛卡尔运动和关节空间下经过同样路径点的轨迹区别,如下图所示,一个是自由曲线,一个是直线轨迹。

幻灯片16

这里笛卡尔运动规划使用的关键函数是MoveIt!中的compute_cartesian_path,它可以将多个路点waypoints之间通过直线轨迹连接到一起,返回值fraction表示可规划轨迹的覆盖率。

幻灯片17

在机械臂运动过程中,如果有障碍物的话,还需要考虑避障的问题。

幻灯片19

比如下图中机械臂在运动规划时,就需要考虑到绿色障碍物的避障问题。

幻灯片20

MoveIt!中有一个场景监听器模块,就是用来检测外部场景信息的,障碍物可以通过三种方式加入场景中:rviz可视化添加、程序添加、传感器检测。本讲我们主要介绍前两种方式。

幻灯片21

在rviz的MoveIt!插件中有一个Scene Object标签页,可以将障碍物模型添加到场景当中来,此后机械臂在运动规划时就会考虑躲避该障碍物了。

幻灯片22

另外一种方式是通过程序操作,不仅可以添加外界障碍物,还可以添加机械臂上的附着物体,模拟抓取到的物体,将作为机械臂的一部分,考虑与外界物体的碰撞。

幻灯片23

这里涉及的主要函数是add_box和attach_box,前者是将添加的物体作为障碍物,后者是将添加的物体作为机械臂的一部分。

幻灯片24

以上就是本讲的内容概要,详细讲解过程和仿真/真机演示请见具体课程。

幻灯片25

更多精彩,欢迎大家关注“古月居”。

幻灯片28

 

更多内容欢迎关注:

微信公众号:古月居 (guyue_home)

新浪微博:古月春旭

知乎专栏:古月居

发表评论

后才能评论

评论列表(52条)

  • 交换。 2020年5月20日 下午12:24

    老师您好,我写了个计算力矩+pd控制器的功能包,算力矩做跟踪,发给ros-control的关节力矩模式接口,现在需要一整条轨迹的关节位置,速度,加速度,想问下,moveit生成的轨迹(关节位置,速度,加速度),可以直接发布出来吗,是以数组的形式吗?
    如果后续,我想实现比方说时间最优的轨迹,是不是需要自己写正逆运动学,以及轨迹规划算法?

  • 山山而川 2020年3月31日 下午2:05

    古老师你好,我想实现一个功能,让机械臂沿圆弧进行运动,然后每隔0.5s判断一次是否要继续运动,我一开始是仿照cartesian_demo写的,加入了一个for循环,以及time.sleep(0.5),可是发现moveit一旦execute一段路径就不会停下,等执行完整端路径后才会执行休息0.5s的命令,这和我的期望不符,有什么可以实现我的目的的方式嘛?还请古老师赐教!

    • 古月 回复 山山而川 2020年4月2日 下午6:14

      moveit运行是这样的,你可以试下0.5秒cancel一下,这样机械臂会停止运动,然后再重新规划

    • 山山而川 回复 古月 2020年4月3日 上午10:20

      古老师,这个cancel怎么实现呀?arm.stop嘛?还请古老师说的再详细一点…(新手刚入门)

    • 山山而川 回复 山山而川 2020年4月3日 下午2:49

      古老师,我还有一个问题想请教你。rosrun rqt_tf_tree rqt_tf_tree,我去查看tf tree(六自由度机器人)然后我发现他的平均更新速率在11hz,但是我rosrun tf tf_echo base_link link_6,发现它在终端上显示是1hz,这是为什么呀?我想以10hz的频率去读取末端位姿,这怎么样才能实现呀?

    • 山山而川 回复 古月 2020年4月11日 上午11:07

      老师你好,我现在又碰到了一个问题,moveit进行了一段轨迹运动后,我用arm.stop将机械臂停下,然后代码如下所示
      if cartesian:
      fraction = 0.0 #路径规划覆盖率
      maxtries = 100 #最大尝试规划次数
      attempts = 0 #已经尝试规划次数

      # 设置机器臂当前的状态作为运动初始状态
      arm.set_start_state_to_current_state()

      # 尝试规划一条笛卡尔空间下的路径,依次通过所有路点
      while fraction < 1.0 and attempts < maxtries: #规划路径 ,fraction返回1代表规划成功 (plan, fraction) = arm.compute_cartesian_path ( waypoints, # waypoint poses,路点列表,这里是5个点 0.001, # eef_step,终端步进值,每隔0.01m计算一次逆解判断能否可达 0.0, # jump_threshold,跳跃阈值,设置为0代表不允许跳跃 True) # avoid_collisions,避障规划 可终端显示Invalid Trajectory: start point deviates from current robot state more than 0.01 joint 'joint_3',这是为什么呀?不是在代码中已经arm.set_start_state_to_current_state()了嘛?为什么还会有起始点与机械臂位置差距大的原因啊?我现在只是在moveit里进行仿真,并没有用到真实机器人。

  • 底角98K 2019年12月11日 下午9:23

    大神,moveit运动规划时,Joint_states中为什么只有各关节位置数据,而没有关节速度

    • 古月 回复 底角98K 2019年12月12日 下午8:03

      demo里是一个简单的仿真,没算到速度级别

    • 底角98K 回复 古月 2019年12月12日 下午9:23

      老师,谢谢您的回复!如果我要得到机械臂在轨迹上运动的实时关节速度和加速度,是不是一定要用运动控制器,像Abotix关节控制器,或在gazebo中仿真用到的那些关节轨迹控制器等

    • 古月 回复 底角98K 2019年12月23日 下午3:25

      需要用可以反馈速度和加速度的控制器

    • 底角98K 回复 古月 2019年12月13日 上午9:19

      老师,您在讲轨迹重定义那块时,moveit_revise_trajectory_demo.py文件中有获得在路径点下的关节速度这一命令,我怎样得到路点的一组关节速度?

    • 古月 回复 底角98K 2019年12月23日 下午3:27

      那个程序获取的路径点中是有速度信息的

  • 李娟 2019年10月23日 上午9:59

    关于第十章的抓取,一直不能成功,显示无法找到目标,请问是无法求得逆解的问题吗?

  • ikea 2019年10月10日 上午9:31

    求教一下joint state节点是在哪儿发布的 想修改一下发布频率没找到

    • ikea 回复 ikea 2019年10月10日 下午1:38

      想获取moveit!生成的路径,订阅/joint_state发现他是频率是10Hz,想获取的路径点更密一点,应该怎么修改

  • 冯朝阳 2019年8月22日 下午3:43

    古老师,我使用的是moveit官网给的python接口,当运行python程序时,出现以下错误,
    Traceback (most recent call last):
    File “move_group_python_interface_tutorial.py”, line 54, in
    from moveit_commander.conversions import pose_to_list
    File “/opt/ros/kinetic/lib/python2.7/dist-packages/moveit_commander/conversions.py”, line 36, in
    from moveit_commander import MoveItCommanderException
    ImportError: cannot import name MoveItCommanderException
    但是这是官网给的程序啊,这个问题卡了我好几天了,非常感谢您的解答。

  • 牛大 2019年8月15日 下午5:35

    古老师,在用moveit做机械臂的工作空间规划时需要指定目标点的orientation,我是先构建姿态矩阵再用公式转换的,可以构建出来的四元数orientation和在rviz中显示看到的总会有区别,某些区域匹配,某些区域就不匹配了,ros里面的orientation有什么特别的设置吗
    q_{0}=\frac{1}{2}\sqrt{1+r_{11}+r_{22}+r_{33}}
    q_{1}=\frac{r_{32}-r_{23}}{4q_{0}}
    q_{2}=\frac{r_{13}-r_{31}}{4q_{0}}
    q_{3}=\frac{r_{21}-r_{12}}{4q_{0}}

    • 古月 回复 牛大 2019年8月18日 上午10:05

      没有什么特别的,可以直接用tf中的API做转换

    • 牛大 回复 古月 2019年8月28日 上午10:02

      我之前只找到了四元数和欧拉角之间的转换函数,point = tf.transformations.quaternion_from_euler(0,0,0.181514)
      但是我的输入是两个点求得的一个矢量,
      请问有实现四元数和矢量之间的转换函数吗

    • 古月 回复 牛大 2019年9月1日 下午1:55

      请参考tf的API文档

  • Ji 2019年8月13日 下午2:04

    古月老师您好,我在使用moveit做碰撞检测时,发现只能完成机械臂和coliision_object之间的碰撞检测,即便使用attach_box,也只是让物体随机械臂运动。我想知道如何在规划中考虑物体和物体之间的碰撞?比如使用机械臂抓取物体,在规划时同时考虑抓取的物体和环境中的物体不产生碰撞。

    • 古月 回复 Ji 2019年8月13日 下午3:37

      避障是在规划时同时考虑的,只要把障碍物体添加入环境

    • Ji 回复 古月 2019年8月13日 下午11:11

      谢谢老师的回复!将物体添加进环境中时,规划时规划器会考虑机器人和环境中物体的碰撞,但是不会考虑环境中物体之间的碰撞。比如机器人抓取一个物放到一个盒子里,我用attached object将物体附在机械臂的end effector,但是在规划的时候抓取的那个物体和盒子之间的碰撞时没有考虑的。我不太清楚这个应该怎么解决,希望您可以给一些指导,十分感谢!

    • 古月 回复 Ji 2019年8月18日 上午10:02

      attached object应该是会考虑和外部物体的碰撞的

    • Ji 回复 古月 2019年8月19日 下午4:24

      我重新尝试了以下,是可以的,之前因为在rviz界面中拖动到碰撞区没有显示红色所以误以为不可以检测。谢谢古月老师!

  • 杨文心欣 2019年8月5日 下午3:30

    古月老师您好!我在按照《ROS机器人开发实践》来做机械臂的仿真,我是用solidwork生成urdf导入gazebo进行仿真,已经可以实现用rviz中的motionplan插件控制机器人运动,但是用python的接口模块movegroupCommdander控制的时候出现了问题,报错如下:
    ➜ ~ rosrun kinect_pitch moveit_target.py
    Failed to import pyassimp, see https://github.com/ros-planning/moveit/issues/86 for more info
    [ INFO] [1564989490.866792332, 6.111000000]: Loading robot model ‘smart_robot’…
    [ INFO] [1564989493.965561275, 6.238000000]: Loading robot model ‘smart_robot’…
    [ WARN] [1564989494.979076240, 6.285000000]: The root link base_link has an inertia specified in the URDF, but KDL does not support a root link with an inertia. As a workaround, you can add an extra dummy link to your URDF.
    [ INFO] [1564989495.295851266, 6.297000000]: Loading robot model ‘smart_robot’…
    [ WARN] [1564989496.483935429, 6.348000000]: The root link base_link has an inertia specified in the URDF, but KDL does not support a root link with an inertia. As a workaround, you can add an extra dummy link to your URDF.
    Traceback (most recent call last):
    File “/home/yang/ws_moveit/src/kinect_pitch/src/moveit_target.py”, line 130, in
    MoveItTarget()
    File “/home/yang/ws_moveit/src/kinect_pitch/src/moveit_target.py”, line 21, in __init__
    self.arm = moveit_commander.MoveGroupCommander(‘arm_right’)
    File “/opt/ros/kinetic/lib/python2.7/dist-packages/moveit_commander/move_group.py”, line 52, in __init__
    self._g = _moveit_move_group_interface.MoveGroupInterface(name, robot_description, ns)
    RuntimeError: Unable to connect to move_group action server ‘place’ within allotted time (5s)

    我检查过rostopic 和rosserver 中的movegroup相关东西都在,➜ ~ rostopic echo /smart_robot/joint_states也可以正常收到机器人的各关节信息,不知道怎么解决了,希望老师能提供帮助,感激不尽!

  • 小李 2019年6月28日 下午3:34

    古老师,请问下,如何能够提高话题订阅的频率,能够在0.1s之内??

    • 古月 回复 小李 2019年6月30日 下午1:24

      订阅者没有固定频率,主要取决于发布者的频率和订阅者的处理速度

    • 湖大小王 回复 古月 2019年8月23日 下午10:00

      胡老师,你好!为了使机械臂实时适应环境变化,需要在机械臂运动过程中实时调整机械臂的状态和目标点,请问这个该怎么操作呢?您有什么建议吗?asyncexecute()函数和execute()函数貌似都不行。

    • 王凯军 回复 古月 2019年10月11日 上午9:47

      古月老师好,请问moveit!中有没有函数能输入机械臂末端位姿后给我返回六个关节角度的?我不用它自己的规划,我就想用它给我算个运动学,然后我自己去生成轨迹。
      and 我下载了PROBOT_anno的工程文件,里面各个文件的功能/如何使用有教程吗?

  • 英白拉多 2019年6月17日 下午9:35

    老师您好,我现在想要用moveit规划ur做一个pick and place,我仿照您书的第十章的写好了代码,但是您的书中没有提到应该将学好的代码放在哪里,之后还有什么配置需要做吗?

  • Damien 2019年5月31日 下午11:34

    老师您好!我在学习您书的第十章时遇到了几个问题:
    1. 运行roslaunch marm_planning arm_planning.launch
    rosrun marm_planning moveit_pick_and_place_demo.py后,在rviz显示了的六轴机械臂模型,但是在抓取和放置目标的过程中,机械臂前段合拢后,目标物体的模型就消失了,在到达放置位置机械臂前段松开后才会重新出现,请问这是什么问题?
    2. 同样是运行这个launch和py文件时,我们的约束条件只有目标物体的中心点,因此末状态时常出现目标物体“横七竖八”的情况,请问有什么方法可以解决这种问题吗?(比如约束末位置时的机械臂参数?)
    谢谢老师!!

  • LWL 2019年5月31日 下午9:32

    老师您好,我想通过moveit控制UR机械臂移动,我写了一个话题不断发布机械臂末端的位姿,想要机械臂订阅这个话题不断的根据话题中的位姿进行移动,请问老师有一些例子?我尝试实现了一下,但是接收到一个点之后,机械臂规划完路径,还没来得及移动,就收到下一个点的位置,然后机械臂就不动了,可能自己用的方法有些问题。

    • 古月 回复 LWL 2019年6月1日 上午8:12

      参考《ROS By Example 2》里有类似的案例

    • LWL 回复 古月 2019年6月1日 下午8:35

      谢谢老师的回复,我今天下载了那本书的电子版,找了一下午没有找到大致在什么位置,主要找了moveit那章,老师您能说类似案例一下大致在哪一章吗?十分感谢老师!

    • 古月 回复 LWL 2019年6月3日 上午10:17

      应该就在moveit那章,有一个识别动态运动球的案例

    • 程仕发 回复 LWL 2019年8月6日 上午9:32

      你好,这本电子书能给我发一本吗?谢谢

  • heyi 2019年5月23日 下午4:22

    古老师,我在运行rosrun marm_planning moveit_cartesian_demo.py _cartesian:=True 时出现Couldn’t find executable named moveit_cartesian_demo.py,什么原因呢

    • 古月 回复 heyi 2019年5月23日 下午5:19

      python文件添加可执行权限

    • heyi 回复 古月 2019年5月23日 下午8:24

      已解决,谢谢

  • li 2019年5月16日 下午9:49

    老师你好,请问从哪里可以获取源码?

  • 牛大 2019年4月28日 上午10:59

    古老师,我在ros机器人开发实践的10.9.2 工作空间规划编程中,参考了你写的那个py源码,只是修改了几个臂名称,为什么运行的时候机械臂不动,会报Unable to construct goal representation,是我的目标位置和姿态构建错了吗,但是这个里面的参数是我在rviz中摆到相应位置后参考rviz上的实现值啊。而且之前参考10.9.1章节时,已经实现了机械臂的关节空间规划,也能动

    • 古月 回复 牛大 2019年4月28日 上午11:41
    • 牛大 回复 古月 2019年4月28日 下午2:38

      这个链接暂时打不开,是设置的问题吗,这是那个源码,和您书上的没啥区别啊
      import rospy, sys
      import moveit_commander
      from moveit_msgs.msg import RobotTrajectory
      from trajectory_msgs.msg import JointTrajectoryPoint
      from geometry_msgs.msg import PoseStamped, Pose
      from tf.transformations import euler_from_quaternion, quaternion_from_euler

      class MoveItIkDemo:
      def __init__(self):
      moveit_commander.roscpp_initialize(sys.argv)
      rospy.init_node(‘moveit_sk_demo’)
      left = moveit_commander.MoveGroupCommander(‘left’)
      end_effector_link = left.get_end_effector_link()
      reference_frame = ‘base_link’
      left.set_pose_reference_frame(reference_frame)
      left.allow_replanning(True)
      left.set_goal_position_tolerance(0.01)
      left.set_goal_orientation_tolerance(0.05)
      left.set_named_target(‘home’)
      left.go()
      rospy.sleep(2)
      target_pose = PoseStamped()
      target_pose.header.frame_id = reference_frame
      target_pose.header.stamp = rospy.Time.now()
      target_pose.pose.position.x = 3.0704
      target_pose.pose.position.y = -22.702
      target_pose.pose.position.z = 4.2895
      target_pose.pose.orientation.x = 0.72141
      target_pose.pose.orientation.y = -0.0021503
      target_pose.pose.orientation.z = -0.013211
      target_pose.pose.orientation.w = 0.69238
      left.set_start_state_to_current_state()
      left.set_pose_target(target_pose, end_effector_link)
      traj = left.plan()
      left.execute(traj)
      rospy.sleep(1)
      left.set_named_target(‘home’)
      left.go()
      moveit_commander.roscpp_shutdown()
      moveit_commander.os._exit(0)

      if __name__ == “__main__”:
      MoveItIkDemo()

    • 古月 回复 牛大 2019年4月30日 上午10:51

      看不出什么问题

    • 牛大 回复 古月 2019年4月28日 下午2:41

      我的臂架很大,所以位置那有的是20多m

    • 牛大 回复 牛大 2019年4月29日 下午5:08

      原来是moveit_setup_assistant 自己生成的文件中少了一个东西,加上就好了,不过现在做求解的时候,会报Unable to sample any valid states for goal tree,这是我的目标姿态有问题吗?

  • wjf 2019年4月21日 下午9:42

    古老师,在这个章节教程里,将probot_demo加入catkin工作空间后,无法编译通过
    CMake Error at probot_demo/CMakeLists.txt:166 (target_link_libraries):
    Attempt to add link library
    “/usr/lib/x86_64-linux-gnu/libconsole_bridge.so” to target
    “moveit_cartesian_demo” which is not built in this directory.

    CMake Error at /opt/ros/kinetic/share/catkin/cmake/custom_install.cmake:13 (_install):
    install TARGETS given target “moveit_random_demo” which does not exist in
    this directory.
    Call Stack (most recent call first):
    probot_demo/CMakeLists.txt:210 (install)

    • 古月 回复 wjf 2019年4月21日 下午11:03

      probot_demo的CMakeLists.txt里边编译moveit_random_demo的部分删掉

    • wjf 回复 古月 2019年4月22日 下午2:10

      老师,我发现问题在哪了,是因为我参照你的probot_demo包,编写自己的package时,Cmakelist.txt文件是复制了probot_demo包里的,在add_executable()和target_link_libraries()函数的参数没有及时修改,最后在不同的包里编译moveit_cartesian_demo和moveit_random_demo等文件,导致编译失败。