chrono车辆仿真_09_动力总成系统详解

动力总成系统详解

一、动力总成的角色:车辆的动力源

1.1 什么是动力总成?

车辆要运动,需要三样东西:产生动力 、转换动力 、传递动力。

复制代码
驾驶员踩油门
      │
      ▼
   ┌────────────────────────────────────────────────┐
   │              动力总成 (Powertrain)               │
   │                                                │
   │   ┌──────────┐      ┌──────────────────┐       │
   │   │  ChEngine│      │ ChTransmission   │       │
   │   │  发动机   │─────▶│    变速箱         │       │
   │   │          │ 扭矩  │   变矩变速        │       │
   │   └──────────┘      └────────┬─────────┘       │
   │                               │                │
   └───────────────────────────────┼────────────────┘
                                   │ driveshaft_torque
                                   ▼
                            ChDrivelineWV
                              传动线
                                   │
                                   ▼
                             车轮驱动车辆

Chrono 的设计哲学:动力总成是车辆的"可选插件"。一个车辆可以没有动力总成(被拖拽、纯运动学仿真),也可以自由组合不同类型的发动机和变速箱。

1.2 三者的职责划分

组件 类的角色 所属继承体系 归属关系
ChPowertrainAssembly 聚合外壳,协调 Engine↔Transmission 独立类(不继承 ChPart) ChVehicle 持有
ChEngine 产生扭矩(燃油→旋转动能) ChPart 派生 被 PowertrainAssembly 持有
ChTransmission 转换扭矩(变矩变速) ChPart 派生 被 PowertrainAssembly 持有
ChDrivelineWV 分配扭矩到各驱动轮 ChPart 派生 ChWheeledVehicle 直接持有(不在 PowertrainAssembly 内)

二、ChPowertrainAssembly:协调者

2.1 类定义全景

cpp 复制代码
class CH_VEHICLE_API ChPowertrainAssembly {
  public:
    ChPowertrainAssembly(std::shared_ptr<ChEngine> engine,
                         std::shared_ptr<ChTransmission> transmission);
    
    // 访问器
    const std::shared_ptr<ChEngine> GetEngine() const;
    const std::shared_ptr<ChTransmission> GetTransmission() const;
    
    // 对外输出:变速箱输出到传动线的力矩
    double GetOutputTorque() const;  // = m_transmission->GetOutputDriveshaftTorque()
    
    void Initialize(std::shared_ptr<ChChassis> chassis);
    void Synchronize(double time, const DriverInputs& driver_inputs, double driveshaft_speed);
    void Advance(double step);

  private:
    std::shared_ptr<ChEngine> m_engine;
    std::shared_ptr<ChTransmission> m_transmission;
};

2.2 ChPowertrainAssembly 不是 ChPart

这是理解动力总成的关键 :ChPowertrainAssembly 不继承 ChPart,它只是一个聚合容器。

为什么这么设计?

复制代码
ChPart 的职责:
  - 身份管理(名字、模板名)
  - 质量/惯性聚合(递归 AddMass/AddInertiaProperties)
  - 可视化
  - JSON 序列化

ChPowertrainAssembly:
  - 它本身没有质量和惯性(质量在 Engine/Transmission 的 ChShaft 中)
  - 它只是一个"中间人",负责协调 Engine ↔ Transmission 之间的数据交换
  - 不需要参与 ChVehicle 的质量聚合递归

2.3 Initialize:分别初始化两个子系统

cpp 复制代码
void ChPowertrainAssembly::Initialize(std::shared_ptr<ChChassis> chassis) {
    m_engine->Initialize(chassis);
    m_transmission->Initialize(chassis);
}

只做两件简单的事:把发动机挂到底盘上,把变速箱也挂到底盘上。

2.4 Synchronize:Engine ↔ Transmission 闭环

cpp 复制代码
void ChPowertrainAssembly::Synchronize(double time,
                                        const DriverInputs& driver_inputs,
                                        double driveshaft_speed) {
    // 第一步:取样------"读取上一时刻的输出"
    double motorshaft_torque = m_engine->GetOutputMotorshaftTorque();
    double motorshaft_speed = m_transmission->GetOutputMotorshaftSpeed();

    // 第二步:同步------"用旧值更新新状态"
    m_engine->Synchronize(time, driver_inputs, motorshaft_speed);
    m_transmission->Synchronize(time, driver_inputs, motorshaft_torque, driveshaft_speed);
}

这是整个动力总成最核心的逻辑。注意一个关键细节:存在半步延迟。

复制代码
时间步 t-1                       时间步 t                              时间步 t+1
  │                                │                                     │
  │  Engine 输出 motorshaft_torque  │                                     │
  │  Transmission 输出 motorshaft_speed                                   │
  │                                │                                     │
  └─────────────▶  PowertrainAssembly.Synchronize(t)                     │
                   │                                                     │
                   │ ① 取 t-1 时刻的输出值                                 │
                   │   motorshaft_torque = Engine(t-1)  ◀── 旧值          │
                   │   motorshaft_speed = Transmission(t-1) ◀── 旧值      │
                   │                                                     │
                   │ ② 用旧值同步 t 时刻的状态                              │
                   │   Engine.Synchronize(t, motorshaft_speed)           │
                   │     ← 变速箱说"你现在该转多快"                          │
                   │   Transmission.Synchronize(t, motorshaft_torque,    │
                   │                          driveshaft_speed)          │
                   │     ← 发动机会"我给了多大力",传动线说"负载多大"           │
                   │                                                     │
                   ▼                                                     │
              引擎和变速箱状态更新完毕 ◀─────────────────────────────────────│

2.5 ChVehicle 中 PowertrainAssembly 的使用

在 ChVehicle 层面,动力总成是一个可选成员:

cpp 复制代码
class ChVehicle {
  protected:
    std::shared_ptr<ChPowertrainAssembly> m_powertrain_assembly;  // 可选持有
};

在派生类 ChWheeledVehicle 的 Synchronize 中,动力总成与传动线配合:

cpp 复制代码
void ChWheeledVehicle::Synchronize(...) {
    // ... 车架同步 ...

    // 是否存在动力总成?
    if (m_powertrain_assembly) {
        // ① 从传动线获取当前驱动轴转速(反馈)
        double driveshaft_speed = m_driveline->GetOutputDriveshaftSpeed();
        
        // ② 同步动力总成(发动机 + 变速箱)
        m_powertrain_assembly->Synchronize(time, driver_inputs, driveshaft_speed);
        
        // ③ 获取变速箱输出力矩,传给传动线
        double powertrain_torque = m_powertrain_assembly->GetOutputTorque();
        m_driveline->Synchronize(time, driver_inputs, powertrain_torque);
    }

    // ... 车轴同步、转向同步 ...
}

三、ChEngine:动力之源

3.1 基类定义

cpp 复制代码
class CH_VEHICLE_API ChEngine : public ChPart {
  public:
    // 当前发动机转速 (rad/s)
    virtual double GetMotorSpeed() const = 0;
    
    // 曲轴输出力矩 (N·m) ------ 传给变速箱
    virtual double GetOutputMotorshaftTorque() const = 0;

  protected:
    void Initialize(std::shared_ptr<ChChassis> chassis);
    
    void Synchronize(double time, 
                     const DriverInputs& driver_inputs,  // 油门 [0,1]
                     double motorshaft_speed);           // 变速箱反馈的转速
    void Advance(double step) {}
};

3.2 两条发动机路线

Chrono 提供两种完全不同的发动机模型:

复制代码
                    ChEngine (抽象基类)
                         │
          ┌──────────────┴──────────────┐
          │                             │
    ChEngineSimple               ChEngineShafts
    ChEngineSimpleMap            (基于 ChShaft 物理元素)
    (纯数学计算)
          │                             │
          │                             │
    经验模型 ------ 快、轻量        物理模型 ------ 真实、精确
    无 ChSystem 耦合             ChShaft 加入 ChSystem
    Advance() 空操作            Advance() 空操作(由系统推进)
3.2.1 ChEngineSimpleMap --- 查表发动机

原理:使用两条转速-力矩曲线,线性插值。

复制代码
扭矩 (N·m)
  │
  │   Map Full Throttle (节气门全开)
  │       ╱╲
  │      ╱  ╲
  │     ╱    ╲
  │    ╱      ╲
  │   ╱        ╲
  │  ╱          ╲
  │ ──────────────── Map Zero Throttle (零节气门,通常是负值=制动)
  │                ╲
  └───────────────────────▶ 转速 (rad/s)
                     怠速             最大转速

Synchronize 实现:

cpp 复制代码
void ChEngineSimpleMap::Synchronize(double time, 
                                     const DriverInputs& inputs,
                                     double motorshaft_speed) {
    // 限制转速范围
    m_motor_speed = Clamp(motorshaft_speed, 0.0, GetMaxEngineSpeed());

    // 查两条曲线
    double fullThrottleTorque = m_full_throttle_map.GetVal(m_motor_speed);
    double zeroThrottleTorque = m_zero_throttle_map.GetVal(m_motor_speed);

    // 线性插值:throttle=0 时走零节气门曲线,throttle=1 时走满节气门曲线
    m_motor_torque = zeroThrottleTorque * (1 - throttle) 
                   + fullThrottleTorque * throttle;
}

特点:

  • 无 ChShaft 物理对象
  • Advance() 为空
  • 发动机转速由变速箱反馈直接设置
  • JSON 配置示例(G500):
json 复制代码
{
  "Name": "G500 Simple Map Engine",
  "Type": "Engine",
  "Template": "EngineSimpleMap",
  "Maximal Engine Speed RPM": 5900,
  "Map Full Throttle": [
    [ -10.0, 240.0 ], [ 1000.0, 400.0 ], [ 1500.0, 500.0 ],
    [ 1800.0, 550.0 ], [ 2250.0, 610.0 ], [ 4750.0, 610.0 ],
    [ 5250.0, 565.0 ], [ 5500.0, 539.0 ], [ 5800.0, 450.0 ],
    [ 5900.0, -100.0 ], [ 5950.0, -200.0 ]
  ],
  "Map Zero Throttle": [
    [ -10.0, 0.0 ], [ 10.0, 0.0 ], [ 1000.0, -10.0 ],
    [ 1500.0, -10.0 ], [ 1800.0, -15.0 ], [ 2250.0, -15.0 ],
    [ 4750.0, -15.0 ], [ 5250.0, -20.0 ], [ 5500.0, -20.0 ],
    [ 5800.0, -20.0 ], [ 5900.0, -100.0 ], [ 5950.0, -200.0 ]
  ]
}
3.2.2 ChEngineSimple --- 更简化的发动机

比 SimpleMap 更简单,使用双曲线公式而非查表:

cpp 复制代码
void ChEngineSimple::Synchronize(...) {
    m_motor_speed = motorshaft_speed;
    
    // 双曲线扭矩曲线(类似直流电机或 CVT)
    if (m_motor_speed <= m_critical_speed) {
        m_motor_torque = GetMaxTorque();  // 恒扭矩区
    } else {
        m_motor_torque = GetMaxPower() / m_motor_speed;  // 恒功率区
    }

    // 超速断油
    if (m_motor_speed >= GetMaxSpeed()) m_motor_torque = 0;

    // 油门调制
    m_motor_torque *= driver_inputs.m_throttle;
}
3.2.3 ChEngineShafts --- 基于 ChShaft 的物理发动机

原理:创建真实的 ChShaft 旋转轴,通过 ChShaftsThermalEngine 物理元素模拟热力发动机。

复制代码
                      ┌───────────────────┐
                      │  ChSystem 物理世界  │
                      │                    │
                      │  ChBody (底盘)     │
                      │    ↑              │
                      │    │ ChShaftBodyRotation  │
                      │    │              │
                      │  ChShaft (motorblock)  │
                      │    ↑              │
                      │    │ ChShaftsThermalEngine  │
                      │    │ (+, - 对偶作用力)  │
                      │  ChShaft (motorshaft)  │  ←→ 连接到变速箱
                      │                    │
                      └───────────────────┘

Initialize 实现:

cpp 复制代码
void ChEngineShafts::Initialize(std::shared_ptr<ChChassis> chassis) {
    auto sys = chassis->GetSystem();

    // ① 创建电机轴(曲轴+飞轮的转动惯量)
    m_motorshaft = make_shared<ChShaft>();
    m_motorshaft->SetInertia(GetMotorshaftInertia());  // 曲轴转动惯量
    sys->AddShaft(m_motorshaft);

    // ② 创建电机壳体
    m_motorblock = make_shared<ChShaft>();
    m_motorblock->SetInertia(GetMotorBlockInertia());
    sys->AddShaft(m_motorblock);

    // ③ 将壳体连接到 3D 底盘刚体(产生"反力矩"------加速时车会仰头)
    m_motorblock_to_body = make_shared<ChShaftBodyRotation>();
    m_motorblock_to_body->Initialize(m_motorblock, chassis->GetBody(), dir);
    sys->Add(m_motorblock_to_body);

    // ④ 创建热力发动机模型(连接壳体↔曲轴)
    m_engine = make_shared<ChShaftsThermalEngine>();
    m_engine->Initialize(m_motorshaft, m_motorblock);
    m_engine->SetTorqueCurve(mTw);  // 设置扭矩-转速曲线
    sys->Add(m_engine);

    // ⑤ 创建发动机损失模型(摩擦、泵气损失等)
    m_engine_losses = make_shared<ChShaftsThermalEngine>();
    m_engine_losses->Initialize(m_motorshaft, m_motorblock);
    m_engine_losses->SetTorqueCurve(mTw_losses);
    sys->Add(m_engine_losses);
}

Synchronize 实现:

cpp 复制代码
void ChEngineShafts::Synchronize(double time, 
                                  const DriverInputs& driver_inputs,
                                  double motorshaft_speed) {
    // 由变速箱反馈设置曲轴转速
    m_motorshaft->SetPosDt(motorshaft_speed);

    // 更新节气门(throttle → 热机模型的燃烧力矩)
    m_engine->SetThrottle(driver_inputs.m_throttle);
}

输出力矩:

cpp 复制代码
double ChEngineShafts::GetOutputMotorshaftTorque() const {
    // 热机正力矩 + 摩擦损失负力矩
    return m_engine->GetReaction1() + m_engine_losses->GetReaction1();
}

特点:

  • 创建真实的 ChShaft 物理元素,质量/惯性由 ChSystem 管理
  • 反力矩效应:ChShaftBodyRotation 将发动机壳体的反作用力矩传递到底盘------急加速时车头仰起
  • 需要底盘已添加到 ChSystem 后才能初始化
  • Advance() 为空操作------ChShaft 的状态由 ChSystem::DoStepDynamics 自动推进

3.3 三种发动机对比

维度 ChEngineSimple ChEngineSimpleMap ChEngineShafts
物理对象 无 无 ChShaft + ChShaftsThermalEngine
扭矩来源 双曲线公式 查转速-力矩表线性插值 ChShaftsThermalEngine 物理求解
发动机损失 无 零节气门曲线(负扭矩) ChShaftsThermalEngine 损失模型
反力矩效应 无 无 有(ChShaftBodyRotation→底盘)
计算速度 最快 快 慢(额外约束求解)
JSON 配置量 3 个参数 ~20 个插值点 ~30 个插值点 + 转动惯量
适用场景 玩具模型 实时仿真、HIL 高保真研究

四、ChTransmission:变矩变速

4.1 基类层次

复制代码
                    ChTransmission (ChPart 派生)
                         │
          ┌──────────────┴──────────────┐
          │                             │
    ChAutomaticTransmission       ChManualTransmission
    (自动变速箱)                     (手动变速箱)
          │                             │
     ┌────┴────┐                   ChManualTransmissionShafts
     │         │                    (离合器 + 齿轮箱)
  SimpleMap  Shafts
  (无液力变矩器) (含液力变矩器)

4.2 ChTransmission 基类

所有变速箱共享的核心接口:

cpp 复制代码
class CH_VEHICLE_API ChTransmission : public ChPart {
  public:
    enum class Type { AUTOMATIC, MANUAL };
    virtual Type GetType() const = 0;

    int GetCurrentGear() const;    // -1=倒档, 0=空档, 1+=前进档
    int GetMaxGear() const;        // 最大前进档位
    void SetGear(int gear);        // 指定档位
    virtual void ShiftUp() = 0;    // 升档
    virtual void ShiftDown() = 0;  // 降档

    // 两个核心输出
    virtual double GetOutputDriveshaftTorque() const = 0;  // → 传动线
    virtual double GetOutputMotorshaftSpeed() const = 0;   // → 发动机

  protected:
    std::vector<double> m_gear_ratios;  // 齿轮传动比列表
    int m_current_gear;                 // 当前档位
    double m_current_gear_ratio;       // 当前传动比

    // 需要在派生类中指定传动比
    virtual void SetGearRatios(std::vector<double>& fwd, double& rev) = 0;
};

传动比的使用------变速箱的核心数学关系:

复制代码
输出扭矩 = 输入扭矩 / 传动比      (T_out = T_in / ratio)
输出转速 = 输入转速 × 传动比      (ω_out = ω_in × ratio)

注意:
  - SimpleMap 模型:齿轮比 > 1 表示减速增扭(典型驱动档)
  - 例如 ratio=0.2 意味着:输入 1000 N·m → 输出 5000 N·m
                                  输入 100 rad/s → 输出 20 rad/s

4.3 ChAutomaticTransmission 自动变速箱

在基类之上增加了自动换挡相关的功能:

cpp 复制代码
class CH_VEHICLE_API ChAutomaticTransmission : public ChTransmission {
  public:
    enum class DriveMode { FORWARD, NEUTRAL, REVERSE };
    enum class ShiftMode { AUTOMATIC, MANUAL };  // 手自一体

    void SetDriveMode(DriveMode mode);  // 切换 P/R/N/D
    void SetShiftMode(ShiftMode mode);  // 自动/手动模式

    // 液力变矩器接口(Shafts 模型实现,SimpleMap 模型返回 0)
    virtual bool HasTorqueConverter() const = 0;
    virtual double GetTorqueConverterSlippage() const = 0;
    virtual double GetTorqueConverterInputTorque() const = 0;
    virtual double GetTorqueConverterOutputTorque() const = 0;
};

DriveMode 切换逻辑:

cpp 复制代码
void ChAutomaticTransmission::SetDriveMode(DriveMode mode) {
    m_drive_mode = mode;
    switch (mode) {
        case DriveMode::FORWARD: SetGear(1);  break;  // 挂 1 档
        case DriveMode::NEUTRAL: SetGear(0);  break;  // 空档
        case DriveMode::REVERSE: SetGear(-1); break;  // 倒档
    }
}

4.4 ChAutomaticTransmissionSimpleMap --- 简化自动变速箱

原理:无液力变矩器,纯查表换挡,齿轮比直接计算输出。

复制代码
发动机 ──▶ [传动比计算] ──▶ 输出轴
               │
               │ 根据当前传动比直接计算
               │ T_out = T_in / ratio
               │ ω_motor = ω_drive / ratio
               ▼
         无液力变矩器
         无物理 ChShaft

Synchronize 实现:

cpp 复制代码
void ChAutomaticTransmissionSimpleMap::Synchronize(double time,
                                                    const DriverInputs& inputs,
                                                    double motorshaft_torque,
                                                    double driveshaft_speed) {
    // 自动换挡逻辑(基于发动机转速的理想换挡点)
    if (m_shift_mode == AUTOMATIC && m_drive_mode == FORWARD && m_current_gear > 0) {
        // 如果转速超过升档点 → 升档
        if (m_current_gear < GetMaxGear() && 
            m_motorshaft_speed > m_shift_points[m_current_gear - 1].second) {
            SetGear(m_current_gear + 1);
        }
        // 如果转速低于降档点 → 降档
        else if (m_current_gear > 1 && 
                 m_motorshaft_speed < m_shift_points[m_current_gear - 1].first) {
            SetGear(m_current_gear - 1);
        }
    }

    // 计算输出转速(反哺发动机)
    m_motorshaft_speed = abs(driveshaft_speed) / m_current_gear_ratio;

    // 计算输出扭矩(传给传动线)
    m_driveshaft_torque = motorshaft_torque / m_current_gear_ratio;
}

换挡逻辑示意:

复制代码
发动机转速
  │
  │             升档点 (upshift)
  │    ┌─────────────────────────────────────▶ 升到 3 档
  │    │   ┌─────────────────────────────▶ 升到 2 档
  │    │   │   ┌─────────────────────▶ 升到 1 档
  │    │   │   │
  │    ▼   ▼   ▼
  │    ┌─────────── 升档转速 (如 4000 RPM)
  │    │           │
  │    │   工作区域 │
  │    │           │
  │    └─────────── 降档转速 (如 1200 RPM)
  │    ▲   ▲   ▲
  │    │   │   └─────────────────────▶ 降到 2 档
  │    │   └─────────────────────────────▶ 降到 1 档
  │    └─────────────────────────────────────▶ 降到空档
  └───────────────────────────────────────────▶ 时间

JSON 配置示例(HMMWV):

json 复制代码
{
  "Name": "HMMWV Simple Map Transmission",
  "Type": "Transmission",
  "Template": "AutomaticTransmissionSimpleMap",
  "Gear Box": {
    "Reverse Gear Ratio": -0.151,
    "Forward Gear Ratios": [
      0.1708, 0.2791, 0.4218, 0.6223, 1.0173, 1.5361
    ],
    "Shift Points Map RPM": [
      [ 1000, 2226 ],
      [ 1000, 2225 ],
      [ 1000, 2210 ],
      [ 1000, 2226 ],
      [ 1000, 2225 ],
      [ 1000, 2700 ]
    ]
  }
}

每个前进档对应一对 降档转速, 升档转速。

4.5 ChAutomaticTransmissionShafts --- 物理自动变速箱

原理:包含完整的液力变矩器 + 齿轮箱 ChShaft 物理建模。

复制代码
                       ChSystem 物理世界
                            │
  发动机曲轴 ──▶ m_motorshaft (ChShaft)
                     │
                     ▼ 液力变矩器输入
              ChShaftsTorqueConverter
                     │  │
          ┌──────────┘  └──────────┐
          │ (输入)          (定子)  │
          ▼                        ▼
     m_shaft_ingear       m_transmissionblock (ChShaft)
          │                        │
          ▼                        │
     ChShaftsGearbox ◄─────────────┘  (齿轮箱 + 反力矩到变速箱壳体)
          │
          ▼
     m_driveshaft (ChShaft) ──▶ 传动线

Initialize 实现:

cpp 复制代码
void ChAutomaticTransmissionShafts::Initialize(std::shared_ptr<ChChassis> chassis) {
    auto sys = chassis->GetSystem();

    // ① 创建电机轴和驱动轴
    m_motorshaft = make_shared<ChShaft>();  m_motorshaft->SetInertia(GetMotorshaftInertia());
    m_driveshaft = make_shared<ChShaft>();  m_driveshaft->SetInertia(GetDriveshaftInertia());
    sys->AddShaft(m_motorshaft);
    sys->AddShaft(m_driveshaft);

    // ② 创建变速箱壳体(连接到底盘,产生反力矩)
    m_transmissionblock = make_shared<ChShaft>();
    m_transmissionblock->SetInertia(GetTransmissionBlockInertia());
    sys->AddShaft(m_transmissionblock);

    m_transmissionblock_to_body = make_shared<ChShaftBodyRotation>();
    m_transmissionblock_to_body->Initialize(m_transmissionblock, chassis->GetBody(), dir);
    sys->Add(m_transmissionblock_to_body);

    // ③ 创建液力变矩器(电机轴 → 中间轴,定子→壳体)
    m_torqueconverter = make_shared<ChShaftsTorqueConverter>();
    m_torqueconverter->Initialize(m_motorshaft, m_shaft_ingear, m_transmissionblock);
    m_torqueconverter->SetCurveCapacityFactor(mK);  // 容量因子曲线
    m_torqueconverter->SetCurveTorqueRatio(mT);     // 扭矩比曲线
    sys->Add(m_torqueconverter);

    // ④ 创建齿轮箱(中间轴 → 驱动轴,壳体→底盘)
    m_gears = make_shared<ChShaftsGearbox>();
    m_gears->Initialize(m_shaft_ingear, m_driveshaft, chassis->GetBody(), dir);
    m_gears->SetTransmissionRatio(m_current_gear_ratio);
    sys->Add(m_gears);
}

液力变矩器特性曲线:

复制代码
容量因子 K            扭矩比 T
  │                    │
  │  K: 小="硬连接"     │  T: 低速时放大扭矩
  │  大="软连接"        │  高速时 1:1
  │                    │
 35│        ──        2.0│      ──
  │      ╱              │    ╱
 15│─────              1.0│───
  │                    │
  └────▶ 速比            └────▶ 速比
 0.0        1.0       0.0        1.0

Synchronize 实现:

cpp 复制代码
void ChAutomaticTransmissionShafts::Synchronize(double time,
                                                  const DriverInputs& inputs,
                                                  double motorshaft_torque,
                                                  double driveshaft_speed) {
    // ① 施加外力:发动机的输入力矩 + 传动线的反馈转速
    m_motorshaft->SetAppliedLoad(motorshaft_torque);
    m_driveshaft->SetPosDt(driveshaft_speed);

    // ② 自动换挡(带防抖延迟)
    if (time - m_last_time_gearshift < m_gear_shift_latency) return;

    double gearshaft_speed = m_shaft_ingear->GetPosDt();
    if (gearshaft_speed > m_upshift_speed) {
        if (m_current_gear < GetMaxGear()) {
            SetGear(m_current_gear + 1);
            m_last_time_gearshift = time;
        }
    } else if (gearshaft_speed < m_downshift_speed) {
        if (m_current_gear > 1) {
            SetGear(m_current_gear - 1);
            m_last_time_gearshift = time;
        }
    }
}

力矩输出:

cpp 复制代码
double ChAutomaticTransmissionShafts::GetOutputDriveshaftTorque() const {
    return m_gears->GetReaction2();  // 齿轮箱对驱动轴的反作用力 = 输出力矩
}

double ChAutomaticTransmissionShafts::GetOutputMotorshaftSpeed() const {
    return m_motorshaft->GetPosDt();  // 电机轴当前转速
}

JSON 配置示例(HMMWV):

json 复制代码
{
  "Name": "HMMWV Shafts Automatic Transmission",
  "Type": "Transmission",
  "Template": "AutomaticTransmissionShafts",
  "Transmission Block Inertia": 10.5,
  "Motorshaft Inertia": 0.5,
  "Driveshaft Inertia": 0.5,
  "Torque Converter": {
    "Capacity Factor Map": [
      [ 0.00, 15.00 ], [ 0.25, 15.00 ], [ 0.50, 15.00 ],
      [ 0.75, 16.00 ], [ 0.90, 18.00 ], [ 1.00, 35.00 ]
    ],
    "Torque Ratio Map": [
      [ 0.00, 2.00 ], [ 0.25, 1.80 ], [ 0.50, 1.50 ],
      [ 0.75, 1.15 ], [ 1.00, 1.00 ]
    ]
  },
  "Gear Box": {
    "Forward Gear Ratios": [ 0.2, 0.4, 0.8 ],
    "Reverse Gear Ratio": -0.1,
    "Upshift RPM": 2500,
    "Downshift RPM": 1200,
    "Shift Latency": 1.0
  }
}

4.6 ChManualTransmissionShafts --- 手动变速箱

与自动变速箱 Shafts 模型结构类似,但用离合器 替换了液力变矩器:

复制代码
发动机 ──▶ m_motorshaft ──▶ ChShaftsClutch ──▶ m_clutchShaft ──▶ ChShaftsGearbox ──▶ m_driveshaft
                                  │
                            离合器调制量
                            (0=分离, 1=结合)

Synchronize 实现:

cpp 复制代码
void ChManualTransmissionShafts::Synchronize(double time,
                                              const DriverInputs& inputs,
                                              double motorshaft_torque,
                                              double driveshaft_speed) {
    m_motorshaft->SetAppliedLoad(motorshaft_torque);
    m_driveshaft->SetPosDt(driveshaft_speed);

    // 空档时离合器分离,否则根据离合器踏板位置调制
    if (GetCurrentGear() == 0) {
        m_clutch->SetModulation(0.0);
    } else {
        m_clutch->SetModulation(1.0 - driver_inputs.m_clutch);
    }
}

JSON 配置示例(Sedan):

json 复制代码
{
  "Name": "Sedan Shafts Manual Transmission",
  "Type": "Transmission",
  "Template": "ManualTransmissionShafts",
  "Transmission Block Inertia": 10.5,
  "Clutch Torque Limit": 500,
  "Gear Box": {
    "Forward Gear Ratios": [ 0.265, 0.489, 0.784, 1.063, 1.276, 1.499 ],
    "Reverse Gear Ratio": -0.333
  }
}

4.7 三种变速箱对比

维度 AutomaticTransmissionSimpleMap AutomaticTransmissionShafts ManualTransmissionShafts
物理对象 无 ChShaft 完整建模 ChShaft 完整建模
液力变矩器 无 ChShaftsTorqueConverter 无(用离合器替代)
离合器 无 无 ChShaftsClutch
换挡逻辑 理想换挡点(转速查表) 实际齿轮轴转速 + 延迟防抖 手动控制
反力矩效应 无 有(变速箱壳体→底盘) 有
Advance() 空操作 空操作(ChShaft 由系统推进) 空操作
JSON 复杂度 简单(传动比 + 换挡点) 复杂(转动惯量 + 液力变矩器曲线) 中等(转动惯量 + 离合器参数)

五、完整数据流:从油门到车轮

复制代码
                         驾驶员输入
                            │
               ┌────────────┼────────────┐
               │ throttle   │ clutch     │ steering/braking
               ▼            ▼            ▼
          ┌──────────┐  ┌──────────┐  ┌──────────┐
          │  Engine   │  │ Clutch   │  │  其他系统  │
          │  发动机   │  │ 离合器   │  │          │
          └─────┬────┘  └────┬─────┘  └──────────┘
                │            │
                │ motorshaft_torque
                ▼            │
          ┌────────────────────────────────────────────┐
          │         ChPowertrainAssembly                │
          │                                            │
          │  ① Engine.Synchronize(throttle, ω_motor)   │
          │        ω_motor ← Transmission.GetSpeed()    │
          │                                            │
          │  ② Transmission.Synchronize(T_motor,        │
          │         ω_driveshaft)                       │
          │        T_driveshaft = T_motor / ratio       │
          │        ω_motor = ω_driveshaft / ratio       │
          │                                            │
          └────────────────────┬───────────────────────┘
                               │ GetOutputTorque()
                               ▼
          ┌────────────────────────────────────────────┐
          │              ChDrivelineWV                  │
          │                                            │
          │  ① 接收 powertrain_torque                   │
          │  ② 通过差速器分配到各驱动轴                   │
          │  ③ 左轮 = 右轮 = T_driveshaft / n (开式)     │
          │                                            │
          └──────┬──────────────────┬──────────────────┘
                 │                  │
          ┌──────┴──────┐    ┌──────┴──────┐
          │  Axle 0      │    │  Axle 1      │
          │  Suspension  │    │  Suspension  │
          │  + Wheel     │    │  + Wheel     │
          │  + Tire      │    │  + Tire      │
          └──────┬──────┘    └──────┬──────┘
                 │                  │
                 ▼                  ▼
              地面反力 ◀────── 轮胎与地面接触

5.1 力矩传递路径

复制代码
油门 (throttle, 0~1)
  │
  ▼
Engine.GetOutputMotorshaftTorque()
  │  曲轴力矩 (N·m)
  ▼
Transmission.Synchronize(motorshaft_torque, driveshaft_speed)
  │  输出力矩 = 输入力矩 / 当前齿轮比
  ▼
Transmission.GetOutputDriveshaftTorque()
  │  driveshaft_torque
  ▼
DrivelineWV.Synchronize(time, inputs, powertrain_torque)
  │  通过差速器/传动轴分配到各轮
  ▼
DrivelineWV.GetSpindleTorque(axle, side)
  │  每个驱动轮的力矩
  ▼
Axle → Suspension.GetAxle(side)
  │  半轴力矩
  ▼
Wheel → Tire → 地面

5.2 力反馈路径

复制代码
地面 → Tire → Wheel → Suspension.GetSpindle(side)
  │  轮胎力传递到 spindle 刚体
  ▼
Suspension → Chassis
  │  通过约束/弹簧传递到底盘
  ▼
ChVehicle.UpdateInertiaProperties()
  │  递归聚合所有子系统的质量/惯性
  ▼
ChSystem::DoStepDynamics()
  │  求解器推进整个物理系统

六、发动机与变速箱的四种自由组合

Chrono 允许自由搭配不同类型的 Engine 和 Transmission:

复制代码
发动机 \ 变速箱    SimpleMap     Shafts Auto    Shafts Manual
────────────────────────────────────────────────────────────
EngineSimple         ✅ 最轻量      ✅ 可能         ✅ 可能
EngineSimpleMap      ✅ 常用        ✅ 合理         ✅ 合理
EngineShafts         ✅ 可能        ✅ 最高保真     ✅ 最高保真

典型组合示例:

组合 适用场景 车辆示例
EngineSimpleMap + AutomaticTransmissionSimpleMap 实时仿真、HIL、游戏 G500、HMMWV、CityBus
EngineShafts + AutomaticTransmissionShafts 高保真研究、NVH 分析 HMMWV、M113、FMTV
EngineShafts + ManualTransmissionShafts 手动挡仿真 Sedan
EngineSimple + AutomaticTransmissionSimpleMap 极简原型 测试用例

七、API 总结

7.1 ChPowertrainAssembly API

API 说明
GetEngine() 获取发动机子模块
GetTransmission() 获取变速箱子模块
GetOutputTorque() 变速箱输出到传动线的力矩
Initialize(chassis) 初始化发动机和变速箱(挂到底盘)
Synchronize(time, inputs, driveshaft_speed) 协调 Engine↔Transmission 闭环更新
Advance(step) 推进两个子系统的状态

7.2 ChEngine 通用 API

API 说明
GetMotorSpeed() 当前发动机转速 (rad/s)
GetOutputMotorshaftTorque() 曲轴输出力矩 (N·m)

7.3 ChEngineSimpleMap 特有 API

API 说明
GetMaxEngineSpeed() 最大发动机转速
SetEngineTorqueMaps(map0, mapF) 设置零节气门和满节气门扭矩曲线

7.4 ChEngineShafts 特有 API

API 说明
GetMotorBlockInertia() 发动机壳体转动惯量
GetMotorshaftInertia() 曲轴+飞轮转动惯量
SetEngineTorqueMap(map) 设置扭矩-转速曲线(热机)
SetEngineLossesMap(map) 设置损失-转速曲线(摩擦)

7.5 ChTransmission 通用 API

API 说明
GetCurrentGear() 当前档位 (-1=倒, 0=空, N=前进)
GetMaxGear() 最大前进档位数
ShiftUp() / ShiftDown() 手动升降档
SetGear(gear) 直接设置档位
GetOutputDriveshaftTorque() 输出到传动线的力矩
GetOutputMotorshaftSpeed() 输出到发动机的转速

7.6 ChAutomaticTransmission 特有 API

API 说明
SetDriveMode(mode) 设置驾驶模式 (P/R/N/D)
SetShiftMode(mode) 设置换挡模式 (自动/手动)
HasTorqueConverter() 是否含液力变矩器
GetTorqueConverterSlippage() 液力变矩器滑差率
GetTorqueConverterInputTorque() 变矩器输入扭矩
GetTorqueConverterOutputTorque() 变矩器输出扭矩

7.7 ChManualTransmission 特有 API

API 说明
HasClutch() 是否含离合器模型

八、设计哲学总结

复制代码
Chrono 动力总成设计的三条核心原则:

1. "可选性"
     动力总成是车辆的"可选插件",不是必须的。
     ChVehicle::m_powertrain_assembly 可能为 nullptr。

2. "可组合性"
     Engine 和 Transmission 是独立的 ChPart 派生类,
     通过 ChPowertrainAssembly 聚合,允许自由搭配。
     经验模型(SimpleMap)和物理模型(Shafts)可以混用。

3. "分层抽象"
     动力总成和传动线严格分离:
       PowertrainAssembly → 负责产生和转换扭矩
       DrivelineWV → 负责分配扭矩到各驱动轮
     两者通过一个 double 值(driveshaft_torque)通信。
相关推荐
hjjdebug1 年前
std::chrono类的简单使用实例及分析
duration·chrono·time_point·system_clock
许野平2 年前
Rust: 利用 chrono 库实现日期和字符串互相转换
开发语言·后端·rust·字符串·转换·日期·chrono
Black.Spider2 年前
C++计算程序运行时间
c++·chrono
会编程的大白熊3 年前
rust - 常用时间处理
rust·chrono