Ros2- Moveit2- Subrame( 子坐标 )

news/2024/11/13 9:17:37/文章来源:https://www.cnblogs.com/ai-ldj/p/18418088

子坐标是在CollisionObjects上定义的坐标。

它们可用于定义您放置在场景中的对象上的兴趣点,例如瓶子的开口、螺丝刀的尖端或螺丝的头部。它们可用于规划和编写机器人指令,例如“拿起瓶子,然后将开口移到水龙头的喷口下方”,或“拿起螺丝刀,然后将其放在螺丝头上方”。

编写专注于机器人操纵对象的代码不仅更易读,而且在机器人之间也更强大、更易于移植。本教程将向您展示如何在碰撞对象上定义子坐标,将它们发布到规划场景并使用它们来规划运动,以便您可以执行以下操作:

 

 

运行演示

完成入门中的步骤后,打开两个终端。在第一个终端中,执行此命令加载 panda,然后等待所有内容加载完成:

roslaunch panda_moveit_config demo.launch

在第二个终端运行教程:

rosrun moveit_tutorials subframes_tutorial

在这个终端您应该能够输入 1-12 的数字来发送命令,并查看机器人和场景如何反应。

代码

此示例的代码可以在 moveit_tutorials GitHub 项目中看到并在下面详细说明。

代码在规划场景中生成一个盒子和一个圆柱体,将圆柱体连接到机器人,然后让您通过命令行发送运动命令。它还定义了两个方便的函数,用于发送运动命令和发布对象。

使用子坐标定义两个 CollisionObjects

此辅助函数创建两个对象并将它们发布到 PlanningScene:一个盒子和一个圆柱体。盒子出现在夹持器前面,圆柱体出现在夹持器的尖端,就像被抓取一样。

void spawnCollisionObjects(moveit::planning_interface::PlanningSceneInterface& planning_scene_interface)
{double z_offset_box = .25;  // The z-axis points away from the gripperdouble z_offset_cylinder = .1;

首先,我们像往常一样开始定义CollisionObject 。

moveit_msgs::CollisionObject box;
box.id = "box";
box.header.frame_id = "panda_hand";
box.primitives.resize(1);
box.primitive_poses.resize(1);
box.primitives[0].type = box.primitives[0].BOX;
box.primitives[0].dimensions.resize(3);
box.primitives[0].dimensions[0] = 0.05;
box.primitives[0].dimensions[1] = 0.1;
box.primitives[0].dimensions[2] = 0.02;
box.primitive_poses[0].position.z = z_offset_box;

然后,我们定义 CollisionObject 的子坐标。子坐标在frame_id坐标系中定义,就像组成对象的形状一样。每个子坐标都包含一个名称和一个姿势。在本教程中,我们设置子坐标的方向,使子坐标的 z 轴指向远离对象的方向。这不是绝对必要的,但遵循惯例是有帮助的,并且可以避免在稍后设置目标姿势的方向时产生混淆。

box.subframe_names.resize(5);
box.subframe_poses.resize(5);box.subframe_names[0] = "bottom";
box.subframe_poses[0].position.y = -.05;
box.subframe_poses[0].position.z = 0.0 + z_offset_box;tf2::Quaternion orientation;
orientation.setRPY(90.0 / 180.0 * M_PI, 0, 0);
box.subframe_poses[0].orientation = tf2::toMsg(orientation);

最后,将对象发布到 PlanningScene。在本教程中,我们发布一个盒子和一个圆柱体。

  box.operation = moveit_msgs::CollisionObject::ADD;cylinder.operation = moveit_msgs::CollisionObject::ADD;planning_scene_interface.applyCollisionObjects({ box, cylinder });
}

创建计划请求

在本教程中,我们使用一个小辅助函数来创建规划请求并移动机器人。

bool moveToCartPose(const geometry_msgs::PoseStamped& pose, moveit::planning_interface::MoveGroupInterface& group,const std::string& end_effector_link)
{

要在规划中使用附在机器人上的对象的子坐标,您需要将 move_group 的末端效应器设置为对象的子坐标。格式必须是object_name/subframe_name,如“示例 1 ”行中所示。当您分离对象时,不要忘记将您的 end_effector_link 重置为机器人链接,并且子坐标不再是机器人的一部分!

group.clearPoseTargets();
group.setEndEffectorLink(end_effector_link);
/*
group.setEndEffectorLink("cylinder/tip");    // Example 1
group.setEndEffectorLink("panda_hand");      // Example 2
*/
group.setStartStateToCurrentState();
group.setPoseTarget(pose);

其余的规划工作照常进行。当然,你也可以使用命令go()代替 plan()execute()

  ROS_INFO_STREAM("Planning motion to pose:");ROS_INFO_STREAM(pose.pose.position.x << ", " << pose.pose.position.y << ", " << pose.pose.position.z);moveit::planning_interface::MoveGroupInterface::Plan myplan;if (group.plan(myplan) && group.execute(myplan))return true;ROS_WARN("Failed to perform motion.");return false;
}

准备场景

在主函数中,我们首先在规划场景中生成对象,然后将圆柱体附加到机器人上。附加圆柱体后,它在 Rviz 中变为紫色。

spawnCollisionObjects(planning_scene_interface);
moveit_msgs::AttachedCollisionObject att_coll_object;
att_coll_object.object.id = "cylinder";
att_coll_object.link_name = "panda_hand";
att_coll_object.object.operation = att_coll_object.object.ADD;
ROS_INFO_STREAM("Attaching cylinder to robot.");
planning_scene_interface.applyAttachedCollisionObject(att_coll_object);

交互式测试机器人

我们设置了一个小型命令行界面,以便您可以与模拟进行交互,并查看它如何响应某些命令。您可以使用它来试验机器人在移除盒子和圆柱体、重生并重新连接它们或创建新的规划请求时的行为。尝试将机器人移动到新位置并在那里重生盒子和圆柱体(它们是相对于机器人手腕生成的)。或者尝试命令 7 和 8 将不同的帧移动到空间中的相同位置。

命令“2”将圆柱尖端移动到盒子的顶部(顶部动画中的右侧)。

else if (character_input == 2)
{ROS_INFO_STREAM("Moving to top of box with cylinder tip");target_pose.header.frame_id = "box/top";target_orientation.setRPY(180.0 / 180.0 * M_PI, 0, 90.0 / 180.0 * M_PI);target_pose.pose.orientation = tf2::toMsg(target_orientation);target_pose.pose.position.z = 0.01;showFrames(target_pose, "cylinder/tip");moveToCartPose(target_pose, group, "cylinder/tip");
}

设置方向

目标姿势相对于箱体子坐标给出:

target_pose.header.frame_id = "box/bottom";

方向由 RPY 角度决定,以对齐圆柱体和箱形副车架:

target_orientation.setRPY(0, 180.0 / 180.0 * M_PI, 90.0 / 180.0 * M_PI);
target_pose.pose.orientation = tf2::toMsg(target_orientation);

为了与盒子保持一定的距离,我们使用一个小的偏移:

target_pose.pose.position.z = 0.01;
showFrames(target_pose, "cylinder/tip");
moveToCartPose(target_pose, group, "cylinder/tip");

技术说明

TF 无法识别子坐标,因此它们不能在 MoveIt 规划请求之外使用。如果您需要对子坐标进行变换,可以使用getFrameTransform函数从PlanningScene中 获取它这将返回一个Eigen::Isometry3d对象,您可以从中提取平移和四元数(请参阅此处)。然后可以使用平移和四元数来创建变换并将其注册到您的 TFListener中

可视化子坐标

目前没有子坐标的可视化!

故障排除

对于您最近没有自己生成的旧版 moveit_config 包,可能没有配置用于子坐标的规划适配器,可能找不到子坐标链接。要修复您的 moveit_config 包,请打开机器人配置文件中的 ompl_planning_pipeline.launch 文件,该文件位于 <robot_moveit_config>/launch 文件夹中。以 Panda 机器人为例,这就是这个文件。编辑此启动文件,找到提到 <arg name="planning_adapters"> 的行,然后在 default_planning_request_adapters/FixStartStatePathConstraints 之后插入 default_planning_request_adapters/ResolveConstraintFrames

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

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

相关文章

精简实用!一分钟搭建文件管理服务!

Dufs —— 一款多功能的实用文件服务器。不仅支持静态文件的托管服务,还具备文件上传、搜索以及访问控制等功能,并且兼容 WebDAV 协议,支持 HTTPS 加密连接,保障了数据传输的安全性。大家好,我是 Java陈序员。 今天,给大家介绍一款精简实用的文件托管服务,一分钟即可搭建…

微信小程序wx.request请求封装

config.js // 请求地址 const BASE_URL = "https://localhost:8080" const TIMEOUT = 10000export {BASE_URL,TIMEOUT }server.js 假设这里返回的数据结构为 {"code": 0,"msg": "提示信息","data": "返回数据" }当…

[附源码]超简洁个人博客网站搭建+SpringBoot+Vue前后端分离

今天带来一款优秀的项目:个人博客系统源码 。 系统采用的流行的前后端分离结构,内含功能包括 "写博客文章",“修改博客文章”,“富文本编辑器”,“评论管理”“管理员角色”,“游客角色”,“文章标签”,“文章分类” 如果您有任何问题,也请联系小编,小编是…

99元阿里云服务器部署若依前后端分离版(ruoyi-vue)

1. 购买阿里云 最近阿里云推出99元套餐,相当划算,薅羊毛搞起 ->新老同享阿里云99一年系统选择centos 2. 安装JDKJDK >= 1.8 虽说推荐1.8版本,但毕竟有点老,我选的JDK17,安装过程如下: # 下载安装包 wget https://download.oracle.com/java/17/archive/jdk-17.0.1_l…

.NET 开源工业级移动端仓库管理系统

前言 在工业生产中,定制化的软件对于每个环节都至关重要。对于仓库管理,推荐一款开源的仓库管理系统(WMS)解决方案。 这款基于.NET 框架开发的移动应用,提供了全面的仓库操作、订单处理、主数据管理、数据分析及个人信息设置等功能,是工业仓库管理的有利助手。 项目介绍 …

Linux下eCal测试计划及进度记录

完整的源代码包:# 安装依赖 sudo apt-get install git cmake doxygen graphviz build-essential zlib1g-dev sudo apt-get install libhdf5-dev libprotobuf-dev libprotoc-dev protobuf-compiler sudo apt-get install libcurl4-openssl-dev libqwt-qt5-dev libyaml-cpp-dev…

闯关提交01

任务:完成SSH连接与端口映射并运行 hello_world.py

Vue3.5中解构props,让父子组件通信更加丝滑

前言 在Vue3.5版本中响应式 Props 解构终于正式转正了,这个功能之前一直是试验性的。这篇文章来带你搞清楚,一个String类型的props经过解构后明明应该是一个常量了,为什么还没丢失响应式呢?本文中使用的Vue版本为欧阳写文章时的最新版Vue3.5.5 关注公众号:【前端欧阳】,给…

【python爬虫案例】利用python爬取豆瓣电影TOP250评分排行数据!

【python爬虫案例】利用python爬取豆瓣电影TOP250评分排行数据,并导出为excel文档一、爬取对象-豆瓣电影TOP250 今天给大家分享一期豆瓣读书TOP排行榜250的python爬虫案例 爬取的目标网址是:https://movie.douban.com/top250咱们以目标为驱动,以兴趣为导向,先来看下爬虫程序…

Ros2 - Moveit2 - DeepGrasp(深度抓握)

MoveIt 深度把握 本教程演示了如何在 MoveIt 任务构造器中使用抓握姿势检测 (GPD)和 Dex-Net 。 GPD(左)和 Dex-Net(右)用于生成拾取圆柱体的抓取姿势。 https://moveit.picknik.ai/main/_images/mtc_gpd_panda.gif 入门 如果您还没有这样做,请确保您已经完成入门指南中…

(装)K8s 总体架构及目录结构

原文:https://www.guoshaohe.com/cloud-computing/kubernetes-source-read/12491. kubernetes 总体架构目前想对kubernetes 1.21 的源码进行一次阅读分析,本篇文章是对k8s的整体架构进行一个大致分析,先要搞清楚每个组件的功能和任务,在根据不同的组件进行深度的源码分析。…

[C++ Daily] calloc 与 malloc

转载 C++ 面试突破 - LeetBook - 力扣(LeetCode)全球极客挚爱的技术成长平台 Kind BorglQI的评论