PX4 SITL · ROS 2 Jazzy · Gazebo Harmonic

让无人机
跟住一个会移动的标签

下视相机识别小车顶部的 AprilTag,按图像时刻补偿机身姿态,再用受限 PD 外环引导 PX4 跟随。这里没有地图,也不把移动标签写进 EKF。

NO GPS NO LiDAR NO SLAM TRUTH ≠ CONTROL
DOWNWARD CAMERA / CONTROL VIEW TAG 0 VALID
无人机下视相机中,小车顶部 AprilTag 被绿色四边形和中心十字标出
绿色标注 = 通过 ID、hamming、质量与时效门控 640×480 · source 20 Hz
CONTROL SIGNAL RAIL只传递目标相对量
camera optical下视图像Image + CameraInfo
apriltag_ros标签位姿ID / hamming / margin
body → NED姿态补偿外参 + timestamped attitude
outer loop受限 PDrelative position + rate
PX4 inner loop姿态 / 推力SET_ATTITUDE_TARGET

核心边界

Tag 告诉飞机“目标在哪”,PX4 负责“把飞机稳住”

它是目标相对视觉伺服,不是全局导航。这个边界决定了为什么不需要 LiDAR,也决定了失去 Tag 后不能宣称水平定点。

Tag ≠ Map

已知物理尺寸的单目 AprilTag 在可见时能够给出带尺度的相机到标签位姿,足以完成开阔、低速、可视范围内的目标相对跟随。

IMU 与气压计仍然是 PX4 的常规飞行传感器。IMU 姿态还会在图像时刻参与刚体坐标变换,但这不是把视觉测量融合进 EKF。

定位来源

水平相对位置只来自 Tag

摄像头看不到标签时,系统没有新的水平位置观测。

飞行稳定

PX4 内环保持原样

外环只发送姿态与推力设定值,不重造姿态控制器。

目标形式

车顶朝上的单个 Tag

脚本轨迹和键盘控制共用同一个差速小车模型。

图形化运行

先让它飞起来,再决定要读多少公式

完整运行时保存在项目目录内。默认命令同时打开 Gazebo 3D 世界与紧凑的 AprilTag 标注相机窗口,结束后自动下降、disarm 和清理。

Ubuntu desktop terminal
$ git clone https://github.com/albert17github/\
  PX4-AprilTag-Follow-Demo.git
$ cd PX4-AprilTag-Follow-Demo
$ ./setup.sh
$ ./demo.sh

首次构建需要约 20 GiB 可用空间。虚拟机里的 Gazebo 窗口可能需要 30–90 秒出现。

Gazebo 图形界面中,X500 无人机正在跟随车顶带 AprilTag 的移动小车
GAZEBO 3D WORLD同一控制链的可见观察器

也可以自己开小车

运行 ./demo.sh --keyboard,保持终端焦点并按住运动键。前进方向始终以小车橙色车头为准;0.4 秒未续按会自动停车。

W / ↑沿车头前进
S / ↓沿车尾后退
A D / ← →原地左右转
Q结束并正常降落

姿态反解

摄像头会跟着机身倾斜,所以测量必须回到重力坐标

控制器按图像曝光时刻配对 PX4 姿态,而不是使用检测回调到达时的“最新姿态”。这避免把渲染、桥接和检测延迟误认为目标移动。

C / OPTICAL

相机系标签位姿

apriltag_ros 使用图像、内参与已知标签尺寸计算 6DoF pose。

B / FRD

固定相机外参

把 optical 轴转换到 PX4 body FRD,并只应用一次相机平移。

N / NED

图像时刻姿态

从姿态缓冲进行 SLERP,将倾斜机体系相对向量旋转到重力对齐坐标。

PX4 / ATTITUDE

受限相对外环

PD、低通、加速度和 8° 倾角限制共同生成姿态与推力。

补偿不是“减去倾角”,而是完整刚体变换

末端样本无法被姿态时间包围、时间差过大或图像过期时,测量会被明确拒绝,不会盲目拼接。

CONTROLLER MAY READ

Tag pose/quality、源图像时间戳、CameraInfo、相机外参、PX4 attitude/state 和气压高度。

CONTROLLER MUST NOT READ

Gazebo truth、GPS/local position、LiDAR odometry、SLAM pose 或 optical-flow position。

飞行证据

不是只展示“能飞”,还要证明控制输入没有越界

正式移动目标运行持续 120 秒。视觉误差与只读 Gazebo truth evaluator 的评分相互接近;evaluator 没有 publication,真值没有形成控制回路。

MOVING TARGET120 s0.5 m/s figure-eight
VISUAL XY RMS0.319 mp95 0.560 m
SETPOINT RATE50.000 Hz最大倾角 6.24°
FINAL STATEDISARMED受控下降并清理
验证场景条件正式结果
静态检测1–3 m、偏移、不同 yaw5/5 · 100% valid · hamming 0
姿态补偿roll/pitch ±15°RMSE 0.459 m → 0.000957 m
静止 Tag 飞行连续 60 秒XY RMS 0.096 m · p95 0.227 m
移动目标跟随0.5 m/s · 120 秒visual RMS 0.319 m · p95 0.560 m
独立真值评分同一移动运行,只读truth RMS 0.324 m · p95 0.574 m
键盘控制WASD / arrows / deadmanPASS · final armed=false

图片 SHA256 可在 assets/SHA256SUMS 复核。完整运行编号与机器可读指标:reports/status.json

丢标处理

看不见 Tag 时,不把“没有观测”包装成“位置保持”

丢标后的目标是先消除危险水平追逐,再给识别恢复留出时间。只有持续丢标达到 10 秒才锁存下降;落地后也不会立即退出。

进入 SHORT_LOSS

保留短时恢复机会,所有新测量仍需重新通过质量和时效门控。

快速衰减追逐指令

不继续追逐最后一个目标速度,避免丢标后加速飞离。

水平回正,保持气压高度

气压计只提供竖直安全信号;系统不宣称水平位置保持。

锁存受控下降

正式测试在 9.94 秒离散周期触发,下降后重新识别也不会取消落地。

零推力后退出

确认落地与 disarm,再保持零推力 3 秒并清理项目进程。

范围限制:当前实现从小车旁边起飞并降落到地面,不实现向移动小车车顶精准降落。该功能需要新的近地视觉、碰撞和安全验证。