制动系统详解
一、制动系统的角色:减速与驻车
1.1 制动器的作用
驾驶员踩刹车 (braking, 0~1) │ ▼ 制动器 (ChBrake) │ ├── 产生制动力矩 (抵抗车轮旋转) ├── 将动能转化为热能 (能量耗散) └── 可选:完全锁死车轮 (驻车/抱死)制动器与整车的关系:
驾驶员的制动输入 (braking=0.5) │ ▼ ┌─────────────────┐ │ ChWheeledVehicle│ │ .Synchronize()│ └────────┬────────┘ │ ┌───────┼───────────┐ │ │ │ ▼ ▼ ▼ ChAxle[0] ChAxle[1] ChAxle[2] │ │ │ ┌───┴───┐ ┌───┴───┐ ┌───┴───┐ │ L R │ │ L R │ │ L R │ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ 制动器 制动器 ... (每个车轮一个)二、ChBrake 基类
2.1 类定义
classCH_VEHICLE_APIChBrake:publicChPart{public:virtual~ChBrake(){}/// 初始化:关联到指定的悬架子系统(获得半轴 ChShaft 的句柄)virtualvoidInitialize(std::shared_ptr<ChChassis>chassis,std::shared_ptr<ChSuspension>suspension,VehicleSide side);/// 同步:接收驾驶员制动输入 [0,1]/// braking = 0 → 不制动/// braking = 1 → 最大制动力矩virtualvoidSynchronize(doubletime,doublebraking)=0;/// 推进状态virtualvoidAdvance(doublestep){}/// 启用/禁用锁止能力(默认关闭)voidEnableLocking(boolval){m_can_lock=val;}/// 获取当前制动力矩virtualdoubleGetBrakeTorque()=0;protected:ChBrake(conststd::string&name);boolm_can_lock;///< 是否可以锁定车轮};2.2 继承关系
ChPart │ ChBrake (抽象基类) / \ ChBrakeSimple ChBrakeShafts (简单制动器) (物理传动轴制动器) │ │ BrakeSimple BrakeShafts (JSON 构建) (JSON 构建)2.3 初始化:获取半轴句柄
Initialize()的关键是获取悬架的半轴(axle shaft)句柄,用于施加制动力矩:
ChBrake::Initialize(chassis, suspension, side) └── suspension->GetAxle(side) → 半轴 ChShaft 句柄 └── suspension->GetRevolute(side) → 轮毂转动副句柄 (ChBrakeSimple 需要) └── suspension->GetBrakeBody(side) → 制动钳安装体 (ChBrakeShafts 需要)制动器不自己创建半轴,而是"借用"悬架中已有的半轴 ChShaft——因为半轴已经在悬架初始化时创建好了。
2.4 质量惯性属性
制动器的质量和惯性始终为 0(它不增加物理质量,只是施加力矩):
voidChBrake::InitializeInertiaProperties(){m_mass=0;m_inertia=ChMatrix33<>(0);m_com=ChFrame<>();m_xform=ChFrame<>();}三、ChBrakeSimple — 简化制动器
3.1 设计原理
使用ChLinkLockBrake约束实现速度相关的阻力矩,配合轮毂转动副的锁定实现抱死。
核心特点:
- 无 ChShaft 物理元素
- 制动力矩与转速相关(ODE 兼容)
- 无法模拟驻车抱死(NSC 约束的固有限制)
- 通过锁死转动副实现驻车
3.2 内部结构
轮毂转动副 (ChLinkLockRevolute) ┌─────────────────────┐ │ spindle (转向节) │ │ ●━━━━━━━━━● │ │ │ │ │ │ │ 半轴 │ │ │ │ │ │ ▼ ▼ ▼ │ ChLinkLockBrake │ (施加阻力矩) │ │ │ └──────────────────────┘3.3 完整源码解析
voidChBrakeSimple::Initialize(std::shared_ptr<ChChassis>chassis,std::shared_ptr<ChSuspension>suspension,VehicleSide side){ChBrake::Initialize(chassis,suspension,side);// 获取轮毂转动副(Suspension 初始化时已创建的 revolute joint)m_hub=suspension->GetRevolute(side);// 复用转动副的两个刚体作为制动器的连接体std::shared_ptr<ChBodyFrame>mbf1(m_hub->GetBody1(),[](ChBodyFrame*){});std::shared_ptr<ChBodyFrame>mbf2(m_hub->GetBody2(),[](ChBodyFrame*){});automb1=std::dynamic_pointer_cast<ChBody>(mbf1);automb2=std::dynamic_pointer_cast<ChBody>(mbf2);// 创建制动约束,与转动副共用同一位置m_brake=chrono_types::make_shared<ChLinkLockBrake>();m_brake->Initialize(mb1,mb2,true,*m_hub->GetMarker1(),*m_hub->GetMarker2());m_hub->GetSystem()->AddLink(m_brake);}voidChBrakeSimple::Synchronize(doubletime,doublebraking){m_modulation=braking;// 设置制动力矩(与制动输入成正比)m_brake->SetBrakeTorque(braking*GetMaxBrakingTorque());// 如果制动输入 > 0.99 且允许锁定 → 锁死转动副if(!m_can_lock)return;if(braking>0.99&&!m_locked){m_hub->Lock(true);// 锁死轮毂(驻车制动)m_locked=true;}elseif(braking<=0.99&&m_locked){m_hub->Lock(false);// 解锁m_locked=false;}}3.4 GetBrakeTorque
virtualdoubleGetBrakeTorque()override{returnm_modulation*GetMaxBrakingTorque();}3.5 派生类 BrakeSimple(JSON 构建)
只需要提供一个参数——最大制动力矩:
{"Name":"HMMWV Brake Front","Type":"Brake","Template":"BrakeSimple","Maximum Torque":4000}四、ChBrakeShafts — 传动轴制动器
4.1 设计原理
使用ChShaftsClutch离合器元素在制动轴和半轴之间产生摩擦力矩。制动轴固定到车架(或制动钳安装体),通过离合器调制传递力矩。
核心特点:
- 完整的 ChShaft 物理建模
- 制动轴具有转动惯量
- 通过离合器传递力矩(可模拟不同程度的制动)
- 反力矩通过 ChShaftBodyRotation 传递到车架/制动钳安装体
4.2 内部结构
ChShaftBodyRotation ┌─────────────────┐ │ 制动轴 (ChShaft) │ ←── 具有转动惯量 │ ● │ │ │ │ │ ChShaftsClutch │ ←── 调制量 = braking (0~1) │ │ │ │ 半轴 (ChShaft) │ ←── 悬架中已有的半轴 └─────────────────┘ 制动轴通过 ChShaftBodyRotation 连接到: ① 车架 (默认) ② 悬架的制动钳安装体 (如果悬架提供 GetBrakeBody)4.3 完整 Initialize 源码
voidChBrakeShafts::Initialize(std::shared_ptr<ChChassis>chassis,std::shared_ptr<ChSuspension>suspension,VehicleSide side){ChBrake::Initialize(chassis,suspension,side);// ① 创建制动轴(制动盘/鼓的转动惯量)m_shaft=chrono_types::make_shared<ChShaft>();m_shaft->SetName(m_name+"_shaft");m_shaft->SetInertia(GetShaftInertia());// 由派生类指定chassis->GetSystem()->AddShaft(m_shaft);// ② 将制动轴连接到车架/制动钳安装体(传递反力矩)autobody=suspension->GetBrakeBody(side);// 获取制动钳安装体if(!body)body=chassis->GetBody();// 默认连接到车架autoconnection=chrono_types::make_shared<ChShaftBodyRotation>();connection->Initialize(m_shaft,body,ChVector3d(0,-1,0));chassis->GetSystem()->Add(connection);// ③ 创建制动离合器(连接制动轴 ↔ 半轴)m_clutch=chrono_types::make_shared<ChShaftsClutch>();m_clutch->SetTorqueLimit(GetMaxBrakingTorque());// 离合器最大传递扭矩m_clutch->Initialize(m_shaft,suspension->GetAxle(side));// 连接到半轴m_clutch->SetModulation(0);// 初始不制动chassis->GetSystem()->Add(m_clutch);}4.4 Synchronize 实现
voidChBrakeShafts::Synchronize(doubletime,doublebraking){m_modulation=braking;m_clutch->SetModulation(braking);// 离合器调制量 = braking (0→分离, 1→完全结合)// 结合程度越高,传递的摩擦力矩越大,半轴减速越快}4.5 力矩传递链
驾驶员 braking = 0.5 │ ▼ ChBrakeShafts::Synchronize └── m_clutch->SetModulation(0.5) │ ▼ ChShaftsClutch 约束求解 └── 传递力矩 = modulation × TorqueLimit │ ▼ 半轴 ChShaft (suspension->GetAxle(side)) └── 受到制动力矩 → 减速 │ ▼ ChShaftBodyRotation (制动轴→车架) └── 反力矩传递到车架 → 整车俯仰/点头4.6 GetBrakeTorque
virtualdoubleGetBrakeTorque()override{returnm_modulation*GetMaxBrakingTorque();}4.7 派生类 BrakeShafts(JSON 构建)
需要两个参数——制动轴转动惯量和最大制动力矩:
{"Name":"HMMWV Brake Front","Type":"Brake","Template":"BrakeShafts","Shaft Inertia":0.4,"Maximum Torque":4000}五、两种制动模型的对比
| 维度 | ChBrakeSimple | ChBrakeShafts |
|---|---|---|
| 底层机制 | ChLinkLockBrake 约束 | ChShaftsClutch 离合器 |
| 物理对象 | 无(复用转动副刚体) | 制动轴 ChShaft + 离合器 |
| 制动力矩 | 制动约束的内力 | 离合器摩擦力矩 |
| 制动轴惯量 | 无 | 有(GetShaftInertia) |
| 反力矩传递 | 通过转动副传递到车架 | 通过 ChShaftBodyRotation 到车架/制动钳体 |
| 车轮锁止 | 锁死转动副(Lock(true)) | 无(暂无实现) |
| ODE 兼容性 | 速度相关力矩(适合 ODE) | 约束求解(NSC/SCM 均可) |
| 适用场景 | 实时仿真、HIL | 高保真制动研究 |
| JSON 参数 | 最大扭矩 | 转动惯量 + 最大扭矩 |
六、制动器在整车中的使用
6.1 ChAxle 中的制动器
每个车轴有两个制动器(左+右),作为 ChAxle 的成员:
classChAxle{public:std::shared_ptr<ChBrake>m_brake_left;std::shared_ptr<ChBrake>m_brake_right;voidInitialize(){if(m_brake_left&&m_brake_right){m_brake_left->Initialize(chassis,m_suspension,LEFT);m_brake_right->Initialize(chassis,m_suspension,RIGHT);}}voidSynchronize(doubletime,constDriverInputs&driver_inputs){if(m_brake_left&&m_brake_right){m_brake_left->Synchronize(time,driver_inputs.m_braking);m_brake_right->Synchronize(time,driver_inputs.m_braking);}}};6.2 制动器是"可选的"
每个车轮可以独立选择是否安装制动器,也可以混用 Simple 和 Shafts:
// 前轴 BrakeShafts,后轴 BrakeSimplem_axles[0]->m_brake_left=BrakeShafts("FrontLeft");m_axles[0]->m_brake_right=BrakeShafts("FrontRight");m_axles[1]->m_brake_left=BrakeSimple("RearLeft");m_axles[1]->m_brake_right=BrakeSimple("RearRight");七、API 总结
7.1 ChBrake 基类 API
| API | 说明 |
|---|---|
EnableLocking(bool) | 启用车轮锁止能力 |
GetBrakeTorque() | 获取当前制动力矩 (N·m) |
Initialize(chassis, suspension, side) | 初始化(获取半轴句柄) |
Synchronize(time, braking) | 根据制动输入 [0,1] 更新制动状态 |
Advance(step) | 推进状态 |
7.2 ChBrakeSimple 特有 API
| API | 说明 |
|---|---|
GetMaxBrakingTorque() | 获取最大制动力矩(纯虚,派生类实现) |
GetBrakeSpeed() | 制动盘/钳的相对角速度 |
7.3 ChBrakeShafts 特有 API
| API | 说明 |
|---|---|
GetShaftInertia() | 制动轴转动惯量(纯虚) |
GetMaxBrakingTorque() | 最大制动力矩(纯虚) |
7.4 BrakeSimple / BrakeShafts(JSON 构建)
| JSON 字段 | BrakeSimple | BrakeShafts |
|---|---|---|
Maximum Torque | ✅ 唯一参数 | ✅ |
Shaft Inertia | ❌ | ✅ |
八、设计哲学总结
Chrono 制动系统的三条核心原则: 1. "薄封装" 制动器本身不引入额外的物理质量(m_mass = 0), 只通过约束/离合器施加力矩,属于"力元素"而非"体元素"。 2. "借鸡生蛋" 制动器不自创半轴,而是通过 Initialize 获取悬架中的半轴句柄, 将制动力矩直接施加到已有的半轴 ChShaft 上。 3. "两种精度可选" Simple:用制动约束实现速度相关阻力矩,适合实时仿真 Shafts:用离合器实现摩擦力矩,适合高保真制动研究 两者可以自由混用(前轴 Shafts + 后轴 Simple)。