跳转至

动力学

LAV2 面向陆空两栖与飞行平台提供统一的动力学参数与接口框架。当前实现将动力学组织为一个共享参数对象,以及若干与执行形式相关的模型实现,便于本地 MuJoCo runner 与 GPU / 任务后端围绕同一套物理常数与接口假设保持一致。这里的模块拆分主要服务于实现组织与数值计算,并不意味着旋翼与接触动力学在物理上已经被完全解耦;例如升力对接触力的影响等耦合关系,当前实现尚未进一步建模。

机体参数

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

  • 环境参数
  • 机身参数
  • 螺旋桨参数
  • 履带参数
  • 与 PX4 对齐的参数

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

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

在模块结构层面,具体动力学实现统一组织在 DynamicsBase 这一公共接口之下,因此旋翼、履带、以及并行后端版本都遵循相同的生命周期与参数归属模式。

时间尺度:sim_dtstep_dt

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

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

旋翼动力学

RotorDynamics 将每个旋翼的 RPM 命令转换为一个 8 维输出向量:

  • 前 4 个量:推力
  • 后 4 个量:反扭矩

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

\[ f_i = c_T \omega_i^2 \]
\[ \tau_i = \left(c_M \omega_i^2 + J_m \dot{\omega}_i\right) d_i \]

其中,\(\omega_i\) 表示旋翼转速,\(f_i\) 表示推力,\(\tau_i\) 表示反扭矩,\(c_T\)\(c_M\) 分别是推力与扭矩系数,\(J_m\) 是电机转动惯量,\(d_i \in \{+1, -1\}\) 用于编码旋翼旋向。实际滤波更新中,还会使用独立的上升/下降时间常数,并对 RPM 变化率做显式裁剪。

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

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

履带动力学

TrackDynamics 对左右履带命令建模,并返回一个 (2, n_w, 2) 形状的数组:

  • 第 0 维:左、右履带两侧
  • 第 1 维:每一侧的轮/接触点
  • 第 2 维:平面力分量 (Fx, Fy)

在当前阶段,对用户来说最关键的理解是:这个模块会根据左右履带命令与机体平面运动,计算各个接触点上的驱动力分布,而本地仿真就是通过这些力来施加履带侧推进效果。

状态与命令约定

本地 runner 使用与控制器接口一致的紧凑状态切片:

  • 旋翼模式动力学消费形状为 (4,) 的电机 RPM 命令
  • 履带模式动力学消费形状为 (2,) 的左右履带命令
  • 履带滑移计算会读取机体系 [u, v, r]

在控制器侧,飞行状态 / 目标向量使用 12 个通道,顺序为:

[x, y, z, vx, vy, vz, roll, pitch, yaw, wx, wy, wz]

履带状态 / 目标向量使用 6 个通道,顺序为:

[x, y, yaw, u, v, r]

理解这些布局之后,再去阅读本地模拟器和各类任务封装会容易很多。

并行后端一致性

lav2/dynamics/torch/ 下的 Torch 实现镜像了 NumPy 版 API,从而让大规模并行训练可以复用同一套动力学逻辑。未来如果引入其它计算框架,例如 JAX 或 Warp,也应遵循相同规则。

当某个动力学模块在 NumPy 路径下新增实现时,并行后端应在各自框架目录下添加同名版本,并在除环境维度以外的行为上保持一致。换句话说,批量实现可以增加额外的 env 轴,但底层的状态、命令与输出语义应保持不变。

API 交叉引用