2. 系统架构设计原则:模块化、分层设计、高内聚低耦合、安全冗余

好,咱们直接进入正题。列车自动驾驶系统,说白了就是一辆高速移动的“计算机”在控制着几十吨重的钢铁。架构设计一旦出问题,后果不堪设想。我这些年做过的项目里,见过太多因为架构混乱导致后期改不动、测不了的惨痛案例。所以今天聊的这几个原则,不是理论空谈,是真正能救命的。

2.1 模块化:把大象装进冰箱,分三步

模块化是什么?就是把一个庞大的系统,拆成一个个独立的小块。每个小块干自己的活,互不干扰。

我个人习惯,在项目一开始就画一张模块划分图。比如列车自动驾驶系统,我会分成这几个核心模块:

  • 感知模块:处理雷达、摄像头、轨道电路信号
  • 决策模块:根据感知结果,计算目标速度、制动曲线
  • 执行模块:控制牵引、制动、车门
  • 通信模块:与地面中心、相邻列车交换数据
  • 诊断模块:自检、故障记录、健康管理

为什么要这么分?我在项目中遇到过一件事:有一次,感知模块和决策模块写在了同一个文件里。结果雷达数据格式一改,整个决策逻辑都得跟着调。改了一个月,还引入了新bug。你想想看,如果一开始就分好模块,改感知模块的时候,决策模块根本不用动。

核心要点:模块之间只通过定义好的接口通信。接口一旦确定,内部怎么改都行。

2.2 分层设计:别让应用层操心硬件的事

分层设计,说白了就是“各司其职”。我习惯把系统分成三层:

层次 职责 举例
应用层 业务逻辑、算法 ATO自动驾驶曲线计算
中间层 协议转换、数据抽象 将传感器原始数据转为标准格式
硬件抽象层 屏蔽硬件差异 统一接口操作制动、牵引设备

嗯,这里要注意:上层不能直接调用下层硬件。我曾经见过一个项目,应用层代码里直接写了GPIO口地址。后来换了硬件平台,所有代码都得重写。这就是典型的没分层。

正确的做法是:应用层只调用中间层的API,中间层再通过硬件抽象层去操作具体设备。这样换硬件,只需要改最下面一层。

我的经验:分层设计初期会多写一些接口代码,感觉“麻烦”。但到了后期维护、升级、换平台的时候,你会感谢当初的自己。

2.3 高内聚低耦合:别让模块之间“藕断丝连”

这两个词经常一起出现。我解释一下:

  • 高内聚:一个模块内部的东西,应该高度相关。比如制动模块里,只放和制动相关的代码。别把空调控制也塞进去。
  • 低耦合:模块之间的依赖关系要尽量少。A模块改了,B模块不应该受影响。

怎么判断耦合度高不高?有个简单方法:你看一个模块的修改,会不会导致其他模块也跟着改。如果会,那就是耦合太高了。

举个例子。我之前做的一个项目,速度计算模块直接调用了制动模块的内部变量。后来制动模块重构,变量名改了,速度计算模块就崩了。这就是典型的耦合过紧。

正确的做法是:模块之间只通过函数参数、返回值、或者消息队列来通信。不要共享全局变量,不要直接访问对方内部数据。

避坑指南:我曾经因为赶工期,允许了两个模块共享一个全局结构体。结果后来调试了整整两周,才发现是某个模块意外修改了结构体里的字段。从那以后,我再也不允许共享全局变量了。

2.4 安全冗余:别把鸡蛋放在一个篮子里

列车系统,安全是第一位的。冗余设计,就是给系统准备“备胎”。

常见的冗余方式有:

  • 硬件冗余:双CPU、双传感器、双制动回路。一个坏了,另一个立刻顶上。
  • 软件冗余:同一功能用两种不同的算法实现,结果互相校验。
  • 数据冗余:关键数据存两份,一份在主存,一份在备份区。

我参与过一个项目,制动系统用了“三取二”架构。三个独立的制动控制器,只要其中两个判断需要制动,系统就执行制动。这样即使一个控制器故障,也不会影响安全。

但冗余不是越多越好。冗余多了,系统复杂度上升,反而可能引入新问题。我的建议是:对安全关键功能做冗余,对非关键功能不做。比如车门控制需要冗余,但空调控制就不需要。

总结一下:模块化让你好拆分,分层让你好维护,高内聚低耦合让你好修改,安全冗余让你不出事。这四个原则,是列车自动驾驶系统架构的基石。

好了,这一章就聊到这儿。下一章咱们会深入讲讲具体的架构模式,比如怎么用状态机来管理列车运行状态。到时候见。