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

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 检测需要以来一些库&#xff0c;分别是: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 因为本人对硬件了解不是很多&#xff0c;所以该篇参考自官方文档。 以下内容源自《【商业】》 仅供学习交流使用 版权 禁止其他平台发布…...

实现任意进制(2—32)转换

2020/01/01 实现原理参考代码测试样例其他补充后记交流 实现原理 本程序借助10进制数为中介数据&#xff0c;实现任意进制数之间的相互转换&#xff08;2-36进制范围&#xff09; 需要注意的是&#xff0c;数值范围不可超出 long long int 所表示的范围&#xff0c;即所输入需…...

Spring Boot 集成 Redis 三种模式实践汇总

背景 项目的某个模块集成了 SpringBoot Redis 包&#xff0c;客户端使用 Lettuce&#xff0c;Redis 测试环境单机模式。但是现场反馈的 Redis 环境是集群&#xff0c;如果简单的修改 spring.redis 配置为集群的配置信息&#xff0c;程序能否能无缝衔接呢&#xff1f; 本文记录…...

MySQL DQL语法

MySQL DQL语法 DQL语法简介 DQL&#xff08;Data Query Language&#xff09;语句是一种用于从数据库中检索数据的语言。它主要用于数据查询和数据分析&#xff0c;而不是对数据库中的数据进行更新、插入或删除。DQL语句通常用于获取特定条件下的数据&#xff0c;进行聚合计算…...

算法之线性表1.1.1(7)带头结点链表的反向输出

设L为带头结点的单链表&#xff0c;编写算法实现从尾到头反向输出每个节点的值。 算法思想&#xff1a; 方法一&#xff1a;将链表压栈再输出&#xff0c;时间复杂度为O(n),空间复杂度为O(n) 方法二&#xff1a;用头插法重新建立单链表在输出&#xff0c;时间复杂度为O(n),空…...

设计模式三:抽象工厂模式(Abstract Factory Pattern)

抽象工厂模式&#xff08;Abstract Factory Pattern&#xff09;是一种创建型设计模式&#xff0c;它提供了一种方式来创建一系列相关或相互依赖的对象&#xff0c;而无需指定具体实现类。 在软件开发中&#xff0c;有时候需要根据不同的条件或环境来创建一组相关的对象。抽象工…...

Linux用户权限问题详解

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

flask中的session介绍

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

记录联想拯救者R720重装系统

文章目录 bios里找不到U盘启动项2023.7.23重装系统后数据记录C盘内存修改默认AppData的路径&#xff08;亲测&#xff0c;没用&#xff09; bios里找不到U盘启动项 制作好启动盘后&#xff0c;开机按F2进入bios后&#xff0c;找不到U盘启动项&#xff0c;如下图所示&#xff1…...

Spring Alibaba Sentinel实现集群限流demo

1.背景 1.什么是单机限流&#xff1f; 小伙伴们或许遇到过下图这样的限流配置 又或者是这样的Nacos动态配置限流规则&#xff1a; 以上这些是什么限流&#xff1f;没错&#xff0c;就是单机限流&#xff0c;那么单机限流有什么弊端呢&#xff1f; 假设我们集群部署3台机器&a…...

102、SOA、分布式、微服务之间有什么关系和区别?

SOA、分布式、微服务之间有什么关系和区别? 分布式架构是指将单体架构中的各个部分拆分&#xff0c;然后部署到不同的机器或进程中去&#xff0c;SOA和微服务基本上都是分布式架构师SOA是一种面向服务的架构&#xff0c;系统的所有服务都注册在总线上&#xff0c;当调用服务时…...

Ubuntu 20.04下的录屏与视频剪辑软件

ubuntu20.04下的录屏与视频剪辑 一、录屏软件SimpleScreenRecorder安装与使用 1、安装 2、设置录制窗口参数 3、开始录制 二、视频剪辑软件kdenlive的安装 1、安装 2、启动 一、录屏软件SimpleScreenRecorder安装与使用 1、安装 &#xff08;1&#xff09;直接在终端输入以下命…...

面试题 -- iOS数据存储

文章目录 一、如果后期需要增加数据库中的字段怎么实现&#xff0c;如果不使用CoreData呢&#xff1f;二、SQLite 数据存储是怎么用&#xff1f;三、简单描述下客户端的缓存机制&#xff1f;四、实现过多线程的Core Data 么&#xff1f;NSPersistentStoreCoordinator&#xff0…...

spring复习:(51)environment、systemProperties、systemEnvironment三个bean是在哪里被添加到容器的?

一、主类&#xff1a; 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.携带固定参数&#xff1a; 2.携带不固定参数&#xff1a; <el-row> <el-col :span"24"> <el-upload :multiple"false" :show-file-list"false" :on-success"f_h…...

scrapy分布式+指纹去重原理

1&#xff0c;指纹去重原理存在于 scrapy.util.requests 里面 需要安装的包 pip install scrapy-redis-cluster # 安装模块 pip install scrapy-redis-cluster0.4 # 安装模块时指定版本 pip install --upgrade scrapy-redis-cluster # 升级模块版本 2&#xff0c;setting配置 …...

FileHub使用教程:Github Token获取步骤,使用快人一步

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

嵌入式开发:单片机嵌入式Linux学习路径

SOC&#xff08;System on a Chip&#xff09;的本质区别在于架构和功能。低端SOC如基于Cortex-M架构的芯片&#xff0c;如STM32和NXP LPC1xxx系列&#xff0c;不具备MMU&#xff08;Memory Management Unit&#xff09;&#xff0c;适用于轻量级实时操作系统如uCOS和FreeRTOS。…...

Libvirt的virsh工具常用命令

在使用Libvirt的virsh工具时&#xff0c;以下是常见的一些命令&#xff1a; 连接到Hypervisor&#xff1a; virsh -c <URI>&#xff1a;连接到指定的Hypervisor&#xff0c;例如 virsh -c qemu:///system 连接到本地的QEMU/KVM Hypervisor。 虚拟机管理&#xff1a; list…...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

day52 ResNet18 CBAM

在深度学习的旅程中&#xff0c;我们不断探索如何提升模型的性能。今天&#xff0c;我将分享我在 ResNet18 模型中插入 CBAM&#xff08;Convolutional Block Attention Module&#xff09;模块&#xff0c;并采用分阶段微调策略的实践过程。通过这个过程&#xff0c;我不仅提升…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

UE5 学习系列(三)创建和移动物体

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

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包&#xff1a; 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 举个例子&#xff1a; 报错 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 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息&#xff0c;对客户进行统一管理&#xff0c;可以把所有客户信息录入系统&#xff0c;进行维护和统计功能。可通过文件的方式保存相关录入数据&#xff0c;对…...

云原生安全实战:API网关Kong的鉴权与限流详解

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关&#xff08;API Gateway&#xff09; API网关是微服务架构中的核心组件&#xff0c;负责统一管理所有API的流量入口。它像一座…...

Leetcode33( 搜索旋转排序数组)

题目表述 整数数组 nums 按升序排列&#xff0c;数组中的值 互不相同 。 在传递给函数之前&#xff0c;nums 在预先未知的某个下标 k&#xff08;0 < k < nums.length&#xff09;上进行了 旋转&#xff0c;使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...