超维空间S2无人机使用说明书——51、基础版——使用yolov8进行目标跟踪

news2025/1/23 17:53:38

引言:为了提高yolo识别的质量,提高了yolo的版本,改用yolov8进行物体识别,同时系统兼容了低版本的yolo,包括基于C++的yolov3和yolov4,以及yolov7。

简介,为了提高识别速度,系统采用了GPU进行加速,在使用7W功率的情况,大概可以稳定在20FPS,满功率情况下可以适当提高。

硬件:D435摄像头,Jetson orin nano 8G

环境:ubuntu20.04,ros-noetic, yolov8

注:目标跟随是在木根识别的基础上进行,因此本小节和yolov8识别小节类似,只是在此基础上添加了跟随控制程序

步骤一: 启动摄像头,获取摄像头发布的图像话题

roslaunch realsense2_camera rs_camera.launch  

请添加图片描述

没有出现红色报错,出现如下界面,表明摄像头启动成功

请添加图片描述

步骤二:启动yolov8识别节点

roslaunch yolov8_ros yolo_v8.launch 

launch文件如下,参数use_cpu设置为false,因为实际使用GPU加速,不是CPU跑,另外参数pub_topic是yolov8识别到目标后发布出来的物体在镜头中的位置,程序作了修改,直接给出目标物的中心位置,其中参数image_topic是订阅的节点话题,一定要与摄像头发布的实际话题名称对应上。

<?xml version="1.0" encoding="utf-8"?>
<launch>

  <!-- Load Parameter -->
  
  <param name="use_cpu"           value="false" />

  <!-- Start yolov8 and ros wrapper -->
  <node pkg="yolov8_ros" type="yolo_v8.py" name="yolov8_ros" output="screen" >
    <param name="weight_path"       value="$(find yolov8_ros)/weights/yolov8n.pt"/>
    <param name="image_topic"       value="/camera/color/image_raw" />
    <param name="pub_topic"         value="/object_position" />
    <param name="camera_frame"      value="camera_color_frame"/>
    <param name="visualize"         value="false"/>
    <param name="conf"              value="0.3" />
  </node>
</launch>

请添加图片描述

出现如下界面表示yolov8启动成功

请添加图片描述

步骤三:打开rqt工具,查看识别效果

注:步骤三不是必须的,可以跳过直接进行步骤四

rqt_image_view 

请添加图片描述

等待出现如下界面后,选择yolov8/detection_image查看yolov8识别效果

请添加图片描述

步骤四:启动跟随控制程序

(1)、终端启动程序

roslaunch follow_yolov8 follow_yolov8.launch  

请添加图片描述

(2)、launch文件详解

<?xml version="1.0" encoding="utf-8"?>
<launch>
  <param name="target_object_id" value="chair" />
  <node pkg="follow_yolov8" type="follow_yolov8" name="follow_yolov8" output="screen" />
</launch>

launch文件中加载的参数target_object_id是指定跟随的目标名称,无人机在识别到这个目标以后,会通过全向的速度控制保持目标始终在无人机的视野中。launch文件中指定参数chair,因此在识别chair以后,可以看到终端会打印日志已经识别到指定的目标物

请添加图片描述

请添加图片描述

步骤五:控制部分代码

此处抛砖引玉,仅仅做最简单的速度控制,读者可以根据自己的理解,添加类似PID等控制跟随的算法,本文不再展开

#include <ros/ros.h>
#include <std_msgs/Bool.h>
#include <geometry_msgs/PoseStamped.h>
#include <geometry_msgs/TwistStamped.h>
#include <mavros_msgs/CommandBool.h>
#include <mavros_msgs/SetMode.h>
#include <mavros_msgs/State.h>
#include <mavros_msgs/PositionTarget.h>
#include <cmath>
#include <tf/transform_listener.h>
#include <nav_msgs/Odometry.h>
#include <mavros_msgs/CommandLong.h>   
#include <yolov8_ros_msgs/BoundingBoxes.h>
#include <string>

#define MAX_ERROR 50
#define VEL_SET   0.15
#define ALTITUDE  0.40

using namespace std;

yolov8_ros_msgs::BoundingBoxes object_pos;
nav_msgs::Odometry local_pos;
mavros_msgs::State current_state;  
mavros_msgs::PositionTarget setpoint_raw;
 
//检测到的物体坐标值
double position_detec_x = 0;
double position_detec_y = 0;
std::string Class = "no_object";

std::string target_object_id = "eight";

void state_cb(const mavros_msgs::State::ConstPtr& msg);

void local_pos_cb(const nav_msgs::Odometry::ConstPtr& msg);

void object_pos_cb(const yolov8_ros_msgs::BoundingBoxes::ConstPtr& msg);

int main(int argc, char **argv)
{
	//防止中文输出乱码
	setlocale(LC_ALL, "");

    //初始化节点,名称为visual_throw
    ros::init(argc, argv, "follow_yolov8");
    
    //创建句柄
    ros::NodeHandle nh;
	 
	//订阅无人机状态话题
	ros::Subscriber state_sub     = nh.subscribe<mavros_msgs::State>("mavros/state", 100, state_cb);
		
	//订阅无人机实时位置信息
    ros::Subscriber local_pos_sub = nh.subscribe<nav_msgs::Odometry>("/mavros/local_position/odom", 100, local_pos_cb);
    
     //订阅实时位置信息
    ros::Subscriber object_pos_sub = nh.subscribe<yolov8_ros_msgs::BoundingBoxes>("object_position", 100, object_pos_cb);
		
	//发布无人机位置控制话题
	ros::Publisher  local_pos_pub = nh.advertise<geometry_msgs::PoseStamped>("mavros/setpoint_position/local", 100);
		
	//发布无人机多维控制话题
    ros::Publisher  mavros_setpoint_pos_pub = nh.advertise<mavros_msgs::PositionTarget>("/mavros/setpoint_raw/local", 100);   
		               
	//请求无人机解锁服务        
	ros::ServiceClient arming_client = nh.serviceClient<mavros_msgs::CommandBool>("mavros/cmd/arming");
		
	//请求无人机设置飞行模式,本代码请求进入offboard
	ros::ServiceClient set_mode_client = nh.serviceClient<mavros_msgs::SetMode>("mavros/set_mode");

	//请求控制舵机客户端
    ros::ServiceClient ctrl_pwm_client = nh.serviceClient<mavros_msgs::CommandLong>("mavros/cmd/command");

    //循环频率
    ros::Rate rate(20.0); 
    
    

    ros::param::get("target_object_id", target_object_id);
   
    //等待连接到PX4无人机
    while(ros::ok() && current_state.connected)
    {
        ros::spinOnce();
        rate.sleep();
    }

    setpoint_raw.type_mask = 1 + 2 + /*4 + 8 + 16 + 32*/ + 64 + 128 + 256 + 512 + 1024 + 2048;
	setpoint_raw.coordinate_frame = 8;
	setpoint_raw.position.x = 0;
	setpoint_raw.position.y = 0;
	setpoint_raw.position.z = 0 + ALTITUDE;
	mavros_setpoint_pos_pub.publish(setpoint_raw);
 
    for(int i = 100; ros::ok() && i > 0; --i)
    {
		mavros_setpoint_pos_pub.publish(setpoint_raw);
        ros::spinOnce();
        rate.sleep();
    }
    
    //请求offboard模式变量
    mavros_msgs::SetMode offb_set_mode;
    offb_set_mode.request.custom_mode = "OFFBOARD";
 
    //请求解锁变量
    mavros_msgs::CommandBool arm_cmd;
    arm_cmd.request.value = true;

    ros::Time last_request = ros::Time::now();
    //请求进入offboard模式并且解锁无人机,15秒后退出,防止重复请求       
   
    while(ros::ok())
    {
    	//请求进入OFFBOARD模式
        if( current_state.mode != "OFFBOARD" && (ros::Time::now() - last_request > ros::Duration(5.0)))
        {
            if( set_mode_client.call(offb_set_mode) && offb_set_mode.response.mode_sent)
            {
                ROS_INFO("Offboard enabled");
            }
           	last_request = ros::Time::now();
       	}
        else 
		{
			//请求解锁
			if( !current_state.armed && (ros::Time::now() - last_request > ros::Duration(5.0)))
			{
		        if( arming_client.call(arm_cmd) && arm_cmd.response.success)
		       	{
		            ROS_INFO("Vehicle armed");
		        }
		        	last_request = ros::Time::now();
			}
		}
	    if(ros::Time::now() - last_request > ros::Duration(5.0))
	    	break;
		mavros_setpoint_pos_pub.publish(setpoint_raw);
        ros::spinOnce();
        rate.sleep();
    } 
	
    while(ros::ok())
    {      
    
   		//此处表示识别到launch文件中指定的目标
		//if(object_pos.bounding_boxes[0].Class == "chair")
		if(Class == target_object_id)
        {
        	ROS_INFO("识别到目标,采用速度控制进行跟随");
			//摄像头向下安装,因此摄像头的Z对应无人机的X前后方向,Y对应Y左右方向
			//无人机左右移动速度控制
			if(position_detec_x-320 >= MAX_ERROR)
			{
				setpoint_raw.velocity.y =  -VEL_SET;
			}					
			else if(position_detec_x-320 <= -MAX_ERROR)
			{
				setpoint_raw.velocity.y =  VEL_SET;
			}	
			else
			{
				setpoint_raw.velocity.y =  0;
			}
			//无人机前后移动速度控制
			if(position_detec_y-240 >= MAX_ERROR)
			{
				setpoint_raw.velocity.x =  -VEL_SET;
			}					
			else if(position_detec_y-240 <= -MAX_ERROR)
			{
				setpoint_raw.velocity.x =  VEL_SET;
			}	
			else
			{
				setpoint_raw.velocity.x =  0;
			}
				
		}
		else
		{
			setpoint_raw.velocity.x =  0;
			setpoint_raw.velocity.y =  0;
		}
		setpoint_raw.type_mask = 1 + 2 +/* 4 + 8 + 16 + 32*/ + 64 + 128 + 256 + 512 /*+ 1024 + 2048*/;
		setpoint_raw.coordinate_frame = 8;
		setpoint_raw.velocity.x = 0;
		setpoint_raw.position.z = 0 + ALTITUDE;
		setpoint_raw.yaw        = 0;
	    mavros_setpoint_pos_pub.publish(setpoint_raw);
		ros::spinOnce();
		rate.sleep();
	}
    return 0;
}

void state_cb(const mavros_msgs::State::ConstPtr& msg)
{
    current_state = *msg;
}

void local_pos_cb(const nav_msgs::Odometry::ConstPtr& msg)
{
    local_pos = *msg;
}

void object_pos_cb(const yolov8_ros_msgs::BoundingBoxes::ConstPtr& msg)
{
	object_pos = *msg;
    position_detec_x = object_pos.bounding_boxes[0].xmin;
    position_detec_y = object_pos.bounding_boxes[0].ymin;
    Class =            object_pos.bounding_boxes[0].Class;
}

从图中可以看出,在10W功率的情况下,大概在30帧的效果,识别准确度比较高

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

解决VNC连接Ubuntu服务器打开终端出现闪退情况

服务器环境 阿里云ECS服务器 操作系统&#xff1a;Ubuntu 20.0.4 如何使用VNC连接阿里云ECS服务器 1.阿里云官方指导&#xff1a;通过VNC搭建Ubuntu 18.04和20.04图形界面 2.新手入门ECS——ubuntu 20.04安装图形化界面和本地VNC连接 问题描述 使用VNC连接上新申请阿里云服…

Python 实现 PDF 到 Word 文档的高效转换(DOC、DOCX)

PDF&#xff08;Portable Document Format&#xff09;已成为一种广泛使用的电子文档格式。PDF的主要优势是跨平台&#xff0c;可以在不同设备上呈现一致的外观。然而&#xff0c;当我们需要对文件内容进行编辑或修改&#xff0c;直接编辑PDF文件会非常困难&#xff0c;而且效果…

分布式技术之分布式数据存储系统

文章目录 什么是分布式数据存储系统&#xff1f;分布式数据存储系统三要素顾客&#xff1a;生产和消费数据导购&#xff1a;确定数据位置货架&#xff1a;存储数据 CAP 理论指出&#xff0c;在分布式系统中&#xff0c;不能同时满足一致性、可用性和分区容错性&#xff0c;指导…

408计算机组成原理错题知识点拾遗

个人向错题相关部分整理&#xff0c;涵盖真题、模拟、课后习题等。 408相关&#xff1a; 408数据结构错题知识点拾遗 408数据结构常考算法基础训练等待完善 408计算机组成原理错题知识点拾遗408操作系统错题知识点拾遗等待完善408计算机网络错题知识点拾遗 408计算机网络各层协…

MYSQL的UPDATE时锁表机制

&#xff08;笔记&#xff0c;只为获取流量券&#xff09; MySQL中&#xff0c;UPDATE 操作涉及到行级锁和表级锁的概念&#xff0c;具体取决于事务隔离级别和被更新的条件, 无索引的情况下&#xff1a; 当表没有索引的情况下&#xff0c;UPDATE 操作通常会涉及到表级锁。这是…

使用Halcon 采集图像并进行简单处理rgbl_to_gray/threshold/connection/fill_up

使用Halcon 采集图像并进行简单处理 文章目录 使用Halcon 采集图像并进行简单处理 下面介绍一个简单的采集图像的例子。在Halcon中利用图像采集接口&#xff0c;使用USB3.0相机实时拍摄图像。采集到图像后对图像进行简单的阀值分割处理&#xff0c;将有物体的区域标记出来。 &a…

------- 计算机网络基础

1.1概述 是什么? 答出独立计算机通信线路连接实现资源共享 计算机网络组成 从组成部分看: 硬件软件协议 从工作方式看: 边缘部分和核心部分 从功能组成看: 通信子网和资源子网 计算机网络性能指标 速率是指数据传输的物理速度&#xff0c;吞吐量是指实际的数据传输…

iPhone 13 Pro 更换『移植电芯』和『超容电池』体验

文章目录 考虑换电池Ⅰ 方案一Ⅱ 方案二 总结危险 Note系列地址 简 述: 首发买的iPhone 13P &#xff08;2021.09&#xff09;&#xff0c;随性使用一年出头&#xff0c;容量就暴跌 85%&#xff0c;对比朋友一起买的同款&#xff0c;还是95%。这已经基本得一天两充 >_<&a…

【机组期末速成】指令系统|机器指令概述|操作数类型与操作类型|寻址方式|指令格式

&#x1f3a5; 个人主页&#xff1a;深鱼~&#x1f525;收录专栏&#xff1a;计算机组成原理&#x1f304;欢迎 &#x1f44d;点赞✍评论⭐收藏 目录 前言&#xff1a; 一、本章考点总览 二、考点分析 1、以下有关指令系统的说法中错误的是&#xff08; &#xff09;。 2…

使用LOTR合并检索提高RAG性能

RAG结合了两个关键元素:检索和生成。它首先使用语义搜索等高级技术来浏览大量数据&#xff0c;包括文本、图像、音频和视频。RAG的本质在于它能够检索相关信息&#xff0c;然后作为下一阶段的基础。生成组件利用大型语言模型的能力&#xff0c;解释这些数据块&#xff0c;制作连…

操作系统大题

目录 作业一&#xff1a; 前驱图 作业二&#xff1a;信号量 作业三&#xff1a;同步算法 1‘’生产者消费者问题 解1&#xff1a; 解2&#xff1a;利用AND信号量解决生产者-消费者问题 解3. 利用管程解决生产者-消费者问题 2‘’ 哲学家进餐问题&#xff08;The Dinning…

Conda:Python环境管理的瑞士军刀

在数据科学和机器学习的世界中&#xff0c;管理各种库和依赖关系的重要性不容忽视。Conda 就是为此而生的强大工具。本文将深入探讨 Conda 的简介、功能以及使用示例&#xff0c;帮助你更好地理解和使用这个工具。 Conda 简介 Conda 是一个开源的包管理系统和环境管理系统&am…

MPLS动态协议LDP配置示例

一、预习&#xff1a; MPLS是一种根据报文中携带的标签来转发数据的技术&#xff0c;两台LSR必须在它们之间转的数据 的标签使用上“达成共识”。LSR之间可以运行LDP来告知其他LSR本设备上的标签绑定信息&#xff0c;从而实现标签报文的正确转发。 LSR&#xff1a;Label Switch…

跨进程通信 macOS XPC 创建实例

一&#xff1a;简介 XPC 是 macOS 里苹果官方比较推荐和安全的的进程间通信机制。 集成流程简单&#xff0c;但是比较绕。 主要需要集成 XPC Server 这个模块&#xff0c;这个模块最终会被 apple 的根进程 launchd 管理和以独立进程的方法唤起和关闭&#xff0c; 我们主app 进…

网络运行状况监控工具

网络运行状况是网络在其操作和环境约束范围内按预期运行的能力&#xff0c;但是&#xff0c;随着云和人工智能等技术的出现&#xff0c;网络变得越来越复杂&#xff0c;维护其 IT 基础设施是一项越来越繁琐的任务。为了确保网络可靠性&#xff0c;组织需要了解每个端点的运行状…

【c/c++】指针例图基础详解

文章目录 指针变量内存指针详解例1例2练习&答案解析 指针变量内存 int main(){// 各类型变量占字节数printf("char: %d\n",sizeof(char)); // 1printf("short: %d\n",sizeof(short)); // 2printf("int: %d\n",sizeof(int)); // 4pri…

详解C语言单链表接口函数

准备工作 创建一个头文件&#xff08;SList.h&#xff09;,两个源文件&#xff08;SList.c和test.c&#xff09; SList.h:用于包含库函数的头文件&#xff0c;链表节点结构体声明&#xff0c;接口函数的声明等【另外两个源文件要包含SList.h这个头文件&#xff0c;才能使用其…

【项目管理】CMMI-项目总体计划模版

目录 1、总体目录结构 2、重点章节概要示例 2.1 第四章 项目管理 2.2 第六章 实施与交付计划 2.3 第七章 运维计划 1、总体目录结构 2、重点章节概要示例 2.1 第四章 项目管理 2.2 第六章 实施与交付计划 2.3 第七章运维计划

【2023年终总结】纵是一路仆仆风尘,也莫忘了仰头

文章目录 1. 写在前面2. 关于生活3. 关于工作4. 关于以后 【作者主页】&#xff1a;吴秋霖 【作者介绍】&#xff1a;Python领域优质创作者、阿里云博客专家、华为云享专家。长期致力于Python与爬虫领域研究与开发工作&#xff01; 【作者推荐】&#xff1a;对JS逆向感兴趣的朋…

vue3+ts+vite自定义组件上传npm流程

1. 创建项目 npm create vite 这里踩坑点&#xff1a; 运行vite生成的vue项目时报错“SyntaxError: Unexpected token ?? at “ 是因为node版本过低 电脑为windows11系统&#xff0c;我当时使用的版本node版本是14.21.3&#xff0c;如下图&#xff0c;后边安装了nvm版本…