别再乱设THR_MDL_FAC了!一文讲透PX4 Offboard控制中推力与PWM的映射关系
深入解析PX4 Offboard控制中推力与PWM的精确映射关系
当你在PX4的Offboard模式下发布推力指令时,是否遇到过这样的困惑:明明发送了0.5的归一化推力,无人机却纹丝不动?这背后隐藏着一个关键参数THR_MDL_FAC,它决定了从控制指令到电机响应的整个映射链条。本文将带你深入PX4的控制内核,揭示推力指令如何一步步转化为PWM信号,以及如何根据你的电机特性正确配置这一关键参数。
1. 推力指令的完整处理链路
PX4固件处理Offboard推力指令的过程可以分解为三个关键阶段:
- 指令归一化处理:无论你通过MAVROS发送的是绝对推力值(单位:牛顿)还是归一化值(0-1范围),PX4都会将其转换为0-1之间的相对推力值
- 推力-信号模型转换:这是
THR_MDL_FAC发挥作用的阶段,将归一化推力转换为电机控制信号 - PWM信号输出:根据电机特性将控制信号映射为实际的PWM脉冲宽度
这个过程中最关键的转换发生在第二阶段,由以下公式定义:
rel_thrust = factor * rel_signal^2 + (1-factor) * rel_signal其中factor就是THR_MDL_FAC参数的值。这个看似简单的公式实际上定义了控制信号与推力之间的非线性关系。
2. THR_MDL_FAC参数的物理意义
THR_MDL_FAC参数本质上描述了你的电机系统对PWM输入的响应特性。理解这个参数需要从电机的基本物理特性入手。
2.1 电机推力产生的原理
无刷电机产生的推力与转速的平方成正比,这源于螺旋桨的空气动力学特性:
F = k * ω²其中:
F是单个电机产生的推力(牛顿)ω是电机转速(rad/s)k是推力系数,取决于螺旋桨尺寸、桨叶形状等
然而,电机的转速与输入的PWM信号通常呈线性关系:
ω = c * PWM因此,推力与PWM的关系就变成了:
F = k * (c * PWM)² = (k*c²) * PWM²2.2 参数设置的三种典型场景
根据电机系统的实际特性,THR_MDL_FAC有三种典型配置:
| 参数值 | 适用场景 | 数学关系 | 实际案例 |
|---|---|---|---|
| 0.0 | PWM与推力呈线性关系 | rel_thrust = rel_signal | 某些舵机或特殊执行机构 |
| 1.0 | PWM与推力呈平方关系 | rel_thrust = rel_signal² | 标准无刷电机+螺旋桨组合 |
| 0.5 | 混合模型 | rel_thrust = 0.5rel_signal² + 0.5rel_signal | 部分有刷电机系统 |
在Gazebo仿真中,默认的Iris模型使用的是平方关系,这也是为什么当THR_MDL_FAC=0时无人机会无法起飞——控制系统和仿真模型对推力生成的理解不一致。
3. 实际应用中的参数调试方法
正确设置THR_MDL_FAC需要结合实验数据和系统特性。以下是详细的调试流程:
3.1 静态推力测试步骤
- 将无人机固定在测试平台上,确保可以测量垂直方向推力
- 通过QGC参数界面将
THR_MDL_FAC设为初始值(通常从1.0开始) - 使用MAVROS发布一系列归一化推力指令(如0.1, 0.2,...,1.0)
- 记录每个指令对应的实际推力值
- 绘制"指令-推力"曲线,分析其符合哪种数学模型
3.2 参数优化技巧
- 平方关系明显:当测量数据显示推力与指令呈明显的二次曲线关系时,保持
THR_MDL_FAC=1.0 - 接近线性关系:如果推力响应接近直线,设置为
THR_MDL_FAC=0.0 - 中间状态:当数据点位于两者之间时,可以通过曲线拟合确定最佳factor值
一个实用的Python代码片段,用于分析测试数据:
import numpy as np from scipy.optimize import curve_fit # 测试数据示例:指令值 vs 测量推力(归一化) commands = np.array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]) thrusts = np.array([0.12, 0.23, 0.34, 0.45, 0.56, 0.68, 0.79, 0.91, 1.04, 1.18]) def model(x, factor): return factor * x**2 + (1-factor) * x popt, pcov = curve_fit(model, commands, thrusts) optimal_factor = popt[0] # 这就是最佳的THR_MDL_FAC值4. 高级应用场景与问题排查
4.1 混合动力系统的特殊处理
某些无人机可能使用不同类型的电机组合,例如:
- 主升力电机(无刷+螺旋桨,平方关系)
- 矢量推力电机(舵机控制,线性关系)
这种情况下可以考虑:
- 为不同电机组设置不同的映射参数(需要修改PX4固件)
- 使用折衷的
THR_MDL_FAC值,并通过控制分配矩阵补偿差异 - 在硬件上添加线性化电路或机械装置
4.2 常见问题与解决方案
问题1:悬停时推力不稳定,无人机上下振荡
- 可能原因:
THR_MDL_FAC设置错误导致推力响应非线性 - 解决方案:重新进行静态推力测试,确保参数与实际特性匹配
问题2:大推力指令时电机响应迟缓
- 可能原因:平方关系导致高推力区灵敏度降低
- 解决方案:在控制器中添加非线性补偿,或调整油门曲线
问题3:仿真中能起飞,但实物无法离地
- 可能原因:仿真模型与实物电机特性不一致
- 解决方案:确保仿真SDF文件中的motorConstant与实物匹配
5. 性能优化与系统集成
理解推力映射关系后,可以进一步优化整个控制系统:
5.1 控制器的非线性补偿
在位置或速度控制器前添加逆模型,消除非线性影响:
def inverse_thrust_model(desired_thrust, factor): # 解二次方程 factor*x² + (1-factor)*x - desired_thrust = 0 a = factor b = 1 - factor c = -desired_thrust discriminant = b**2 - 4*a*c return (-b + np.sqrt(discriminant)) / (2*a)5.2 与姿态控制的协同工作
推力映射的准确性直接影响姿态控制性能,因为:
- 姿态误差通过PID控制器产生推力修正量
- 这些修正量需要准确映射为电机响应
- 错误的映射会导致超调或响应不足
建议调试顺序:
- 先在地面静态测试中调好
THR_MDL_FAC - 在悬停测试中微调姿态控制参数
- 最后进行动态飞行测试
在实际项目中,我曾遇到过一个典型案例:无人机在高速转弯时总是失稳。经过数据分析发现,问题根源正是THR_MDL_FAC设置不当导致大推力指令下的响应非线性,修正参数后问题立即解决。这提醒我们,底层参数的正确理解往往能解决看似复杂的控制问题。
