ROS2 学习(二)工作空间,节点

news/2025/2/14 8:01:20/

工作空间介绍

workspace 是存放整个项目的大目录。

其中包含:

src:源码。

build:编译文件。

install:安装空间,存放编译成功后的目标文件。

log:日志。

我们新建一个工作空间目录,其中包含 src 目录,git clone https://gitee.com/guyuehome/ros2_21_tutorials.git 到 src 目录中。

在工作目录中安装依赖(通过 rosdepc),编译工作空间,设置环境变量。

代码功能包可以通过 ros 的 pkg create 功能创建。在 src 文件夹下执行:

$ ros2 pkg create --build-type ament_cmake learning_pkg_c
$ ros2 pkg create --build-type ament_python learning_pkg_python

C 功能包中包含 package.xml 和 CMakeLists.txt。package.xml 包含包基本信息和所需依赖,CMakeLists.txt 指明如何编译。

Python 功能包中包含 package.xml 和 Setup.cfg/Setup.py,Setup.py 中包含一些程序配置,入口节点等。

https://docs.ros.org/en/humble/Tutorials/Workspace/Creating-A-Workspace.html
https://docs.ros.org/en/humble/Tutorials/Creating-Your-First-ROS2-Package.html

节点

节点是机器人的基本单元,独立执行具体任务。他们可以是不同编程语言,运行在不同位置(云端,本地……)

Helloworld 案例

目标:隔0.5s输出一次 helloworld.

在 learning_node/learning_node/node_helloworld .py 案例中可以看到:

#!/usr/bin/env python3 
# -*- coding: utf-8 -*-"""
@作者: 古月居(www.guyuehome.com)
@说明: ROS2节点示例-发布“Hello World”日志信息, 使用面向过程的实现方式
"""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接口

rclpy:系统。

node:节点。

前面的部分都是固定的, import 包,定义 main 函数,初始化接口。

然后在 learning_node/setup.py 中:

from setuptools import setuppackage_name = 'learning_node'setup(name=package_name,version='0.0.0',packages=[package_name],data_files=[('share/ament_index/resource_index/packages',['resource/' + package_name]),('share/' + package_name, ['package.xml']),],install_requires=['setuptools'],zip_safe=True,maintainer='Hu Chunxu',maintainer_email='huchunxu@guyuehome.com',description='TODO: Package description',license='TODO: License declaration',tests_require=['pytest'],entry_points={'console_scripts': ['node_helloworld       = learning_node.node_helloworld:main','node_helloworld_class = learning_node.node_helloworld_class:main','node_object            = learning_node.node_object:main','node_object_webcam     = learning_node.node_object_webcam:main',],},
)

entry_points 入口点中包含了对应要编译的文件,才可以被 ros run 中找到 learning_node 功能包以及其中的程序,程序中的入口函数。

另一种编程方式(更推荐)是面向节点对象的编程方式。在 node_helloworld_class.py 中:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-"""
@作者: 古月居(www.guyuehome.com)
@说明: ROS2节点示例-发布“Hello World”日志信息, 使用面向对象的实现方式
"""import rclpy                                     # ROS2 Python接口库
from rclpy.node import Node                      # ROS2 节点类
import time"""
创建一个HelloWorld节点, 初始化时输出“hello world”日志
"""
class HelloWorldNode(Node):def __init__(self, name):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接口

物品识别

识别图片中的红苹果。

#!/usr/bin/env python3 
# -*- coding: utf-8 -*-"""
@作者: 古月居(www.guyuehome.com)
@说明: ROS2节点示例-通过颜色识别检测图片中出现的苹果
"""import rclpy                            # ROS2 Python接口库
from rclpy.node import Node             # ROS2 节点类import cv2                              # OpenCV图像处理库
import numpy as np                      # Python数值计算库lower_red = np.array([0, 90, 128])     # 红色的HSV阈值下限
upper_red = np.array([180, 255, 255])  # 红色的HSV阈值上限def object_detect(image):hsv_img = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)                               # 图像从BGR颜色模型转换为HSV模型mask_red = cv2.inRange(hsv_img, lower_red, upper_red)                          # 图像二值化contours, hierarchy = cv2.findContours(mask_red, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE) # 图像中轮廓检测for cnt in contours:                                                          # 去除一些轮廓面积太小的噪声if cnt.shape[0] < 150:continue(x, y, w, h) = cv2.boundingRect(cnt)                                      # 得到苹果所在轮廓的左上角xy像素坐标及轮廓范围的宽和高cv2.drawContours(image, [cnt], -1, (0, 255, 0), 2)                        # 将苹果的轮廓勾勒出来cv2.circle(image, (int(x+w/2), int(y+h/2)), 5, (0, 255, 0), -1)           # 将苹果的图像中心点画出来cv2.imshow("object", image)                                                    # 使用OpenCV显示处理后的图像效果cv2.waitKey(0)cv2.destroyAllWindows()def main(args=None):                                                              # ROS2节点主入口main函数rclpy.init(args=args)                                                         # ROS2 Python接口初始化node = Node("node_object")                                                     # 创建ROS2节点对象并进行初始化node.get_logger().info("ROS2节点示例:检测图片中的苹果")image = cv2.imread('/home/jingqing3948/Develop/ros/dev_ws/src/ros2_21_tutorials/learning_node/learning_node/apple.jpg')  # 读取图像object_detect(image)                                                            # 苹果检测rclpy.spin(node)                                                               # 循环等待ROS2退出node.destroy_node()                                                            # 销毁节点对象rclpy.shutdown()                                                               # 关闭ROS2 Python接口

1691975253963

也可以把 image 改成调用摄像头,来动态识别。

cap = cv2.VideoCapture(0)while rclpy.ok():ret, image = cap.read()          # 读取一帧图像if ret == True:object_detect(image)          # 苹果检测

当然,节点并不是孤立的,比如用摇杆控制游戏界面。


http://www.ppmy.cn/news/1033903.html

相关文章

麦肯锡发布《2023科技趋势展望报告》,生成式AI、下一代软件开发成为趋势,软件测试如何贴合趋势?

近日&#xff0c;麦肯锡公司发布了《2023科技趋势展望报告》。报告列出了15个趋势&#xff0c;并把他们分为5大类&#xff0c;人工智能革命、构建数字未来、计算和连接的前沿、尖端工程技术和可持续发展。 类别一&#xff1a;人工智能革命 生成式AI 生成型人工智能标志着人工智…

实习笔记(一)

自定义注解&#xff1a; 自定义注解中有三个元注解Target,Retention,Document /*** 系统日志注解** author Mark sunlightcsgmail.com*/ Target(ElementType.METHOD) Retention(RetentionPolicy.RUNTIME) Documented public interface SysLog {String value() default "…

Linux怎样处理网络请求——彻底理解IO多路复用

常见的网络IO模型 网络 IO 模型分为四种&#xff1a;同步阻塞 IO、同步非阻塞IO、IO 多路复用、异步非阻塞 IO(Async IO, AIO)&#xff0c;其中AIO为异步IO&#xff0c;其他都是同步IO 同步阻塞IO 同步阻塞IO&#xff1a;在线程处理过程中&#xff0c;如果涉及到IO操作&…

Python 基础语法 | 常量表达式,变量,注释,输入输出

常量和表达式 我们可以把 Python 当成一个计算器&#xff0c;来进行一些算术运算 print(1 2 - 3) # 0 print(1 2 * 3) # 7 print(1 2 / 3) # 1.6666666666666665注意&#xff1a; print 是一个 Python 内置的 函数可以使用 - * / () 等运算符进行算术运算&#xff0c;先…

Python采集天气数据,做可视化分析【附源码】

嗨害大家好鸭&#xff01;我是小熊猫~ 毕业设计大家着急吗&#xff1f; 没事&#xff0c;我来替大家着急 源码、素材python永久安装包:点击此处跳转文末名片获取 本文知识点: 动态数据抓包 requests发送请求 结构化非结构化数据解析 开发环境: python 3.8 运行代码 pycharm 2…

01|Java中常见错误或不清楚

补充&#xff1a;length vs length() vs size() 1 java中的length属性是针对数组说的,比如说你声明了一个数组,想知道这个数组的长度则用到了length这个属性. 2 java中的length()方法是针对字符串String说的,如果想看这个字符串的长度则用到length()这个方法. 3.java中的siz…

【Git】安装以及基本操作

目录 一、初识Git二、 在Linux底下安装Git一&#xff09;centOS二&#xff09;Ubuntu 三、 Git基本操作一&#xff09; 创建本地仓库二&#xff09;配置本地仓库三&#xff09;认识工作区、暂存区、版本库四&#xff09;添加文件五&#xff09;查看.git文件六&#xff09;修改文…

学习笔记整理-JS-06-函数

一、函数基本使用 1. 什么是函数 函数就是语句的封装&#xff0c;可以让这些代码方便地被复用。函数具有"一次定义&#xff0c;多次调用"的优点。使用函数&#xff0c;可以简化代码&#xff0c;让代码更具有可读性。 2. 函数的定义和调用 和变量类似&#xff0c;函…