当前位置: 首页 > 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…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者&#xff1a;来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗&#xff1f;了解下一期 Elasticsearch Engineer 培训的时间吧&#xff01; Elasticsearch 拥有众多新功能&#xff0c;助你为自己…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

反射获取方法和属性

Java反射获取方法 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时访问和操作类的内部属性和方法。通过反射&#xff0c;可以动态地创建对象、调用方法、改变属性值&#xff0c;这在很多Java框架中如Spring和Hiberna…...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角&#xff0c;以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向&#xff0c;距离坐标原点x个像素;第二个是y坐标&#xff0c;表示当前位置为垂直方向&#xff0c;距离坐标原点y个像素。 坐标体系-像素 …...

【HTTP三个基础问题】

面试官您好&#xff01;HTTP是超文本传输协议&#xff0c;是互联网上客户端和服务器之间传输超文本数据&#xff08;比如文字、图片、音频、视频等&#xff09;的核心协议&#xff0c;当前互联网应用最广泛的版本是HTTP1.1&#xff0c;它基于经典的C/S模型&#xff0c;也就是客…...

并发编程 - go版

1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程&#xff0c;系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成

一个面向 Java 开发者的 Sring-Ai 示例工程项目&#xff0c;该项目是一个 Spring AI 快速入门的样例工程项目&#xff0c;旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计&#xff0c;每个模块都专注于特定的功能领域&#xff0c;便于学习和…...

阿里云Ubuntu 22.04 64位搭建Flask流程(亲测)

cd /home 进入home盘 安装虚拟环境&#xff1a; 1、安装virtualenv pip install virtualenv 2.创建新的虚拟环境&#xff1a; virtualenv myenv 3、激活虚拟环境&#xff08;激活环境可以在当前环境下安装包&#xff09; source myenv/bin/activate 此时&#xff0c;终端…...

6️⃣Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙

Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙 一、前言:离区块链还有多远? 区块链听起来可能遥不可及,似乎是只有密码学专家和资深工程师才能涉足的领域。但事实上,构建一个区块链的核心并不复杂,尤其当你已经掌握了一门系统编程语言,比如 Go。 要真正理解区…...