1. 为什么要在PX4仿真中集成YOLO在无人机自主飞行应用中实时目标检测是避障、跟踪等任务的基础能力。传统激光雷达方案成本高昂而基于摄像头的视觉方案更具性价比。我在实际项目中发现YOLO算法凭借其出色的实时性能在1080Ti上可达45FPS和不错的准确率特别适合无人机这种资源受限的平台。PX4作为目前最流行的开源飞控系统其Gazebo仿真环境可以完美复现真实飞行场景。但默认配置只包含基础传感器需要手动集成视觉算法。这里有个坑要注意仿真摄像头的图像话题名称在不同机型上可能不同iris机型默认是/iris/usb_cam/image_raw而typhoon_h480则使用/rgbd_camera/image_raw。2. 搭建带摄像头的仿真环境2.1 修改无人机模型文件首先要在无人机模型中添加摄像头。以iris机型为例找到PX4-Autopilot/Tools/simulation/gazebo-classic/sitl_gazebo-classic/models/iris/iris.sdf文件添加如下代码块include urimodel://fpv_cam/uri pose0.1 0 0 0 1.57 0/pose /include joint namefpv_cam_joint typerevolute childfpv_cam::link/child parentiris::base_link/parent axis xyz0 0 1/xyz limit upper0/upper lower0/lower /limit /axis /joint这里pose参数中的1.57弧度约90度让摄像头垂直向下适合地面目标检测。如果要做前向避障需要改为0弧度朝前。2.2 创建动态测试场景在~/catkin_ws/src下新建dynamic_objects包添加一个移动车辆的模型cd ~/catkin_ws/src catkin_create_pkg dynamic_objects创建models/moving_car/model.sdf文件关键部分如下plugin namemoving_plugin filenamelibgazebo_ros_planar_move.so commandTopiccmd_vel/commandTopic odometryTopicodom/odometryTopic publishOdometrytrue/publishOdometry publishOdometryTftrue/publishOdometryTf robotBaseFramebase_link/robotBaseFrame odometryFrameodom/odometryFrame xyVelocityMax2/xyVelocityMax /plugin这个插件让车辆以最大2m/s速度随机移动模拟真实动态场景。3. YOLOv5环境部署实战3.1 安装PyTorch和Ultralytics推荐使用YOLOv5而非原文的darknet版本因为PyTorch生态更完善conda create -n yolov5 python3.8 conda activate yolov5 pip install torch1.12.1cu113 torchvision0.13.1cu113 --extra-index-url https://download.pytorch.org/whl/cu113 pip install ultralytics opencv-python实测在RTX 3060上YOLOv5s模型能达到140FPS的推理速度完全满足实时性要求。3.2 ROS节点开发创建detection_node.py处理图像话题#!/usr/bin/env python3 import rospy from sensor_msgs.msg import Image from cv_bridge import CvBridge from ultralytics import YOLO class YOLODetector: def __init__(self): self.model YOLO(yolov5s.pt) self.bridge CvBridge() self.pub rospy.Publisher(/detection_result, Image, queue_size10) rospy.Subscriber(/iris/usb_cam/image_raw, Image, self.callback) def callback(self, msg): cv_image self.bridge.imgmsg_to_cv2(msg, bgr8) results self.model(cv_image) annotated results[0].plot() self.pub.publish(self.bridge.cv2_to_imgmsg(annotated, bgr8)) if __name__ __main__: rospy.init_node(yolo_detector) YOLODetector() rospy.spin()这个节点会订阅摄像头图像运行YOLO推理后发布带检测框的结果图像。4. 全系统联调与优化4.1 启动流程优化编写整合启动脚本start_simulation.sh#!/bin/bash # 启动Gazebo仿真 gnome-terminal --tab --titlePX4 -- bash -c roslaunch px4 mavros_posix_sitl.launch; exec bash sleep 15 # 启动YOLO检测 gnome-terminal --tab --titleYOLO -- bash -c rosrun my_package detection_node.py; exec bash # 启动QGC地面站 gnome-terminal --tab --titleQGC -- bash -c ../QGroundControl.AppImage; exec bash4.2 性能调优技巧在~/.bashrc中添加这些环境变量提升Gazebo性能export SVGA_VGPU100 # 禁用GPU加速避免黑屏 export GAZEBO_RESOURCE_PATH/usr/share/gazebo-11 export OGRE_RESOURCE_PATH/usr/lib/x86_64-linux-gnu/OGRE-1.9.0对于低配电脑可以降低仿真画质physics typeode max_step_size0.01/max_step_size !-- 增大步长减少计算量 -- real_time_update_rate250/real_time_update_rate !-- 降低更新频率 -- /physics5. 动态目标跟踪实战5.1 检测结果坐标转换通过cv2.projectPoints将2D检测框转换为3D坐标def pixel_to_distance(u, v, depth_image): # 假设已知相机内参 fx 554.254691 # 焦距x fy 554.254691 # 焦距y cx 320.5 # 光心x cy 240.5 # 光心y z depth_image[v, u] x (u - cx) * z / fx y (v - cy) * z / fy return (x, y, z)5.2 简单跟踪算法实现基于检测框中心点实现PID跟踪class SimpleTracker: def __init__(self): self.last_x 0 self.integral 0 def update(self, current_x): error current_x - 320 # 假设图像中心x320 self.integral error derivative error - self.last_x # PID参数需要实际调试 Kp 0.8 Ki 0.001 Kd 0.3 output Kp*error Ki*self.integral Kd*derivative self.last_x current_x return output这个输出值可以直接作为PX4的MAV_CMD_DO_REPOSITION命令参数。