3. 核心功能模块划分:感知、决策、控制、通信、人机交互
各位同学,今天我们来聊聊列车自动驾驶软件最核心的骨架——功能模块划分。说实话,我见过不少刚入行的工程师,一上来就急着写代码,结果模块之间耦合得像一团乱麻。我个人习惯是,先花半天时间把模块边界画清楚,后面写代码反而快得多。
列车自动驾驶系统,说白了就是五个模块:感知、决策、控制、通信、人机交互。这五个模块各司其职,又紧密配合。我曾在一次项目中遇到过模块划分不清的情况,结果联调时出了问题,排查了整整三天才发现是感知模块把数据格式传错了。嗯,从那以后我对模块接口规范就特别较真。
3.1 感知模块——列车的「眼睛和耳朵」
感知模块负责收集列车周围的环境信息。你想想看,列车在轨道上跑,它得知道前方有没有障碍物、当前速度是多少、信号灯是什么颜色。这些信息从哪里来?
- 传感器数据采集:雷达、激光雷达、摄像头、速度传感器、加速度计等
- 轨道占用检测:通过轨道电路或应答器获取轨道占用状态
- 信号系统接口:读取地面信号机的显示状态
- 定位信息:GPS、里程计、信标校正等多源融合定位
重要提醒:感知模块的数据质量直接决定了后续决策的准确性。我在项目中遇到过传感器噪声导致误判的情况,所以一定要做数据滤波和有效性校验。
这里我给出一个简单的传感器数据融合伪代码示例:
// 传感器数据融合示例
function fuseSensorData(radarData, cameraData, odometerData) {
// 时间戳对齐
let alignedData = alignTimestamps(radarData, cameraData);
// 数据有效性检查
if (!isValid(alignedData)) {
return { status: 'ERROR', message: '传感器数据异常' };
}
// 加权融合
let fusedPosition = weightedAverage(
radarData.position, 0.4,
cameraData.position, 0.3,
odometerData.position, 0.3
);
return { status: 'OK', position: fusedPosition };
}
3.2 决策模块——列车的「大脑」
决策模块是整个系统的核心。它接收感知模块传来的信息,然后决定列车该怎么走。说白了,就是回答三个问题:现在该加速还是减速?要不要紧急制动?下一站怎么停?
我建议把决策模块分成三个层次:
- 战略决策:运行计划、时刻表调整、线路选择
- 战术决策:速度曲线规划、停车点计算、节能策略
- 操作决策:牵引/制动指令、车门控制、空调调节
| 决策层级 | 时间尺度 | 典型决策内容 |
|---|---|---|
| 战略决策 | 分钟级 | 是否跳站、是否晚点调整 |
| 战术决策 | 秒级 | 目标速度、制动曲线 |
| 操作决策 | 毫秒级 | 牵引力大小、制动缸压力 |
个人经验:战术决策层最容易出问题。我曾经遇到过一个场景,列车在弯道上需要提前减速,但决策模块没有考虑线路曲率,结果乘客体验很差。后来我们在决策模型里加入了线路几何参数,才解决了这个问题。
3.3 控制模块——列车的「手脚」
控制模块负责把决策指令变成实际的物理动作。它直接跟列车硬件打交道,比如牵引系统、制动系统、车门系统等。
控制模块的核心是闭环控制。你想想看,决策模块说「加速到80km/h」,控制模块就得精确地调节牵引力,同时还要监控实际速度,形成一个反馈回路。
- 牵引控制:调节电机输出扭矩
- 制动控制:电制动与空气制动的协调
- 车门控制:开关门时序、防夹检测
- 空调控制:车厢温度调节
避坑指南:我曾经在控制模块里犯过一个低级错误——没有做输出限幅。结果有一次传感器故障,控制模块输出了一个巨大的牵引力指令,差点造成事故。从那以后,所有控制输出都必须经过安全限幅检查。
3.4 通信模块——列车的「神经网络」
通信模块负责列车内部和外部之间的信息交换。内部通信是各个子系统之间的数据传递,外部通信是列车与地面控制中心、其他列车之间的交互。
我个人习惯把通信模块分成三个子层:
- 物理层:无线通信(4G/5G、Wi-Fi)、有线通信(MVB、CAN总线)
- 协议层:TCP/IP、UDP、TRDP(列车实时数据协议)
- 应用层:数据格式定义、消息序列、心跳机制
这里要注意的是,列车通信对实时性和可靠性要求极高。我建议采用双冗余通信链路,一条主用一条备用,切换时间不能超过100毫秒。
// 通信心跳检测示例
function heartbeatCheck() {
let lastHeartbeat = getLastHeartbeatTime();
let currentTime = getCurrentTime();
if (currentTime - lastHeartbeat > 2000) { // 2秒无心跳
switchToBackupChannel();
logWarning('主通信链路故障,切换到备用链路');
}
}
3.5 人机交互模块——列车的「面孔」
人机交互模块是司机和乘客与系统打交道的界面。虽然说是自动驾驶,但人机交互依然不可或缺。司机需要监控系统状态,乘客需要获取出行信息。
我建议把HMI分成两个子模块:
- 司机台HMI:速度表、信号显示、故障报警、手动干预接口
- 乘客信息HMI:到站显示、换乘指引、紧急通话按钮
设计原则:人机交互要遵循「最少操作」原则。自动驾驶模式下,司机的主要任务是监控,而不是操作。所以界面设计要突出关键信息,减少不必要的干扰。
嗯,这里还要提一下,人机交互模块的响应时间很关键。司机按下紧急制动按钮后,系统必须在200毫秒内响应。我曾经测试过一个HMI原型,按钮按下后要等1秒才有反应,这显然是不合格的。
3.6 模块间的协作关系
五个模块不是孤立的,它们之间通过定义好的接口进行数据交换。我画了一张模块协作图(这里用文字描述):
- 感知模块采集数据,处理后发送给决策模块
- 决策模块根据感知信息做出决策,生成控制指令
- 控制模块执行指令,同时将执行结果反馈给决策模块
- 通信模块贯穿所有模块,提供数据传输通道
- 人机交互模块从各模块获取状态信息,并向司机/乘客展示
说白了,这就是一个闭环系统。感知→决策→控制→执行→反馈→再感知。任何一个环节出问题,整个系统都会受影响。
我的建议:在项目初期,一定要把模块间的接口协议定死。数据格式、传输频率、异常处理方式,这些都要写进设计文档里。我见过太多项目因为接口没定好,后期联调时改来改去,浪费了大量时间。
好了,这一章的内容就到这里。核心功能模块划分是架构设计的基石,把这五个模块的边界和职责搞清楚,后面的工作就会顺利很多。下一章我们会深入讲解感知模块的详细设计,包括传感器选型和数据融合算法。