ROS2机器人编程简述humble-第三章-COMPUTATION GRAPH .2

news2024/11/14 0:35:41

ROS2机器人编程简述humble-第三章-PERCEPTION AND ACTUATION MODELS .1

避开障碍物计算图如何呢?

该应用程序的计算图非常简单:订阅激光主题的节点向机器人发布速度命令

控制逻辑解释:输入的感知信息并产生控制命令(输出)。这个逻辑就是要用FSM实现的。逻辑控制将以20 Hz反复运行。执行频率取决于发布控制命令。

通常,接收信息的频率与发布信息的频率不同(差异)。必须处理这个问题。不要抱怨问题,要解决问题。如果希望软件在不同的机器人上运行,不能为机器人指定特定的主题。在例子中,它订阅的主题是/input scan,并在/output vel中发布。这些主题不存在或与模拟机器人的主题相对应。当执行它时(在部署时),将重新映射端口以将它们连接到特定机器人的真实主题。

在这里讨论一点。为什么使用重映射而不是传递主题名称作为参数?嗯,这是许多ROS2开发人员提倡的一种替代方案。当一个节点不总是具有相同的订阅者/发布者时,这个替代方案可能更方便,并且只能在配置参数的YAML文件中指定。

一个好的方法是,如果节点中的发布者和订阅者的数量是已知的,则使用通用主题名称(如本示例中使用的名称),并执行重新映射。使用通用主题名称可能更好(/cmd_vel是许多机器人的通用控制速度主题)。经验丰富的ROS2程序员将在文档中阅读它使用的主题,了解ROS2节点信息,并快速使用remap,而不是寻找要在配置中设置的正确参数文件夹。

尽管本书主要使用C++,但在本章中,将提供两种类似的实现,一种是C++实现,另一种是Python实现,每种都包含在不同的包中:br2-fsm-bumpgo-cpp和br2-fsm bumpgo-py。

案例cpp:

#include <string>
#include <memory>

#include "behaviortree_cpp_v3/behavior_tree.h"
#include "behaviortree_cpp_v3/bt_factory.h"
#include "behaviortree_cpp_v3/utils/shared_library.h"
#include "behaviortree_cpp_v3/loggers/bt_zmq_publisher.h"

#include "ament_index_cpp/get_package_share_directory.hpp"

#include "rclcpp/rclcpp.hpp"


int main(int argc, char * argv[])
{
  rclcpp::init(argc, argv);

  auto node = rclcpp::Node::make_shared("patrolling_node");

  BT::BehaviorTreeFactory factory;
  BT::SharedLibrary loader;

  factory.registerFromPlugin(loader.getOSName("br2_forward_bt_node"));
  factory.registerFromPlugin(loader.getOSName("br2_back_bt_node"));
  factory.registerFromPlugin(loader.getOSName("br2_turn_bt_node"));
  factory.registerFromPlugin(loader.getOSName("br2_is_obstacle_bt_node"));

  std::string pkgpath = ament_index_cpp::get_package_share_directory("br2_bt_bumpgo");
  std::string xml_file = pkgpath + "/behavior_tree_xml/bumpgo.xml";

  auto blackboard = BT::Blackboard::create();
  blackboard->set("node", node);
  BT::Tree tree = factory.createTreeFromFile(xml_file, blackboard);

  auto publisher_zmq = std::make_shared<BT::PublisherZMQ>(tree, 10, 1666, 1667);

  rclcpp::Rate rate(10);

  bool finish = false;
  while (!finish && rclcpp::ok()) {
    finish = tree.rootNode()->executeTick() != BT::NodeStatus::RUNNING;

    rclcpp::spin_some(node);
    rate.sleep();
  }

  rclcpp::shutdown();
  return 0;
}

其中,如br2_is_obstacle_bt_node:

#include <string>
#include <utility>

#include "br2_bt_bumpgo/IsObstacle.hpp"

#include "behaviortree_cpp_v3/behavior_tree.h"

#include "sensor_msgs/msg/laser_scan.hpp"
#include "rclcpp/rclcpp.hpp"

namespace br2_bt_bumpgo
{

using namespace std::chrono_literals;
using namespace std::placeholders;

IsObstacle::IsObstacle(
  const std::string & xml_tag_name,
  const BT::NodeConfiguration & conf)
: BT::ConditionNode(xml_tag_name, conf)
{
  config().blackboard->get("node", node_);

  laser_sub_ = node_->create_subscription<sensor_msgs::msg::LaserScan>(
    "/input_scan", 100, std::bind(&IsObstacle::laser_callback, this, _1));

  last_reading_time_ = node_->now();
}

void
IsObstacle::laser_callback(sensor_msgs::msg::LaserScan::UniquePtr msg)
{
  last_scan_ = std::move(msg);
}

BT::NodeStatus
IsObstacle::tick()
{
  if (last_scan_ == nullptr) {
    return BT::NodeStatus::FAILURE;
  }

  double distance = 1.0;
  getInput("distance", distance);

  if (last_scan_->ranges[last_scan_->ranges.size() / 2] < distance) {
    return BT::NodeStatus::SUCCESS;
  } else {
    return BT::NodeStatus::FAILURE;
  }
}

}  // namespace br2_bt_bumpgo

#include "behaviortree_cpp_v3/bt_factory.h"
BT_REGISTER_NODES(factory)
{
  factory.registerNodeType<br2_bt_bumpgo::IsObstacle>("IsObstacle");
}

后退:

vel_msgs.linear.x = -0.3;

前进:

vel_msgs.linear.x = 0.3;

转向:

vel_msgs.angular.z = 0.5;

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度学习:DenseNet思想总结

深度学习&#xff1a;DenseNet思想总结前言DenseNetResNetDense connectionComposite functionPooling layersGrowth rateBottleneck layersCompressionImplementation Details总结前言 论文中提出的架构为了确保网络层之间的最大信息流&#xff0c;将所有层直接彼此连接。为了…

JUC面试(八)——阻塞队列

阻塞队列 队列&#xff0c;FIFO BlockingQueue 阻塞队列&#xff0c;排队拥堵&#xff0c;首先它是一个队列&#xff0c;而一个阻塞队列在数据结构中所起的作用大致如下图所示&#xff1a; 线程1往阻塞队列中添加元素&#xff0c;而线程2从阻塞队列中移除元素 当阻塞队列是空…

Java基础(程序流程控制)

程序流程控制1..顺序结构程序从上到下逐行执行&#xff0c;中间没有判断和跳转2.分支结构根据条件&#xff0c;选择性执行某段代码有if-else和switch-case两种分支需要注意根据相应的方法&#xff0c;来输入指定类型的值。如果不匹配则会异常&#xff1a;InputMisMatchExceptio…

结构型模式-桥接模式

1.概述 现在有一个需求&#xff0c;需要创建不同的图形&#xff0c;并且每个图形都有可能会有不同的颜色。我们可以利用继承的方式来设计类的关系&#xff1a; 我们可以发现有很多的类&#xff0c;假如我们再增加一个形状或再增加一种颜色&#xff0c;就需要创建更多的类。试…

2.5总线标准

文章目录一、引子二、总线标准1.基本概念2.总线标准&#xff08;1&#xff09;系统总线①ISA②EISA扩展总线③拓展&#xff08;2&#xff09;局部总线①VESA②PCI③AGP④PCI-E&#xff08;3&#xff09;设备总线①RS-232C②SCSI③PCMCIA④USB3.连接硬盘总线标准①IDE②SATA三、…

JAVA 服务内存占用太高

一、问题现象 某天&#xff0c;运维老哥突然找我&#xff1a;“你们的某 JAVA 服务内存占用太高&#xff0c;告警了&#xff01;GC 后也没释放&#xff0c;内存只增不减&#xff0c;是不是内存泄漏了&#xff01;” 然后我赶紧看了下监控&#xff0c;一切正常&#xff0c;距离上…

redis缓存问题引进

1、缓存使用 为了系统性能的提升&#xff0c;我们一般都会将部分数据放入缓存中&#xff0c;加速访问。而 db 承担数据落 盘工作。 哪些数据适合放入缓存&#xff1f;  即时性、数据一致性要求不高的  访问量大且更新频率不高的数据&#xff08;读多&#xff0c;写少&…

BigDecimal BigInteger的使用

1、BigDiCemal 【问题】在项目中&#xff0c;我们进行计算的时候&#xff0c;有时候需要考虑 四舍五入&#xff0c;精度丢失的问题&#xff0c;面对这种问题&#xff0c;我们应该怎么处理&#xff1f; System.out.println(0.20.1);System.out.println(0.3-0.1);System.out.prin…

SEO中社交信号的重要性:Facebook分析

你可能认为 SEO中的社交信号是一些无用的社交账号&#xff0c;但它在搜索引擎优化中占有重要地位。Facebook是目前全球最大的社交媒体平台&#xff0c;它已经成为我们日常生活不可缺少的一部分。如何分析和利用好 Facebook&#xff0c;是我们学习 SEO的重中之重。在接下来的内容…

58 应用服务 hang 住, 导致服务 503 Service Unavailable

前言 这是之前 我们测试环境出现的一个问题 一个项目, 代码调整了之后, 发布到测试环境 之后, 几分钟之后 整个系统访问这个服务 出现了 "503 Service Unavailable", 然后 当时的处理方式为 临时重启服务 但是过了一会儿之后 同样的问题还是会出现, 导致 前端服务…

Functions重要部分

Functions1. Defining Functions2. Looking Up Names in Environments1. Defining Functions 赋值&#xff08;Assignment&#xff09;是一种简单的抽象方式&#xff1a;把值&#xff08;values&#xff09;和名称&#xff08;names&#xff09;联系起来。 定义函数&#xff0…

《从零开始编写一个直播服务器》 C++ 实现一个最简单的RTSP流媒体服务器

流媒体开发系列文章 文章目录流媒体开发系列文章前言一、rtsp流是什么&#xff1f;二、使用步骤1.服务器代码总结前言 在安防行业中&#xff0c;onvif协议与gb协议是两种标准&#xff0c;gb是国内安防行业的标准&#xff0c;onvif是国外的安防行业的标准&#xff0c;其中gb281…

AcWing 1013. 机器分配(分组背包问题与方案记录)

一、题目 二、思路 这道题其实不太容易看出背后的模型。这道题本质上是一个分组背包问题。我们将每一个公司看成一组&#xff0c;而在每一个组内&#xff0c;将不同情况下的盈利状况看作物品的价值&#xff0c;而得到这种利益所需的机器数目看作物品的体积。 因此&#xff0c…

SpringSession笔记

第一章、Session会话管理概述Session和Cookie回顾Session机制由于HTTP是无状态的协议&#xff0c;每次浏览器与服务器的交互过程就是一次对话&#xff0c;对话结束之后服务器不能记住你这个人。下次对话的时候服务端无法识别你是上次的人&#xff0c;所以需要一种机制来记录用户…

Win10 突然蓝屏安全模式进不了,没有别的电脑和装机U盘,怎么把资料临时导出来?

环境: Win 10专业版 DELL 3490 移动硬盘/普通U盘 问题描述: Win10 突然蓝屏安全模式进不了,没有别的电脑和装机U盘,怎么把资料临时导出来?目前可以进入Win RE 疑难-高级选项 解决方案: 1.先插入,移动硬盘或者普通U盘 2.多重启几次,自动修复系统失败画面,点击高…

Linux嵌入式开发——压缩与解压缩

文章目录Linux嵌入式开发——压缩与解压缩一、前期准备二、Linux下的压缩格式三、gzip压缩工具1、gzip压缩文件2、gzip压缩文件夹四、bzip2压缩工具五、tar打包工具tar参数对.tar.bz2进行压缩和解压缩压缩解压缩对.tar.gz进行压缩和解压缩压缩解压缩六、其他格式的压缩和解压缩…

Qt扫盲-网络编程概述

网络编程概述一、Qt网络编程概述二、Qt对Http&#xff0c;FTP应用层协议支持三、TCP通信编程支持四、UDP通信编程支持五、主机信息的获取六、网络代理七、底层管理的支持一、Qt网络编程概述 Qt Network模块提供了允许我们编写TCP/IP客户端和服务器的类。它提供了低级类来完成基…

【Java寒假打卡】JavaWeb-Session

【Java寒假打卡】JavaWeb-Session概述常用的方法HttpSession的获取HttpSession的使用概述 常用的方法 HttpSession的获取 HttpSession的使用 在第一个Servlet中获取请求的用户名获取HttpSession对象将用户名设置到共享数据中在第二个Servlet中获取HttpSession对象获取共享数据用…

java8新特性

接口中默认方法修饰为普通方法&#xff0c;实现接口时不需要重写方法Lambda表达式Stream流并行流原理校验当前对象是否为null当前对象为null,设置默认值 接口中默认方法修饰为普通方法Lambda表达式使用Lambda表达式 依赖于函数接口 在接口中只能够允许有一个抽象方法在函数接…

SpringCloud笔记

2023年最新笔记&#xff0c;全文约 3 万字&#xff0c;蕴含 Spring Cloud 常用组件 Nacos、OpenFeign、Seata、Sentinel 等 〇、简介 什么是Spring Cloud&#xff1f; ​ Spring Cloud是一系列框架的有序集合&#xff0c;是一种基于微服务的分布式架构技术。它利用 Spring Boot…