ros2 launch 集合 gazebo yolov8 rviz2
目录
1. ros2 yolov8 检测需要以来一些库,分别是:rclpy cv_bridge std_msgs sensor_msgs sensor_msgs_py vision_msgs
2. 创建一个新的功能包
3. 建立 yolo_launch.py 里面先加载gazebo和rviz2,在创建好本地的yolov8的node文件后也加入进来。
4. 创建好本地的yolov8的node文件
5. 修改setup.py文件
6. 编译包
7. 运行launch文件
1. ros2 yolov8 检测需要以来一些库,分别是:rclpy cv_bridge std_msgs sensor_msgs sensor_msgs_py vision_msgs
(1) rclpy Python语言的ROS Client Library,操作ROS2的节点话题服务
(2) cv-bridge 在ROS图像消息和OpenCV图像之间进行转换的一个功能包
(3) std-msgs 一种标准消息类型包,包含了一些常用的基本数据类型的消息定义
以上设计的是图像依赖的,下面两个是获取其他数据类型的
---------------------------------------------------------------
(4) sensor-msgs-py point_cloud2模块
(5) vision-msgs ROS的与算法无关的计算机视觉消息类型,ROS视觉信息介绍该软件包定义了一组消息,以统一ROS中的计算机视觉和对象检测工作
# 库安装命令如下:
sudo apt-get install ros-galactic-rclpy
sudo apt-get install ros-galactic-cv-bridge
sudo apt-get install ros-galactic-std-msgs
sudo apt-get install ros-galactic-sensor-msgs-py
sudo apt-get install ros-galactic-vision-msgs
2. 创建一个新的功能包
ros2 pkg create ros_yolov8 --build-type ament_python --node-name detect_node --dependencies rclpy cv_bridge std_msgs sensor_msgs sensor_msgs_py vision_msgs
运行结果:
going to create a new package package name: ros_yolov8 destination directory: package format: 3 version: 0.0.0 description: TODO: Package description maintainer: licenses: ['TODO: License declaration'] build type: ament_python dependencies: ['rclpy', 'cv_bridge', 'std_msgs', 'sensor_msgs', 'sensor_msgs_py', 'vision_msgs'] node_name: detect_node creating folder ./ros_yolov8 creating ./ros_yolov8/package.xml creating source folder creating folder ./ros_yolov8/ros_yolov8 creating ./ros_yolov8/setup.py creating ./ros_yolov8/setup.cfg creating folder ./ros_yolov8/resource creating ./ros_yolov8/resource/ros_yolov8 creating ./ros_yolov8/ros_yolov8/__init__.py creating folder ./ros_yolov8/test creating ./ros_yolov8/test/test_copyright.py creating ./ros_yolov8/test/test_flake8.py creating ./ros_yolov8/test/test_pep257.py creating ./ros_yolov8/ros_yolov8/detect_node.py
# ./ros_yolov8/package.xml
<?xml version="1.0"?>
......<depend>rclpy</depend>
<depend>cv_bridge</depend>
<depend>std_msgs</depend>
<depend>sensor_msgs</depend>
<depend>sensor_msgs_py</depend>
<depend>vision_msgs</depend>......
</package>
3. 建立 yolo_launch.py 里面先加载gazebo和rviz2,在创建好本地的yolov8的node文件后也加入进来。
# 创建一个新目录来存储(launch)启动文件
cd ./ros_yolov8 && mkdir launch
cd ./ros_yolov8/launch && touch detect_demo.launch.py
tree ./ros_yolov8/launch
运行结果:
./ros_yolov8/launch └── detect_demo.launch.py
#!/usr/bin/python3
# ./ros_yolov8/launch/detect_demo.launch.pyimport osfrom ament_index_python.packages import get_package_share_directoryfrom launch import LaunchDescription
from launch_ros.actions import Nodefrom launch.substitutions import LaunchConfiguration
from launch.actions import DeclareLaunchArgument
from launch.conditions import IfConditionfrom launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSourcedef generate_launch_description():# all kinds of file pathros_root_path = "/xxx/ros2_ws"try:pkg_name = "ros_yolov8"share_pkg_path = get_package_share_directory(pkg_name)except:share_pkg_path = os.path.join(ros_root_path, "install", pkg_name, "share", pkg_name)print(f"{share_pkg_path=}")assert os.path.exists(share_pkg_path)# -1-Include the Gazebo launch file, provided by the gazebo_ros packageworld_file_path = os.path.join(share_pkg_path, 'worlds', 'yolo.world')# 包含其它的launch文件 :/opt/ros/galactic/share/gazebo_ros/launch/gazebo.launch.py# $ ros2 launch /opt/ros/galactic/share/gazebo_ros/launch/gazebo.launch.py world:=/xxx/yolo.worldgazebo_ros_dirpath = get_package_share_directory('gazebo_ros')print(f"{gazebo_ros_dirpath=}")gazebo_launch_filepath = os.path.join(gazebo_ros_dirpath, 'launch', 'gazebo.launch.py')print(f"{gazebo_launch_filepath=}")assert os.path.exists(gazebo_launch_filepath)# -2-Include the Rviz2 config file, provided by the rviz2 package# /opt/ros/galactic/lib/rviz2/rviz2# $ ros2 run rviz2 rviz2 -d # start rviz2rviz_filepath = os.path.join(share_pkg_path, 'rviz2', 'yolo.rviz')print(f"{rviz_filepath=}")assert os.path.exists(rviz_filepath)# Nodesgazebo_cmd = IncludeLaunchDescription(PythonLaunchDescriptionSource([gazebo_launch_filepath]),launch_arguments={'world': world_file_path}.items())static_transform_cmd = Node(package='tf2_ros',executable='static_transform_publisher',name='static_transform_publisher',arguments=["0", "0", "0", "0", "0", "0", "map", "camera_link_optical"],output='screen')start_rviz_cmd = Node(package='rviz2',executable='rviz2',name='rviz2',arguments=['-d', rviz_filepath],output='screen')# Launch arguments# start yolov8_nodestart_yolov8_node = Node(package='ros_yolov8',executable='yolov8_node',name='yolov8_node',output='screen',arguments=["-model", "/xxx/yolo.pt"])# Add everything to launch description and returnld = LaunchDescription()ld.add_action(gazebo_cmd)ld.add_action(static_transform_cmd)ld.add_action(start_rviz_cmd)ld.add_action(start_yolov8_node)return ld"""
/opt/ros/galactic/lib/tf2_ros/static_transform_publisher
# ros2 run tf2_ros static_transform_publisher "0" "0" "0" "0" "0" "0" "map" "camera_link_optical"
# -2-1- map axis between origin and world
"""
4. 创建好本地的yolov8的node文件
# ./ros_yolov8/ros_yolov8/yolov8_node.pyimport os
import sys
import time
import argparse
import random
import torch
# ROS2的客户端库(python) rclpy
import rclpy
from rclpy.qos import qos_profile_sensor_data
from rclpy.node import Node
# image-----below----
# topic sensor_msgs/msg/Image to cv2
import cv2
from sensor_msgs.msg import Image
from cv_bridge import CvBridge
# yolov8
from ultralytics import YOLOdef parse_argument():parser = argparse.ArgumentParser(description='detect image from topic (gazebo)')parser.add_argument('-model', type=str, default='/xxx/yolo.pt')parser.add_argument('-device', type=str, default='cpu')parser.add_argument('-conf_threshold', type=float, default=0.5)parser.add_argument('-iou_threshold', type=float, default=0.7)parser.add_argument('-enable', type=bool, default=True)parser.add_argument('-input_image_topic', type=str, default='/camera/image_raw')parser.add_argument('-show_inference_image', type=bool, default=True)parser.add_argument('-save', type=bool, default=False)args, unknown = parser.parse_known_args()return argsclass Yolov8Node(Node):# Node constructordef __init__(self) -> None:super().__init__("yolov8_node")# node paramsself.args = parse_argument()#self._class_to_color = {}self.cv_bridge = CvBridge()# yoloself.yolo = YOLO(self.args.model)self.yolo.fuse()print(f"{self.args.device=}")self.yolo.to(self.args.device)# topic publishers & subscribersself._infer_pub = self.create_publisher(Image, "inference_image", 10)self._image_sub = self.create_subscription(Image,self.args.input_image_topic,self.image_cb,qos_profile_sensor_data)def image_cb(self, msg: Image) -> None:# if self.args.enable:# record start timefps_start_t = time.time()# convert to cv image & predictcv_image = self.cv_bridge.imgmsg_to_cv2(msg)infer_start_t = time.perf_counter()results = self.yolo.predict(source=cv_image,verbose=False,stream=False,conf=self.args.conf_threshold,iou=self.args.iou_threshold,show=self.args.show_inference_image,mode="predict",save=self.args.save)end_time = time.perf_counter()# visualize the results on the frameannotated_image = results[0].plot()# record the end time and calculate FPSfps = 1.0 / (end_time - fps_start_t)cv2.putText(annotated_image, "FPS: {:.2f}".format(fps), (10, 30),cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2, cv2.LINE_AA)results = results[0].cpu()for b in results.boxes:label = self.yolo.names[int(b.cls)]score = float(b.conf)if score < self.args.conf_threshold:continue# get boxes valuesbox = b.xywh[0]x_center = float(box[0])y_center = float(box[1])x_size = float(box[2])y_size = float(box[3])x_min = round(x_center - x_size / 2.0)x_max = round(x_center + x_size / 2.0)y_min = round(y_center - y_size / 2.0)y_max = round(y_center + y_size / 2.0)# draw boxes for debuggingif label not in self._class_to_color:r = random.randint(0, 255)g = random.randint(0, 255)b = random.randint(0, 255)self._class_to_color[label] = (r, g, b)color = self._class_to_color[label]cv2.rectangle(cv_image, (x_min, y_min), (x_max, y_max), color, 2)label = "{} ({:.3f})".format(label, score)pos = (x_min + 5, y_min + 25)font = cv2.FONT_HERSHEY_SIMPLEXcv2.putText(cv_image, label, pos, font,1, color, 1, cv2.LINE_AA)# append msgself._infer_pub.publish(self.cv_bridge.cv2_to_imgmsg(annotated_image, encoding=msg.encoding))def main():rclpy.init()node = Yolov8Node()rclpy.spin(node)node.destroy_node()rclpy.shutdown()if __name__ == '__main__':main()
5. 修改setup.py文件
# ./ros_yolov8/setup.py
from setuptools import setup
import os
from glob import globpackage_name = 'ros_yolov8'setup(name=package_name,version='0.0.0',packages=[package_name],# new ros2_ws/install/{package_name}/share/*, copy from src/{package_name}/*data_files=[('share/ament_index/resource_index/packages', ['resource/' + package_name]),('share/' + package_name, ['package.xml']),# During installation, we need to copy the launch files(os.path.join('share', package_name, "launch"), glob('launch/*launch.[pxy][yma]*')),# Same with the RViz2 configuration file.(os.path.join('share', package_name, "rviz2"), glob('rviz2/*')),# And the Gazebo world files.(os.path.join('share', package_name, "worlds"), glob('worlds/*')),# And the config files.(os.path.join('share', package_name, "config"), glob('config/*')),],
......
6. 编译包
source /opt/ros/galactic/setup.bash
colcon build --packages-select ros-yolov8
. install/setup.bash
7. 运行launch文件
ros2 launch /xxx/ros_yolov8/launch/detect_demo.launch.py
# 或
ros2 launch ros_yolov8 detect_demo.launch.py
相关文章:
ros2 launch 集合 gazebo yolov8 rviz2
目录 1. ros2 yolov8 检测需要以来一些库,分别是:rclpy cv_bridge std_msgs sensor_msgs sensor_msgs_py vision_msgs 2. 创建一个新的功能包 3. 建立 yolo_launch.py 里面先加载gazebo和rviz2,在创建好本地的yolov8的node文件后也加入进来。 4. 创建好本地的yol…...

SD NAND【商业】
SD NAND【商业】 前言版权推荐SD NAND外观NAND与TF卡的区别雷龙CS SD NAND(贴片式TF卡)性能体验及应用 最后 前言 2023-7-23 16:20:19 因为本人对硬件了解不是很多,所以该篇参考自官方文档。 以下内容源自《【商业】》 仅供学习交流使用 版权 禁止其他平台发布…...
实现任意进制(2—32)转换
2020/01/01 实现原理参考代码测试样例其他补充后记交流 实现原理 本程序借助10进制数为中介数据,实现任意进制数之间的相互转换(2-36进制范围) 需要注意的是,数值范围不可超出 long long int 所表示的范围,即所输入需…...

Spring Boot 集成 Redis 三种模式实践汇总
背景 项目的某个模块集成了 SpringBoot Redis 包,客户端使用 Lettuce,Redis 测试环境单机模式。但是现场反馈的 Redis 环境是集群,如果简单的修改 spring.redis 配置为集群的配置信息,程序能否能无缝衔接呢? 本文记录…...
MySQL DQL语法
MySQL DQL语法 DQL语法简介 DQL(Data Query Language)语句是一种用于从数据库中检索数据的语言。它主要用于数据查询和数据分析,而不是对数据库中的数据进行更新、插入或删除。DQL语句通常用于获取特定条件下的数据,进行聚合计算…...
算法之线性表1.1.1(7)带头结点链表的反向输出
设L为带头结点的单链表,编写算法实现从尾到头反向输出每个节点的值。 算法思想: 方法一:将链表压栈再输出,时间复杂度为O(n),空间复杂度为O(n) 方法二:用头插法重新建立单链表在输出,时间复杂度为O(n),空…...
设计模式三:抽象工厂模式(Abstract Factory Pattern)
抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,它提供了一种方式来创建一系列相关或相互依赖的对象,而无需指定具体实现类。 在软件开发中,有时候需要根据不同的条件或环境来创建一组相关的对象。抽象工…...

Linux用户权限问题详解
Linux用户权限问题详解 【一】Linux权限的概念(1)用户类型(2)如何切换用户(3)用户相关的一些命令 【二】Linux文件权限管理(1)文件访问者的分类(2)文件类型和…...

flask中的session介绍
flask中的session介绍 在Flask中,session是一个用于存储特定用户会话数据的字典对象。它在不同请求之间保存数据。它通过在客户端设置一个签名的cookie,将所有的会话数据存储在客户端。以下是如何在Flask应用中使用session的基本步骤: 首先…...

记录联想拯救者R720重装系统
文章目录 bios里找不到U盘启动项2023.7.23重装系统后数据记录C盘内存修改默认AppData的路径(亲测,没用) bios里找不到U盘启动项 制作好启动盘后,开机按F2进入bios后,找不到U盘启动项,如下图所示࿱…...

Spring Alibaba Sentinel实现集群限流demo
1.背景 1.什么是单机限流? 小伙伴们或许遇到过下图这样的限流配置 又或者是这样的Nacos动态配置限流规则: 以上这些是什么限流?没错,就是单机限流,那么单机限流有什么弊端呢? 假设我们集群部署3台机器&a…...
102、SOA、分布式、微服务之间有什么关系和区别?
SOA、分布式、微服务之间有什么关系和区别? 分布式架构是指将单体架构中的各个部分拆分,然后部署到不同的机器或进程中去,SOA和微服务基本上都是分布式架构师SOA是一种面向服务的架构,系统的所有服务都注册在总线上,当调用服务时…...

Ubuntu 20.04下的录屏与视频剪辑软件
ubuntu20.04下的录屏与视频剪辑 一、录屏软件SimpleScreenRecorder安装与使用 1、安装 2、设置录制窗口参数 3、开始录制 二、视频剪辑软件kdenlive的安装 1、安装 2、启动 一、录屏软件SimpleScreenRecorder安装与使用 1、安装 (1)直接在终端输入以下命…...
面试题 -- iOS数据存储
文章目录 一、如果后期需要增加数据库中的字段怎么实现,如果不使用CoreData呢?二、SQLite 数据存储是怎么用?三、简单描述下客户端的缓存机制?四、实现过多线程的Core Data 么?NSPersistentStoreCoordinator࿰…...
spring复习:(51)environment、systemProperties、systemEnvironment三个bean是在哪里被添加到容器的?
一、主类: package cn.edu.tju.study.service.anno;import cn.edu.tju.study.service.anno.config.MyConfig; import cn.edu.tju.study.service.anno.domain.Person; import com.sun.javafx.runtime.SystemProperties; import org.springframework.context.annotat…...

element ui 上传控件携带参数到后端
1.携带固定参数: 2.携带不固定参数: <el-row> <el-col :span"24"> <el-upload :multiple"false" :show-file-list"false" :on-success"f_h…...
scrapy分布式+指纹去重原理
1,指纹去重原理存在于 scrapy.util.requests 里面 需要安装的包 pip install scrapy-redis-cluster # 安装模块 pip install scrapy-redis-cluster0.4 # 安装模块时指定版本 pip install --upgrade scrapy-redis-cluster # 升级模块版本 2,setting配置 …...

FileHub使用教程:Github Token获取步骤,使用快人一步
FileHub介绍 filehub是我开发的一个免费文件存储软件,可存万物。软件仓库:GitHub - Sjj1024/s-hub: 一个使用github作为资源存储的软件 软件下载地址:。有问题可以留言或者提Issue, 使用第一步:获取Github Token 使…...

嵌入式开发:单片机嵌入式Linux学习路径
SOC(System on a Chip)的本质区别在于架构和功能。低端SOC如基于Cortex-M架构的芯片,如STM32和NXP LPC1xxx系列,不具备MMU(Memory Management Unit),适用于轻量级实时操作系统如uCOS和FreeRTOS。…...
Libvirt的virsh工具常用命令
在使用Libvirt的virsh工具时,以下是常见的一些命令: 连接到Hypervisor: virsh -c <URI>:连接到指定的Hypervisor,例如 virsh -c qemu:///system 连接到本地的QEMU/KVM Hypervisor。 虚拟机管理: list…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...

UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

九天毕昇深度学习平台 | 如何安装库?
pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子: 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...

云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...
Leetcode33( 搜索旋转排序数组)
题目表述 整数数组 nums 按升序排列,数组中的值 互不相同 。 在传递给函数之前,nums 在预先未知的某个下标 k(0 < k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...