动力总成系统详解
一、动力总成的角色:车辆的动力源
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)通信。