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

评论

112条评论
  1. Gravatar 头像

    Heisenberg 回复

    我在用程序来控制自己的一个机械臂的时候显示出来这个,
    Debug: Starting goal sampling thread
    Debug: Waiting for space information to be set up before the sampling thread can begin computation...
    [ INFO] [1516341636.616862283]: Planner configuration 'arm' will use planner 'geometric::RRTConnect'. Additional configuration parameters will be set when the planner is constructed.
    Debug: RRTConnect: Planner range detected to be 5.025360
    Info: RRTConnect: Starting planning with 1 states already in datastructure
    Debug: RRTConnect: Waiting for goal region samples ...
    Debug: Beginning sampling thread computation
    Error: RRTConnect: Unable to sample any valid states for goal tree
    at line 215 in /tmp/binarydeb/ros-kinetic-ompl-1.2.1/src/ompl/geometric/planners/rrt/src/RRTConnect.cpp
    Info: RRTConnect: Created 1 states (1 start + 0 goal)
    Info: No solution found after 5.006646 seconds
    Debug: Attempting to stop goal sampling thread...
    Debug: Stopped goal sampling thread after 0 sampling attempts

    kinetic版本的moveit 谢谢古月大神

    • 古月

      古月 回复

      @Heisenberg 运动规划失败了,试一下换一个规划的插件,或者运动学求解器

      • Gravatar 头像

        Heisenberg 回复

        @古月 请问怎么更换规划的插件呢

        • 古月

          古月 回复

          @Heisenberg 运动规划失败的话可以在rviz的moveit插件标签页中找到一个下拉列表,更换运动规划插件,也可以使用wiki上的方法修改运动学规划期,比如fastik和tracik。

  2. Gravatar 头像

    Heisenberg 回复

    古月大神,我这个模型启动后,会显示No active joints or end effectors found for group 'arm'. Make sure you have defined an end effector in your SRDF file and that kinematics.yaml is loaded in this node's namespace. 然后我用代码也控制不了。用代码发送一个命令之后直接显示一个Link 'paw' not found in model 'arm'
    [ WARN] [1516280460.185282516]: Position constraint link model paw not found in kinematic model. Constraint invalid.

    • 古月

      古月 回复

      @Heisenberg 你这个模型有问题吧,找不到规划组,用的是书里的模型么?

      • Gravatar 头像

        Heisenberg 回复

        @古月 并不是 是我自己的一个模型,现在提示No active joints or end effectors found for group 'arm'. Make sure you have defined an end effector in your SRDF file and that kinematics.yaml is loaded in this node's namespace.
        然后我在代码里面运行的时候直接输出末端执行器的名字时是可以获得末端执行器的。虽然现在显示的是这个,但是并没有提示错误,但是用代码给他一个位姿的时候,moveit会输出一个error:Error: RRTConnect: Unable to sample any valid states for goal tree
        at line 215 in /tmp/binarydeb/ros-kinetic-ompl-1.2.1/src/ompl/geometric/planners/rrt/src/RRTConnect.cpp
        感觉毫好迷啊。不像是一个时间的问题我的是六轴的,而且位姿变化并不大。

        • 古月

          古月 回复

          @Heisenberg 你说的末端执行器是机械臂之外的夹爪么?moveit配置的时候group有没有针对夹爪单独配置?运动规划失败的话可以在rviz的moveit插件标签页中找到一个下拉列表,更换运动规划插件,也可以使用wiki上的方法修改运动学规划期,比如fastik和tracik。

  3. Gravatar 头像

    heisenberg 回复

    老哥 我这个在16.04上面 试了两个机械臂 在末端执行器上都没有那个可以拖动的东西是什么情况啊 还有那个我这个plan一直提示错误error: cannot convert ‘moveit::planning_interface::MoveItErrorCode’ to ‘bool’ in initialization
    bool success = group.plan(my_plan);

  4. Gravatar 头像

    qqh 回复

    古月大哥,这个目标位置的设定有讲究吗?为什么我试了好多组都规划失败了呢?

    • 古月

      古月 回复

      @qqh 这个需要设置在机器人工作方位内,另外针对不同的运动学算法,效果也不太一样,可以使用不同的算法试一下

  5. Gravatar 头像

    dobot 回复

    胡老师,公司让做一个四自由度机械臂的运动规划,但是我做到目标位置这里时,遇到了一个问题:
    我已设置了目标位置的坐标如下:
    target_pose.orientation.w=1.0;
    target_pose.position.x=0.16;
    target_pose.position.y=0.0;
    target_pose.position.z=0.283;
    (我的四自由度模型比较小,也确定这个参数是在机器人可达范围之内的)
    但是在运行这个目标位置程序的时候出现:Fail: ABORTED: No motion plan found. No execution at tempted
    我怎么修改参数也是一直出现这个问题,而且我在网上查了各种解决办法,也修改了逆运动学插件,还是解决不了问题,最后还是换成了KDL再次尝试修改,但是一直就是不行。那么具体这个参数是如何设置的呢?怎么计算才能得到呢?

    • Gravatar 头像

      qqh 回复

      @dobot 这个目标位置的设定有讲究吗?为什么我试了好多组都规划失败了呢?

      • Gravatar 头像

        dobot 回复

        @qqh 应该是有相应的方法的,我也是尝试了好多次都失败了,所以只能咨询古大神了!

    • 古月

      古月 回复

      @dobot 首先你的模型应该是确认没有问题的,也使用MoveIt进行了正确的配置。然后再进行运动学求解的调试,可以通过代码试一下你设置的这个位置是否可以求的逆解,如果无法求解,说明是运动学部分的问题,可以试以下fast_ik或者trac_ik,这两个插件我一直在用,感觉效果还不错。

      • Gravatar 头像

        dobot 回复

        @古月 非常感谢胡老师的指导,就在刚才我先用moveit_fk_demo.py进行了运动学求解,得到我所设的这个点可以达到,那问题应该是出在运动学这块了,我先学习一下moveit官网的ikfast这个插件教程,再来检测我的模型的运动学问题,这回应该是没问题了,非常感谢胡老师迟来的指导,非常感谢!

        • 古月

          古月 回复

          @dobot 赞,不好意思,前两天在台北参加ROS Taipei年会,回复晚了。

  6. Gravatar 头像

    qqh 回复

    古月大哥,请问那个程序里给的目标位置是相对于什么坐标系来说的啊

  7. Gravatar 头像

    杨轶帆 回复

    想问一下,在catkin build moveit_tutorials的时候报错,该怎么解决。紧急。
    error: cannot convert 'moveit::planning_interface:MoveItErrorCode' to 'bool' in initialization
    bool success = move_group.plan(my_plan);
    error: cannot convert 'moveit::planning_interface:MoveItErrorCode' to 'bool' in assignment
    success = move_group.plan(my_plan);
    error: cannot convert 'moveit::planning_interface:MoveItErrorCode' to 'bool' in assignment
    success = move_group.plan(my_plan);
    error: cannot convert 'moveit::planning_interface:MoveItErrorCode' to 'bool' in assignment
    success = move_group.plan(my_plan);
    error: cannot convert 'moveit::planning_interface::moveiterrorcode' to 'bool' in assignment
    success = two_arms_move_group.plan(two_arms_plan);

    谢谢。

    • 古月

      古月 回复

      @杨轶帆 C++语法错误,plan的返回值是moveit::planning_interface:MoveItErrorCode,不是bool。可能是因为ROS版本不一致导致,可以修改代码试一下

  8. Gravatar 头像

    徐松 回复

    古月大神您好,我在学习《ROS By Example》时遇到一个问题,试了好多种方法,还是解决不了,需要请教您一下,我现在在做逆运动学求解那部分,逆运动学求解的py脚本里定义了几种位姿,其中有moveit设置好的resting、forward、wave几种状态,还有自己通过xyz坐标,xyzw四元数设定的位姿,但是执行时,resting、forward、wave都可以实现,自己设定的却求解不出来,我以为是我设定的位姿有问题,或者达不到,然后我就通过current命令输出位姿(包括position xyz,和orientation xyzw),然后把输出的位姿数据复制过去,还是求不出解,,你知道可能是什么原因吗?
    终端显示:Fail :ABORTED:No motion plan found 。No execution attempted

    • 古月

      古月 回复

      @徐松 这样描述不好确定问题所在,可能是配置的问题,对照例程代码中的配置流程检查以下,看下有没有配置坐标系等参数:

      # Set the target pose. This particular pose has the gripper oriented horizontally
      # 0.85 meters above the ground, 0.10 meters to the right and 0.20 meters ahead of
      # the center of the robot base.
      target_pose = PoseStamped()
      target_pose.header.frame_id = reference_frame
      target_pose.header.stamp = rospy.Time.now()
      target_pose.pose.position.x = 0.20
      target_pose.pose.position.y = -0.1
      target_pose.pose.position.z = 0.85
      target_pose.pose.orientation.x = 0.0
      target_pose.pose.orientation.y = 0.0
      target_pose.pose.orientation.z = 0.0
      target_pose.pose.orientation.w = 1.0

      # Set the start state to the current state
      right_arm.set_start_state_to_current_state()

      # Set the goal pose of the end effector to the stored pose
      right_arm.set_pose_target(target_pose, end_effector_link)

      # Plan the trajectory to the goal
      traj = right_arm.plan()

      # Execute the planned trajectory
      right_arm.execute(traj)

  9. Gravatar 头像

    pdmike 回复

    @古月 hello 古神 我又有问题来请教啦,就是我用RVIZ规划处一条可行轨迹后,怎么把轨迹中motion planning slider里的每个点坐标保存下来

    • 古月

      古月 回复

      @pdmike 如果配置了controller,可以看到规划出的轨迹,但只有部分路点;或者使用代码规划,并且保存轨迹,同样只有路点;如果需要获取每个周期的插补点,需要找到插补计算的相关源码。或者打印机器人的运动状态joints_state

      • Gravatar 头像

        pdmike 回复

        @古月 好的 我试下 有问题再来请教 谢谢

      • Gravatar 头像

        pdmike 回复

        @古月 @古月 我现在用代码规划可以得到整条joints_state, 怎样获取整条轨迹中末端执行器的XYZ坐标

        • 古月

          古月 回复

          @pdmike 这个需要用FK做计算,或者用TF也可以获取

  10. Gravatar 头像

    小飞 回复

    胡老师,请问cartesian_path下只能走直线,不能走圆弧吗?那假如我要绕障碍走,是只能用setposetarget来运动吗?

    • 古月

      古月 回复

      @小飞 圆弧可以细分成多个直线,然后再用cartesian_path走

  11. Gravatar 头像

    小飞 回复

    胡老师,有个问题想请教一下。自定义目标点加入不在机器人的工作空间内,规划会失败,这样就会浪费时间。能不能在规划前快速判断目标点是否在工作空间内呢?请问有什么好的建议吗?

    • 古月

      古月 回复

      @小飞 机器人的工作范围不是可以根据机械参数计算得到么,或者在规划前先用运动学计算一下是否可以求解成功

  12. Gravatar 头像

    glen 回复

    古神,我用computeCartesianPath来计算笛卡尔路径来控制机械臂走圆弧,程序如下:
    while(j < 1000 && ros::ok()){

    //计算笛卡尔坐标系路径
    double eef_resolution = std::min(0.005,radius*(angular_range / point_count));

    fraction = group.computeCartesianPath(waypointsL,eef_resolution,0.0,trajectory1);

    ROS_INFO("Visualizing plan left (cartesian path) (%.2f%% acheived)",fraction * 100.0);

    // move_group_interface::MoveGroup group("arm_group");

    if(fraction == 1.0){

    break;
    }

    // j++;
    }
    但是,有时候完成度是100%,有的时候是44%,不能保证每次100%,该怎么处理呢,困扰了好久

    • 古月

      古月 回复

      @glen 调整一下IK算法试试,也可以自己写一个圆弧算法,不用ROS中的笛卡尔规划

  13. 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})

  14. Gravatar 头像

    郭剑 回复

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

  15. Gravatar 头像

    tak 回复

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

    • 古月

      古月 回复

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

  16. 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库的智能指针未初始化,请问古月君该如何解决,感激不尽。

  17. 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/,应该是你所用的功能包路径吧

  18. 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

  19. 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

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

    • 古月

      古月 回复

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

  20. 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节点

  21. Gravatar 头像

    sunanger 回复

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

    • 古月

      古月 回复

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

  22. Gravatar 头像

    dechao 回复

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

    • 古月

      古月 回复

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

  23. 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 回复

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

  24. Gravatar 头像

    海漩涡 回复

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

      • Gravatar 头像

        海漩涡 回复

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

        • Gravatar 头像

          王振利 回复

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

  25. 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.
    真心希望您能帮我解决这个问题,非常感谢!

  26. 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

  27. 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

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

  28. Gravatar 头像

    jimmyjiao 回复

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

    • 古月

      古月 回复

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

  29. 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显示路径的,没有用到

  30. Gravatar 头像

    海漩涡 回复

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

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

    • 古月

      古月 回复

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

  31. Gravatar 头像

    海漩涡 回复

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

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

  32. Gravatar 头像

    海漩涡 回复

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

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

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

    • 古月

      古月 回复

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

  33. Gravatar 头像

    章金锋 回复

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

  34. Gravatar 头像

    增达信购 回复

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

  35. 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

  36. Gravatar 头像

    王聪 回复

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

    • 古月

      古月 回复

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

发表评论

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