有多少人工,就有多少智能

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

拾取和放置

注意:本教程中使用的功能已弃用。要执行拾取和放置操作,应使用 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);

 

posted @ 2024-09-12 12:04  lvdongjie-avatarx  阅读(91)  评论(0编辑  收藏  举报