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

news/2024/9/18 3:10:58/文章来源:https://www.cnblogs.com/ai-ldj/p/18409914

拾取和放置

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

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/795960.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高等数学 1.9 连续函数的运算与初等函数的连续性

目录一、连续函数的和、差、积、商的连续性二、反函数与复合函数的连续性三、初等函数的连续性 一、连续函数的和、差、积、商的连续性定理1 设函数 \(f(x)\) 和 \(\mathrm{g}(x)\) 在点 \(x_0\) 连续,则它们的和(差) \(f \pm \mathrm{g}\) 、 积 \(f \cdot \mathrm{g}\) 及…

美团面试:G1 垃圾回收底层原理是什么?说说你的调优过程?

文章很长,且持续更新,建议收藏起来,慢慢读!疯狂创客圈总目录 博客园版 为您奉上珍贵的学习资源 : 免费赠送 :《尼恩Java面试宝典》 持续更新+ 史上最全 + 面试必备 2000页+ 面试必备 + 大厂必备 +涨薪必备 免费赠送 :《尼恩技术圣经+高并发系列PDF》 ,帮你 实现技术自由,…

Diffusion系列 - DDPM 公式推导 + 代码 -(二)

Denoising Diffusion Probabilistic Model(DDPM)原理1. 生成模型对比 记 真实图片为 \(x_0\),噪声图片为 \(x_t\),噪声变量 \(z\sim \mathcal{N}(\mu,\sigma^2)\),噪声变量 \(\varepsilon \sim \mathcal{N}(0,I)\),编码过程 \(q\),解码过程 \(p\)。 GAN网络 \[z\xrightarr…

springboot启动apache版本报错

springboot An incompatible version [1.2.32] of the Apache Tomcat Native library is installed, while Tomcat requires version [1.2.34] 解决办法: 到tomcat的链接地址,找对应的版本 http://archive.apache.org/dist/tomcat/tomcat-connectors/native/ 找到1.2.34下的 …

算法 - 课程笔记

调度问题插入排序分治法 分治法是将原问题划分为多个规模较小的子问题,这些子问题可以独立求解,将子问题的解进行综合得到原问题的解。算法设计一般使用递归算法,算法分析一般使用递归表达式。归并排序 归并排序,就是分组再合并,将一个数组等分为左右两个子数组,然后再使…

学弟去字节面试,一小时被问了 50 题。。

分享一下我问的题目,大家也可以试着答答看。大家好,我是程序员鱼皮。昨天直播面试了一位 25 届的学弟,暂且就叫他 “阿强” 吧。 阿强非常优秀,不仅有半年的实习经历、有自己的项目,而且还参加过大厂(字节)的面试。 面试开场前,我问学弟:你上次面试字节时,感受如何?…

绩效考核中如何做自我评估

绩效考核中,员工的自我评估是一个重要环节。如何能将自己的现状,表现,能力等等用文字表达出来,是很多员工的痛苦。国外很多研究中,给了我们很多启示,今天就让我们来介绍一下海外在员工自我评估中的一些研究成果。自我评估的重要性 自我评估对员工和管理者同样有用。评估通…

为什么chrome有时候无法访问github?——RuTracker插件的代理功能会让浏览器无法访问github

去插件那里把代理关掉就行了(把滑块点成灰色) 也可以开个无痕模式,无痕的黑窗口会忽略一些插件

PbootCMS后台访问地址及默认帐号密码是多少

PBootCMS 的后台默认账号和密码通常会在官方文档或开发手册中给出。如果你在源码包中没有找到相关信息,可以参考以下默认设置: 默认后台访问路径后台访问路径:http(s)://yourdomain.com/admin.php将yourdomain.com替换为你的实际域名。默认账号和密码初始账号:admin 初始密…

pbootcms升级提示 执行SQL发生错误!错误:duplicate column name: picstitle

当你在升级PBootCMS时遇到“执行SQL发生错误!错误:duplicate column name: picstitle”的问题,这通常表示在升级过程中,数据库表结构的变更脚本未能正确执行,导致新的字段名称与现有字段冲突。以下是如何解决这个问题的一些步骤: 解决方案备份数据库:在进行任何数据库操…

pbootcms伪静态设置教程含apache、naginx、IIS不同环境配置规则

其实pbootcms伪静态已经整理好, 在根目录就可以找到 作为使用者, 只需要根据不同的服务器环境, 使用不同格式的数据就行。 naginx #请复制下面伪静态配置到nginx配置文件中: #规则适合PbootCMS V2.0+版本location / {if (!-e $request_filename){rewrite ^/(.*)$ /index.ph…