☰
PX4 SetpointConfigReply 消息详解:外部模式设定点配置的请求-应答机制
2026/10/2 8:15:53 网站建设 项目流程
  • 嵌入式
  • 物联网
  • 机器人
  • 自动驾驶
  • 智能硬件

【免费下载链接】PX4-Autopilot

PX4 Autopilot Software

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

导读

SetpointConfigReply是 PX4 飞控中一组 uORB 消息setpoint_config/setpoint_config_reply的应答消息,用于外部模式(external mode)向 PX4 提出设定点类型(setpoint type)配置请求后,由 PX4 返回校验结果与模式需求标志。本文基于 SetpointConfigReply 文档 及仓库源码,完整讲解该消息的字段语义、RESULT枚举、模式需求标志(mode_req_*)的生成规则,并结合 commander 模块 的实现揭示 PX4 底层应答链路,帮助你在开发外部模式(如 Offboard 自定义模式、DDS/ROS 2 集成)时正确解析应答并完成武装检查。

消息定位:一对请求-应答的 uORB 主题

SetpointConfigReply不是孤立存在的消息,它与SetpointConfig构成一对请求-应答关系:

  • 外部模式发布SetpointConfig(主题setpoint_config,PX4 侧订阅路径为/fmu/in/setpoint_config),声明自己希望使用的设定点类型、来源模式(source_id)、是否生效(should_apply)以及超时(timeout_ms);
  • PX4 的 commander 模块校验请求后,发布SetpointConfigReply(主题setpoint_config_reply,外部订阅路径为/fmu/out/setpoint_config_reply),携带校验结果(result)与使用该设定点类型所需的控制模式标志(mode_req_*)。

主题桥接关系可以在 uxrce_dds_client 的 dds_topics.yaml 与 zenoh 的 dds_topics.yaml 中找到印证:两条消息分别映射为/fmu/in/setpoint_config与/fmu/out/setpoint_config_reply,意味着 DDS(ROS 2)与 Zenoh 外部节点都可以通过这套接口与 PX4 完成设定点配置协商。

字段定义与语义

SetpointConfigReply定义于 msg/versioned/SetpointConfigReply.msg,完整字段如下(单位、枚举约束见下表):

名称类型单位 [Frame]范围/枚举说明
timestampuint64us自系统启动以来的时间(微秒),由 PX4 在发布时填充
typeuint16设定点类型,取值对应SetpointConfig::TYPE_*(见下文 TYPE 枚举)
source_iduint8发送SetpointConfig请求的模式对应的nav_state
resultuint8RESULT校验结果(成功/失败/不支持/未知类型)
mode_req_angular_velocitybool是否要求角速度(rates)控制
mode_req_attitudebool是否要求姿态控制
mode_req_local_altbool是否要求本地高度控制
mode_req_local_positionbool是否要求本地位置控制

其中type与source_id由 PX4 从收到的SetpointConfig请求中原样回填(见 ModeManagement.cpp),保证外部模式能把应答与自己的请求一一对应起来。

type字段的取值即SetpointConfig消息中定义的TYPE_*枚举(定义于 msg/versioned/SetpointConfig.msg),本文消息原样引用,不再重复定义:

枚举值数值对应设定点消息
TYPE_INVALID0无效类型
TYPE_DIRECT_ACTUATORS1ActuatorMotors与ActuatorServos
TYPE_MULTICOPTER_GOTO2GotoSetpoint
TYPE_FIXEDWING_LATERAL_LONGITUDINAL3FixedWingLateralSetpoint与FixedWingLongitudinalSetpoint
TYPE_TRAJECTORY4TrajectorySetpoint
TYPE_RATES5VehicleRatesSetpoint
TYPE_ATTITUDE6VehicleAttitudeSetpoint
TYPE_ROVER_POSITION7RoverPositionSetpoint
TYPE_ROVER_SPEED_ATTITUDE8RoverSpeedSetpoint与RoverAttitudeSetpoint
TYPE_ROVER_SPEED_RATE9RoverSpeedSetpoint与RoverRateSetpoint
TYPE_ROVER_SPEED_STEERING10RoverSpeedSetpoint与RoverSteeringSetpoint
TYPE_ROVER_THROTTLE_ATTITUDE11RoverThrottleSetpoint与RoverAttitudeSetpoint
TYPE_ROVER_THROTTLE_RATE12RoverThrottleSetpoint与RoverRateSetpoint
TYPE_ROVER_THROTTLE_STEERING13RoverThrottleSetpoint与RoverSteeringSetpoint
TYPE_TRAJECTORY_6DOF14TrajectorySetpoint6dof
TYPE_THRUST_AND_TORQUE15VehicleThrustSetpoint与VehicleTorqueSetpoint
TYPE_POSITION_TRIPLET16PositionSetpointTriplet

RESULT 枚举:校验结果的四种取值

result字段使用RESULT枚举(定义于SetpointConfigReply.msg,本文消息的 Enums 小节 完整列出):

枚举名类型值说明
RESULT_SUCCESSuint80校验通过,设定点类型可用于当前飞控/机型
RESULT_FAILURE_OTHERuint81其他失败(例如请求中携带的source_id不是有效模式)
RESULT_UNSUPPORTEDuint82当前机型不支持该设定点类型(例如多旋翼上请求固定翼横向-纵向设定点)
RESULT_UNKNOWN_SETPOINT_TYPEuint83设定点类型未知(例如类型值超出TYPE_*枚举范围)

常量 MESSAGE_VERSION

消息定义了一个版本常量,用于 uORB 消息格式的版本校验:

名称类型值
MESSAGE_VERSIONuint320

当前版本为 0,对应 PX4 对setpoint_config/setpoint_config_reply接口的初始定义。

源码级实现:PX4 如何生成 SetpointConfigReply

在 PX4 内部,应答逻辑位于 commander 模块的ModeManagement::checkConfigControlSetpointUpdates()(见 ModeManagement.cpp)。该函数订阅setpoint_config主题,循环取出请求并发布对应应答,核心流程如下:

  1. 回填标识字段:从请求拷贝source_id与type到应答消息,供外部模式匹配请求与应答;
  2. 校验模式有效性:若source_id对应的模式不存在,打印一次错误日志Setpoint config request for invalid mode: %i并返回RESULT_FAILURE_OTHER;
  3. 校验设定点类型:调用mode_util::isSetpointTypeValid(),结合当前机型(vehicle_type)与是否 VTOL(is_vtol)判断类型是否受支持,结果映射为RESULT_SUCCESS/RESULT_UNSUPPORTED/RESULT_UNKNOWN_SETPOINT_TYPE;
  4. 填充模式需求标志:仅当结果为RESULT_SUCCESS时,调用mode_util::getControlMode()得到对应的vehicle_control_mode标志,并按如下规则映射为四个mode_req_*布尔字段:
reply.mode_req_angular_velocity = config_control_setpoint.flag_control_rates_enabled; reply.mode_req_attitude = config_control_setpoint.flag_control_attitude_enabled; reply.mode_req_local_alt = config_control_setpoint.flag_control_altitude_enabled || config_control_setpoint.flag_control_climb_rate_enabled; reply.mode_req_local_position = config_control_setpoint.flag_control_position_enabled || config_control_setpoint.flag_control_velocity_enabled;
  1. 应用请求:若请求中should_apply == true,则将mode.current_setpoint_type更新为该校验通过的设定点类型(函数返回had_update = true,触发 commander 后续的模式状态刷新);should_apply == false时仅作"预检"用途——不改变当前配置,仅让外部模式确认该设定点类型在当前机型的可用性;
  2. 发布应答:填充timestamp后通过_setpoint_config_reply_pub.publish(reply)发布setpoint_config_reply(订阅/发布句柄定义见 ModeManagement.hpp)。

需要特别说明的是:mode_req_*标志只是 PX4 对"使用该设定点类型需要开启哪些控制回路"的声明,PX4 本身不会据此执行武装检查,而是由外部模式自行把这些标志应用到它的武装检查应答(arming check reply)中——这一点在原消息注释中已明确:"A mode will use these and apply them to the arming check reply (PX4 does not do that itself)."

模式需求标志的生成依据:setpoint_types 实现

mode_req_*四个字段并非独立配置,而是从mode_util::getControlMode()产出的控制模式标志推导而来。对应实现位于 src/modules/commander/ModeUtil/setpoint_types.cpp(枚举与接口声明见 setpoint_types.hpp),每种设定点类型映射到一组vehicle_control_mode标志,例如:

设定点类型触发的控制标志(节选)推导出的 mode_req
TYPE_TRAJECTORYrates + attitude + altitude + climb_rate + velocity + position四个mode_req_*全为 true
TYPE_RATESrates仅mode_req_angular_velocity为 true
TYPE_ATTITUDErates + attitudemode_req_angular_velocity与mode_req_attitude为 true
TYPE_DIRECT_ACTUATORS无控制标志四个mode_req_*全为 false
TYPE_POSITION_TRIPLETrates + attitude + altitude + climb_rate + velocity + position + auto四个mode_req_*全为 true

注意一个细节:mode_req_local_alt由flag_control_altitude_enabled || flag_control_climb_rate_enabled推导,mode_req_local_position由flag_control_position_enabled || flag_control_velocity_enabled推导,因此"仅提供速度/爬升率"的设定点类型也会被标记为需要本地位置/高度。正如原消息注释所提示的:某些设定点类型可以被降级使用(例如不带位置控制的TrajectorySetpoint),此时 PX4 仍然会置位全部需求标志,由外部模式自行忽略mode_req_local_position。

机型适配:isSetpointTypeValid 的过滤规则

应答中的result直接取决于mode_util::isSetpointTypeValid()(setpoint_types.cpp)的判定,规则如下:

  • 通用类型:TYPE_TRAJECTORY、TYPE_RATES、TYPE_ATTITUDE、TYPE_THRUST_AND_TORQUE、TYPE_POSITION_TRIPLET以及TYPE_DIRECT_ACTUATORS对所有机型返回RESULT_SUCCESS;
  • 多旋翼专用:TYPE_MULTICOPTER_GOTO仅当vehicle_type == VEHICLE_TYPE_ROTARY_WING时成功,否则RESULT_UNSUPPORTED;
  • 固定翼/VTOL 专用:TYPE_FIXEDWING_LATERAL_LONGITUDINAL仅当机型为固定翼或 VTOL 时成功;
  • 地面车专用:TYPE_ROVER_*系列仅当vehicle_type == VEHICLE_TYPE_ROVER时成功;
  • 航天器场景:TYPE_TRAJECTORY_6DOF在机型未指定(VEHICLE_TYPE_UNSPECIFIED)时成功——源码注释指出该类型供 spacecraft 使用,而这类载体通常不设置vehicle_type;
  • 兜底:TYPE_INVALID或超出枚举范围的值返回RESULT_UNKNOWN_SETPOINT_TYPE。

这正是RESULT_UNSUPPORTED(当前机型不支持该设定点类型)与RESULT_UNKNOWN_SETPOINT_TYPE(类型本身未知)两种错误码在代码层面的区分依据:前者是"类型合法但不适用于本机",后者是"类型值根本无法识别"。

典型使用流程与实战建议

结合以上实现,外部模式(例如通过 ROS 2 / DDS 或 Zenoh 连接的外部控制节点)使用这套接口的推荐流程为:

  1. 预检(不生效):发布SetpointConfig,should_apply = false,订阅setpoint_config_reply,检查result == RESULT_SUCCESS,确认当前机型支持目标设定点类型;此阶段不会改动 PX4 内部配置;
  2. 激活(生效):预检通过后重新发布请求,should_apply = true且source_id指向自身模式的nav_state,让 PX4 将该设定点类型设为当前模式的配置;若result != RESULT_SUCCESS,应根据RESULT_UNSUPPORTED/RESULT_UNKNOWN_SETPOINT_TYPE/RESULT_FAILURE_OTHER做差异化处理;
  3. 武装检查:读取应答中的mode_req_angular_velocity、mode_req_attitude、mode_req_local_alt、mode_req_local_position,将其合并到自己的武装检查应答中(PX4 不会代劳);
  4. 超时设置:通过请求消息的timeout_ms配置设定点超时(0 表示禁用),当超时时间内未收到设定点时 PX4 触发 failsafe——该字段不在应答中出现,但应答的成功与否决定了该配置是否被采纳。

需要留意应答的处理边界:commander 单次最多处理 5 个排队请求(max_updates = 5),因此高频率重复请求时,外部模式应按source_id+type匹配应答,而不是假设每次发布都会得到一条应答。

小结

SetpointConfigReply是 PX4 外部模式设定点协商机制中的应答侧消息:type/source_id回显请求身份,result表达机型适配性校验结果,四个mode_req_*标志向外部模式声明使用该设定点类型所需的控制回路,最终由外部模式自行用于武装检查。理解该消息后,你可以:

  • 在开发自定义外部模式时正确完成"预检 → 激活 → 武装检查"三步协商;
  • 通过RESULT枚举精确区分"不支持"与"未知类型"两种失败原因;
  • 借助 setpoint_types.cpp 与 ModeManagement.cpp 的源码,进一步定制或调试设定点类型与机型适配逻辑。

消息的规范定义文件为 msg/versioned/SetpointConfigReply.msg,请求侧消息见 SetpointConfig,应答生成的完整实现见 commander 模式管理模块。

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

【免费下载链接】PX4-Autopilot

PX4 Autopilot Software

项目地址:https://gitcode.com/gh_mirrors/px/PX4-Autopilot
点击查看免费下载
上一篇:DS4Windows 快速上手:把 PS4/PS5 手柄变成 PC 游戏认得的 Xbox 手柄
下一篇:ncmdumpGUI实测手记:把打不开的网易云ncm音乐转成通用MP3,全程只点了三次鼠标

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询