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

引言:为了提高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帧的效果,识别准确度比较高

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

添加 Android App Links

添加 Android App Links功能 介绍一个简单的效果Android配置Add Url intent filtersAdd logic to handle the intentAssociate website 搭建网页支持AppLinks 介绍 Android App Links 是指将用户直接转到 Android 应用内特定内容的 HTTP 网址。Android App Links 可为您的应用带…

大数据学习(30)-Spark Shuffle

&&大数据学习&& &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 承认自己的无知&#xff0c;乃是开启智慧的大门 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4dd;支持一下博主哦&#x1f91…

re:Invent 2023技术上新|Amazon DynamoDB与OpenSearch Service的Zero-ETL集成

Amazon DynamoDB 与 Amazon OpenSearch Service 的 Zero-ETL 集成已正式上线&#xff0c;该服务允许您通过自动复制和转换您的 DynamoDB 数据来搜索数据&#xff0c;而无需自定义代码或基础设施。这种 Zero-ETL 集成减少了运营负担和成本&#xff0c;使您能够专注于应用程序。这…

用通俗易懂的方式讲解大模型:基于 Langchain 和 ChatChat 部署本地知识库问答系统

之前写了一篇文章介绍基于 LangChain 和 ChatGLM 打造自有知识库问答系统&#xff0c;最近该项目更新了0.2新版本&#xff0c;这个版本与之前的版本差别很大&#xff0c;底层的架构发生了很大的变化。 该项目最早是基于 ChatGLM 这个 LLM&#xff08;大语言模型&#xff09;来…

【SAP-FICO】--总账标识配置路径OBXR

FICO业务需求&#xff1a; F-02&#xff0c;财务会计凭证填写09客户A时&#xff0c;带出的总账标识为可编辑。 需求截图&#xff1a; 第一步&#xff1a;了解需求 首先&#xff0c;我们要明白&#xff0c;财务凭证生成&#xff0c;是分多种类型&#xff08;不同类型的凭证&a…

HarmonyOS自学-Day4(TodoList案例)

目录 文章声明⭐⭐⭐让我们开始今天的学习吧&#xff01;TodoList小案例 文章声明⭐⭐⭐ 该文章为我&#xff08;有编程语言基础&#xff0c;非编程小白&#xff09;的 HarmonyOS自学笔记&#xff0c;此类文章笔记我会默认大家都学过前端相关的知识知识来源为 HarmonyOS官方文…

ES6+ 面试常问题

一、let const var 的区别 1. var&#xff1a; 没有块级作用域的概念&#xff0c;有函数作用域和全局作用域的概念全局作用域性下创建变量会被挂在到 windows 上存在变量提升同一作用域下&#xff0c;可以重复赋值创建未初始化&#xff0c;值为 undefined 2. let&#xff1a…

相机删除视频恢复后损坏打不开修复方法

同事对热恋5年的女朋友精心准备了一场浪漫求婚仪式&#xff0c;让朋友帮忙用单反相机拍摄记录这一美好时刻。不巧的的是朋友清理相机空间时&#xff0c;不小心把这一视频删除了&#xff0c;找人帮忙把视频恢复了&#xff0c;却无奈发现恢复出来的视频播放不了&#xff0c;真是好…

【第4期】Springboot集成阿里云对象存储OSS+Vue+Iview文件上传组件

本期简介 文件上传是非常常见的功能&#xff0c;本期要实现的功能是将文件存储到阿里云分布式对象存储OSS中&#xff0c;这样做的好处是随便哪里都可以方便的展示出该图片&#xff0c;并且图片以链接形式在客户端浏览器渲染&#xff0c;流量不会经过后台&#xff0c;降低后台压…

【23.12.29期--Spring篇】Spring的 IOC 介绍

介绍一下Spring的IOC ✔️引言✔️ lOC的优点✔️Spring的IOC✔️ 拓展知识仓✔️IOC是如何实现的&#xff1f; ✔️引言 所谓的IOC (inversion of control) &#xff0c;就是控制反转的意思。何为控制反转? 在传统的程序设计中&#xff0c;应用程序代码通常控制着对象的创建和…

Pycharm 切换interpreter---python的环境和第三方库问题

这篇回答两个问题&#xff1a; 1.为什么在 pycharm中打开新的project&#xff0c;切换interpreter 之后发现自己之前装的库消失了&#xff1f; 2.为什么 interpreter 切换到python3.8了&#xff0c; terminal 还是在 3.9&#xff1f;&#xff1f; 问题的关键&#xff1a;搞懂什…

STM32CubeMX学习(二) USB CDC 双向通信

STM32CubeMX学习&#xff08;二&#xff09; USB CDC 双向通信 简介CubeMX新建工程&#xff08;串口LED&#xff09;测试串口和LED串口接收测试USB CDC通信 简介 利用正点原子F407探索者开发板&#xff0c;测试基于USB CDC的双向数据通信。 CubeMX新建工程&#xff08;串口LE…

工业企业出口技术复杂度测算(2000-2014年)

工业企业出口技术复杂度的测算是对工业企业出口产品的技术含量和复杂度进行评估的过程。这种测算通常涉及分析出口产品的研发强度、生产过程的复杂性、所需的技术知识水平以及产品在全球市场上的竞争力。技术复杂度高的产品可能包括高端制造业产品&#xff0c;如先进电子设备、…

如何使用idea部署springboot项目全过程

博主介绍&#xff1a; ✌至今服务客户已经1000、专注于Java技术领域、项目定制、技术答疑、开发工具、毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精彩专栏 推荐订阅 &#x1f447;&#x1f3fb; 不然下次找不到 Java项目精品实…

单机+内部备份_全备案例

此场景为单机数据库节点内部备份&#xff0c;方便部署和操作&#xff0c;但备份REPO与数据库实例处于同一个物理主机&#xff0c;冗余度较低。 前期准备 配置ksql免密登录(必须) 在Kingbase数据库运行维护中&#xff0c;经常用到ksql工具登录数据库&#xff0c;本地免密登录…

Unity | 快速修复Animation missing错误

目录 一、背景 二、效果 三、解决办法 一、背景 最近在做2D 骨骼动画相关的Demo&#xff0c;我自己使用Unity引擎进行骨骼绑定并创建了anim后&#xff0c;一切正常&#xff0c;anim也能播放。但是昨天我修改Obj及子物体的名称&#xff08;由中文改为英文&#xff0c;如&…

数据分析师,就是做报表?错!!

企业作为数据载体&#xff0c;没有数据&#xff0c;大概率也不会再有企业存在 !! 数据分析师&#xff0c;正是这只小舟的船桨&#xff0c;掌舵所有人的命运。注意&#xff0c;是分析师&#xff0c;不是表哥&#xff0c;表姐... 那么作为数据分析师&#xff0c;应该有哪些硬技能…

Python入门学习篇(十二)——内置函数匿名函数

1 内置函数——数学函数 1.1 绝对值函数 1.1.1 语法 abs(参数) # 里面的参数既可以是整数,也可以是小数1.1.2 示例代码 m -1.99 n -9 print(f"{m}的绝对值为: {abs(m)}") print(f"{n}的绝对值为: {abs(n)}")1.1.3 运行截图 1.2 求商和余数 1.2.1 语…

[Angular] 笔记 16:模板驱动表单 - 选择框与选项

油管视频&#xff1a; Select & Option (Template Driven Forms) Select & Option 在 pokemon.ts 中新增 interface: export interface Pokemon {id: number;name: string;type: string;isCool: boolean;isStylish: boolean;acceptTerms: boolean; }// new interface…

算法基础之蒙德里安的梦想

蒙德里安的梦想 核心思想&#xff1a; 状态压缩dp 总方案 横放的方案 剩下的地方竖着放是固定的了 状态压缩 &#xff1a; 将每一列的图(横终点 横起点 竖) 用一个二进制数存下 向后凸的为1 反之为0 状态计算&#xff1a; 所有 i – 1 列 不冲突的 都加和 f[i , j] f[i - 1…