- 嵌入式
- 物联网
- 机器人
- 自动驾驶
- 智能硬件
【免费下载链接】PX4-Autopilot
PX4 Autopilot Software
manual_control_switches 是 PX4 Autopilot 中承载遥控器(RC)各类拨杆开关状态的 uORB 话题,将摇杆输入之外的“离散开关信息”——解锁/锁定、返航、盘旋、offboard、急停、终止、起落架、VTOL 转换、拍照录像、载荷供电等——统一封装为结构化消息,供 manual_control、commander 等上层模块消费。读完本文,你将掌握该消息的完整字段与常量定义、RC 通道到开关状态的量化映射逻辑、开关触发动作请求的底层调用链,以及如何用 RC_MAP_* / RC_*_TH 参数完成实际遥控器开关配置。
消息概览:一个话题承载全部开关状态
PX4 使用 uORB 消息在模块间传递数据。ManualControlSwitches.msg 定义的manual_control_switches话题是“开关集合”的唯一事实来源:它不包含摇杆杆量(那是 manual_control_setpoint 的职责),只包含每一位开关的当前位置与当前选中的模式槽位(mode slot)。该消息的生成端是 rc_update 模块,消费端包括 manual_control 模块、commander 的预飞检查 以及 MAVLink 流。
从数据流角度看,整条链路为:
RC 接收机 → rc_update(通道→开关状态量化)→ manual_control_switches 话题 → manual_control(开关变化→action_request)→ commander 执行模式/解锁/终止等动作 → manualControlCheck(预飞健康检查) → MANUAL_CONTROL MAVLink 流(转发给地面站)消息字段:每一个开关的语义
下表完整列出 ManualControlSwitches.md(与 msg/ManualControlSwitches.msg 一致)定义的全部字段。所有开关字段类型均为uint8,取值使用下文常量表中的SWITCH_POS_*枚举。
| 字段名 | 类型 | 说明 |
|---|---|---|
timestamp | uint64 | 消息发布时刻,自系统启动以来的微秒数 |
timestamp_sample | uint64 | 原始数据采样的时间戳(微秒),用于标识 RC 采样时刻 |
mode_slot | uint8 | 飞行模式选择器当前所处的槽位(1~6,取值MODE_SLOT_*) |
arm_switch | uint8 | 解锁/锁定开关:_DISARMED_(OFF)、ARMED(ON) |
return_switch | uint8 | 返航(Return)两位开关(强制项):_NORMAL_、RETURN |
loiter_switch | uint8 | 盘旋两位开关(可选):_MISSION_、LOITER |
offboard_switch | uint8 | offboard 两位开关(可选):_NORMAL_、OFFBOARD |
kill_switch | uint8 | 油门急停(throttle kill):_NORMAL_、KILL |
termination_switch | uint8 | 触发不可撤销的飞行终止(termination) |
gear_switch | uint8 | 起落架开关:_DOWN_(放下)、UP(收起) |
transition_switch | uint8 | VTOL 转换开关:_HOVER(悬停/多旋翼)、FORWARD_FLIGHT(前飞/固定翼) |
photo_switch | uint8 | 拍照触发开关 |
video_switch | uint8 | 录像触发开关 |
engage_main_motor_switch | uint8 | 主电机接合开关(用于直升机) |
payload_power_switch | uint8 | 载荷供电开关(支持三位:ON/MIDDLE/OFF) |
switch_changes | uint32 | 自发布以来开关状态发生变化的总次数(计数器) |
其中两个时间戳的区别值得注意:timestamp_sample是 RC 帧原始采样时刻,timestamp是 rc_update 发布消息的时刻;两者结合可用于评估链路延迟,也为日志回放(如 logged_topics.cpp 记录的该话题)提供时间基准。
消息常量:开关位置与模式槽位枚举
消息定义中同时内嵌了两组常量,它们不是独立枚举文件,而是随消息生成的 C++ 枚举(manual_control_switches_s::SWITCH_POS_ON等),因此在所有消费端代码中可直接引用。
开关位置常量(SWITCH_POS_*):
| 常量 | 值 | 含义 |
|---|---|---|
SWITCH_POS_NONE | 0 | 开关未映射到任何通道 |
SWITCH_POS_ON | 1 | 开关激活(通道值 = 1,即满量程) |
SWITCH_POS_MIDDLE | 2 | 中间位置(通道值 = 0) |
SWITCH_POS_OFF | 3 | 开关未激活(通道值 = -1) |
模式槽位常量(MODE_SLOT_*):
| 常量 | 值 | 含义 |
|---|---|---|
MODE_SLOT_NONE | 0 | 未分配任何模式槽位 |
MODE_SLOT_1~MODE_SLOT_6 | 1 ~ 6 | 槽位 1~6 被选中 |
MODE_SLOT_NUM | 6 | 槽位总数 |
注意SWITCH_POS_ON对应通道归一化值 1、SWITCH_POS_OFF对应 -1、SWITCH_POS_MIDDLE对应 0——这与下方 rc_update 的量化函数完全对应:它先把 RC 通道值从 [-1, 1] 重新缩放到 [0, 1],再与阈值比较得出 ON/OFF。
数据生产端:rc_update 如何把通道变成开关状态
manual_control_switches的发布实现在 rc_update.cpp 的 UpdateManualSwitches()。它依次完成三件事:计算模式槽位、量化每一位开关、按节流规则发布。
模式槽位的两种来源
mode_slot有两种映射方式,由参数决定:
- 单通道 6 槽位模式(RC_MAP_FLTMODE > 0):把一个通道的连续位置等分为 6 个槽位。源码中的计算公式(rc_update.cpp)先将通道值在 [-1-0.05, 1+0.05] 区间内归一化到 0~1,再乘以
MODE_SLOT_NUM(6)并加上半槽宽度做取整修正,最后 +1 得到 1~6 的槽位号。超过 6 会被钳位到 6。 - 按钮模式(RC_MAP_FLTM_BTN 位掩码):每个被掩码的通道对应一个模式槽位(最低位通道 = 槽位 1),当某通道值超过 0.5(约 75% 量程)且经过去抖滞后(hysteresis)确认持续按压后,才写入对应槽位(rc_update.cpp)。该方式要求
RC_MAP_FLTMODE必须为 0,两者互斥。
开关位置的量化:两位开关与三位开关
两位开关通过getRCSwitchOnOffPosition()(rc_update.cpp)量化:若该功能未映射通道则返回SWITCH_POS_NONE;否则把通道值重缩放为 [0,1],再与阈值(可正可负表示比较方向)比较,高于阈值返回SWITCH_POS_ON,否则SWITCH_POS_OFF。
三位开关(载荷供电)使用getRCSwitch3WayPosition()(rc_update.cpp),同时比较 ON 阈值与 MID 阈值:高于 ON 阈值为 ON,介于两者之间为 MIDDLE,低于 MID 阈值为 OFF。
各开关在 UpdateManualSwitches() 中逐一赋值:
return_switch←FUNCTION_RETURN通道 +RC_RETURN_THloiter_switch←FUNCTION_LOITER通道 +RC_LOITER_THoffboard_switch←FUNCTION_OFFBOARD通道 +RC_OFFB_THkill_switch←FUNCTION_KILLSWITCH通道 +RC_KILLSWITCH_THtermination_switch←FUNCTION_TERMINATION通道,固定阈值 0.75arm_switch←FUNCTION_ARMSWITCH通道 +RC_ARMSWITCH_THtransition_switch←FUNCTION_TRANSITION通道 +RC_TRANS_THgear_switch←FUNCTION_GEAR通道 +RC_GEAR_THengage_main_motor_switch←FUNCTION_ENGAGE_MAIN_MOTOR通道 +RC_ENG_MOT_THpayload_power_switch←FUNCTION_PAYLOAD_POWER通道 +RC_PAYLOAD_TH/RC_PAYLOAD_MIDTH(三位)
发布节流与 switch_changes 计数
为防止 RC 数据抖动导致高频发布,rc_update.cpp 要求“连续两次开关数据在 1 秒内保持一致”才认可该数据;随后只有在状态发生变化时才立即发布,否则以约 1 Hz 的速率周期发布。每次检测到状态变化,switch_changes计数器加 1,该字段随消息一起发布,可作为开关活动量与 RC 数据质量的诊断指标。
参数配置:Radio Switches 参数组
与开关映射直接对应的参数集中在 src/modules/rc_update/params.yaml 的Radio Switches组(默认值均以当前仓库为准):
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
RC_MAP_FLTMODE | enum 0~18 | 0 | 单通道飞行模式选择(非零时独占模式选择,分配 6 个槽位) |
RC_MAP_FLTM_BTN | bitmask | 0 | 按钮式模式选择位掩码(每通道一个槽位,最多 6 位;需RC_MAP_FLTMODE=0) |
RC_MAP_RETURN_SW | enum 0~18 | 0 | 返航开关通道 |
RC_MAP_LOITER_SW | enum 0~18 | 0 | 盘旋开关通道 |
RC_MAP_OFFB_SW | enum 0~18 | 0 | offboard 开关通道 |
RC_MAP_KILL_SW | enum 0~18 | 0 | 急停开关通道(立即将全部输出置为解锁值,不触发降落伞;可撤销,拨回即恢复控制;5 秒后系统自动解锁,需重新预飞检查与解锁) |
RC_MAP_TERM_SW | enum 0~18 | 0 | 终止开关通道(触发不可逆飞行终止:全部输出置为 failsafe 值并触发 MAVLink 降落伞;不可撤销,须重启系统) |
RC_MAP_ARM_SW | enum 0~18 | 0 | 解锁开关通道(分配后禁用摇杆解锁/锁定) |
RC_MAP_TRANS_SW | enum 0~18 | 0 | VTOL 转换开关通道 |
RC_MAP_GEAR_SW | enum 0~18 | 0 | 起落架开关通道 |
RC_MAP_PAY_SW | enum 0~18 | 0 | 载荷供电开关通道 |
RC_RETURN_TH/RC_LOITER_TH/RC_OFFB_TH/RC_KILLSWITCH_TH/RC_ARMSWITCH_TH/RC_TRANS_TH/RC_GEAR_TH/RC_ENG_MOT_TH/RC_PAYLOAD_TH | float -1~1 | 0.75 | 各开关激活阈值;符号表示比较方向(正:通道值 > 阈值时为真;负:通道值 < 阈值时为真) |
RC_PAYLOAD_MIDTH | float -1~1 | 0.25 | 载荷供电三位开关的中间位阈值 |
模式槽位最终指向的具体飞行模式由 commander 参数COM_FLTMODE1~COM_FLTMODE6决定(见 ManualControl.cpp 的 navStateFromParam),每个槽位对应一个导航状态(如 0=Manual、3=Auto Mission、5=Auto RTL 等,100+ 为外部模式)。
数据消费端:manual_control 的开关处理逻辑
ManualControl::processSwitches() 是核心消费逻辑。它首先要求当前有效输入源为 RC(data_source == manual_control_setpoint_s::SOURCE_RC),否则重置历史状态、不响应任何开关变化——这保证了非 RC 输入源(如 GCS 虚拟摇杆)不会误触发开关动作。
在 RC 有效的前提下,模块对每个字段做边沿检测(与上一次状态比较),仅在状态翻转时触发对应动作:
| 字段 | 触发条件 | 动作 |
|---|---|---|
mode_slot | 槽位变化 | evaluateModeSlot() 按COM_FLTMODE{n}发送ACTION_SWITCH_MODE |
arm_switch | ON / OFF | ACTION_ARM/ACTION_DISARM(若COM_ARM_SWISBTN开启则作为按钮,发送ACTION_TOGGLE_ARMING) |
return_switch | ON / OFF | ACTION_SWITCH_MODE到AUTO_RTL/ 回到模式槽位 |
loiter_switch | ON / OFF | ACTION_SWITCH_MODE到AUTO_LOITER/ 回到模式槽位 |
offboard_switch | ON / OFF | ACTION_SWITCH_MODE到OFFBOARD/ 回到模式槽位 |
kill_switch | ON / OFF | ACTION_KILL/ACTION_UNKILL |
termination_switch | ON(仅上升沿) | ACTION_TERMINATION(不可撤销) |
gear_switch | ON / OFF(且上一次不是 NONE) | 发布landing_gear:GEAR_UP/GEAR_DOWN |
transition_switch | ON / OFF | ACTION_VTOL_TRANSITION_TO_FIXEDWING/ACTION_VTOL_TRANSITION_TO_MULTICOPTER |
photo_switch | ON(上升沿) | 相机模式切至 Image 并发送拍照命令 |
video_switch | ON(上升沿) | 相机模式切至 Video 并发送录像命令 |
payload_power_switch | ON / (OFF 或 MIDDLE) | 使能/关断载荷供电(需编译时定义PAYLOAD_POWER_EN) |
模式请求通过sendActionRequest()(ManualControl.cpp)发布action_request话题,由 commander 最终执行;若槽位未分配模式(navStateFromParam返回 -1),请求会被直接丢弃。此外,在未解锁状态下收到第一帧开关数据时,模块会立即按当前mode_slot初始化模式(ManualControl.cpp),方便飞手在起飞前预先选中模式。
预飞检查:开关位置也是健康状态
commander 的 manualControlCheck.cpp 在解锁前读取manual_control_switches,若以下开关处于危险位置则拒绝解锁并告警:
return_switch == SWITCH_POS_ON→ “Return switch engaged”kill_switch == SWITCH_POS_ON→ “Kill switch engaged”gear_switch == SWITCH_POS_ON→ “Landing gear switch set in UP position”(起落架处于收起位置不允许解锁)
这解释了为何原消息文档将return_switch标注为“mandatory”:返航开关不仅是模式选择的一部分,也是预飞检查的组成部分。
MAVLink 桥接与测试验证
- MAVLink 转发:MANUAL_CONTROL.hpp 将
return_switch、loiter_switch、offboard_switch、kill_switch的SWITCH_POS_*值按位打包进 MAVLinkMANUAL_CONTROL报文的buttons位段,使地面站可实时看到开关状态。 - 单元测试:ManualControlTest.cpp 的
ModeSwitch用例直接向manual_control_switches发布MODE_SLOT_1~MODE_SLOT_6,断言manual_control依序发出ACTION_SWITCH_MODE且 mode 与navStateFromParam输出一致,验证了模式槽位→动作请求的完整映射。 - 日志记录:logged_topics.cpp 将该话题列入日志组,
switch_changes与mode_slot等字段可在 Flight Review 中用于事后分析飞手操作。
结语
manual_control_switches是连接物理遥控器开关与飞控逻辑动作的枢纽消息:rc_update 负责把 RC 通道量化为标准化的开关位置枚举,manual_control 负责把开关边沿翻译为action_request,commander 与预飞检查负责最终执行与安全把关。理解其字段、常量与参数映射关系,即可在 QGroundControl 中正确配置RC_MAP_*与RC_*_TH参数,实现返航、盘旋、offboard、急停、终止、起落架、VTOL 转换乃至拍照录像等全部开关功能;而switch_changes与timestamp_sample则为诊断 RC 链路质量与操作时序提供了第一手数据。
- 嵌入式
- 物联网
- 机器人
- 自动驾驶
- 智能硬件
【免费下载链接】PX4-Autopilot
PX4 Autopilot Software
相关推荐
PX4 ActionRequest UORB 消息深度解析:从 RC 输入到飞控状态机的动作请求链路
PX4 ActionRequest UORB 消息深度解析:从 RC 输入到飞控状态机的动作请求链路 ActionRequest 是 PX4 内部组件向飞行器主
嵌入式物联网机器人自动驾驶智能硬件PX4-Autopilot 的 DistanceSensorModeChangeRequest uORB 消息:测距传感器启停请求机制详解
PX4 Autopilot 的 DistanceSensorModeChangeRequest uORB 消息:测距传感器启停请求机制详解 导读 Distanc
嵌入式物联网机器人自动驾驶智能硬件PX4-Autopilot uORB 消息深度解析:ConfigOverrides 外部模式配置覆盖机制
PX4 Autopilot uORB 消息深度解析:ConfigOverrides 外部模式配置覆盖机制 ConfigOverrides 是 PX4 Autop
嵌入式物联网机器人自动驾驶智能硬件
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考