MoveIt2-humble----在 RViz 中实现可视化

官方文档上的教程,从moveit1的melodic到moveit2的foxy基本一致,但是从最新的humble开始有了很大的变化,其中之一便是 lambda表达式 的广泛使用。

本节为教程的第二节,会介绍一个工具(moveit_visual_tools),它能够通过在 rviz 中呈现可视化,从而帮助你更容易理解你的 Moveit 应用在做什么。

1 添加 moveit_visual_tools 依赖包

把下面这行添加到 hello_moveit 项目下 package.xml 中其它<depend>的下面:

<depend>moveit_visual_tools</depend>

然后在 CMakeLists.txt中添加下面这行到find_package声明中:

find_package(moveit_visual_tools REQUIRED)

在该文件后面,扩展ament_target_dependencies宏调用来包含这个新的依赖,如:

ament_target_dependencies(hello_moveit"moveit_ros_planning_interface""moveit_visual_tools""rclcpp"
)

为了核实依赖已经正确添加,在hello_moveit.cpp中添加include路径:

#include <moveit_visual_tools/moveit_visual_tools.h>

保存后打开一个新终端,编译看是否报错。

2 创建 ROS 执行器并在线程中循环节点

在初始化 MoveItVisualTools 之前,需要有一个执行器在 ROS 节点上不断循环。

这是必要的操作,来让MoveItVisualTools与 ROS服务和话题交互。

#include <thread>  // <---- add this to the set of includes at the top...// 创建一个 ROS loggerauto const logger = rclcpp::get_logger("hello_moveit");// 循环一个单线程执行器来让 MoveItTools 与 ROS 交互rclcpp::executors::SingleThreadedExecutor executor;executor.add_node(node);// 实例化一个线程对象,使用 lambda表达式来构造auto spinner = std::thread([&executor]() { executor.spin(); });// Create the MoveIt MoveGroup Interface...// Shutdown ROSrclcpp::shutdown();  // <--- 这将会使线程中的回调函数返回spinner.join();  // <--- 在结束前加入子线程,等待子线程结束,主进程才可以退出return 0;
}

然后重新编译工作空间确保没有语法错误。

3 创建并初始化 MoveItVisualTools

在创建 MoveGroupInterface 后创建和初始化 MoveItVisualTools:

// Create the MoveIt MoveGroup Interface
using moveit::planning_interface::MoveGroupInterface;
auto move_group_interface = MoveGroupInterface(node, "panda_arm");// Construct and initialize MoveItVisualTools
auto moveit_visual_tools = moveit_visual_tools::MoveItVisualTools{node, "panda_link0", rviz_visual_tools::RVIZ_MARKER_TOPIC,move_group_interface.getRobotModel()};
moveit_visual_tools.deleteAllMarkers();
moveit_visual_tools.loadRemoteControl();

我们传递以下参数到构造函数中:

  1. ROS节点
  2. 机械臂的 base link
  3. 要使用的 marker 话题(稍后介绍)
  4. 机器人模型 robot model(从 move_group_interface 中获得)

下一步,我们调用其成员函数去删除所有的标记,这会清除 Rviz 中所有以前运行遗留下来的绘制状态。

最后,加载远程控制。远程控制是一个简单的插件,它能在 Rviz 中提供一个按钮来与我们的程序进行交互。

4 为可视化编写闭包

在初始化后,我们创建一些闭包(闭包是引用了自由变量的函数),这样我们就能在程序的后面调用这些闭包来帮助在 Rviz 中描述可视化。

// 创建用于可视化的闭包
auto const draw_title = [&moveit_visual_tools](auto text) {auto const text_pose = [] {auto msg = Eigen::Isometry3d::Identity();msg.translation().z() = 1.0;return msg;}();moveit_visual_tools.publishText(text_pose, text, rviz_visual_tools::WHITE,rviz_visual_tools::XLARGE);
};
auto const prompt = [&moveit_visual_tools](auto text) {moveit_visual_tools.prompt(text);
};
auto const draw_trajectory_tool_path =[&moveit_visual_tools,jmg = move_group_interface.getRobotModel()->getJointModelGroup("panda_arm")](auto const trajectory) {moveit_visual_tools.publishTrajectoryLine(trajectory, jmg);};

这三个闭包都引用了 moveit_visual_tools,最后一个闭包引用了一个指向我们所规划的关节组对象的指针。

这些闭包调用了一个moveit_visual_tools上的函数,改变了 Rviz 中的一些东西:

  1. 第一个闭包draw_title:在 RViz 中机械臂的上方一米处添加了文本,方便看运行状态;
  2. 第二个闭包prompt:这个函数会阻止程序进行,直到用户按下 RViz 中的next按钮,方便 debug;
  3. 第三个闭包draw_trajectory_tool_path :画出了我们规划的轨迹路径。

你可能会好奇我们为什么要用 lambda 表达式。原因是它能更简单地编码,便于以后阅读和理解。当你写软件时,把功能分解为命名函数,有助于复用和测试。

5 Visualize the steps of your program

在程序中更新规划和计算部分的代码,以包括以上创建的新特性:

// Set a target Pose
auto const target_pose = [] {geometry_msgs::msg::Pose msg;msg.orientation.w = 1.0;msg.position.x = 0.28;msg.position.y = -0.2;msg.position.z = 0.5;return msg;
}();
move_group_interface.setPoseTarget(target_pose);// Create a plan to that target pose
prompt("Press 'Next' in the RvizVisualToolsGui window to plan");
draw_title("Planning");
moveit_visual_tools.trigger();
auto const [success, plan] = [&move_group_interface] {moveit::planning_interface::MoveGroupInterface::Plan msg;auto const ok = static_cast<bool>(move_group_interface.plan(msg));return std::make_pair(ok, msg);
}();// Execute the plan
if (success) {draw_trajectory_tool_path(plan.trajectory_);moveit_visual_tools.trigger();prompt("Press 'Next' in the RvizVisualToolsGui window to execute");draw_title("Executing");moveit_visual_tools.trigger();move_group_interface.execute(plan);
} else {draw_title("Planning Failed!");moveit_visual_tools.trigger();RCLCPP_ERROR(logger, "Planing failed!");
}

我们会注意到,在每次调用后,我们必须调用moveit_visual_tools中的trigger方法,才能改变 RViz 中呈现的东西。原因是发送给 RViz 的消息是批处理的,并在调用trigger时发送,以减少 marker 话题的带宽。

最后,再次编译程序并确保所有添加的代码是正确的。

6 在 RViz 中启用可视化

打开一个新终端,和之前一样,先启动 demo launch 来打开 RViz:

source install/setup.bash
ros2 launch moveit2_tutorials demo.launch.py
在 RViz 中,取消选择 “Displays”中的 “MotionPlanning”,这节中用不到这个插件

 为了添加用于交互的按钮,我们打开“Panels/Add New Panel”菜单

 选中RvizVisualToolsGui并点击 OK。这会在左下角创建一个新的面板,带有Next按钮,我们在后面会用到。

 最后,我们需要添加Marker Array去描绘我们添加的可视化。在“Displays”面板中点击“Add”按钮:

选中Marker Array并点击 OK

Marker Array面板中找到 Topic,编辑为/rviz_visual_tools

 

7 运行程序

在一个新终端中运行 hello_moveit 节点,你会发现程序停住了,并显示了如下的提示:

[INFO] [1652822889.492940200] [hello_moveit.remote_control]: Waiting to continue: Press 'Next' in the RvizVisualToolsGui window to plan

在 RViz 中点击 Next 按钮,会发现完成规划,并显示 title 和规划出的轨迹线。再点击 Next 按钮,机械臂开始执行规划。

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

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

相关文章

运动员场景分割系统源码&数据集分享

运动员场景分割系统源码&#xff06;数据集分享 [yolov8-seg-HGNetV2&#xff06;yolov8-seg-aux等50全套改进创新点发刊_一键训练教程_Web前端展示] 1.研究背景与意义 项目参考ILSVRC ImageNet Large Scale Visual Recognition Challenge 项目来源AAAI Global Al lnnovati…

麒麟 操作系统介绍| 银河麒麟和中标麒麟操作系统| Kylin 麒麟iso 镜像下载地址 银河麒麟操作系统v10 |

目录 #申请试用小技巧&#xff0c; 所有麒麟系列的版本如下 详细介绍如下&#xff1a; 银河麒麟高级服务器操作系统 V10 1. 龙芯-MIPS64el 版 2. 申威版 3. 兆芯版 4. 海光版 5. 飞腾版 6. 鲲鹏版 7. AMD64版 8. 龙芯-LoongArch64 版 9. ARM64版 银河麒麟桌面操作…

SpringMVC源码-AbstractUrlHandlerMapping处理器映射器将实现Controller接口的方式定义的路径存储进去

DispatcherServlet的initStrategies方法用来初始化SpringMVC的九大内置组件 initStrategies protected void initStrategies(ApplicationContext context) {// 初始化 MultipartResolver:主要用来处理文件上传.如果定义过当前类型的bean对象&#xff0c;那么直接获取&#xff0…

【学习笔记】kruskal重构树

前言 最近一场div2没开出C2&#xff0c;猛掉104分。 赛后补E&#xff0c;发现自己连E1都没思路&#xff0c;一问才知道是kruskal重构树。 好吧&#xff0c;OI时期欠下的债该还了。 kruskal重构树是什么 它是一棵 2 n − 1 2n-1 2n−1 个点的二叉树。点有点权&#xff0c;下…

异常场景分析

优质博文&#xff1a;IT-BLOG-CN 为了防止黑客从前台异常信息&#xff0c;对系统进行攻击。同时&#xff0c;为了提高用户体验&#xff0c;我们都会都抛出的异常进行拦截处理。 一、异常处理类 Java把异常当做是破坏正常流程的一个事件&#xff0c;当事件发生后&#xff0c;…

https访问报错:net::ERR_CERT_DATE_INVALLD

目录 简介异常排查原因解决补充 简介 访问https资源出现报错 异常 排查 将地址拿到浏览器进行访问&#xff0c;可以很清晰的看到出现该问题的原因 原因 1、SSL证书已过期 2、服务器日期不准&#xff0c;不在证书有效期 解决 1、重新申请SSL证书&#xff0c;并配置 2、校正…

VMware桥接模式无法连接网络

windows下打开控制面板&#xff0c;找到WLAN&#xff0c;记住下面的名称&#xff08;带有VMware的都是虚拟机的网卡&#xff0c;要找到物理主机的网卡&#xff09; 回到VMware&#xff0c;编辑——打开虚拟网络编辑器 桥接选择上面的WLAN下的网络名称&#xff0c;确定即可。&…

【学习笔记】手写一个简单的 Spring MVC

目录 一、什么是Spring MVC &#xff1f; Spring 和 Spring MVC 的区别&#xff1f; Spring MVC 的运行流程&#xff1f; 二、实现步骤 1. DispatcherServlet 1. 创建一个中央分发器 拦截所有请求 测试 2. 接管 IOC 容器 1. 创建配置文件 2. 修改 web.xml 配置文件 …

输电线路悬垂线夹检测无人机航拍图像数据集,总共1600左右图片,悬垂线夹识别,标注为voc格式

输电线路悬垂线夹检测无人机航拍图像数据集&#xff0c;总共1600左右图片&#xff0c;悬垂线夹识别&#xff0c;标注为voc格式 输电线路悬垂线夹检测无人机航拍图像数据集介绍 数据集名称 输电线路悬垂线夹检测数据集 (Transmission Line Fittings Detection Dataset) 数据集…

在mac中通过ip连接打印机并实现双面打印

首先需要找到电脑自带的打印。添加打印机。 填写好打印机的ip地址&#xff0c;然后添加。 填写好ip地址后&#xff0c;直接添加就行 添加完打印机后其实就可以打印了。但是有些功能可能实现不了&#xff0c;比如说双面打印。为了实现双面打印的功能&#xff0c;需要再进行设置…

代码随想录算法训练营第五十四天|LeetCode42 接雨水、LeetCode84 柱状图中最大的矩形

LeetCode42 接雨水 代码随想录题目链接/文章讲解/视频讲解&#xff1a; 代码随想录代码随想录PDF&#xff0c;代码随想录网站&#xff0c;代码随想录百度网盘&#xff0c;代码随想录知识星球&#xff0c;代码随想录八股文PDF&#xff0c;代码随想录刷题路线&#xff0c;代码随…

GEE开发之Modis_NDWI数据分析和获取

GEE开发之Modis_NDWI数据分析和获取 0 数据介绍NDWI介绍MOD09GA介绍 1 NDWI天数据下载2 NDWI月数据下载3 NDWI年数据下载 前言&#xff1a;本文主要介绍Modis下的NDWI数据集的获取。归一化差异水指数 (NDWI) 对植被冠层液态水含量的变化很敏感。它来自近红外波段和第二个红外波…

PMP--冲刺题--解题--21-30

文章目录 11.风险管理--数据分析--成本效益分析--如果能够把单个项目风险的影响进行货币量化&#xff0c;那么就可以通过成本收益分析来确定备选风险应对策略的成本有效性。 特性要取消&#xff0c;要想继续做的话&#xff0c;就得看能不能给组织带来收益。21、 [单选] 在迭代审…

【NoSQL】portswigger NoSQL注入 labs 全解

目录 NoSQL NoSQL 数据库模型 NoSQL 注入的类型 NoSQL 语法注入 检测 MongoDB 中的语法注入 lab1:检测 NoSQL 注入 NoSQL 运算符注入 提交查询运算符 检测 MongoDB 中的运算符注入 lab2:利用 NoSQL 运算符注入绕过身份验证 利用语法注入来提取数据 MongoDB 中的数据…

Golang | Leetcode Golang题解之第446题等差数列划分II-子序列

题目&#xff1a; 题解&#xff1a; func numberOfArithmeticSlices(nums []int) (ans int) {f : make([]map[int]int, len(nums))for i, x : range nums {f[i] map[int]int{}for j, y : range nums[:i] {d : x - ycnt : f[j][d]ans cntf[i][d] cnt 1}}return }

Ubuntu 搭建 GitLab

1. 安装依赖&#xff1a; sudo apt update sudo apt install -y curl openssh-server ca-certificates2. 添加 GitLab 包仓库&#xff1a; curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | sudo bash3. 安装 GitLab&#xff1a; s…

UE5数字人制作平台使用及3D模型生成

第10章 数字人制作平台使用及3D模型生成 在数字娱乐、虚拟现实&#xff08;VR&#xff09;、增强现实&#xff08;AR&#xff09;等领域&#xff0c;高质量的3D模型是数字内容创作的核心。本章将引导你了解如何使用UE5&#xff08;Unreal Engine 5&#xff09;虚幻引擎这一强大…

多模态大语言模型(MLLM)-Blip2深度解读

前言 Blip2是一个多模态大语言模型&#xff0c;因其提出时间较早&#xff08;2023年&#xff09;&#xff0c;且效果较好&#xff0c;很快成为一个标杆性工作。Blip2中提出的Q-former也成为衔接多模态和文本的重要桥梁。 Blip2发表时间是2023年&#xff0c;现在引用已经3288了…

【AIGC】ChatGPT是如何思考的:探索CoT思维链技术的奥秘

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | ChatGPT 文章目录 &#x1f4af;前言&#x1f4af;什么是CoT思维链CoT思维链的背景与技术发展需求 &#x1f4af;CoT思维链的工作原理&#x1f4af;CoT思维链的应用领域&#x1f4af;CoT思维链的优势&#x1f4af;CoT思维…

【JavaEE】【多线程】进程与线程的概念

目录 进程系统管理进程系统操作进程进程控制块PCB关键属性cpu对进程的操作进程调度 线程线程与进程线程资源分配线程调度 线程与进程区别线程简单操作代码创建线程查看线程 进程 进程是操作系统对一个正在运行的程序的一种抽象&#xff0c;可以把进程看做程序的一次运行过程&a…