ROS学习

1.ROS工作空间

存放项目开发相关文件的文件夹;

  • src:代码空间(Source Space)
  • install:安装空间(Install Space)
  • build:编译空间(Build Space)
  • log:日志空间(Log Space)

2.colcon是一个包构建工具 

sudo apt install python3-colcon-ros
sudo apt install python3-colcon-ros

3.source命令

在当前bash环境下读取并执行FileName中的命令。

source命令(从 C Shell 而来)是bash shell的内置命令。点命令,就是个点符号,(从Bourne Shell而来)是source的另一名称。

source(或点)命令通常用于重新执行刚修改的初始化文档,如 .bash_profile 和 .profile 这些配置文件。

4.功能包

将不同的功能代码放在不同的功能包中,降低耦合,提高软件复用率

5.节点:机器人的工作细胞

第一个节点(面向过程编程)

import rclpy                                     # ROS2 Python接口库
from rclpy.node import Node                      # ROS2 节点类
import timedef main(args=None):                             # ROS2节点主入口main函数rclpy.init(args=args)                        # ROS2 Python接口初始化node = Node("node_helloworld")               # 创建ROS2节点对象并进行初始化while rclpy.ok():                            # ROS2系统是否正常运行node.get_logger().info("Hello World")    # ROS2日志输出time.sleep(0.5)                          # 休眠控制循环时间node.destroy_node()                          # 销毁节点对象    rclpy.shutdown()                             # 关闭ROS2 Python接口

面向对象编程

import rclpy                                     # ROS2 Python接口库
from rclpy.node import Node                      # ROS2 节点类
import time"""
创建一个HelloWorld节点, 初始化时输出“hello world”日志
"""
class HelloWorldNode(Node):def __init__(self, name):                        # 构造函数# 调用父类 Node 的构造函数来初始化父类部分。super() 函数返回父类对象的实例,super().__init__(name) 调用父类 Node 的初始化方法,将 name 参数传递给父类的构造函数# super().__init__() 是 Python 中的一个方法,常用于调用父类的构造函数(__init__())。它的作用是让子类能够继承并正确初始化父类的属性和行为。super().__init__(name)                       # ROS2节点父类初始化while rclpy.ok():                            # ROS2系统是否正常运行self.get_logger().info("Hello World")    # ROS2日志输出time.sleep(0.5)                          # 休眠控制循环时间def main(args=None):                                 # ROS2节点主入口main函数rclpy.init(args=args)                            # ROS2 Python接口初始化node = HelloWorldNode("node_helloworld_class")   # 创建ROS2节点对象并进行初始化node.destroy_node()                              # 销毁节点对象rclpy.shutdown()                                 # 关闭ROS2 Python接口

在编写程序之后或者更改程序之后一定要进行重新编译

colcon build

实际运行的程序位于

~/dev_ws/install/learning_node/lib/python3.10/site-packages/learning_node

6.话题:节点间传递数据的桥梁(特性:单向传输,无法满足所有数据传输需求)

 安装ROS2中针对相机的标准驱动

sudo apt install ros-humble-usb-cam
ros2 run usb_cam usb_cam_node_exeros2 topic list

usb_cam_node_exe 会从连接的 USB 摄像头(通常是 /dev/video0 设备)读取图像数据。它会定期获取摄像头帧并将图像转换为 ROS 2 的消息格式。

  • 节点初始化

    • 在 ROS 2 中,usb_cam_node_exe 通过继承 ROS 2 的 Node 类来创建一个节点。这个节点负责捕获图像数据并将其发布到 ROS 话题上。
    • 当启动 usb_cam_node_exe 时,它会初始化 ROS 2 接口,并创建一个节点对象。节点会使用相机驱动库(例如 v4l2)来获取摄像头的图像数据。
  • 图像数据捕获

    • usb_cam_node_exe 会从连接的 USB 摄像头(通常是 /dev/video0 设备)读取图像数据。它会定期获取摄像头帧并将图像转换为 ROS 2 的消息格式。
  • 图像消息发布

    • 一旦图像数据被获取,usb_cam_node_exe 会将图像数据包装到一个 ROS 2 消息中,通常是 sensor_msgs/msg/Image 消息类型。
    • 该节点通过 ROS 2 的 发布者(Publisher)机制,将 sensor_msgs/msg/Image 类型的消息发布到相应的话题上(如 /usb_cam/image_raw)。
    • 消息的内容包含图像的像素数据以及一些附加的元数据,如图像的大小、编码格式、时间戳等。
  • 摄像头信息发布

    • 除了图像数据外,usb_cam_node_exe 还会发布相机的相关信息,通常是通过 sensor_msgs/msg/CameraInfo 消息。这些信息包括相机的内参、畸变系数、投影矩阵等。
    • 这些数据通过 sensor_msgs/msg/CameraInfo 类型的消息发布到 /usb_cam/camera_info 话题。
  • 循环和定时发布

    • 通常,图像捕获和发布操作会在一个循环中进行,确保定期地从摄像头获取图像数据并发布。为了避免过度占用 CPU,通常会添加一定的延时(例如,每帧捕获后暂停一定时间)。
    • 发布间隔通常取决于相机的帧率和节点的配置。
#include "rclcpp/rclcpp.hpp"
#include "sensor_msgs/msg/image.hpp"
#include "sensor_msgs/msg/camera_info.hpp"
#include "cv_bridge/cv_bridge.h"
#include "usb_cam/usb_cam.h"  // USB摄像头的驱动class UsbCamNode : public rclcpp::Node
{
public:UsbCamNode(): Node("usb_cam_node"){// 创建一个发布者来发布图像数据image_pub_ = this->create_publisher<sensor_msgs::msg::Image>("/usb_cam/image_raw", 10);// 创建一个发布者来发布相机信息camera_info_pub_ = this->create_publisher<sensor_msgs::msg::CameraInfo>("/usb_cam/camera_info", 10);// 初始化摄像头(例如:设置设备文件、分辨率等)usb_cam_ = std::make_shared<UsbCam>("video0", 640, 480);// 循环捕获并发布图像timer_ = this->create_wall_timer(std::chrono::milliseconds(100),  // 定时器:每100ms执行一次std::bind(&UsbCamNode::publish_image, this));}private:void publish_image(){// 从USB摄像头捕获一帧图像auto frame = usb_cam_->capture_frame();// 将图像转换为ROS消息(cv_bridge帮助进行转换)sensor_msgs::msg::Image::SharedPtr msg = cv_bridge::CvImage(std_msgs::msg::Header(), "bgr8", frame).toImageMsg();// 设置时间戳和其他信息msg->header.stamp = this->get_clock()->now();// 发布图像消息image_pub_->publish(*msg);// 发布摄像头信息(如果需要)sensor_msgs::msg::CameraInfo camera_info_msg;camera_info_msg.header.stamp = msg->header.stamp;camera_info_pub_->publish(camera_info_msg);}rclcpp::Publisher<sensor_msgs::msg::Image>::SharedPtr image_pub_;rclcpp::Publisher<sensor_msgs::msg::CameraInfo>::SharedPtr camera_info_pub_;std::shared_ptr<UsbCam> usb_cam_;  // 用于处理USB摄像头rclcpp::TimerBase::SharedPtr timer_;  // 定时器,用于定期捕获和发布
};int main(int argc, char **argv)
{rclcpp::init(argc, argv);rclcpp::spin(std::make_shared<UsbCamNode>());rclcpp::shutdown();return 0;
}

内部结构详解

  • 节点创建UsbCamNode 继承自 rclcpp::Node,通过调用 this->create_publisher<sensor_msgs::msg::Image> 创建图像发布者。
  • USB 摄像头初始化:通过 UsbCam 类(假设是自定义的摄像头驱动类)初始化摄像头设备(例如 /dev/video0)。
  • 定时器create_wall_timer 用于设置一个定时器,每 100 毫秒调用一次 publish_image 方法。该方法从摄像头捕获一帧图像,并将其转换为 ROS 2 消息后发布。
  • 图像数据转换:使用 cv_bridge 库将 OpenCV 图像转换为 ROS 消息。cv_bridge::CvImage 会将 OpenCV 格式的图像(cv::Mat)转换为 ROS 图像消息(sensor_msgs::msg::Image)。
  • 消息发布:每次捕获一帧图像后,图像消息通过 image_pub_ 发布到 /usb_cam/image_raw,并通过 camera_info_pub_ 发布相机信息到 /usb_cam/camera_info
rqt_graph # 查看节点间的关系

7.服务:节点间的你问我答

ros2 serviceros2 service list# 通过命令行发送请求
ros2 service call /get_target_position learning_interface/srv/GetObjectPosition "get: True"

8.通信接口:数据传递的标准结构

/opt/ros/humble/share目录下有.msg/.srv/.action文件格式的定义
#查看ros下所有的标准接口定义
ros2 interface list
# 查看某个指定格式的定义
ros2 interface show sensor_msgs/msg/Image 

新增一个 msg/Point3D.msg 文件

步骤1:在包的 msg 目录中新增消息文件
  1. 创建消息文件:首先在你的 ROS 2 包中创建一个新的消息文件。例如,在 msg 目录下创建 Point3D.msg 文件。

    • 路径:your_package/msg/Point3D.msg
    • 内容示例:
    float64 x
    float64 y
    float64 z
    

    该文件定义了一个 Point3D 消息,包含 3 个浮动变量 xyz,通常用于表示三维坐标。

步骤2:修改 CMakeLists.txt
  1. 修改 CMakeLists.txt 文件:你需要在 CMakeLists.txt 文件中增加新增的消息定义,并重新生成接口代码。

    假设你已经有了类似以下的代码:

rosidl_generate_interfaces(${PROJECT_NAME}"msg/ObjectPosition.msg""srv/AddTwoInts.srv""srv/GetObjectPosition.srv""action/MoveCircle.action"
)

 现在,新增你刚才创建的 Point3D.msg 文件:

rosidl_generate_interfaces(${PROJECT_NAME}"msg/ObjectPosition.msg""msg/Point3D.msg"  # 新增的消息文件"srv/AddTwoInts.srv""srv/GetObjectPosition.srv""action/MoveCircle.action"
)

这告诉 CMake 在编译时生成 Point3D.msg 的相关代码。

步骤3:修改 package.xml 文件
  1. 修改 package.xml 文件:确保你已经在 package.xml 文件中声明了对消息生成的依赖。你需要确保已包含以下依赖项:

<build_depend>rosidl_default_generators</build_depend>
<exec_depend>rosidl_default_runtime</exec_depend>
步骤4:重新编译包
  1. 重新编译项目:完成上述修改后,运行以下命令来重新构建你的 ROS 2 包:

colcon build --packages-select your_package

这将重新编译包,并根据你在 CMake 文件中指定的接口生成相应的代码(例如 C++ 和 Python 代码)。

步骤5:验证生成的文件
  1. 验证生成的文件:在构建完成后,你可以检查生成的文件。在 build 目录下的相应包中,检查是否生成了 Point3D 的相关代码。

    • 如果是 C++,会生成 Point3D.hppPoint3D.cpp 文件。
    • 如果是 Python,会生成相应的 Python 文件。

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

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

相关文章

【vue3】实现pdf在线预览的几种方式

今天一天对当前可用的pdf预览插件做了测试&#xff0c;主要需求是只能预览不能下载&#xff0c;但对于前端来说&#xff0c;没有绝对的禁止&#xff0c;这里只罗列实现方式。 目前采用vue3版本为&#xff1a;3.2.37 iframevue-officepdfjs-dist iframe 先说最简单的&#xf…

Springboot中使用Elasticsearch(部署+使用+讲解 最完整)

目录 引言 一、docker中安装Elasticsearch 1、创建es专有的网络 2、开放端口 3、在es-net网络上安装es和kibana 4、可能出现的问题 5、测试 6、安装IK分词器 7、测试IK分词器 二、结合业务实战 1、准备依赖 2、配置yml 3、读取yml配置 4、准备es配置类 5、编写测…

文件夹上传到github分支最后github上面还是没有文件和文件夹

环境&#xff1a; github 问题描述&#xff1a; 文件夹上传到github分支最后github上面还是没有文件和文件夹, 和这样一样 解决方案&#xff1a; 从 git ls-tree -r HEAD 的输出中可以看到&#xff0c;metahuman-stream 文件夹显示为如下内容&#xff1a; 160000 commi…

基于Go语言 XTA AI聊天界面实现

项目开源地址: XTA-AI-SDK 人工智能技术的迅速发展&#xff0c;AI聊天应用变得越来越流行。本文将介绍如何使用Go语言和LCL库&#xff08; Lazarus Component Library&#xff09;创建一个功能丰富的AI聊天界面。项目主要包含以下模块&#xff1a; 项目背景 本项目旨在为开发…

C++入门小清单

在上一篇文章中我向大家介绍了关于C的命名空间的用处以及一些&#xff0c;这篇内容主要是讲解有关C入门的一些小知识&#xff0c;大家可以通过此文章初步进行一个了解&#xff0c;这些东西在之后的C学习中都会有更多的妙用&#xff0c;如果有小伙伴感兴趣C的命名空间&#xff0…

【kafka系列】日志存储设计 消息写入、读取

目录 日志存储设计 1. 日志存储的目录结构 2. 日志内容格式设计 3. 日志索引设计 4. 设计优势 消息写入流程 示例 流程图 消息读取流程 示例 关键设计细节 流程图 日志存储设计 Kafka的日志存储是其高吞吐、持久化能力的核心设计&#xff0c;其结构包含目录组织、…

复杂电磁环境下无人机自主导航增强技术研究报告——地磁匹配与多源数据融合方法,附matlab代码

本文给出介绍和matlab程序&#xff0c;来实现地磁辅助惯性导航仿真验证&#xff0c;包含地磁基准图构建、飞行轨迹生成、INS误差建模、地磁匹配定位及多源数据融合等模块。通过对比分析验证地磁匹配修正惯性导航累积误差的有效性&#xff0c;可视化显示卫星拒止环境下的航迹修正…

springboot项目读取 resources 目录下的文件的9种方式

1. 使用 ClassLoader.getResourceAsStream() 方法 InputStream inputStream getClass().getClassLoader().getResourceAsStream(“file.txt”); 2.使用 Class.getResourceAsStream() 方法 InputStream inputStream getClass().getResourceAsStream(“/file.txt”); 3.使用 Re…

基于SSM+uniapp的鲜花销售小程序+LW示例参考

1.项目介绍 系统角色&#xff1a;管理员、商户功能模块&#xff1a;用户管理、商户管理、鲜花分类管理、鲜花管理、订单管理、收藏管理、购物车、充值、下单等技术选型&#xff1a;SSM&#xff0c;Vue&#xff08;后端管理web&#xff09;&#xff0c;uniapp等测试环境&#x…

硕成C语言22【一些算法和数组的概念】

1.求水仙花数 #include <stdio.h>int main() {//求水仙花数&#xff1a;1.三位数 2.个位的立方十位的立方百位的立方该数int unit, tens, hundreds;for (int i 100; i < 1000; i)//i表示该水仙花数{unit i / 1 % 10;tens i / 10 % 10;hundreds i / 100 % 10;if (…

游戏引擎学习第101天

回顾当前情况 昨天的进度基本上完成了所有内容&#xff0c;但我们还没有进行调试。虽然我们在运行时做的事情大致上是对的&#xff0c;但还是存在一些可能或者确定的bug。正如昨天最后提到的&#xff0c;既然现在时间晚了&#xff0c;就不太适合开始调试&#xff0c;所以今天我…

无人机航迹规划:互联银行系统优化(Connected Banking System Optimizer,CBSO)求解无人机路径规划MATLAB

一、互联银行系统优化算法 互联银行系统优化&#xff08;Connected Banking System Optimizer&#xff0c;CBSO&#xff09;算法是2024年由Mehrdad Nemati等人提出的一种智能优化算法&#xff0c;其灵感来源于银行系统之间的连接和交易过程。在银行系统中&#xff0c;核心银行…

【清晰教程】通过Docker为本地DeepSeek-r1部署WebUI界面

【清晰教程】本地部署DeepSeek-r1模型-CSDN博客 目录 安装Docker 配置&检查 Open WebUI 部署Open WebUI 安装Docker 完成本地DeepSeek-r1的部署后【清晰教程】本地部署DeepSeek-r1模型-CSDN博客&#xff0c;通过Docker为本地DeepSeek-r1部署WebUI界面。 访问Docker官…

css简介

一.css-网页的美容师 css也是一种标记语言&#xff0c;主要用于设置HTML页面中的文本内容(字体大小对齐方式)&#xff0c;图片外形&#xff08;宽高 边框样式 边距等&#xff09;以及版面的布局和外观显示样式。 二.css语法规范 css规则由两个主要的部分构成:选择器以及一条…

Postman如何流畅使用DeepSeek

上次写了一篇文章是用chatBox调用api的方式使用DeepSeek&#xff0c;但是实际只能请求少数几次就不再能给回响应。这回我干脆用最原生的方法Postman调用接口请求好了。 1. 通过下载安装Postman软件 postman下载(https://pan.quark.cn/s/c8d1c7d526f3)&#xff0c;包含7.0和10…

DC-6靶机渗透测试全过程

目录 前期准备 一、渗透测试 1.IP地址查询 2.端口信息搜寻 3.网页信息搜集 wappalyzer WPScan 反弹shell graham用户 反弹出jens的shell nmap提权 二、总结 前期准备 攻击机&#xff1a; kali windows11 靶机&#xff1a;DC-6靶机&#xff08;调至NAT模式&#xff0…

以若依移动端版为基础,实现uniapp的flowable流程管理

1.前言 此代码是若依移动端版为基础&#xff0c;实现flowable流程管理&#xff0c;支持H5、APP和微信小程序三端。其中&#xff0c;APP是在安卓在雷电模拟器环境下完成的&#xff0c;其他环境未测试&#xff0c;此文章中所提及的APP均指上述环境。移动端是需要配合若依前后端分…

C++ Primer 返回值和return语句

欢迎阅读我的 【CPrimer】专栏 专栏简介&#xff1a;本专栏主要面向C初学者&#xff0c;解释C的一些基本概念和基础语言特性&#xff0c;涉及C标准库的用法&#xff0c;面向对象特性&#xff0c;泛型特性高级用法。通过使用标准库中定义的抽象设施&#xff0c;使你更加适应高级…

dma_ddr 的编写 通过mig控制ddr3

此外还有别的模块 本模块是 其中一个 timescale 1ns/1ps module dma_ctrl (input wire ui_clk , //100MHZ 用户时钟input wire ui_rst_n ,//写fifo的写端口 input wire wf_wr_clk , //由数据产生模块的时…

【15】思科AireOS:创建使用 PSK 认证的 WLAN

1. 概述 在 Cisco AireOS 无线局域网控制器(WLC)上,您可以配置基于预共享密钥(PSK)的 WLAN,以提供无线访问。PSK 认证是一种 WPA2/WPA3 个人模式下常用的认证方式,适用于家庭或小型企业环境。 本指南将详细介绍如何在 Cisco AireOS WLC 上配置 PSK 认证的 WLAN,并确保…