跳转至

动力学

LAV2 面向陆空两栖与飞行平台提供统一的动力学参数与接口框架。其实现将动力学组织为一个共享参数对象,以及若干与执行形式相关的模型实现,使得本地 MuJoCo 运行器与 GPU/任务端后端能够在相同的物理常数和接口约定上保持一致。

已知建模限制

这里的模块拆分主要服务于实现组织与数值计算,并不意味着旋翼与接触动力学在物理上已经被完全解耦。例如升力对接触力的影响等耦合关系,尚未进一步建模。

机体参数

VehicleParams 是平台最核心的参数接口。它将机体描述划分为:

  • 环境参数
  • 机身参数
  • 螺旋桨参数
  • 地面驱动参数
  • 与 PX4 对齐的参数

其中一部分值来自直接配置,另一部分则会在 __post_init__ 中派生出来,例如推力与反扭矩系数、默认初始 RPM,以及悬停油门相关量。因此在实际使用中,VehicleParams 不仅定义平台的原始常数,也定义了下游动力学与控制器真正消费的量。

需要质量、惯量、仿真步长、旋翼系数或驱动几何参数时,应优先从 VehicleParams 出发,而不是把相关字面量散落在各个模块中。

在模块结构层面,显式动力学实现统一组织在 DynamicsBase 这一公共接口之下。地面接触由轮组几何与仿真器接触约束表示,不再使用独立的解析履带外力模块。

时间尺度:sim_dt 与 step_dt

一旦同一套动力学被放到本地单速率模拟器之外使用,这两个时间参数就会变得非常重要。sim_dt 表示执行器与物理积分步长,而 step_dt 表示控制器更新步长。

在带 decimation 的框架中,例如 Isaac Lab,这两者往往并不相同,因为物理引擎的步进频率通常高于控制策略或命令更新频率。当后续引入高层与低层策略异步运行时,这种区分也同样重要。把这两个字段统一保存在 VehicleParams 中,可以避免将频率假设隐含在单个模块内部。

旋翼动力学

RotorDynamics 将每个旋翼的 RPM 命令转换为一个批量 (N, 8) 输出数组:

  • 每个环境的前 4 个量:推力
  • 每个环境的后 4 个量:反扭矩

它的更新规则遵循标准的旋翼模型结构。命令转速不会被瞬时施加,而是先经过滤波与速率限制;随后根据旋翼速度与电机角加速度计算推力与反扭矩:

\[ f_i = c_T \omega_i^2 \]
\[ \tau_i = c_M \omega_i^2 d_i \]

其中,\(\omega_i\) 表示旋翼转速,\(f_i\) 表示推力,\(\tau_i\) 表示反扭矩,\(c_T\) 与\(c_M\) 分别是推力与扭矩系数,\(d_i \in \{+1, -1\}\) 通过 VehicleParams.spin_dir 编码旋翼旋向;约定 +1 为顺时针,-1 为逆时针。实际滤波更新中,还会使用独立的上升/下降时间常数,并对 RPM 变化率做显式裁剪。

要让这个模型真正有意义,它必须和真实平台参数保持一致,尤其包括:

  • 初始旋翼转速
  • 电机惯量与时间常数
  • 推力与扭矩系数
  • 最大 RPM
  • 旋翼旋向

气动效应

可选气动层组合了机体阻力、给定外力、地面效应与近壁面效应。地面效应与壁面效应依次修正各旋翼的力,阻力和给定外力作用于机体。表面几何在各环境的局部世界系中计算,力及力遥测使用车辆机体系;后端适配层将每个旋翼的气动力增量转换到对应旋翼 link 坐标系,与标称旋翼力叠加后逐旋翼施加。四种效应默认均关闭。

机体阻力与给定外力

令 \(R_{wb}\) 将机体系向量旋转到世界系,\(R_{bw}=R_{wb}^{\mathsf T}\),且 \(\mathbf v^b=R_{bw}\mathbf v^w\)。当前机体外力模型为

\[ \mathbf F_{\mathrm{body}}^b =-\mathbf C_{\mathrm{drag}}\mathbf v^b +R_{bw}\mathbf F_{\mathrm{ext}}^w, \]

其中 \(\mathbf C_{\mathrm{drag}}\) 为对角矩阵,单位为 N s/m,\(\mathbf F_{\mathrm{ext}}^w\) 是给定的世界系外力。这是 Pegasus 中质量归一化线性阻力的力形式:若其加速度系数为 \(\mathbf D\),则 \(\mathbf C_{\mathrm{drag}}=m\mathbf D\)。

\(\mathbf F_{\mathrm{ext}}^w\) 表示给定扰动。若后续扩展为物理风场,可根据相对空速和经辨识的气动关系计算作用力。

逐旋翼地面效应

对第 \(i\) 个旋翼,LAV2 采用以下逐旋翼逆比值模型:

\[ \frac{\lVert\mathbf T_{\mathrm{pre},i}\rVert} {\lVert\mathbf T_{\mathrm{ge},i}\rVert} =1-\kappa_g\left(\frac{r_p}{4z_i}\right)^2. \]

这里 \(r_p\) 是桨叶半径,\(z_i\) 是沿推力反方向到地面的距离,\(\kappa_g\) 是无量纲辨识系数。\(\kappa_g=1\) 对应面向直升机旋翼的 Cheeseman--Bennett 镜像理论关系。Kan 等人的小型无人机实验表明,基于悬停推导的模型迁移到多旋翼前飞状态时会产生较大误差。因此,LAV2 保留经验默认值 \(\kappa_g=0.171\) 作为微型多旋翼的初始值,再通过具体平台的系统辨识确定任务参数。由于该逆比值模型在某些系数和很小的 \(z_i\) 下存在奇点,max_ground_effect_gain 会限制最终推力倍率(默认最大为 2),避免无界放大。

部分实现将分母写成 \(b-\kappa_g(r_p/(4z_i))^2\)。其中 \(b\) 由远场条件固定为 1:当 \(z_i\to\infty\) 时,\(\lVert\mathbf T_{\mathrm{pre},i}\rVert/\lVert\mathbf T_{\mathrm{ge},i}\rVert\to1\)。若辨识得到 \(b\ne1\),它表示与高度无关的整体推力比例,更适合归入基础旋翼推力标定。因此,LAV2 的可配置系数对应 ground_effect_k,而 ground_effect_b=1 隐含在公式中。

MuJoCo-Drones-Gym(arXiv:2606.08039)采用的是整机附加力:

\[ \Delta F_z^{\mathrm{gnd}} =C_{\mathrm{gnd}}\sum_i\lVert\mathbf T_i\rVert \left(\frac{r_p}{4h}\right)^2. \]

在弱地效条件下展开 LAV2 的逆比值,可得 \(\Delta T_i\approx\kappa_g T_i(r_p/(4z_i))^2\);当各旋翼高度相同且 \(C_{\mathrm{gnd}}=\kappa_g\) 时,两种写法一阶一致。逐旋翼形式可以表达桌边、倾斜姿态或局部表面产生的非对称合力与力矩。MuJoCo-Drones-Gym 将该附加项归于 Neural Lander,而 Neural Lander 本身采用学习方法描述未建模近地气动力;因此上面的解析关系追溯至 Cheeseman--Bennett。

逐旋翼壁面效应

对于壁面,令 \(d_i\) 为桨尖到壁面的净距,\(\bar d_i=d_i/r_p\),\(\mathbf e_3\) 为世界系竖直方向,\(\mathbf e_d\) 为旋翼指向壁面的方向。LAV2 实现 Ding 等人的经验模型:

\[ \begin{aligned} \mathbf T_{0,i}&=(\mathbf T_{\mathrm{ge},i}^{\mathsf T}\mathbf e_3)\mathbf e_3,\\ \gamma_h(\bar d_i)&=a_1b_1^{\bar d_i},\\ \gamma_v(\bar d_i)&=1+a_2b_2^{\bar d_i},\\ \mathbf T_{h,i}&=\gamma_h(\bar d_i)\lVert\mathbf T_{0,i}\rVert\mathbf e_d +(\mathbf T_{\mathrm{ge},i}-\mathbf T_{0,i}),\\ \mathbf T_{v,i}&=\gamma_v(\bar d_i)\lVert\mathbf T_{0,i}\rVert\mathbf e_3,\\ \mathbf T_{\mathrm{act},i}&=\mathbf T_{h,i}+\mathbf T_{v,i}. \end{aligned} \]

Ding 等人用半径 38 mm 的涵道桨实验数据最小二乘拟合得到 \((a_1,b_1,a_2,b_2)=(0.21,0.34,0.06,0.54)\)。其推导假设准稳态、不可压、无黏、无旋且密度恒定,并忽略壁面与涵道引起的阻力。这组参数和近似直立飞行假设可作为小型多旋翼的初始模型;对于不同的旋翼、涵道、姿态范围或机体布局,可通过系统辨识更新参数。

相关模型族

MuJoCo-Drones-Gym 还包含三类相关模型:

  • 其桨叶阻力模型引用 Förster 对 Crazyflie 2.0 的系统辨识结果,将机体系速度再乘以旋翼角速度之和;LAV2 当前采用固定线性机体阻力。两类模型使用各自的系数单位和辨识数据。
  • 其稳态风使用相对空速二次阻力,阵风与 Dryden 模型还引入时变过程,其中 Dryden 尺度来自 MIL-F-8785C。这些模型可作为 LAV2 当前给定外力的后续扩展。
  • 其下洗公式及系数针对上下排列的 Crazyflie。下洗更适合后续多机任务。

表面距离目前针对无限解析地面和壁面平面计算。set_wall_plane() 可以为每个环境更新一个平面;有限边缘和运动表面的自动更新仍属于场景层扩展。扰动力和距离属于仿真特权状态;若作为可部署策略的 actor 观测,需要配套实机传感器或估计器。

参考文献:

  • Cheeseman 与 Bennett,《The Effect of the Ground on a Helicopter Rotor in Forward Flight》,ARC Reports and Memoranda No. 3021,1955。
  • Jacinto 等人,《Pegasus Simulator》,ICUAS 2024,doi:10.1109/ICUAS60882.2024.10556959。
  • Kan 等人,《Analysis of Ground Effect for Small-Scale UAVs in Forward Flight》,RA-L 2019,doi:10.1109/LRA.2019.2929993。
  • Ding 等人,《Aerodynamic Effect for Collision-Free Reactive Navigation of a Small Quadcopter》,npj Robotics 2023,doi:10.1038/s44182-023-00002-9。
  • Förster,《System Identification of the Crazyflie 2.0 Nano Quadrocopter》,ETH Zürich 硕士论文,2015。
  • Shi 等人,《Neural Lander》,ICRA 2019,doi:10.1109/ICRA.2019.8794351。
  • Tayal,《MuJoCo-Drones-Gym》,2026,arXiv:2606.08039。
  • 美国国防部,MIL-F-8785C,1980。

与 PX4 SITL Gazebo Classic 的对照

PX4 SITL Gazebo Classic 可以作为逐旋翼气动力实现的参考,但不能直接 替代 LAV2 的气动模型。其多旋翼 motor 插件根据旋翼速度计算推力,按旋翼 轴向相对气流削弱推力,并加入与转速相关的桨盘内阻力、反扭矩和滚转力矩; 风速以世界系相对速度进入 motor 模型的相对气流计算。可参考 gazebo_motor_model.cpp 以及 Iris 的参数文件 iris.sdf.jinja。

PX4 Classic 的多旋翼路径没有提供 LAV2 当前的解析地效和壁效,因此 PX4 的电机与阻力系数只能作为后续旋翼阻力建模的参考,不能直接用作 LAV2 的壁效参数。

地面驱动执行器

地面平台使用关节化轮组与仿真器接触模型。在 MuJoCo 中,LAV2 将左右输出轴速度目标分别发送给每侧唯一的主动关节,再通过 equality 约束同步主动轮与承重轮组;ATMO 同样每侧只使用一个闭环速度伺服器,并用 equality 约束表示前后轮壳之间的同步带传动。

Isaac Lab 沿用相同的二维侧速度目标和“每侧一个主动关节”契约。当前 LAV2 与 ATMO USD 仍需后续补齐与 MJCF 一致的关节拓扑和机械耦合;不能通过向从动关节重复下发 ActionTerm 目标来替代资产级耦合。

这样可以明确分离控制器、actuator 与接触职责:DifferentialDriveController 负责底盘级命令分配,平台适配层把每侧目标映射到物理关节,速度伺服器按配置的增益与力矩上限输出,物理引擎负责求解轮地作用力。当命令是轮速时,速度伺服增益是闭环跟踪增益,不能用开环 DC 电机的转矩—转速斜率代替。

GroundDriveActuatorAdapter 表示从实车响应日志中辨识得到的 actuator 侧效应。它接收批量的理想左右输出轴目标,在不改变控制器物理轮距的前提下施加标定后的偏航分配比例,在侧速度限幅时保持共模/差模命令关系,并以物理频率推进左右独立的指令延迟。runner 只负责把该模型连接到后端 actuator,不再持有传动响应语义。 同一个批量模型通过 randomize() 提供相对标称值的逐环境偏航比例与左右增益采样。Isaac Lab 由 reset event 调用该方法,在这里将指令延迟保持为零,并继续使用官方 DelayedPDActuator 实现随机延迟、闭环速度响应与力矩限幅。

状态与命令约定

所有控制器与轨迹接口使用字典形式的状态与目标对象。所有状态数组均为批量形式,带有一个前导环境维度 N(num_envs)。整个控制栈使用的字典键如下:

键 形状 单位 描述
pos (N, 3) m 世界坐标系位置
vel (N, 3) m/s 世界坐标系速度
vel_b (N, 3) m/s 机体系速度
att_euler (N, 3) rad 横滚、俯仰、偏航(XYZ 内旋)
att_quat (N, 4) — 四元数(xyzw)
att_rotmat (N, 9) — 旋转矩阵(行主序展平)
ang_vel (N, 3) rad/s 机体系角速度
thrust (N, 1) N 总推力目标

飞行状态字典包含 pos、vel、att_euler、att_quat、att_rotmat 与 ang_vel。地面控制器状态字典包含 pos、att_euler、vel_b 与 ang_vel(注意此处使用 vel_b 而非 vel)。

飞行与地面控制器都遵循 ControllerBase 的更新签名:update(target: dict, state: dict) -> ArrayLike。control_mask 字典控制哪些目标通道由外部提供、哪些由级联内部生成。

当 N = 1(单环境)时,批量形状仍为 (1, 3)、(1, 4) 等。前导环境维度是所有后端共享的 Array API 接口约定。

明确上述字典约定之后,再去阅读本地模拟器、控制器栈和各类任务封装会容易很多。

并行后端一致性

lav2/dynamics/ 下的顶层模块是后端无关的 Array API 实现,通过 self._xp 分发,同一份代码支持 NumPy、Torch、JAX 和 CuPy。

API 交叉引用