超维空间S2无人机使用说明书——52、初级版——使用PID算法进行基于yolo的目标跟踪

引言:在实际工程项目中,为了提高系统的响应速度和稳定性,往往需要采用一定的控制算法进行目标跟踪。这里抛砖引玉,仅采用简单的PID算法进行目标的跟随控制,目标的识别依然采用yolo。对系统要求更高的,可以对算法进行改进,也欢迎读者与我们联系,合作开发。

步骤一:打开摄像头

注意:为了获取目标物的三维位置信息,我们采用了D435深度摄像头,仅供参考,可根据需要自行选择即可

roslaunch realsense2_camera rs_camera.launch

请添加图片描述

查看话题,需要/camera/color/image_raw和/camera/depth/image_rect_raw

请添加图片描述

步骤二:打开yolo识别节点,具体yolo版本可以根据需要选择

 roslaunch darknet_ros darknet_ros.launch 

请添加图片描述

没有报错的情况下,会弹出识别效果图,如下:

请添加图片描述## 注:我这里训练的是自己打印的H型地标,具体可以根据需要选择合适的目标物

步骤三:打开三维坐标转换节点

该节点可以直接一话题的形式输出目标物的名称和真实的位置信息

roslaunch darknet_real_position darknet_real_position.launch

请添加图片描述

launch文件解析

此处的launch文件,以参数的方式指定了识别目标。比如landing,因此这个节点只会把指定的landing地标位置信息打印出来,其他的目标通通忽略

请添加图片描述

查看话题数据/object_position

请添加图片描述

请添加图片描述

从上述图片可以看出,系统非常准确的给出了目标物的名称和真实的位置信息,单位是米。需要指出的是,这里的位置是相对于D435摄像头的位置信息,X表示横向位置,Y表示纵向位置,Z表示实际的距离信息

步骤四:启动PID跟随节点。注意,可以先不要启动mavros,仅仅测试PID控制器发布出的速度是否正确。在确认了没问题后在启动mavros节点,无人机就可以进行正常的跟随运动了

roslaunch follow_pid follow_pid.launch 

请添加图片描述

launch文件解析

这里仅仅进行偏航角度和距离的控制,如果需要对高度方向控制。可以直接复制代码进行简单的修改即可。参数linear_x_p和linear_x_d是距离的PID控制,同理yaw_rate_p和yaw_rate_d是角度的控制。参数target_x_angle是期望保持的角度,通常设置为0即可。最后参数target_distance是期望保持的距离,单位是毫米

请添加图片描述

代码如下:

#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 <string>#define MAX_ERROR 0.20
#define VEL_SET   0.10
#define ALTITUDE  0.40using namespace std;float target_x_angle = 0;
float target_distance = 2000;
float linear_x_p = 0.5;
float linear_x_d = 0.33;
float yaw_rate_p = 4.0;
float yaw_rate_d = 15;geometry_msgs::PointStamped object_pos; 
nav_msgs::Odometry local_pos;
mavros_msgs::State current_state;  
mavros_msgs::PositionTarget setpoint_raw;
//检测到的物体坐标值
string current_frame_id   = "no_object";
double current_position_x = 0;
double current_position_y = 0;
double current_distance   = 0;//1、订阅无人机状态话题
ros::Subscriber state_sub;//2、订阅无人机实时位置信息
ros::Subscriber local_pos_sub;//3、订阅实时位置信息
ros::Subscriber object_pos_sub;//4、发布无人机多维控制话题
ros::Publisher  mavros_setpoint_pos_pub;//5、请求无人机解锁服务        
ros::ServiceClient arming_client;//6、请求无人机设置飞行模式,本代码请求进入offboard
ros::ServiceClient set_mode_client;void pid_control()
{static float last_error_x_angle = 0;static float last_error_distance = 0;				float x_angle;float distance;if(current_position_x == 0 && current_position_y == 0 && current_distance == 0){x_angle  = target_x_angle;distance = target_distance;}else{x_angle = current_position_x / current_distance;distance = current_distance;}float error_x_angle = x_angle - target_x_angle;float error_distance = distance - target_distance;if(error_x_angle > -0.01 && error_x_angle < 0.01)  {error_x_angle = 0;}if(error_distance > -80 && error_distance < 80) {error_distance = 0;}setpoint_raw.velocity.x = error_distance*linear_x_p/1000 + (error_distance - last_error_distance)*linear_x_d/1000;if(setpoint_raw.velocity.x < -0.3)  {setpoint_raw.velocity.x = -0.3;}else if(setpoint_raw.velocity.x > 0.3) {setpoint_raw.velocity.x = 0.3;	}setpoint_raw.yaw_rate = error_x_angle*yaw_rate_p + (error_x_angle - last_error_x_angle)*yaw_rate_d;if(setpoint_raw.yaw_rate < -0.5)  {setpoint_raw.yaw_rate = -0.5;}else if(setpoint_raw.yaw_rate > 0.5) {setpoint_raw.yaw_rate = 0.5;}mavros_setpoint_pos_pub.publish(setpoint_raw);last_error_x_angle  = error_x_angle;last_error_distance = error_distance;
}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 geometry_msgs::PointStamped::ConstPtr& msg)
{object_pos = *msg;current_position_x = object_pos.point.x*(-1000);current_position_y = object_pos.point.y*(-1000);//此处将距离由单位米改称毫米,方便提高控制精度current_distance   = object_pos.point.z*1000;current_frame_id   = object_pos.header.frame_id; pid_control();	 //ROS_INFO("current_position_x = %f",current_position_x);//ROS_INFO("current_position_y = %f",current_position_y);//ROS_INFO("current_distance = %f"  ,current_distance);
}int main(int argc, char *argv[])
{ros::init(argc, argv, "follow_pid");ros::NodeHandle nh;state_sub     = nh.subscribe<mavros_msgs::State>("mavros/state", 100, state_cb);local_pos_sub = nh.subscribe<nav_msgs::Odometry>("/mavros/local_position/odom", 100, local_pos_cb);object_pos_sub = nh.subscribe<geometry_msgs::PointStamped>("object_position", 100, object_pos_cb);mavros_setpoint_pos_pub = nh.advertise<mavros_msgs::PositionTarget>("/mavros/setpoint_raw/local", 100);   arming_client = nh.serviceClient<mavros_msgs::CommandBool>("mavros/cmd/arming");set_mode_client = nh.serviceClient<mavros_msgs::SetMode>("mavros/set_mode");ros::Rate rate(20.0); ros::param::get("linear_x_p",linear_x_p);ros::param::get("linear_x_d",linear_x_d);ros::param::get("yaw_rate_p",yaw_rate_p);ros::param::get("yaw_rate_d",yaw_rate_d);ros::param::get("target_x_angle", target_x_angle);ros::param::get("target_distance",target_distance);//等待连接到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 = 1;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(15.0))break;mavros_setpoint_pos_pub.publish(setpoint_raw);ros::spinOnce();rate.sleep();}*/   while(ros::ok()){//ROS_INFO("11111");ros::spinOnce();rate.sleep();}}

步骤五:在上述基础上再打开mavros,即可开始跟随控制。代码后续会在B站进行讲解。同时会提供相应的实机演示。链接会在后续给出。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

buuctf-Misc 题目解答分解100-102

100.[ACTF新生赛2020]明文攻击 下载下来&#xff0c;就是一个压缩包&#xff0c;里面有压缩文件&#xff0c;解压出来 压缩包里面flag 但是加密了 用notepad 打开图片&#xff0c;发现是有flag 线索的 用notepad 打开 在末尾发现 压缩包不完整&#xff0c;找到了PK 所在的16…

独立站的个性化定制:提升用户体验的关键

随着电子商务的竞争加剧&#xff0c;用户体验成为了企业赢得市场的关键因素之一。独立站作为企业品牌形象和产品展示的重要平台&#xff0c;其个性化定制的程度直接影响着用户体验。本文将探讨独立站的个性化定制如何提升用户体验&#xff0c;并通过代码示例说明实现个性化定制…

3D视觉-结构光测量-线结构光测量

概述 线结构光测量中&#xff0c;由激光器射出的激光光束透过柱面透镜扩束&#xff0c;再经过准直&#xff0c;产生一束片状光。这片光束像刀刃一样横切在待测物体表面&#xff0c;因此线结构光法又被成为光切法。线结构光测量常采用二维面阵 CCD 作为接受器件&#xff0c;因此…

将本地工作空间robot_ws上传到gitee仓库

git config --global user.name "geniusChinaHN" git config --global user.email "12705243geniuschinahnuser.noreply.gitee.com" cd ~/robot_ws #git init#创建原始仓库时候用 git add . git commit -m "上传文件内容描述" #git remote add r…

QT上位机开发(倒计时软件)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 倒计时软件是生活中经常遇到的一种场景。比如运动跑步&#xff0c;比如学校考试&#xff0c;比如论文答辩等等&#xff0c;只要有时间限制规定的地…

CentOS7安装部署Zookeeper

文章目录 CentOS7安装部署Zookeeper一、前言1.简介2.架构3.集群角色4.特点5.环境 二、正文1.部署服务器2.基础环境1&#xff09;主机名2&#xff09;Hosts文件3&#xff09;关闭防火墙4&#xff09;JDK 安装部署 3.单机部署1&#xff09;下载和解压2&#xff09;配置文件3&…

centos 7.9 升级系统默认的python2.7到python 2.7.18

centos 7.9 升级系统默认的python2.7到python 2.7.18 备份旧版本 mv /usr/bin/python /usr/bin/python_2.7.5 下载新版本 Download Python | Python.org Python Release Python 2.7.18 | Python.org wget https://www.python.org/ftp/python/2.7.18/Python-2.7.18.tgz cd /…

QT中的信号与槽的讲解

文章目录 信号及其特点槽及其特点代码演示标准信号与标准槽函数方式一方式二 自定义信号和槽connect()函数信号和槽函数存在函数重载的情况下Qt的信号槽机制注意事项 信号及其特点 信号&#xff1a;是一种特殊的函数&#xff0c;又称信号函数&#xff0c;俗称信号&#xff0c;…

Peter算法小课堂—浮点数危机

大家先想想下面这个代码运行结果&#xff1a; #include <bits/stdc.h> using namespace std; int main(){double x5.2;double y4.11.1;cout<<(x<y)<<endl;cout<<x-y<<endl;return 0; } 最终发现&#xff0c; &#xff1f;&#xff1f;&…

力扣:63. 不同路径 II(动态规划)

题目&#xff1a; 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish”&#xff09;。 现在考虑网格中有障碍物。那…

Android 理解Context

文章目录 Android 理解ContextContext是什么Activity能直接new吗&#xff1f; Context结构和源码一个程序有几个ContextContext的作用Context作用域获取ContextgetApplication()和getApplicationContext()区别Context引起的内存泄露错误的单例模式View持有Activity应用正确使用…

据报道,微软的下一代 Surface 笔记本电脑将是其首款真正的“人工智能 PC”

明年&#xff0c;微软计划推出 Surface Laptop 6和 Surface Pro 10&#xff0c;这两款设备将提供 Arm 和 Intel 两种处理器选项。不愿意透露姓名的不透露姓名人士透露&#xff0c;这些新设备将引入先进的人工智能功能&#xff0c;包括配备下一代神经处理单元 (NPU)。据悉&#…