当前位置: 首页 > news >正文

【中文注释】planning_scene_tutorial.cpp

planning_scene_tutorial.cpp

#include <rclcpp/rclcpp.hpp>// MoveIt 相关头文件
#include <moveit/robot_model_loader/robot_model_loader.h>
#include <moveit/planning_scene/planning_scene.h>
#include <moveit/kinematic_constraints/utils.h>// BEGIN_SUB_TUTORIAL stateFeasibilityTestExample
//
// 用户可以为 PlanningScene 类指定自定义约束
// 通过使用 setStateFeasibilityPredicate 函数来实现自定义的回调函数。
// 以下是一个简单的示例,用于检查 Panda 机器人中的 "panda_joint1" 关节是否为正角度:
bool stateFeasibilityTestExample(const moveit::core::RobotState& robot_state, bool /*verbose*/)
{const double* joint_values = robot_state.getJointPositions("panda_joint1");return (joint_values[0] > 0.0);
}
// END_SUB_TUTORIALstatic const rclcpp::Logger LOGGER = rclcpp::get_logger("planning_scene_tutorial");int main(int argc, char** argv)
{rclcpp::init(argc, argv);rclcpp::NodeOptions node_options;node_options.automatically_declare_parameters_from_overrides(true);auto planning_scene_tutorial_node = rclcpp::Node::make_shared("planning_scene_tutorial", node_options);rclcpp::executors::SingleThreadedExecutor executor;executor.add_node(planning_scene_tutorial_node);std::thread([&executor]() { executor.spin(); }).detach();// BEGIN_TUTORIAL//// 设置// ^^^^^//// PlanningScene 类可以使用 RobotModel 或 URDF 和 SRDF 轻松设置和配置。// 不过这不是推荐的方式,建议使用 PlanningSceneMonitor 来创建和维护当前的规划场景,// 使用来自机器人关节和传感器的数据来进行维护。在这个教程中,我们将直接实例化一个// PlanningScene 类,但这种实例化方式仅用于说明。robot_model_loader::RobotModelLoader robot_model_loader(planning_scene_tutorial_node, "robot_description");const moveit::core::RobotModelPtr& kinematic_model = robot_model_loader.getModel();planning_scene::PlanningScene planning_scene(kinematic_model);// 碰撞检测// ^^^^^^^^^^//// 自碰撞检测// ~~~~~~~~~~~//// 首先,我们检查机器人当前状态是否处于自碰撞状态,// 即当前的配置是否会导致机器人各部分互相碰撞。// 我们需要构造一个 CollisionRequest 对象和一个 CollisionResult 对象,// 然后将它们传入碰撞检测函数中。碰撞检测的结果会保存在 CollisionResult 对象中。// 自碰撞检测使用的是机器人的未加垫版本,直接使用 URDF 中提供的碰撞网格,未额外添加任何填充。collision_detection::CollisionRequest collision_request;collision_detection::CollisionResult collision_result;planning_scene.checkSelfCollision(collision_request, collision_result);RCLCPP_INFO_STREAM(LOGGER, "Test 1: Current state is " << (collision_result.collision ? "in" : "not in")<< " self collision");// 改变机器人状态// ~~~~~~~~~~~~~~~~//// 现在,我们来改变机器人的当前状态。规划场景会维护当前状态,// 我们可以获取一个引用来修改它,然后再次检查新配置下的碰撞情况。// 请注意,每次新的碰撞检测前都需要清除 CollisionResult。moveit::core::RobotState& current_state = planning_scene.getCurrentStateNonConst();current_state.setToRandomPositions();collision_result.clear();planning_scene.checkSelfCollision(collision_request, collision_result);RCLCPP_INFO_STREAM(LOGGER, "Test 2: Current state is " << (collision_result.collision ? "in" : "not in")<< " self collision");// 只检查某个组// ~~~~~~~~~~~~~~//// 接下来,我们只对 Panda 机器人的手部进行碰撞检测,// 即检查手部是否与机器人身体的其他部分发生碰撞。// 我们可以通过在 CollisionRequest 中添加组名 "hand" 来实现这一点。collision_request.group_name = "hand";current_state.setToRandomPositions();collision_result.clear();planning_scene.checkSelfCollision(collision_request, collision_result);RCLCPP_INFO_STREAM(LOGGER, "Test 3: Current state is " << (collision_result.collision ? "in" : "not in")<< " self collision");// 获取碰撞信息// ~~~~~~~~~~~~~//// 首先手动设置 Panda 机械臂到一个我们知道会发生自碰撞的位置。// 请注意,这个状态实际上已经超出了 Panda 关节的限制,我们可以直接检查这一点。std::vector<double> joint_values = { 0.0, 0.0, 0.0, -2.9, 0.0, 1.4, 0.0 };const moveit::core::JointModelGroup* joint_model_group = current_state.getJointModelGroup("panda_arm");current_state.setJointGroupPositions(joint_model_group, joint_values);RCLCPP_INFO_STREAM(LOGGER, "Test 4: Current state is "<< (current_state.satisfiesBounds(joint_model_group) ? "valid" : "not valid"));// 现在,我们可以获取 Panda 机械臂在某个给定配置下的所有碰撞信息。// 通过在 CollisionRequest 中填写相应的字段并指定返回的最大接触数量,// 我们可以请求这些碰撞信息。collision_request.contacts = true;collision_request.max_contacts = 1000;collision_result.clear();planning_scene.checkSelfCollision(collision_request, collision_result);RCLCPP_INFO_STREAM(LOGGER, "Test 5: Current state is " << (collision_result.collision ? "in" : "not in")<< " self collision");collision_detection::CollisionResult::ContactMap::const_iterator it;for (it = collision_result.contacts.begin(); it != collision_result.contacts.end(); ++it){RCLCPP_INFO(LOGGER, "Contact between: %s and %s", it->first.first.c_str(), it->first.second.c_str());}// 修改允许的碰撞矩阵(Allowed Collision Matrix, ACM)// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//// Allowed Collision Matrix (ACM) 提供了一种机制,让碰撞检测器忽略某些对象之间的碰撞:// 包括机器人自身的部分之间的碰撞以及机器人与环境中的物体之间的碰撞。// 我们可以告诉碰撞检测器忽略前面提到的所有链接之间的碰撞,即使它们实际上是碰撞的,// 碰撞检测器也会忽略这些碰撞,返回该状态为“未发生碰撞”。// 在这个例子中,我们同时对 ACM 和当前状态进行了复制,并传入碰撞检测函数。collision_detection::AllowedCollisionMatrix acm = planning_scene.getAllowedCollisionMatrix();moveit::core::RobotState copied_state = planning_scene.getCurrentState();collision_detection::CollisionResult::ContactMap::const_iterator it2;for (it2 = collision_result.contacts.begin(); it2 != collision_result.contacts.end(); ++it2){acm.setEntry(it2->first.first, it2->first.second, true);}collision_result.clear();planning_scene.checkSelfCollision(collision_request, collision_result, copied_state, acm);RCLCPP_INFO_STREAM(LOGGER, "Test 6: Current state is " << (collision_result.collision ? "in" : "not in")<< " self collision");// 完整碰撞检测
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// 虽然我们之前已经进行了自碰撞检测,但我们可以使用 checkCollision 函数,
// 该函数不仅会检测自碰撞,还会检测与环境(当前为空)的碰撞。
// 这是在路径规划中最常用的一组碰撞检测函数。注意,与环境的碰撞检测会使用机器人带有缓冲区的版本。
// 缓冲区可以帮助机器人在环境中与障碍物保持一定距离。
collision_result.clear();
planning_scene.checkCollision(collision_request, collision_result, copied_state, acm);
RCLCPP_INFO_STREAM(LOGGER, "测试 7: 当前状态 " << (collision_result.collision ? "发生" : "未发生") << " 自碰撞");// 约束检测
// ^^^^^^^^^^^^^^^^^^^
//
// PlanningScene 类中还包含便于使用的函数来检测约束。
// 约束可以有两种类型:
// (a) 从 :moveit_codedir:`KinematicConstraint<moveit_core/kinematic_constraints/include/moveit/kinematic_constraints/kinematic_constraint.h>`
// 中选择的约束集:如关节约束(JointConstraint)、位置约束(PositionConstraint)、方向约束(OrientationConstraint)和可视性约束(VisibilityConstraint)。
// (b) 用户通过回调函数自定义的约束。我们将首先看一个简单的 KinematicConstraint 示例。
//
// 检测运动学约束
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 我们将首先对熊猫机器人(Panda robot)的 panda_arm 组的末端执行器定义一个简单的位置和方向约束。
// 注意,这里使用了一些便捷的函数来填充约束(这些函数可以在
// :moveit_codedir:`utils.h<moveit_core/kinematic_constraints/include/moveit/kinematic_constraints/utils.h>`
// 文件中找到,该文件位于 moveit_core 的 kinematic_constraints 目录下)。std::string end_effector_name = joint_model_group->getLinkModelNames().back();geometry_msgs::msg::PoseStamped desired_pose;
desired_pose.pose.orientation.w = 1.0;
desired_pose.pose.position.x = 0.3;
desired_pose.pose.position.y = -0.185;
desired_pose.pose.position.z = 0.5;
desired_pose.header.frame_id = "panda_link0";
moveit_msgs::msg::Constraints goal_constraint =kinematic_constraints::constructGoalConstraints(end_effector_name, desired_pose);// 现在,我们可以使用 PlanningScene 类中的 isStateConstrained 函数检查某个状态是否符合此约束。copied_state.setToRandomPositions();
copied_state.update();
bool constrained = planning_scene.isStateConstrained(copied_state, goal_constraint);
RCLCPP_INFO_STREAM(LOGGER, "测试 8: 随机状态 " << (constrained ? "符合" : "不符合") << " 约束");// 当需要多次检查相同约束(例如在规划器中)时,有一种更高效的方法来检测约束。
// 我们首先构建一个 KinematicConstraintSet,预处理 ROS 约束消息并为快速处理做好设置。kinematic_constraints::KinematicConstraintSet kinematic_constraint_set(kinematic_model);
kinematic_constraint_set.add(goal_constraint, planning_scene.getTransforms());
bool constrained_2 = planning_scene.isStateConstrained(copied_state, kinematic_constraint_set);
RCLCPP_INFO_STREAM(LOGGER, "测试 9: 随机状态 " << (constrained_2 ? "符合" : "不符合") << " 约束");// 也可以直接使用 KinematicConstraintSet 类来完成此操作。kinematic_constraints::ConstraintEvaluationResult constraint_eval_result =kinematic_constraint_set.decide(copied_state);
RCLCPP_INFO_STREAM(LOGGER, "测试 10: 随机状态 " << (constraint_eval_result.satisfied ? "符合" : "不符合") << " 约束");// 用户定义的约束
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// CALL_SUB_TUTORIAL stateFeasibilityTestExample// 现在,每当调用 isStateFeasible 时,就会调用这个用户定义的回调函数。planning_scene.setStateFeasibilityPredicate(stateFeasibilityTestExample);
bool state_feasible = planning_scene.isStateFeasible(copied_state);
RCLCPP_INFO_STREAM(LOGGER, "测试 11: 随机状态 " << (state_feasible ? "可行" : "不可行"));// 每当调用 isStateValid 时,将执行三个检查:
// (a) 碰撞检测 (b) 约束检测 (c) 使用用户定义回调的可行性检测。bool state_valid = planning_scene.isStateValid(copied_state, kinematic_constraint_set, "panda_arm");
RCLCPP_INFO_STREAM(LOGGER, "测试 12: 随机状态 " << (state_valid ? "有效" : "无效"));// 注意,所有通过 MoveIt 和 OMPL 可用的规划器都会执行碰撞检测、约束检测以及使用用户定义回调的可行性检测。
// 结束教程rclcpp::shutdown();
return 0;

相关文章:

【中文注释】planning_scene_tutorial.cpp

planning_scene_tutorial.cpp #include <rclcpp/rclcpp.hpp>// MoveIt 相关头文件 #include <moveit/robot_model_loader/robot_model_loader.h> #include <moveit/planning_scene/planning_scene.h> #include <moveit/kinematic_constraints/utils.h>…...

【Vue3】 h()函数的用法

目录 介绍 参数 使用案例 1.创建虚拟 DOM 元素 2. 组件的动态渲染 3. 创建功能组件 4.渲染动态属性 5. 使用插槽 6. 创建动态标签 介绍 h() 函数用于辅助创建虚拟 DOM 节点&#xff0c;它是 hypescript 的简称——能生成 HTML (超文本标记语言) 的 JavaScript&#x…...

Flask如何实现前后端分离项目

在现代Web开发中&#xff0c;前后端分离是一种常见的架构模式&#xff0c;其中前端和后端分别独立开发和部署&#xff0c;通过API进行通信。Flask作为后端框架&#xff0c;可以很容易地与前端框架&#xff08;如React、Vue.js或Angular&#xff09;配合使用来实现前后端分离。以…...

二维码生成器 1.02.41| 一站式QR码生成器和美化工具

二维码生成器是一个有用的QR码生成器应用程序。可以轻松地为网站链接、文本、WiFi、名片、短信、社交媒体账户等生成QR码。该应用支持更改QR码的颜色、码眼图案和框架&#xff0c;并可以添加徽标和文本&#xff0c;使QR码更加美观。使用此QR码生成器&#xff0c;可以使用设计精…...

腾讯云视立方·直播 SDK 合规使用指南

为帮助使用直播 SDK 的开发运营者&#xff08;以下简称“您”&#xff09;在符合个人信息保护相关法律法规、政策及标准的规定下合规接入、使用第三方SDK&#xff0c;深圳市腾讯计算机系统有限公司&#xff08;以下简称"我们"&#xff09;特制定《直播 SDK 接入使用说…...

在 Spring 中使用 @EhCache 注解作为缓存

文章目录 项目概况项目设置一个简单的 RESTful Web 服务Spring 整合 EhCache第 1 步&#xff1a;更新依赖项以使用 EhCache Spring 注解第 2 步&#xff1a;设置自定义缓存管理器第 3 步&#xff1a;配置 EhCache第 4 步&#xff1a;测试缓存 刷新缓存总结推荐阅读文章 EhCache…...

npm install进度卡在 idealTree:node_global: sill idealTree buildDeps

ping一下源&#xff1a;ping http://registry.npm.taobao.org/ ping不通&#xff0c;原因&#xff1a;原淘宝npm永久停止服务&#xff0c;已更新新域名~~震惊&#xff01;&#xff01;&#xff01; 重新安装&#xff1a;npm config set registry https://registry.npmmirror.c…...

力扣1031. 两个非重叠子数组的最大和

力扣1031. 两个非重叠子数组的最大和 题目解析及思路 题目要求找到两段长分别为firstLen 和 secondLen的子数组&#xff0c;使两段元素和最大 图解见灵神 枚举第二段区间的右端点&#xff0c;在左边剩余部分中找出元素和最大的第一段区间&#xff0c;并用前缀和优化求子数组…...

【Unity实战篇】 接入百度翻译,实现文本自动翻译功能

前言【Unity实战篇】 接入百度自动翻译,实现文本自动翻译功能一、获取百度翻译开发平台的APPID和密钥二、Unity中接入自动翻译功能三、Unity中实现自动翻译文本Text功能总结前言 日常在做项目的过程中,游戏本地化几乎已经成为必不可少的一步。本篇文章将演示怎样在Unity中接入…...

ubuntu samba

参考&#xff1a; 基于Ubuntu22.04的Samba服务器搭建教程&#xff08;新手保姆级教程&#xff09;_ubuntu samba-CSDN博客 当时按照这个不行&#xff1a; 主要做了这些修改 1、ufw 打开端口 这些都打开了 Samba服务使用的端口和协议如下1234: Port 137 (UDP) - NetBIOS 名…...

Linux系统和数据库常用的命令2

Linux系统和数据库常用的命令2 1、两台Linux机器ssh免密登录 client端登录server端需要免密&#xff0c;只需把公钥发送到server就可&#xff0c;会在server端生成一个authorized_keys文件 # 108机器上[rootclient ~]# ssh-keygen -t rsa // 非对称算法 Generating public/…...

Golang | Leetcode Golang题解之第468题验证IP地址

题目&#xff1a; 题解&#xff1a; func validIPAddress(queryIP string) string {if sp : strings.Split(queryIP, "."); len(sp) 4 {for _, s : range sp {if len(s) > 1 && s[0] 0 {return "Neither"}if v, err : strconv.Atoi(s); err …...

mermaid 图表相关

1.mermaid图表的代码 1.1 flowchart 流程图代码 flowchart TDA[Christmas] -->|Get money| B(Go shopping)B --> C{Let me think}C -->|One| D[Laptop]C -->|Two| E[iPhone]C -->|Three| F[fa:fa-car Car]1.2 sequece 时序图代码 sequenceDiagramAlice->&…...

Unity接入人工智能

在Unity接入人工智能中&#xff0c;本篇实现了接入百度智能云ai进行npc智能对话&#xff0c;通过http方式&#xff0c;并非插件&#xff0c;适合于所有支持Http链接的Unity版本。对于Chartgpt可以参考本篇内容的实现过程。 1-4节讲解测试&#xff0c;第5节讲解Unity中的实现&a…...

C语言笔记 14

函数原型 函数的先后关系 我们把自己定义的函数isPrime()写在main函数上面 是因为C的编译器自上而下顺序分析你的代码&#xff0c;在看到isPrime的时候&#xff0c;它需要知道isPrime()的样子——也就是isPrime()要几个参数&#xff0c;每个参数的类型如何&#xff0c;返回什么…...

Cpp::STL—list类的模拟实现(上)(13)

文章目录 前言一、结点类的实现二、迭代器类的实现迭代器类的存在意义迭代器类的模板参数构造函数运算符的重载--运算符的重载、!运算符的重载*运算符的重载->运算符的重载 总结 前言 注意本篇难度偏高&#xff0c;其主要体现在迭代器类的实现&#xff01;   什么&#xf…...

ListView的Items绑定和comboBox和CheckBox组合使用实现复选框的功能

为 ListView 控件的内容指定视图模式的方法&#xff0c;参考官方文档。 ComboBox 样式和模板 案例说明&#xff1a;通过checkBox和ComboBox的组合方式实现下拉窗口的多选方式&#xff0c;同时说明了ListView中Items项目的两种绑定方式. 示例&#xff1a; 设计样式 Xaml代码…...

PetaLinux工程的常用命令——petalinux-build

petalinux-build&#xff1a;编译项目或指定组件。 注&#xff1a;有些命令我没用过&#xff0c;瞎翻译有可能会翻译错了。 用法: petalinux-build [options] 可选参数: -h, --help 显示函数用法。 -p, --project <PROJECT> PetaLinuxSDK项目的路径。默认…...

【Qt】窗口预览(1)—— 菜单栏

窗口预览&#xff08;1&#xff09; 1. QMainWindow2. QMenuBar——菜单栏2.1 创建菜单栏/将菜单栏添加到widget中2.2 addMenu——在菜单栏中添加菜单2.3 在菜单中添加选项2.4 添加快捷键2.5 支持嵌套添加菜单2.6 添加信号2.7 添加分割线 1. QMainWindow Qt窗口是通过QMainWin…...

揭秘酱香型白酒中的6大劣质酒的特点,守好你的健康与钱包

你知道吗&#xff1f;居然有 90%的人都喝过这 6 种劣质酱香型白酒&#xff0c;今天酱酒亮哥就带大家一起揭开它们的真面目&#xff0c;看看你中招了没有&#xff01; 先说那种有很浓的生粮味的酱酒&#xff0c;就像刚磨出来还没烧开的豆浆味&#xff0c;喝起来那叫一个难受。想…...

C#拓展方法

定义 扩展方法使你能够向现有类型“添加”方法&#xff0c;而无需创建新的派生类型、重新编译或以其他方式修改原始类型。 扩展方法是一种静态方法&#xff0c;但可以像扩展类型上的实例方法一样进行调用。 对于用 C#、F# 和 Visual Basic 编写的客户端代码&#xff0c;调用扩…...

02.顺序表、链表简述+对比

目录 一、线性表 二、顺序表 三、链表 四、顺序表和链表的区别 一、线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列&#xff08;相同特性指都为整型int、字符型char或其它类型&#xff09;。 线性表是一种在实际中广泛使用的数据…...

前端布局与响应式设计综合指南(三)

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;Css篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来Css篇专栏内容:前端布局与响应式设计综合指南(三) 目录 42、px/em/rem有什么区别&#xff1f;为什么通常给font-s…...

当今SNARKs全景

1. 引言 前序博客有&#xff1a; ZKP历史总览SNARK原理示例SNARK性能及安全——Prover篇SNARK性能及安全——Verifier篇Transparent 且 Post-quantum zkSNARKsSNARK DesignRollup项目的SNARK景观 SNARKs因&#xff1a; proof size证明时长验证时长密码学信任假设是否需要tr…...

PMP敏捷专题课:敏捷原则与理念

信息发射源、看板是敏捷相关的词汇。 需求不明确&#xff1a;敏捷的关键词。 明确的端对端工作范围是传统项目管理的关键词。所以&#xff0c;应该采用&#xff1a;混合的&#xff0c;多轨制&#xff0c;瀑布态这样的声明周期 STACEY矩阵。 敏捷价值观指引者我们敏捷的实现。…...

有两个水桶,容量分别为5升和3升,请问如何使用这两个桶得到4升的水?

网上看到的一个面试的题目&#xff0c;感觉挺有意思的记录一下 可以按照以下步骤使用这两个桶得到 4 升的水&#xff1a; 将 5 升水桶装满水&#xff0c;倒入 3 升水桶中&#xff0c;此时 5 升水桶中还剩下 2 升水。将 3 升水桶中的水全部倒掉&#xff0c;然后将 5 升水桶中的…...

pytorch_lightning笔记

Debug 1. 快速运行一次所有的代码 (fast_dev_run) 训练了好长时间但是在训练or 验证的时候崩溃了 使用 fast_dev_run运行5个batch 的 training validation test and predication 查看是否存在错误&#xff1a; train Trainer(fast_dev_runTrue) # True 时为5 train Train…...

从零开始了解云WAF,您的网站安全升级指南

网站安全对任何线上业务来说至关重要&#xff0c;尤其是在网络威胁不断升级的今天。无论是流量高峰期还是日常运营&#xff0c;确保数据安全与服务稳定是每个网站运营者最关心的事情。云WAF&#xff08;Web应用防火墙&#xff09;作为一种高效的安全防护手段&#xff0c;正逐渐…...

Python脚本爬取目标网站上的所有链接

一、爬取后txt文件保存 需要先pip install requests和BeautifulSoup库 import requests from bs4 import BeautifulSoup# 定义要爬取的新闻网站URL url https://www.chinadaily.com.cn/ # China Daily 网站# 发送请求获取页面内容 response requests.get(url)# 检查请求是否…...

Linux下以编译源码的方式安装Qt5与Qt6及其使用

文章目录 概要资源下载依赖安装编译Qt5Qt6 遇到的问题qtchooser使用 概要 自 Qt 5.15 开始&#xff0c;不再提供 open source offline installers&#xff0c;也就是原来的 .run 的安装文件&#xff0c;只能通过源码编译来安装了参考文章 资源下载 源码网址&#xff0c;链接…...