首页 > 其他分享 >Ros2 - Moveit2 - Pick And Place(拾取和放置)

Ros2 - Moveit2 - Pick And Place(拾取和放置)

时间:2024-09-12 12:02:21浏览次数:14  
标签:pose collision objects Place Pick primitives place Moveit2 posture

拾取和放置

注意:本教程中使用的功能已弃用。要执行拾取和放置操作,应使用 MoveIt 任务构造器 (MTC)(使用 MoveIt 任务构造器拾取和放置)。

 

在 MoveIt 中,抓取是使用 MoveGroup 接口完成的。为了抓取一个物体,我们需要创建moveit_msgs::Graspmsg,以便定义抓取操作中涉及的各种姿势和姿态。观看此视频以查看本教程的输出:

https://youtu.be/QBJPxx_63Bs

入门

如果您还没有这样做,请确保您已经完成入门指南中的步骤。

运行演示

打开两个终端。在第一个终端中启动 RViz 并等待所有内容完成加载:

roslaunch panda_moveit_config demo.launch

在第二个终端中运行拾取和放置教程:

rosrun moveit_tutorials pick_place_tutorial

您应该会看到与本教程开头的视频类似的内容。

理解moveit_msgs::Grasp

有关完整文档,请参阅moveit_msgs/Grasp.msg。

该消息的相关字段是:-

  • trajectory_msgs/JointTrajectory pre_grasp_posture- 这定义了我们进行抓取之前末端执行器组中关节的轨迹位置。

  • trajectory_msgs/JointTrajectory grasp_posture- 定义了末端执行器组中关节抓取物体的轨迹位置。

  • geometry_msgs/PoseStamped grasp_pose- 末端执行器应尝试抓取的姿势。

  • moveit_msgs/GripperTranslation pre_grasp_approach- 这用于定义接近物体的方向和行进的距离。

  • moveit_msgs/GripperTranslation post_grasp_retreat- 这用于定义抓住物体后移动的方向和行进的距离。

  • moveit_msgs/GripperTranslation post_place_retreat- 这用于定义物体放置在某个位置后移动的方向和行进的距离。

 

完整代码

整个代码可以moveit_tutorials GitHub 项目中看到。

创建环境

创建向量来容纳 3 个碰撞对象。

std::vector<moveit_msgs::CollisionObject> collision_objects;
collision_objects.resize(3);

添加最初保存多维数据集的第一个表。

collision_objects[0].id = "table1";
collision_objects[0].header.frame_id = "panda_link0";

/* Define the primitive and its dimensions. */
collision_objects[0].primitives.resize(1);
collision_objects[0].primitives[0].type = collision_objects[0].primitives[0].BOX;
collision_objects[0].primitives[0].dimensions.resize(3);
collision_objects[0].primitives[0].dimensions[0] = 0.2;
collision_objects[0].primitives[0].dimensions[1] = 0.4;
collision_objects[0].primitives[0].dimensions[2] = 0.4;

/* Define the pose of the table. */
collision_objects[0].primitive_poses.resize(1);
collision_objects[0].primitive_poses[0].position.x = 0.5;
collision_objects[0].primitive_poses[0].position.y = 0;
collision_objects[0].primitive_poses[0].position.z = 0.2;
collision_objects[0].primitive_poses[0].orientation.w = 1.0;

添加第二张表,我们将在其中放置立方体。

collision_objects[1].id = "table2";
collision_objects[1].header.frame_id = "panda_link0";

/* Define the primitive and its dimensions. */
collision_objects[1].primitives.resize(1);
collision_objects[1].primitives[0].type = collision_objects[1].primitives[0].BOX;
collision_objects[1].primitives[0].dimensions.resize(3);
collision_objects[1].primitives[0].dimensions[0] = 0.4;
collision_objects[1].primitives[0].dimensions[1] = 0.2;
collision_objects[1].primitives[0].dimensions[2] = 0.4;

/* Define the pose of the table. */
collision_objects[1].primitive_poses.resize(1);
collision_objects[1].primitive_poses[0].position.x = 0;
collision_objects[1].primitive_poses[0].position.y = 0.5;
collision_objects[1].primitive_poses[0].position.z = 0.2;
collision_objects[1].primitive_poses[0].orientation.w = 1.0;

定义我们将要操作的对象

collision_objects[2].header.frame_id = "panda_link0";
collision_objects[2].id = "object";

/* Define the primitive and its dimensions. */
collision_objects[2].primitives.resize(1);
collision_objects[2].primitives[0].type = collision_objects[1].primitives[0].BOX;
collision_objects[2].primitives[0].dimensions.resize(3);
collision_objects[2].primitives[0].dimensions[0] = 0.02;
collision_objects[2].primitives[0].dimensions[1] = 0.02;
collision_objects[2].primitives[0].dimensions[2] = 0.2;

/* Define the pose of the object. */
collision_objects[2].primitive_poses.resize(1);
collision_objects[2].primitive_poses[0].position.x = 0.5;
collision_objects[2].primitive_poses[0].position.y = 0;
collision_objects[2].primitive_poses[0].position.z = 0.5;
collision_objects[2].primitive_poses[0].orientation.w = 1.0;

选择管道

创建要尝试的抓握向量,目前仅创建单个抓握。这在使用抓握生成器生成和测试多个抓握时非常有用。
std::vector<moveit_msgs::Grasp> grasps;
grasps.resize(1);

设置抓握姿势

这是 panda_link8 的姿势。
确保在设置 grasp_pose 时,将其设置为操纵器中最后一个链接的姿势,在本例中为panda_link8。您必须补偿从panda_link8到末端执行器手掌的变换。

grasps[0].grasp_pose.header.frame_id = "panda_link0";
tf2::Quaternion orientation;
orientation.setRPY(-M_PI / 2, -M_PI / 4, -M_PI / 2);
grasps[0].grasp_pose.pose.orientation = tf2::toMsg(orientation);
grasps[0].grasp_pose.pose.position.x = 0.415;
grasps[0].grasp_pose.pose.position.y = 0;
grasps[0].grasp_pose.pose.position.z = 0.5;

设置预抓取方法

/* Defined with respect to frame_id */
grasps[0].pre_grasp_approach.direction.header.frame_id = "panda_link0";
/* Direction is set as positive x axis */
grasps[0].pre_grasp_approach.direction.vector.x = 1.0;
grasps[0].pre_grasp_approach.min_distance = 0.095;
grasps[0].pre_grasp_approach.desired_distance = 0.115;

设置抓捕后撤退

/* Defined with respect to frame_id */
grasps[0].post_grasp_retreat.direction.header.frame_id = "panda_link0";
/* Direction is set as positive z axis */
grasps[0].post_grasp_retreat.direction.vector.z = 1.0;
grasps[0].post_grasp_retreat.min_distance = 0.1;
grasps[0].post_grasp_retreat.desired_distance = 0.25;

抓握前设置 eef 姿势

openGripper(grasps[0].pre_grasp_posture);
openGripper 函数
/* Add both finger joints of panda robot. */
posture.joint_names.resize(2);
posture.joint_names[0] = "panda_finger_joint1";
posture.joint_names[1] = "panda_finger_joint2";

/* Set them as open, wide enough for the object to fit. */
posture.points.resize(1);
posture.points[0].positions.resize(2);
posture.points[0].positions[0] = 0.04;
posture.points[0].positions[1] = 0.04;
posture.points[0].time_from_start = ros::Duration(0.5);

抓握时 eef 的姿势设定

closedGripper(grasps[0].grasp_posture);
closedGripper 功能
/* Add both finger joints of panda robot. */
posture.joint_names.resize(2);
posture.joint_names[0] = "panda_finger_joint1";
posture.joint_names[1] = "panda_finger_joint2";

/* Set them as closed. */
posture.points.resize(1);
posture.points[0].positions.resize(2);
posture.points[0].positions[0] = 0.00;
posture.points[0].positions[1] = 0.00;
posture.points[0].time_from_start = ros::Duration(0.5);

 设置支撑面为表1。

move_group.setSupportSurfaceName("table1");

调用 pick 来使用给定的抓握方式拾取物体

move_group.pick("object", grasps);

放置管道

TODO(@ridhwanluthra) - 调用 place 函数可能会导致“所有提供的 place 位置都失败。正在以详细模式重试最后一个位置。”这是一个已知问题。

理想情况下,您会创建一个要尝试的 place 位置向量,尽管在此示例中,我们仅创建了一个 place 位置。

std::vector<moveit_msgs::PlaceLocation> place_location;
place_location.resize(1);

设定地点 位置 姿势

place_location[0].place_pose.header.frame_id = "panda_link0";
tf2::Quaternion orientation;
orientation.setRPY(0, 0, M_PI / 2);
place_location[0].place_pose.pose.orientation = tf2::toMsg(orientation);

/* For place location, we set the value to the exact location of the center of the object. */
place_location[0].place_pose.pose.position.x = 0;
place_location[0].place_pose.pose.position.y = 0.5;
place_location[0].place_pose.pose.position.z = 0.5;

设置预定位方法

/* Defined with respect to frame_id */
place_location[0].pre_place_approach.direction.header.frame_id = "panda_link0";
/* Direction is set as negative z axis */
place_location[0].pre_place_approach.direction.vector.z = -1.0;
place_location[0].pre_place_approach.min_distance = 0.095;
place_location[0].pre_place_approach.desired_distance = 0.115;

设置放置后撤退

/* Defined with respect to frame_id */
place_location[0].post_place_retreat.direction.header.frame_id = "panda_link0";
/* Direction is set as negative y axis */
place_location[0].post_place_retreat.direction.vector.y = -1.0;
place_location[0].post_place_retreat.min_distance = 0.1;
place_location[0].post_place_retreat.desired_distance = 0.25;

放置物体后设置eef的姿势

/* Similar to the pick case */
openGripper(place_location[0].post_place_posture);

设置支撑面如Table2。

group.setSupportSurfaceName("table2");

调用 place 来使用给定的位置放置物体。

group.place("object", place_location);

 

标签:pose,collision,objects,Place,Pick,primitives,place,Moveit2,posture
From: https://www.cnblogs.com/ai-ldj/p/18409914

相关文章

  • ROS2 - Moveit2 - Planning with Approximated Constraint Manifolds(使用近似约束流
    使用近似约束流形进行规划OMPL支持自定义约束,以使规划轨迹遵循所需的行为。约束可以在关节空间和笛卡尔空间中定义,后者基于方向或位置。在规划轨迹时,每个关节状态都需要遵循所有设置的约束,默认情况下,这是通过拒绝采样来执行的。然而,这可能会导致非常长的规划时间,特别是当约束非......
  • Ros2 - Moveit2 - TimeParameter(时间参数化)
    时间参数化MoveIt目前主要是一个运动规划框架-它规划关节或末端执行器的位置,但不规划速度或加速度。但是,MoveIt确实利用后处理来对速度和加速度值的运动轨迹进行时间参数化。下面我们将解释MoveIt这一部分所涉及的设置和组件。 速度控制来自文件默认情况下,MoveIt将关......
  • Ros2- Moveit2 - Visualizing Collisions(可视化碰撞)
    本节将引导您了解C++示例代码,该代码可让您在RViz中移动和与机器人手臂交互时可视化机器人本身与世界之间的碰撞接触点。入门运行代码使用Roslaunch启动文件直接从moveit_tutorials运行代码:roslaunchmoveit_tutorialsvisualizing_collisions_tutorial.launch现在......
  • ROS2 - Moveit2 - 创建Moveit插件(MoveIt Plugins)
    创建MoveIt插件本节详细说明了如何在ROS中添加插件。两个必需元素是基类和插件类。插件类继承自基类并覆盖其虚拟函数。用于此目的的主要库是pluginlib。本教程包含三种不同类型的插件,即运动规划器、控制器管理器和约束采样器。运动规划器插件在本节中,我们将展示如何将新......
  • ios16.2版本以上mui的picker选择器显示异常的修复方案
    问题描述muipickerios16.2系统及以上,选择器滚动错误错乱,显示异常但是可以正常选择用多个ios手机测试了,凡是升级到16.2及以上的均会产生这个的问题。使用官方的示例,放到升级到16.2的ios手机上测试,问题同样存在https://www.dcloud.io/hellomui/examples/picker.html(这是官方案例,......
  • python中的 pickle 词解
    概述Python有pickle这个便利的功能。这个功能可以将程序运行中的对象保存为文件。如果加载保存过的pickle文件,可以立刻复原之前程序运行中的对象。解答在Python中,pickle模块用于将对象序列化(即将对象的状态转换为可存储或传输的字节流),并且能够反序列化(即从字节流恢复对象)。至......
  • 【Moveit2】MoveGroupInterface设置目标姿态,然后创建一个计划到该姿态的运动路径,stati
    PlanandExecuteusingMoveGroupInterface//CreatetheMoveItMoveGroupInterfaceusingmoveit::planning_interface::MoveGroupInterface;automove_group_interface=MoveGroupInterface(node,"panda_arm");//SetatargetPoseautoconsttarget_p......
  • ROS2- Moveit2 - 运动规划API(Motion Planning API)
     在MoveIt中,运动规划器使用插件基础结构加载。这允许MoveIt在运行时加载运动规划器。在此示例中,我们将运行执行此操作所需的C++代码。入门如果您还没有这样做,请确保您已经完成入门指南中的步骤。 运行演示打开两个shell。在第一个shell中启动RViz并等待所有内......
  • ROS2- Moveit2 -Planning Scene ROS API (规划场景 ROS API)
    在本教程中,我们将研究如何使用规划场景差异来执行两项操作:在世界中添加和移除物体将物体安装到机器人上或从机器人上卸下入门如果您还没有这样做,请确保您已经完成入门指南中的步骤。运行代码打开两个shell。在第一个shell中启动RViz并等待所有内容完成加载:ros......
  • Ros2-Moveit2-PlanningSceneMonitor(规划场景监控)
    PlanningSceneMonitor是维护最新规划场景的推荐接口。RobotState、CurrentStateMonitor、PlanningScene、PlanningSceneMonitor和PlanningSceneInterface之间的关系一开始可能非常令人困惑。本教程旨在阐明这些关键概念。机器人状态RobotState是机器人的快照。它包含RobotMod......