news 2026/9/28 20:00:37

PX4-Autopilot uORB 消息 IrlockReport 详解:IR-Lock 红外信标定位数据结构与驱动实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PX4-Autopilot uORB 消息 IrlockReport 详解:IR-Lock 红外信标定位数据结构与驱动实现
  • 嵌入式
  • 物联网
  • 机器人
  • 自动驾驶
  • 智能硬件

【免费下载链接】PX4-Autopilot

PX4 Autopilot Software

项目地址:https://gitcode.com/gh_mirrors/px/PX4-Autopilot
点击查看免费下载

导读

IrlockReport是 PX4-Autopilot 中用于承载 IR-Lock 红外信标传感器(IR-LOCK 及 Pixy 视觉传感器)检测结果的 uORB 消息主题。本文以消息定义文档docs/en/msg_docs/IrlockReport.md为骨架,完整讲解该消息的六个字段及其语义,并结合仓库源码(msg/IrlockReport.msg、src/drivers/irlock/irlock.cpp)深入剖析字段的底层来源——包括 I2C 原始像素数据的校验、像素到tan(theta)的角度换算公式、驱动发布逻辑,以及下游landing_target_estimator模块如何消费该消息完成精准着陆目标估计。读完本文,你将掌握 IrlockReport 消息的完整数据结构、驱动侧的数据生成链路,以及如何查看该主题的实测数据。

IrlockReport 消息概览

IrlockReport在 PX4 的 uORB 消息体系中属于传感器测量类消息,其源定义文件位于 msg/IrlockReport.msg,官方文档说明如下:

IRLOCK_REPORT message data.

该消息只有一个实例话题irlock_report(**TOPICS:** irlock_report),由 IRLock 驱动发布,供着陆目标估计等模块订阅。其消息结构体在编译期由px_generate_uorb_topic_files.py自动生成,对应头文件为uORB/topics/irlock_report.h(驱动与消费模块均通过该头文件引用消息类型irlock_report_s)。

字段总表

名称类型描述
timestampuint64自系统启动以来的时间(微秒),用于时间同步与消息时效判断
signatureuint16目标签名(target signature),用于区分不同的信标标识
pos_xfloat32目标与相机投影中心在相机 x 轴方向夹角的正切值tan(theta)
pos_yfloat32目标与相机投影中心在相机 y 轴方向夹角的正切值tan(theta)
size_xfloat32目标沿相机 x 轴方向的尺寸,单位为tan(theta)
size_yfloat32目标沿相机 y 轴方向的尺寸,单位为tan(theta)

字段语义深度解读

timestamp:测量时间戳

timestamp为uint64类型,表示消息发布时间相对于系统启动的时刻(微秒)。在驱动源码中,该值取自hrt_absolute_time()(见 irlock.cpp),即硬件实时时钟的绝对时间。该字段是下游模块判断测量新鲜度、与机体姿态/位置数据对齐的关键依据——landing_target_estimator在融合时会将_irlockReport.timestamp直接透传到输出的vehicle_landing_target报告中(LandingTargetEstimator.cpp)。

signature:目标签名

signature为uint16类型,代表被检测目标的签名编号。IR-Lock 传感器支持对具有不同编码/签名的红外信标进行区分,驱动解析出的签名来自 I2C 数据块中的signature字段(irlock.cpp),并经过与像素坐标、尺寸之和的 CRC 校验后才被采用(详见下文"数据校验"小节)。

pos_x / pos_y:目标角度位置(tan(theta) 归一化)

pos_x、pos_y均为float32,表示目标相对相机成像中心的角度偏移,但不是角度本身,而是角度的正切值:

  • pos_x:相机 x 轴方向(向右)上目标与投影中心的夹角正切;
  • pos_y:相机 y 轴方向(向下)上目标与投影中心的夹角正切。

原文档(及源消息注释)明确给出了坐标系约定:

When looking along the optical axis of the camera, x points right, y points down, and z points along the optical axis.

即:沿相机光轴方向观察时,x 轴向右、y 轴向下、z 轴沿光轴方向。因此pos_x/pos_y实际构成了一条指向目标的单位射线在 x、y 方向的分量,配合 z 分量 1,即可在机体坐标系下重建目标方向向量——这正是下游估计器计算目标相对位置的基础。

在驱动实现中,像素坐标到tan(theta)的换算公式为(irlock.cpp):

block->pos_x = (pixel_x - IRLOCK_CENTER_X) * IRLOCK_TAN_ANG_PER_PIXEL_X; block->pos_y = (pixel_y - IRLOCK_CENTER_Y) * IRLOCK_TAN_ANG_PER_PIXEL_Y;

其中IRLOCK_CENTER_X/IRLOCK_CENTER_Y为图像中心像素(320×200 分辨率下为 160/100),IRLOCK_TAN_ANG_PER_PIXEL_X/Y为每个像素对应的正切角增量,由传感器视场角推导:

#define IRLOCK_FOV_X (60.0f * M_PI_F / 180.0f) // 水平视场 60° #define IRLOCK_FOV_Y (35.0f * M_PI_F / 180.0f) // 垂直视场 35° #define IRLOCK_TAN_HALF_FOV_X 0.57735026919f // tan(0.5 * 60°) #define IRLOCK_TAN_HALF_FOV_Y 0.31529878887f // tan(0.5 * 35°) #define IRLOCK_TAN_ANG_PER_PIXEL_X (2 * IRLOCK_TAN_HALF_FOV_X / IRLOCK_RES_X) #define IRLOCK_TAN_ANG_PER_PIXEL_Y (2 * IRLOCK_TAN_HALF_FOV_Y / IRLOCK_RES_Y)

可以看到,正切角采用"每像素正切角增量 × 像素偏移"的线性近似,是视觉测量领域常见的针孔模型简化,便于下游直接构造方向向量而无需反三角运算。

size_x / size_y:目标尺寸

size_x、size_y为float32,表示目标在相机 x/y 轴方向上的尺寸,同样以tan(theta)为单位。驱动侧由像素尺寸乘以上述每像素正切角增量得到(irlock.cpp):

block->size_x = pixel_size_x * IRLOCK_TAN_ANG_PER_PIXEL_X; block->size_y = pixel_size_y * IRLOCK_TAN_ANG_PER_PIXEL_Y;

该尺寸信息可用于估计目标到相机的距离(已知目标实际物理尺寸时),或作为目标大小/遮挡的判断依据。

消息源文件与自动生成机制

IrlockReport 的权威定义是msg/目录下的源消息文件,其完整内容如下(与文档中的"Source Message"折叠块一致):

# IRLOCK_REPORT message data uint64 timestamp # time since system start (microseconds) uint16 signature # When looking along the optical axis of the camera, x points right, y points down, and z points along the optical axis. float32 pos_x # tan(theta), where theta is the angle between the target and the camera center of projection in camera x-axis float32 pos_y # tan(theta), where theta is the angle between the target and the camera center of projection in camera y-axis float32 size_x #/** size of target along camera x-axis in units of tan(theta) **/ float32 size_y #/** size of target along camera y-axis in units of tan(theta) **/

PX4 构建系统通过 Tools/msg/px_generate_uorb_topic_files.py 将该文件生成为 C/C++ 可用的头文件uORB/topics/irlock_report.h与结构体irlock_report_s,同时为文档站点生成字段文档。因此修改字段定义时,应直接编辑.msg文件而非生成产物。

驱动侧数据生成链路:从 I2C 像素到 uORB 消息

IrlockReport 消息由src/drivers/irlock/irlock.cpp中的IRLOCK驱动发布,该驱动面向通过 I2C 连接的 IR-Lock 与 Pixy 视觉传感器。核心链路如下:

  1. 周期调度:驱动以IRLOCK_CONVERSION_INTERVAL_US = 20000us(20ms,即 50Hz)周期调用RunImpl()(irlock.cpp)。
  2. 帧同步:sync_device()读取 I2C 同步字,识别IRLOCK_SYNC(0xAA55)或IRLOCK_RESYNC(0x5500)+IRLOCK_ADJUST(0xAA)组合,确认一帧数据的起始(irlock.cpp)。
  3. 块读取与 CRC 校验:read_device_block()每次读取 12 字节的目标块(checksum、signature、pixel_x、pixel_y、size_x、size_y 各 2 字节),并执行校验:signature + pixel_x + pixel_y + pixel_size_x + pixel_size_y == checksum,不通过则累计_read_failures并丢弃该块(irlock.cpp)。
  4. 像素→正切角换算:按上文公式将像素偏移与尺寸换算为tan(theta)单位。
  5. 发布:驱动最多解析IRLOCK_OBJECTS_MAX = 5个目标,但 uORB 消息仅发布第一个目标(targets[0])的 signature、pos_x、pos_y、size_x、size_y,并附带帧时间戳(irlock.cpp)。

从源码结构看,irlock_report_s是"单目标"消息,而驱动内部保留了多目标解析能力(irlock_s结构含targets[5]),两者在设计上存在取舍:uORB 层面仅暴露首个目标,多目标信息目前未向外部传递。

下游消费:landing_target_estimator 中的使用

IrlockReport 的核心消费方是着陆目标估计模块src/modules/landing_target_estimator/LandingTargetEstimator.cpp。该模块通过uORB::Subscription _irlockReportSub{ORB_ID(irlock_report)}(LandingTargetEstimator.h)订阅消息,处理流程(LandingTargetEstimator.cpp):

  1. 收到新irlock_report后,先校验机体姿态、本地位置与底部距离(dist_bottom_valid)是否有效,并检查pos_x/pos_y是否为有限浮点数(PX4_ISFINITE),无效测量直接跳过;
  2. 由pos_x/pos_y构造机体坐标系下的目标方向向量sensor_ray = [pos_x * scale_x, pos_y * scale_y, 1],其中scale_x/scale_y为传感器缩放参数;
  3. 依次按传感器安装偏航角sensor_yaw与机体姿态四元数旋转该射线到导航坐标系;
  4. 利用底部距离dist_bottom与传感器高度偏移,将射线缩放为地面坐标系中的相对位置,并叠加offset_x/offset_y安装偏移,输出vehicle_landing_target报告。

这解释了为何消息字段采用tan(theta)而非绝对像素:下游可直接将其视作射线方向向量分量,无需相机内参即可完成三角定位。

启动与配置方式

IRLock 驱动与传感器使能参数定义于 src/drivers/irlock/parameters.yaml:

参数类型默认值说明
SENS_EN_IRLOCKboolean0IR-LOCK 传感器(外部 I2C)使能开关,修改后需重启(reboot_required: true)

在飞控固件(ROMFS)的传感器初始化脚本 ROMFS/px4fmu_common/init.d/rc.sensors 中,当SENS_EN_IRLOCK为 1 时执行:

irlock start -X

其中-X表示使用外部 I2C 总线。驱动默认 7 位 I2C 地址为0x54,默认 I2C 频率 400 kHz(irlock.cpp)。也可通过 NuttShell 手动控制:

irlock start # 启动驱动(可附加 -X -a 0x54 等总线/地址参数) irlock stop # 停止驱动 irlock status # 查看驱动状态与读取错误计数(read errors)

status命令输出read errors计数,可用于排查 I2C 通信与数据校验失败情况。

在仿真环境中观察消息

仓库还提供了 Gazebo-classic 仿真模型1011_gazebo-classic_iris_irlock(ROMFS/px4fmu_common/init.d-posix/airframes/1011_gazebo-classic_iris_irlock),配合 SITL 可复现 IR-Lock 目标检测场景。运行时可通过如下方式查看irlock_report主题内容:

# 进入 PX4 控制台后 listener irlock_report

该命令将按发布频率打印timestamp、signature、pos_x、pos_y、size_x、size_y的实时数值,便于验证驱动换算与消息发布是否正确。

总结

IrlockReport 是 PX4 视觉着陆系统中的关键测量消息:其timestamp承载测量时间,signature标识目标签名,pos_x/pos_y以tan(theta)形式表达目标相对光轴的角度偏移,size_x/size_y表达目标尺寸。消息由 IRLock I2C 驱动以 50Hz 周期发布,数据经历帧同步、CRC 校验、像素→正切角换算后进入 uORB,最终被landing_target_estimator消费,结合机体姿态与高度估计出着陆目标的地面相对位置。理解这套数据结构与数据链路,是调试 IR-Lock 精准着陆功能、扩展多目标能力或接入自定义红外信标方案的基础。

  • 嵌入式
  • 物联网
  • 机器人
  • 自动驾驶
  • 智能硬件

【免费下载链接】PX4-Autopilot

PX4 Autopilot Software

项目地址:https://gitcode.com/gh_mirrors/px/PX4-Autopilot
点击查看免费下载

相关推荐

上一篇:Label Studio数据库备份自动化终极指南:5步实现定时任务与云存储集成
下一篇:Go-Ethereum Git工作流:feature分支与PR模板

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/28 20:00:32

计量芯片报警引脚 vs 寄存器报警:选型思路与实战避坑指南

硬件同事拿着原理图问我:这个报警引脚到底接不接?不接的话还能省一个GPIO。我当时第一反应是“接上总比没有强”,后来才发现这事儿没那么简单。很多计量芯片(BL0937、HLW8032、RN8209、ATT7022这些)都同时提供两条报警…

作者头像 李华
网站建设 2026/9/28 20:00:32

公众号历史文章采集:用 XPath 与 Cookie 打通 TaoToken 配置链路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/28 19:58:38

UWB超宽带定位接入PX4:从GPS失效到室内自主飞行的完整指南

在室外跑惯GPS航点的固定翼和穿越机,一到室内停车场、隧道、厂区这类环境,我第一反应就是先检查信号数。GPS在遮挡严重的环境里要么搜不到星,要么位置一跳就是十几米,飞控的EKF滤波器直接被脏数据带偏,姿态都跟着晃。后…

作者头像 李华