ROS探索总结(二十六)——MoveIt编程

  • 内容
  • 评论
  • 相关

  在之前的基础学习中,我们已经对moveit有了一个基本的认识,在实际的应用中,GUI提供的功能毕竟有限,很多实现还是需要我们在代码中完成,moveitmove_group也提供了丰富的C++ API,不仅可以帮助我们使用代码完成GUI可以实现的功能,还可以加入更多丰富的功能。我们继续使用《Mastering ROS for robotics Programming》中的源码作为学习对象。

clip_image002

 

一、创建功能包

首先,我们先创建一个新的功能包,来放置我们的代码:

  1. $ catkin_create_pkg seven_dof_arm_test catkin cmake_modules interactive_markers moveit_core moveit_ros_perception moveit_ros_planning_interface pluginlib roscpp std_msgs

  也可以直接使用《Mastering ROS for robotics Programming》中的seven_dof_arm_test功能包。

二、随机轨迹

  通过rvizplanning插件的功能,我们可以为机器人产生一个随机的目标位置,让机器人完成运动规划并移动到目标点。使用代码同样可以实现相同的功能,我们首先从这个较为简单的例程入手,对Moveit C++ API有一个初步的认识。

  二话不说,先上代码(源码文件 test_random.cpp可以在源码包中找到):

  1. //首先要包含API的头文件
  2. #include <moveit/move_group_interface/move_group.h>
  3. int main(int argc, char **argv)
  4. {
  5.   ros::init(argc, argv, "move_group_interface_demo", ros::init_options::AnonymousName);
  6.   // 创建一个异步的自旋线程(spinning thread)
  7.   ros::AsyncSpinner spinner(1);
  8.   spinner.start();
  9.   // 连接move_group节点中的机械臂实例组,这里的组名arm是我们之前在setup assistant中设置的
  10.   move_group_interface::MoveGroup group("arm");
  11.   // 随机产生一个目标位置
  12.   group.setRandomTarget();
  13.   // 开始运动规划,并且让机械臂移动到目标位置
  14.   group.move();
  15.   ros::waitForShutdown();
  16. }

   已经在代码中加入了重点代码的解释,move_group_interface::MoveGroup用来声明一个机械臂的示例,后边都是针对该实例进行控制。

   除了moveit,可能很多人对ROS单节点中的多线程API接触的比较少。一般我们使用的自旋API都是spin()或者spinonce(),但是有些情况下会有问题,比如说我们有两个回调函数,第一个回调函数会延时5秒,那么当我们开始spin()时,回调函数会顺序执行,第二个回调函数会因为第一个回调函数的延时,在5秒之后才开始执行,这个当然是我们无法接受的,所如果采用多线程的spin(),就不会存在这个问题了。关于ROS多线程的问题,可以参考wiki等资料:

http://wiki.ros.org/roscpp/Overview/Callbacks%20and%20Spinning

http://www.cnblogs.com/feixiao5566/p/5288206.html

   然后修改CMakeLists文件,编译代码,执行下边的命令:

  1. $ roslaunch seven_dof_arm_config demo.launch
  2. $ rosrun seven_dof_arm_test test_random_node

   稍等一下,我们就可以在rviz中看到机械臂的动作了。

clip_image004

 

三、自定义目标位置并完成规划

接下来我们继续学习如何使用API自定义一个目标位置并让机器人运动过去。源码是 test_custom.cpp,这里我删掉了部分冗余的代码,进行了部分修改:

  1. // 包含miveit的API头文件
  2. #include <moveit/move_group_interface/move_group.h>
  3.  
  4. int main(int argc, char **argv)
  5. {
  6.   ros::init(argc, argv, "move_group_interface_tutorial");
  7.   ros::NodeHandle node_handle; 
  8.   ros::AsyncSpinner spinner(1);
  9.   spinner.start();
  10.  
  11.   moveit::planning_interface::MoveGroup group("arm");
  12.  
  13.   // 设置机器人终端的目标位置
  14.   geometry_msgs::Pose target_pose1;
  15.   target_pose1.orientation.w = 0.726282;
  16.   target_pose1.orientation.x= 4.04423e-07;
  17.   target_pose1.orientation.y = -0.687396;
  18.   target_pose1.orientation.z = 4.81813e-07;
  19.  
  20.   target_pose1.position.x = 0.0261186;
  21.   target_pose1.position.y = 4.50972e-07;
  22.   target_pose1.position.z = 0.573659;
  23.   group.setPoseTarget(target_pose1);
  24.  
  25.  
  26.   // 进行运动规划,计算机器人移动到目标的运动轨迹,此时只是计算出轨迹,并不会控制机械臂运动
  27.   moveit::planning_interface::MoveGroup::Plan my_plan;
  28.   bool success = group.plan(my_plan);
  29.  
  30.   ROS_INFO("Visualizing plan 1 (pose goal) %s",success?"":"FAILED");   
  31.  
  32.   //让机械臂按照规划的轨迹开始运动。
  33.   //if(success)
  34.   //    group.execute(my_plan);
  35.  
  36.   ros::shutdown(); 
  37.   return 0;
  38. }

     对比生成随机目标的源码,基本上只有只是加入了设置终端目标位置的部分代码,此外这里规划路径使用的是plan(),这个对应rvizplanningplan按键,只会规划路径,可以在界面中看到规划的路径,但是并不会让机器人开始运动,如果要让机器人运动,需要使用execute(my_plan),对应execute按键。当然,我们也可以使用一个move()来代替paln()execute()。具体的API说明,可以参考官方的文档:

http://docs.ros.org/jade/api/moveit_ros_planning_interface/html/classmoveit_1_1planning__interface_1_1MoveGroup.html

  1. $ roslaunch seven_dof_arm_config demo.launch
  2. $ rosrun seven_dof_arm_test test_custom_node

     

clip_image006

 

四、碰撞检测

moveit可以帮助我们完成机器人的自身碰撞检测和环境障碍物碰撞检测,rivzGUI中,我们可以通过 Planning Scene插件来导入障碍物并且对障碍物进行编辑,现在我们在前边学习内容的基础上,通过代码加入一个障碍物,看下会对运动规划有什么影响。

  1. // 包含API的头文件
  2. #include <moveit/move_group_interface/move_group.h>
  3. #include <moveit/planning_scene_interface/planning_scene_interface.h>
  4. #include <moveit_msgs/AttachedCollisionObject.h>
  5. #include <moveit_msgs/CollisionObject.h>
  6.  
  7. int main(int argc, char **argv)
  8. {
  9.     ros::init(argc, argv, "add_collision_objct");
  10.     ros::NodeHandle nh;
  11.     ros::AsyncSpinner spin(1);
  12.     spin.start();
  13.  
  14.     // 创建运动规划的情景,等待创建完成
  15.     moveit::planning_interface::PlanningSceneInterface current_scene;
  16.     sleep(5.0);
  17.  
  18.     // 声明一个障碍物的实例,并且为其设置一个id,方便对其进行操作,该实例会发布到当前的情景实例中
  19.     moveit_msgs::CollisionObject cylinder;
  20.     cylinder.id = "seven_dof_arm_cylinder";
  21.  
  22.     // 设置障碍物的外形、尺寸等属性   
  23.     shape_msgs::SolidPrimitive primitive;
  24.     primitive.type = primitive.CYLINDER;
  25.     primitive.dimensions.resize(3);
  26.     primitive.dimensions[0] = 0.6;
  27.     primitive.dimensions[1] = 0.2;
  28.  
  29.     // 设置障碍物的位置
  30.     geometry_msgs::Pose pose;
  31.     pose.orientation.w = 1.0;
  32.     pose.position.x =  0.0;
  33.     pose.position.y = -0.4;
  34.     pose.position.z =  0.4;
  35.  
  36.     // 将障碍物的属性、位置加入到障碍物的实例中
  37.     cylinder.primitives.push_back(primitive);
  38.     cylinder.primitive_poses.push_back(pose);
  39.     cylinder.operation = cylinder.ADD;
  40.  
  41.     // 创建一个障碍物的列表,把之前创建的障碍物实例加入其中
  42.     std::vector<moveit_msgs::CollisionObject> collision_objects;
  43.     collision_objects.push_back(cylinder);
  44.  
  45.     // 所有障碍物加入列表后(这里只有一个障碍物),再把障碍物加入到当前的情景中,如果要删除障碍物,使用removeCollisionObjects(collision_objects)
  46.     current_scene.addCollisionObjects(collision_objects);
  47.  
  48.     ros::shutdown();
  49.  
  50.     return 0;
  51. }

我们再来编译运行一下,看看会发生什么。

  1. $ roslaunch seven_dof_arm_config demo.launch
  2. $ rosrun seven_dof_arm_test add_collision_objct

   稍等五秒钟,有没有看到,现在界面中多了一个圆柱体。

clip_image008

scene objects中可以对障碍物的属性进行再次调整。

        clip_image010

   障碍物加入之后,再运动机械人的时候,就会检测机器人是否会与障碍物发生碰撞,比如我们用鼠标拖动机器人的终端,让机器人和障碍物发生碰撞:

clip_image012

有没有看到机械臂的部分links变成了红色,这就说明这些links和障碍物发生了碰撞,如果此时进行运动规划,会提示错误的。

clip_image014

上面的代码只是在场景中加入了障碍物,碰撞检测由moveit的插件完成,那么我们如何通过代码来检测是否发生了碰撞呢?可以学习源码包中的 check_collision.cpp

  1. #include <ros/ros.h>
  2. // 包含moveit的API
  3. #include <moveit/robot_model_loader/robot_model_loader.h>
  4. #include <moveit/planning_scene/planning_scene.h>
  5. #include <moveit/kinematic_constraints/utils.h>
  6. #include <eigen_conversions/eigen_msg.h>
  7.  
  8. int main(int argc, char **argv)
  9. {
  10.   ros::init (argc, argv, "arm_kinematics");
  11.   ros::AsyncSpinner spinner(1);
  12.   spinner.start();
  13.  
  14.   // 加载机器人的运动学模型到情景实例中
  15.   robot_model_loader::RobotModelLoader robot_model_loader("robot_description");
  16.   robot_model::RobotModelPtr kinematic_model = robot_model_loader.getModel();
  17.   planning_scene::PlanningScene planning_scene(kinematic_model);
  18.  
  19.   // 自身碰撞检测
  20.   // 首先需要创建一个碰撞检测的请求对象和响应对象,然后调用碰撞检测的API checkSelfCollision,检测结果会放到collision_result中
  21.   collision_detection::CollisionRequest collision_request;
  22.   collision_detection::CollisionResult collision_result;
  23.   planning_scene.checkSelfCollision(collision_request, collision_result);
  24.   ROS_INFO_STREAM("1. Self collision Test: "<< (collision_result.collision ? "in" : "not in")
  25.                   << " self collision");
  26.  
  27.   // 修改机器人的状态
  28.   // 我们可以使用场景实例的getCurrentStateNonConst()获取当前机器人的状态,然后修改机器人的状态到一个随机的位置,
  29.   // 清零collision_result的结果后再次检测机器人是否发生滋生碰撞
  30.   robot_state::RobotState& current_state = planning_scene.getCurrentStateNonConst();
  31.   current_state.setToRandomPositions();
  32.   collision_result.clear();
  33.   planning_scene.checkSelfCollision(collision_request, collision_result);
  34.   ROS_INFO_STREAM("2. Self collision Test(Change the state): "<< (collision_result.collision ? "in" : "not in"));
  35.  
  36.   // 我们也可以指定查询一个group是否和其他部分发生碰撞,只需要在collision_request中修改group_name属性
  37.   collision_request.group_name = "arm";
  38.   current_state.setToRandomPositions();
  39.   collision_result.clear();
  40.   planning_scene.checkSelfCollision(collision_request, collision_result);
  41.   ROS_INFO_STREAM("3. Self collision Test(In a group): "<< (collision_result.collision ? "in" : "not in"));
  42.  
  43.   // 获取碰撞关系
  44.   // 首先,我们先让机器人发生自身碰撞 
  45.   std::vector<double> joint_values;
  46.   const robot_model::JointModelGroup* joint_model_group =
  47.   current_state.getJointModelGroup("arm");
  48.   current_state.copyJointGroupPositions(joint_model_group, joint_values);
  49.   joint_values[2] = 1.57; //原来的代码这里是joint_values[0],并不会导致碰撞,我改成了joint_values[2],在该状态下机器人会发生碰撞
  50.   current_state.setJointGroupPositions(joint_model_group, joint_values);
  51.   ROS_INFO_STREAM("4. Collision points "
  52.                   << (current_state.satisfiesBounds(joint_model_group) ? "valid" : "not valid"));
  53.  
  54.   // 然后我们再来检测机器人是否发生了自身碰撞,已经发生碰撞的是哪两个部分
  55.   collision_request.contacts = true;
  56.   collision_request.max_contacts = 1000;
  57.   collision_result.clear();
  58.   planning_scene.checkSelfCollision(collision_request, collision_result);
  59.   ROS_INFO_STREAM("5. Self collision Test: "<< (collision_result.collision ? "in" : "not in")
  60.                   << " self collision");
  61.  
  62.   collision_detection::CollisionResult::ContactMap::const_iterator it;
  63.   for(it = collision_result.contacts.begin();
  64.       it != collision_result.contacts.end();
  65.       ++it)
  66.   {
  67.     ROS_INFO("6 . Contact between: %s and %s",
  68.              it->first.first.c_str(),
  69.              it->first.second.c_str());
  70.   }
  71.  
  72.   // 修改允许碰撞矩阵(Allowed Collision Matrix,acm)
  73.   // 我们可以通过修改acm来指定机器人是否检测自身碰撞和与障碍物的碰撞,在不检测的状态下,即使发生碰撞,检测结果也会显示未发生碰撞
  74.   collision_detection::AllowedCollisionMatrix acm = planning_scene.getAllowedCollisionMatrix();
  75.   robot_state::RobotState copied_state = planning_scene.getCurrentState();
  76.   collision_detection::CollisionResult::ContactMap::const_iterator it2;
  77.   for(it2 = collision_result.contacts.begin();
  78.       it2 != collision_result.contacts.end();
  79.       ++it2)
  80.   {
  81.     acm.setEntry(it2->first.first, it2->first.second, true);
  82.   }
  83.   collision_result.clear();
  84.   planning_scene.checkSelfCollision(collision_request, collision_result, copied_state, acm);
  85.  
  86.   ROS_INFO_STREAM("6. Self collision Test after modified ACM: "<< (collision_result.collision ? "in" : "not in")
  87.                   << " self collision");
  88.  
  89.   // 完整的碰撞检测
  90.   // 同时检测自身碰撞和与障碍物的碰撞
  91.   collision_result.clear();
  92.   planning_scene.checkCollision(collision_request, collision_result, copied_state, acm);
  93.  
  94.   ROS_INFO_STREAM("6. Full collision Test: "<< (collision_result.collision ? "in" : "not in")
  95.                   << " collision");
  96.  
  97.   ros::shutdown();
  98.   return 0;
  99. }

编译运行:

  1. $ roslaunch seven_dof_arm_config demo.launch
  2. $ roslaunch seven_dof_arm_test check_collision

     可以看到碰撞检测的结果:

clip_image016

 

  更多MoveIt API的使用例程还可以参考下边的链接:

http://docs.ros.org/indigo/api/pr2_moveit_tutorials/html/planning/src/doc/move_group_interface_tutorial.html

 

  还有MoveIt interfaceClass文档:

http://docs.ros.org/indigo/api/moveit_ros_planning_interface/html/classmoveit_1_1planning__interface_1_1MoveGroup.html


原创文章,转载请注明: 转载自古月居

本文链接地址: ROS探索总结(二十六)——MoveIt编程

微信 OR 支付宝 扫描二维码
为本文作者 打个赏
pay_weixinpay_weixin

评论

70条评论
  1. Gravatar 头像

    刘奇奇 回复

    古老师您好,我想问一下,我按照您的步骤,在我的工作空间下创建了seven_dof_arm_test功能包,在src目录下创建了随机轨迹文件test_random.cpp,请问怎么更改CMakeLists.txt文件?
    我这么添加的,老是出错:
    add_executable(test_random src/test_random.cpp)
    target_link_libraries(test_random ${catkin_LIBRARIES} ${Boost_LIBRARIES})
    install(TARGETS test_random DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION})

  2. Gravatar 头像

    郭剑 回复

    请问一下 AttachedCollisionObject 和 CollisionObject 有什么区别?

  3. Gravatar 头像

    tak 回复

    @古月 你好 我想问下 如果机器人在moveit 规划轨迹时,约束末端执行器pitch 和roll 角度不变,但是不约束yaw,程序应该怎么写或者怎么MoveIt 怎么设置

    • 古月

      古月 回复

      @tak 不好意思,这个问题暂时我也不清楚怎么使用moveit设置

  4. Gravatar 头像

    liqi 回复

    古月神您好,我在学习Mastering ROS for Robotic Programming这本书的时候,想实习实现抓取放置操作,下载了Moveit_simple_grasp这个package以后catkin_make通过了
    但是运行roslaunch seven_dof_arm_gazebograsp_generator_server.launch这个指令的时候出现了错误,如下

    SUMMARY
    ========

    PARAMETERS
    * /moveit_simple_grasps_server/base_link: base_link
    * /moveit_simple_grasps_server/end_effector: gripper
    * /moveit_simple_grasps_server/gripper/end_effector_name: gripper
    * /moveit_simple_grasps_server/gripper/end_effector_parent_link: gripper_roll_link
    * /moveit_simple_grasps_server/gripper/grasp_pose_to_eef: [0.0, 0.0, 0.0]
    * /moveit_simple_grasps_server/gripper/grasp_pose_to_eef_rotation: [0.0, 0.0, 0.0]
    * /moveit_simple_grasps_server/gripper/grasp_posture: [1.0, 1.0]
    * /moveit_simple_grasps_server/gripper/grasp_time_from_start: 4.0
    * /moveit_simple_grasps_server/gripper/joints: ['finger_joint1',...
    * /moveit_simple_grasps_server/gripper/postplace_time_from_start: 4.0
    * /moveit_simple_grasps_server/gripper/pregrasp_posture: [0.0, 0.0]
    * /moveit_simple_grasps_server/gripper/pregrasp_time_from_start: 4.0
    * /moveit_simple_grasps_server/group: arm
    * /rosdistro: indigo
    * /rosversion: 1.11.21

    NODES
    /
    moveit_simple_grasps_server (moveit_simple_grasps/moveit_simple_grasps_server)

    ROS_MASTER_URI=http://localhost:11311

    core service [/rosout] found
    process[moveit_simple_grasps_server-1]: started with pid [4196]
    [ERROR] [1507774107.485511281]: Grasp configuration parameter `pregrasp_time_from_start` missing from rosparam server. Did you load your end effector's configuration yaml file? Searching in namespace: /moveit_simple_grasps_server/right
    moveit_simple_grasps_server: /usr/include/boost/smart_ptr/shared_ptr.hpp:653: typename boost::detail::sp_member_access::type boost::shared_ptr::operator->() const [with T = const moveit::core::RobotModel; typename boost::detail::sp_member_access::type = const moveit::core::RobotModel*]: Assertion `px != 0' failed.
    [moveit_simple_grasps_server-1] process has died [pid 4196, exit code -6, cmd /home/liqi/catkin_ws/devel/lib/moveit_simple_grasps/moveit_simple_grasps_server __name:=moveit_simple_grasps_server __log:=/home/liqi/.ros/log/d1043298-ae95-11e7-845f-000c29b384c9/moveit_simple_grasps_server-1.log].
    log file: /home/liqi/.ros/log/d1043298-ae95-11e7-845f-000c29b384c9/moveit_simple_grasps_server-1*.log
    all processes on machine have died, roslaunch will exit
    shutting down processing monitor...
    ... shutting down processing monitor complete

    为什么参数服务器上找不到pregrasp_time_from_start这个参数呢,通过rosparam get都能够输出他的值,然后另一个错误是Boost库的智能指针未初始化,请问古月君该如何解决,感激不尽。

  5. Gravatar 头像

    孔维霞 回复

    你好,这个是我结合您跟另外一个人的教程编写的
    运行roslaunch lwr_description demo.launch时
    while processing /opt/ros/indigo/share/urdf/launch/planning_context.launch:
    Invalid roslaunch XML syntax: [Errno 2] No such file or directory: u'/opt/ros/indigo/share/urdf/launch/'
    The traceback for the exception was written to the log file
    这个是什么原因阿,planning_context.launch这个文件和demo.launch都在文件夹里阿。

    • 古月

      古月 回复

      @孔维霞 路径不对吧,为什么是/opt/ros/indigo/share/urdf/launch/,应该是你所用的功能包路径吧

  6. Gravatar 头像

    redundant manipulator 回复

    古月居,怎么让机器人 在两点之间走直线或者圆弧,或者直接让机器人走一个椭圆路径?求解释或者 给出相应的网站

    • 古月

      古月 回复

      @redundant manipulator 走直线可以用MoveIt!的笛卡尔运动,圆弧需要自己实现,可以参考机器人学教科书中的轨迹规划

      • Gravatar 头像

        redundant manipulator 回复

        @古月 古老师,走线段已经实现了,最关键的一步,我想查看机器人走线段过程中的运动学逆解,也就是关节空间轨迹。我查看了一下,MoveIt! Visual Tools这个工具包。但是哪个函数是把关节轨迹发布的?然后用rqt_plot 就能画出关节空间轨迹
        。 或者有没有其他方法?

        • 古月

          古月 回复

          @redundant manipulator FollowJointsTrajectory是关节空间的轨迹,可以打印出来看,或者打印joints_state话题,是实时的关节状态

          • Gravatar 头像

            redundant manipulator 回复

            @古月 有3处关节偏置的7自由度机器人MotomanVA1400 走线段已经实现了,求逆解用的trac-ik插件。有个问题,实现走线段的 关节轨迹是连续的,没有突变,这令我震惊,因为7自由度 在一个末端位恣上有无穷多个逆解,算法是怎么选择的? 是以上一个位恣逆解作为 待求下一个待求位恣的迭代初始值么?
            我在看代码,代码层层调用的逆解函数太多了,第1层是 服务包装的函数
            bool move_group::MoveGroupCartesianPathService::computeService(moveit_msgs::GetCartesianPath::Request& req,
            moveit_msgs::GetCartesianPath::Response& res)
            第2层 double moveit::core::RobotState::computeCartesianPath(。。。)
            用步长路径离散,把每一个离散点及姿态传入下一层函数。
            是不是借助回调函数,更新当前的RobotState类的成员变量,来保存逆解值的?如下

            if (setFromIK(group, pose, link->getName(), 1, 0.0, validCallback, options))
            {
            traj.push_back(RobotStatePtr(new RobotState(*this)));
            }
            第3层 bool moveit::core::RobotState::setFromIK()
            这个函数太长了。。。。。。
            solver->searchPositionIK()
            重点 好多个,没抓住一个 ??
            4层才是真正实现
            searchPositionIK()
            qq:593859610

  7. Gravatar 头像

    烤鸡排 回复

    古神,我想请问一下,我在使用moveit的配置助手时运行第一步creat然后按第一步load,当运行到70%时,闪退了,怎么办?

    boss@boss-virtual-machine:~$ catkin_create_pkg seven_dof_arm_test catkin cmake_modules interactive_markers moveit_core moveit_ros_perception moveit_ros_planning_interface pluginlib roscpp std_msgs
    usage: catkin_create_pkg [-h] [--meta] [-s [SYS_DEPS [SYS_DEPS ...]]]
    [-b [BOOST_COMPS [BOOST_COMPS ...]]] [-V PKG_VERSION]
    [-D DESCRIPTION] [-l LICENSE] [-a AUTHOR]
    [-m MAINTAINER] [--rosdistro ROSDISTRO]
    name [dependencies [dependencies ...]]
    catkin_create_pkg: error: File exists: /home/boss/seven_dof_arm_test/CMakeLists.txt
    boss@boss-virtual-machine:~$ roslaunch seven_dof_arm_config demo.launch
    [demo.launch] is neither a launch file in package [seven_dof_arm_config] nor is [seven_dof_arm_config] a launch file name
    The traceback for the exception was written to the log file
    boss@boss-virtual-machine:~$ $ rosrun seven_dof_arm_test test_random_node
    $:未找到命令
    boss@boss-virtual-ma

    这些是它跳出来的代码。求古神帮忙!!!

    • 古月

      古月 回复

      @烤鸡排 上边的代码不是你建功能包的命令么?你用配置助手试试其他机械臂模型,或者把源码中的机器人模型单独拿出来,在配置助手里新建功能包

  8. Gravatar 头像

    pdmike 回复

    古神 你好 我直接把Mastering ROS for Robotics Programming 中 第十章的demo 直接复制到我的工作区进行编译 但是编译出错
    ####
    #### Running command: "make -j1 -l1" in "/home/aicrobo/catkin_ws/build"
    ####
    Scanning dependencies of target add_collision_objct
    [ 14%] Building CXX object seven_dof_arm_test/CMakeFiles/add_collision_objct.dir/src/add_collision_objct.cpp.o
    Linking CXX executable /home/aicrobo/catkin_ws/devel/lib/seven_dof_arm_test/add_collision_objct
    [ 14%] Built target add_collision_objct
    Scanning dependencies of target check_collision
    [ 28%] Building CXX object seven_dof_arm_test/CMakeFiles/check_collision.dir/src/check_collision.cpp.o
    Linking CXX executable /home/aicrobo/catkin_ws/devel/lib/seven_dof_arm_test/check_collision
    [ 28%] Built target check_collision
    Scanning dependencies of target find_ee_coordinate
    [ 42%] Building CXX object seven_dof_arm_test/CMakeFiles/find_ee_coordinate.dir/src/find_ee_coordinate.cpp.o
    Linking CXX executable /home/aicrobo/catkin_ws/devel/lib/seven_dof_arm_test/find_ee_coordinate
    /opt/ros/indigo/lib/libmoveit_planning_scene_monitor.so: undefined reference to `ros::WallTimer::setPeriod(ros::WallDuration const&, bool)'
    collect2: error: ld returned 1 exit status
    make[2]: *** [/home/aicrobo/catkin_ws/devel/lib/seven_dof_arm_test/find_ee_coordinate] Error 1
    make[1]: *** [seven_dof_arm_test/CMakeFiles/find_ee_coordinate.dir/all] Error 2
    make: *** [all] Error 2
    Invoking "make -j1 -l1" failed
    有两个demo是编译通过 其余都是这个错,麻烦帮我看下是什么问题 谢谢

      • Gravatar 头像

        pdmike 回复

        @古月 indigo 网上整合的

      • Gravatar 头像

        pdmike 回复

        @古月 感谢古神 已经搞定 第二链接很给力

          • Gravatar 头像

            pdmike 回复

            @古月 古神 还有个问题 就是我用的是UR机器人 我在RVIZ中导入的官方模型,如果我现在要在机械臂上加入一个工具,比如抓手,然后我的抓手模型是proe画的,应该怎么加,是用proe转solidworks再导入,还是直接转成dae格式的3D文件,用RVIZ中的scene objects 导入?

            • 古月

              古月 回复

              @pdmike 如果你的抓手是有关节需要控制的,就需要转换成URDF模型,加到UR的模型里,dae格式没办法控制

              • Gravatar 头像

                pdmike 回复

                @古月 如果不控制 只是将一个工具3d模型与机器人法兰盘相连,应该怎么做比较简单

                • 古月

                  古月 回复

                  @pdmike 可以在UR的模型法兰盘前端加一个link,然后关联dae文件

                  • Gravatar 头像

                    pdmike 回复

                    @古月 古神 怎么把用solidworks URDF 插件转化好的工具机械手模型和现有的UR机械臂urdf在ROS中进行整合啊 有教程吗

                    • 古月

                      古月

                      @pdmike 这个就是URDF模型的编辑,参考URDF的教程就行,应该设计一个joint和一个link就行

                  • Gravatar 头像

                    pdmike 回复

                    @古月 搞定了 古神 谢谢 还有个问题 就是那个调整各个轴位置的joint state 界面 是怎么打开的?

                    • 古月

                      古月

                      @pdmike 这个需要启动joint_state_publisher节点

  9. Gravatar 头像

    sunanger 回复

    月哥你好,感谢你的分享!
    小弟在开发时遇到一个问题,我的机器人时四自由度,有一个平移关节,用moveit_setup_assistant配置好后,在kinematic.yaml中设置了position_only_ik : true选项,这时运行demo.launch,可以自由的拖动交互工具,但我再用代码开发时,使用set_position_target函数时,一直是无法成功,但改为set_random_target就可以,我确认我设置的position的位置是可以达到的,请问大侠这时怎么回事啊?无比感激。

    • 古月

      古月 回复

      @sunanger 这个我也没办法确定是什么问题,试一下修改运动学插件

  10. Gravatar 头像

    dechao 回复

    月哥,请教个问题,
    1.这里的碰撞检测是不是使用的FCL库?
    2.自身碰撞检测这个有对应的源码吗?一直没有找到。
    谢谢

    • 古月

      古月 回复

      @dechao MoveIt默认使用的是FCL。
      源码参考:http://wiki.ros.org/fcl

  11. Gravatar 头像

    Y-liberal 回复

    古月老师,上面第一个程序里面定义的my_plan,我认为是group.plan()这个函数将轨迹值放入了my_plan这个结构体里面了,但是我用ROS_INFO("%s",my_plan)这行代码运行之后,完全是空白,不知道怎样才能显示my_plan的值呢?或者是我对程序里面的my_plan的理解有误,请您指教一下。

    • 古月

      古月 回复

      @Y-liberal 不能这样打印, my_plan是moveit::planning_interface::MoveGroup::Plan结构体,看一下http://docs.ros.org/jade/api/moveit_ros_planning_interface/html/structmoveit_1_1planning__interface_1_1MoveGroup_1_1Plan.html,打印里边的trajectory_

      • Gravatar 头像

        Y-liberal 回复

        @古月 古月老师,我用ROS_INFO("%s",my_plan.trajectory_)在打印trajectroy_的时候,有一个warning提示说moveit
        _msgs::RobotTrajectory {aka moveit_msgs::RobotTraje
        ctory_<std::allocator >}
        后来又换成了%f, %d, <ste::allocator>等各种数据类型,都显示不出来,我不知道问题出在哪里。

        • 古月

          古月 回复

          @Y-liberal trajectroy_不是字符串或者整型数,是结构体,不能这样打印,看下这个数据结构是什么样的,打印里边的值

          • Gravatar 头像

            Y-liberal 回复

            @古月 哦,那我再看一下,谢谢古月老师。

  12. Gravatar 头像

    海漩涡 回复

    月哥你好
    使用moveit的接口setFromIK进行运动学反解
    此接口需要pose:包含位置和姿态,然而我只想给位置不关注姿态,这样moveit里能实现吗

      • Gravatar 头像

        海漩涡 回复

        @古月 有什么办法能获得有效的姿态?因为我随便设的姿态无法得到反解结果。

        • Gravatar 头像

          王振利 回复

          @海漩涡 请问大侠,我也设置了positon_only_ik,但是在demo.lauch中可以,在代码中执行就不行,请问是为什么

  13. Gravatar 头像

    杨记周 回复

    古月大神,最近一直在学习您的moveit编程,也有很多收获,可是我在学习的时候却遇到了几个问题,这些问题也已经困扰了我几天了,所以想向您请教以下.当我使用自定义目标位置并完成规划时,如果我使用group.move()时,机械臂会执行,当我使用group.plan()规划时,就会提示无法解决规划问题的错误,机械臂也不会执行相应动作.还有我指定的一些目标点明明时可以到达的(我在rviz中已经测试可以到达),当我执行group.move()或者group.plan(),也会提示这种错误:
    [ INFO] [1500121663.842961617]: Unable to solve the planning problem
    [ERROR] [1500121663.843402246]: Unable to transform from frame '' to frame '/base_link'. Returning identity.
    真心希望您能帮我解决这个问题,非常感谢!

  14. Gravatar 头像

    daishij 回复

    博主您好 有个问题想请教一下,在运行test_random.cpp后发生错误如下 不知该如何解决
    [ INFO] [1497407451.190135995]: Loading robot model 'mico'...
    [ INFO] [1497407451.190278606]: No root/virtual joint specified in SRDF. Assuming fixed joint
    [ INFO] [1497407451.434377821]: Loading robot model 'mico'...
    [ INFO] [1497407451.434418702]: No root/virtual joint specified in SRDF. Assuming fixed joint
    [ INFO] [1497407452.258207938]: TrajectoryExecution will use old service capability.
    [ INFO] [1497407452.258269802]: Ready to take MoveGroup commands for group mico_arm.
    [ INFO] [1497407452.290881463]: ABORTED: No motion plan found. No execution attempted.
    运行demo的窗口报错如下:
    [ WARN] [1497407936.118023847]: Unable to find a valid state nearby the start state (using jiggle fraction of 0.050000 and 100 sampling attempts). Passing the original planning request to the planner.
    [ WARN] [1497407936.118554278]: LBKPIECE1: Skipping invalid start state (invalid state)
    [ERROR] [1497407936.118688816]: LBKPIECE1: Motion planning start tree could not be initialized!
    [ INFO] [1497407936.118785454]: No solution found after 0.000292 seconds
    [ WARN] [1497407936.128501546]: Goal sampling thread never did any work.
    [ INFO] [1497407936.128587437]: Unable to solve the planning problem
    非常感谢

    • 古月

      古月 回复

      @daishij 请参考:https://groups.google.com/forum/#!topic/moveit-users/a3W5sQcxRAM

  15. Gravatar 头像

    Candy 回复

    博主你好,看您的微博学到了很多有用的ROS相关知识,受益匪浅。我在 moveit 编程随机轨迹这里复制了示例的test_random.cpp并修改Camkelist.text 后编译显示
    CMake Error at /opt/ros/hydro/share/catkin/cmake/catkinConfig.cmake:75 (find_package):
    Could not find a configuration file for package cmake_modules.

    Set cmake_modules_DIR to the directory containing a CMake configuration
    file for cmake_modules. The file will have one of the following names:

    cmake_modulesConfig.cmake
    cmake_modules-config.cmake

    这样的错误,不知道为什么,求能解答一下!

  16. Gravatar 头像

    jimmyjiao 回复

    博主您好,看到您的博客收获很大。现在有个问题想请教下您。激光雷达的有效距离是在30cm-8m,也就是说当激光雷达扫到30cm之内时,无法得到数据。这个在移动机器人中,应该不少见吧,您当时是如何解决这样的问题的?举个例子,如果在比较狭窄的环境中,比如说迷宫,当小车卡在某个角落中,按照movebase包的原理,会原地打转,但是如果左右两边检测到了障碍物,就卡住了,无法逃离当前状态。

    • 古月

      古月 回复

      @jimmyjiao 你好,这个问题确实经常遇到,我之前试过用超声波检测近距离的障碍,辅助避障。另外你用的激光雷达盲区有30cm么,激光雷达盲区应该比较小,确定不是红外?

  17. Gravatar 头像

    Shawn 回复

    在test_custom.cpp例子中,源码多了几行代码,我没看懂,
    moveit::planning_interface::PlanningSceneInterface
    planning_scene_interface;
    ros::Publisher display_publisher =
    node_handle.advertise("/move_group/
    display_planned_path", 1, true);
    moveit_msgs::DisplayTrajectory display_trajectory;

    进行了初始化,却没有在后面的代码中用上。

    您也提到这部分代码是冗余的,删除了。

    原作者留下这部分代码的用意是什么?

    • 古月

      古月 回复

      @Shawn 这个应该是用于rviz显示路径的,没有用到

  18. Gravatar 头像

    海漩涡 回复

    月哥,你好
    我在弄随机轨迹那个例子时,我的程序总是卡在move这个函数不往下走了,但是机器人是动了的。

    操作多次,结果都一样。请问下你当时的效果也是这样的吗

    • 古月

      古月 回复

      @海漩涡 我运行的时候是没有问题的,你试一下《Mastering ROS for robotics Programming》里边提供的源码,或者在rviz中用target设置一下目标位置。

  19. Gravatar 头像

    海漩涡 回复

    月哥,我最近在研究moveit,使用它对机器人的手臂进行控制。
    在博客的评论里问了你很多问题了,感觉这样交流不是很方面

    望能够提供QQ或邮箱,日后能更好的交流。
    我的QQ469249801

  20. Gravatar 头像

    海漩涡 回复

    月哥,请教下你有没有用moveit的compute_cartesian_path接口来计算一系列waypoints的轨迹

    我在使用此接口时规划的结果是 30% 45% 80% 等都有。

    我想知道怎么正确的使用此接口?

    • 古月

      古月 回复

      @海漩涡 你好,这个接口我很早以前试过,好像不太好用,就是按照文档上的说明使用的

  21. Gravatar 头像

    章金锋 回复

    古月,您好,不知道怎么能联系上您,所以只能给您留言了,我是上海哲谦应用科技的,说大了就是看你的文章在学习,直接点就是想找您合作,方便的话,您能把你的联系方式发到我的邮箱吗?zzhang0617@163.com 希望您能看到我的这条留言,也希望您能给我发个联系邮件,我们具体谈,谢谢!

  22. Gravatar 头像

    增达信购 回复

    我对你博客的爱,你永远不会明白!

  23. Gravatar 头像

    tanxiaohai 回复

    月哥你好,看了你几篇文章了学到了很多,非常感谢

    想请教你个问题:
    我在网上下载的urdf通过setup assistant进行配置完后,想用artibox模拟器来进行运动规划的测试。
    我现在遇到的问题是我能跑起:
    /arbotix
    /right_gripper_controller
    /robot_state_publisher

    这三个节点,我想用rviz来显示我的机器人,之后再用moveIt来控制。但是我确在配置文件中找不到rviz的配置文件。

    请问下怎样才能获得与urdf对应的rviz配置文件???

    • 古月

      古月 回复

      @tanxiaohai 你好,用setup assistant生成的rviz配置文件在configb包的launch文件夹下,moveit.rviz

  24. Gravatar 头像

    王聪 回复

    想问一下能在kinetic上安装moveit吗?官方好像还没有,但是ubuntu装的16版本

    • 古月

      古月 回复

      @王聪 你好,我没试过kinetic版本,但是我看到moveit有这个版本的源码,应该是可以安装的,用tab试一下

发表评论

电子邮件地址不会被公开。 必填项已用*标注