当前位置:   article > 正文

Moveit + Gazebo:搭建双臂仿真平台(方案一)_moveit双臂规划

moveit双臂规划

环境ubuntu20.04 ROS-noetic

        国内少有搭建Moveit和Gazebo联合仿真的教程,对于搭建双臂等复杂的仿真平台更是鲜有资料,因此想要把自己的见解分享出来供大家参考,共同提高。

        本文提出了两种方法实现Moveit 对双臂的规划,并在gazebo中进行仿真

方案一

        首先是方案一,主要思路是:使用moveit setup assistant配置规划组的时候,创建一个父组,包含两条臂的规划组。

        先说方案一的优缺点:

        优点:两条臂互相知道对方的存在,Moveit进行规划的时候会考虑到两条臂之间的避障

        缺点:Moveit不能实现对两条臂的独立控制,如果对单独臂的规划组进行操作时,规划动作的执行是阻塞的,即一条臂执行完,另一条臂才能继续执行;如果对含有两个臂的规划组的父组进行操作时,存在的问题是:Moveit规划时总是保证两个臂的运行时间是一致的,即两个臂的轨迹长度相差较大时,Moveit使两个臂的运行速度相差很大,保证两者同时开始,同时结束。

        这样不能实现我想要的两个臂比较独立的控制,但是实现起来比较简单。

实现的效果展示:

主要过程参考moveit官方教程:Multiple Robot Arms — moveit_tutorials Noetic documentation

         但是官方教程中,并未详细说明如何控制双臂同时规划,所以这里我们对该部分详细说明,教程中已有的部分不再赘述,建议读者先仔细阅读教程。


Moveit setup assistant配置

        进入正文,首先在 moveit setup assistant配置部分,我们在完成教程已有的内容后,还需要增加一个group,我这里命令为dual_arm(ps:这里前后图片规划组的名称一个是dual_arm 一个是dual_arms,是我两次实践过程中命名不同而已,读者要注意统一,别被我误导)

        选择 add subgroups 然后把之前创建的四个group(这部分内容看官方教程)分别是right_arm 、left_arm、left_hand、right_hand添加进去

        然后是关于eef末端执行器的配置,制定两个末端执行器,这里是为了方便后续编程同时控制双臂,指明两个臂各自的末端执行器,后续才能通过编程接口进行控制。

        这里moveit setup assistant配置我们需要额外添加的部分(或者与教程不同的部分)就全部完成了,生成moveit_config包,我这里命名的是 dual_arm_moveit_config,生成之后进行编译,运行demo.launch ,运行效果如下图所示:

         当rviz界面左下角MotionPlanning插件,Planning Group选择dual_arms(dual_arm)时,可以看到两条臂都有可以被拖动的标记,拖动 goal state到一个你想要的位置,然后plan execute,可以看到两条臂同时运动了!

        如果两条臂处于碰撞状体时,接触的相应部分也会变红,这说明Moveit在规划时会考虑两条臂之间的碰撞。

        当然Planning Group选择right_arm或者left_arm时也能实现对单独臂进行控制。


编程接口

        刚才仅是在rviz中的可视化界面实现了控制,下面介绍如何通过编程接口进行对双臂的控制。

先给出代码,主要的介绍都在注释中。

  1. #include <ros/ros.h>
  2. #include <moveit/move_group_interface/move_group_interface.h>
  3. //包含需要的头文件
  4. int main(int argc, char** argv)
  5. {
  6. ros::init(argc,argv,"demo");
  7. ros::NodeHandle node_handle;
  8. //ros节点初始化
  9. //开辟线程,主要作用是为move group节点获取当前机器人状态
  10. ros::AsyncSpinner spinner(1);
  11. spinner.start();
  12. //这些string都是之前我们在setup assistant配置中定义的,一定要保持一致
  13. static const std::string right_arm_group = "right_arm";
  14. static const std::string left_arm_group = "left_arm";
  15. static const std::string dual_arm_group = "dual_arms";
  16. static const std::string right_end_effector_link = "right_arm_link8";
  17. static const std::string left_end_effector_link = "left_arm_link8";
  18. //实例化move group接口
  19. moveit::planning_interface::MoveGroupInterface right_arm_move_group_interface(right_arm_group);
  20. moveit::planning_interface::MoveGroupInterface left_arm_move_group_interface(left_arm_group);
  21. moveit::planning_interface::MoveGroupInterface dual_arm_move_group_interface(dual_arm_group);
  22. //这个ready也是在setup assistant配置中提前定义好的pose,详细过程见官方教程
  23. right_arm_move_group_interface.setNamedTarget("ready");
  24. left_arm_move_group_interface.setNamedTarget("ready");
  25. //实例化一些plan
  26. moveit::planning_interface::MoveGroupInterface::Plan right_arm_plan;
  27. moveit::planning_interface::MoveGroupInterface::Plan left_arm_plan;
  28. moveit::planning_interface::MoveGroupInterface::Plan dual_arm_plan;
  29. //对机械臂运行到ready位姿进行规划和执行,可以看到机械臂的运动是阻塞执行的,直到right arm执行完,才去执行left arm,因此这是我们需要dual arm group的原因
  30. bool rgt_success = (right_arm_move_group_interface.plan(right_arm_plan) == moveit::planning_interface::MoveItErrorCode::SUCCESS);
  31. if(rgt_success)
  32. {
  33. right_arm_move_group_interface.execute(right_arm_plan);
  34. }
  35. bool lft_success = (left_arm_move_group_interface.plan(left_arm_plan) == moveit::planning_interface::MoveItErrorCode::SUCCESS);
  36. if(lft_success)
  37. {
  38. left_arm_move_group_interface.execute(left_arm_plan);
  39. }
  40. //实例化两个pose,从当前pose进行修改,获得target pose
  41. geometry_msgs::PoseStamped current_right_arm_pose = right_arm_move_group_interface.getCurrentPose();
  42. geometry_msgs::PoseStamped current_left_arm_pose = left_arm_move_group_interface.getCurrentPose();
  43. geometry_msgs::PoseStamped target_right_arm_pose = current_right_arm_pose;
  44. target_right_arm_pose.pose.position.z -= 0.3;
  45. target_right_arm_pose.pose.position.x += 0.4;
  46. target_right_arm_pose.pose.position.x = -target_right_arm_pose.pose.position.x;
  47. geometry_msgs::PoseStamped target_left_arm_pose = current_left_arm_pose;
  48. target_left_arm_pose.pose.position.z += 0.2;
  49. //设置双臂的规划目标,可以看到setPoseTarget函数通过指定了末端执行器的link来区分两个臂,可以看到两个臂是同时运行的dual_arm_move_group_interface.setPoseTarget(target_right_arm_pose,right_end_effector_link);
  50. dual_arm_move_group_interface.setPoseTarget(target_left_arm_pose,left_end_effector_link);
  51. bool dual_success = (dual_arm_move_group_interface.plan(dual_arm_plan) == moveit::planning_interface::MoveItErrorCode::SUCCESS);
  52. if(dual_success)
  53. {
  54. dual_arm_move_group_interface.execute(dual_arm_plan);
  55. }
  56. //结束
  57. ros::shutdown();
  58. return 0;
  59. }

 这是官网code API文档介绍:Source Code & API | MoveIt

cmakelist:

  1. cmake_minimum_required(VERSION 3.0.2)
  2. project(dual_arms)
  3. ## Compile as C++11, supported in ROS Kinetic and newer
  4. # add_compile_options(-std=c++11)
  5. ## Find catkin macros and libraries
  6. ## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
  7. ## is used, also find other catkin packages
  8. find_package(catkin REQUIRED COMPONENTS
  9. roscpp
  10. geometry_msgs
  11. moveit_ros_planning_interface
  12. moveit_ros_planning
  13. )
  14. ## System dependencies are found with CMake's conventions
  15. # find_package(Boost REQUIRED COMPONENTS system)
  16. ## Uncomment this if the package has a setup.py. This macro ensures
  17. ## modules and global scripts declared therein get installed
  18. ## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
  19. # catkin_python_setup()
  20. ################################################
  21. ## Declare ROS messages, services and actions ##
  22. ################################################
  23. ## To declare and build messages, services or actions from within this
  24. ## package, follow these steps:
  25. ## * Let MSG_DEP_SET be the set of packages whose message types you use in
  26. ## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...).
  27. ## * In the file package.xml:
  28. ## * add a build_depend tag for "message_generation"
  29. ## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET
  30. ## * If MSG_DEP_SET isn't empty the following dependency has been pulled in
  31. ## but can be declared for certainty nonetheless:
  32. ## * add a exec_depend tag for "message_runtime"
  33. ## * In this file (CMakeLists.txt):
  34. ## * add "message_generation" and every package in MSG_DEP_SET to
  35. ## find_package(catkin REQUIRED COMPONENTS ...)
  36. ## * add "message_runtime" and every package in MSG_DEP_SET to
  37. ## catkin_package(CATKIN_DEPENDS ...)
  38. ## * uncomment the add_*_files sections below as needed
  39. ## and list every .msg/.srv/.action file to be processed
  40. ## * uncomment the generate_messages entry below
  41. ## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)
  42. ## Generate messages in the 'msg' folder
  43. # add_message_files(
  44. # FILES
  45. # Message1.msg
  46. # Message2.msg
  47. # )
  48. ## Generate services in the 'srv' folder
  49. # add_service_files(
  50. # FILES
  51. # Service1.srv
  52. # Service2.srv
  53. # )
  54. ## Generate actions in the 'action' folder
  55. # add_action_files(
  56. # FILES
  57. # Action1.action
  58. # Action2.action
  59. # )
  60. ## Generate added messages and services with any dependencies listed here
  61. # generate_messages(
  62. # DEPENDENCIES
  63. # std_msgs # Or other packages containing msgs
  64. # )
  65. ################################################
  66. ## Declare ROS dynamic reconfigure parameters ##
  67. ################################################
  68. ## To declare and build dynamic reconfigure parameters within this
  69. ## package, follow these steps:
  70. ## * In the file package.xml:
  71. ## * add a build_depend and a exec_depend tag for "dynamic_reconfigure"
  72. ## * In this file (CMakeLists.txt):
  73. ## * add "dynamic_reconfigure" to
  74. ## find_package(catkin REQUIRED COMPONENTS ...)
  75. ## * uncomment the "generate_dynamic_reconfigure_options" section below
  76. ## and list every .cfg file to be processed
  77. ## Generate dynamic reconfigure parameters in the 'cfg' folder
  78. # generate_dynamic_reconfigure_options(
  79. # cfg/DynReconf1.cfg
  80. # cfg/DynReconf2.cfg
  81. # )
  82. ###################################
  83. ## catkin specific configuration ##
  84. ###################################
  85. ## The catkin_package macro generates cmake config files for your package
  86. ## Declare things to be passed to dependent projects
  87. ## INCLUDE_DIRS: uncomment this if your package contains header files
  88. ## LIBRARIES: libraries you create in this project that dependent projects also need
  89. ## CATKIN_DEPENDS: catkin_packages dependent projects also need
  90. ## DEPENDS: system dependencies of this project that dependent projects also need
  91. catkin_package(
  92. # INCLUDE_DIRS include
  93. # LIBRARIES dual_arms
  94. # CATKIN_DEPENDS other_catkin_pkg
  95. # DEPENDS system_lib
  96. )
  97. ###########
  98. ## Build ##
  99. ###########
  100. ## Specify additional locations of header files
  101. ## Your package locations should be listed before other locations
  102. include_directories(
  103. include
  104. ${catkin_INCLUDE_DIRS}
  105. )
  106. ## Declare a C++ library
  107. # add_library(${PROJECT_NAME}
  108. # src/${PROJECT_NAME}/dual_arms.cpp
  109. # )
  110. ## Add cmake target dependencies of the library
  111. ## as an example, code may need to be generated before libraries
  112. ## either from message generation or dynamic reconfigure
  113. # add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
  114. ## Declare a C++ executable
  115. ## With catkin_make all packages are built within a single CMake context
  116. ## The recommended prefix ensures that target names across packages don't collide
  117. # add_executable(${PROJECT_NAME}_node src/dual_arms_node.cpp)
  118. add_executable(demo src/demo.cpp)
  119. ## Rename C++ executable without prefix
  120. ## The above recommended prefix causes long target names, the following renames the
  121. ## target back to the shorter version for ease of user use
  122. ## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node"
  123. # set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "")
  124. ## Add cmake target dependencies of the executable
  125. ## same as for the library above
  126. # add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
  127. add_dependencies(demo ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
  128. ## Specify libraries to link a library or executable target against
  129. # target_link_libraries(${PROJECT_NAME}_node
  130. # ${catkin_LIBRARIES}
  131. # )
  132. target_link_libraries(demo
  133. ${catkin_LIBRARIES}
  134. )
  135. #############
  136. ## Install ##
  137. #############
  138. # all install targets should use catkin DESTINATION variables
  139. # See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html
  140. ## Mark executable scripts (Python etc.) for installation
  141. ## in contrast to setup.py, you can choose the destination
  142. # catkin_install_python(PROGRAMS
  143. # scripts/my_python_script
  144. # DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
  145. # )
  146. ## Mark executables for installation
  147. ## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html
  148. # install(TARGETS ${PROJECT_NAME}_node
  149. # RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
  150. # )
  151. ## Mark libraries for installation
  152. ## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html
  153. # install(TARGETS ${PROJECT_NAME}
  154. # ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  155. # LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  156. # RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION}
  157. # )
  158. ## Mark cpp header files for installation
  159. # install(DIRECTORY include/${PROJECT_NAME}/
  160. # DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
  161. # FILES_MATCHING PATTERN "*.h"
  162. # PATTERN ".svn" EXCLUDE
  163. # )
  164. ## Mark other files for installation (e.g. launch and bag files, etc.)
  165. # install(FILES
  166. # # myfile1
  167. # # myfile2
  168. # DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
  169. # )
  170. #############
  171. ## Testing ##
  172. #############
  173. ## Add gtest based cpp test target and link libraries
  174. # catkin_add_gtest(${PROJECT_NAME}-test test/test_dual_arms.cpp)
  175. # if(TARGET ${PROJECT_NAME}-test)
  176. # target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
  177. # endif()
  178. ## Add folders to be run by python nosetests
  179. # catkin_add_nosetests(test)

效果视频

Moveit+Gazebo:搭建双臂仿真平台(方案一)_哔哩哔哩_bilibili 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/爱喝兽奶帝天荒/article/detail/818763
推荐阅读
相关标签
  

闽ICP备14008679号