3. 系统架构的顶层表达
在SysML中,系统架构的顶层表达并不是一张“大而全”的图,而是由三类互补的视图共同承担:包图(Package Diagram)负责组织模型、模块定义图(BDD,Block Definition Diagram)负责定义系统结构,而架构分层与视图则决定这些模型元素如何被划分到不同抽象层次中。理解这三者的分工,是避免模型“越画越乱”的关键。
包图:模型的组织骨架
包图解决的是“模型放在哪里”的问题,而不是“系统由什么组成”的问题。在SysML中,包(Package)是最基本的命名空间与容器,它可以包含模块、值类型、接口、活动、状态机,也可以包含子包。包图通过<<import>>、<<access>>、<<merge>>等依赖关系表达包之间的引用与可见性。
一个典型的系统架构模型可以按以下方式分包:
- 需求包(Requirements):存放需求图与需求元素,供架构元素追溯。
- 架构包(Architecture):按逻辑层、物理层、接口层再分子包。
- 参数包(Parametrics):存放约束模块与参数绑定关系。
- 验证包(Verification):存放测试用例与验证活动。
包图的价值在于:当模型规模达到数百个元素时,包结构决定了模型是否可导航、可复用、可分工。一个常见错误是把所有模块都塞进一个包,导致命名冲突和循环依赖。正确的做法是让包之间的依赖尽量单向,例如“验证包”依赖“架构包”,而“架构包”不反向依赖“验证包”。
模块定义图:系统结构的定义
模块定义图(BDD)是SysML中定义系统结构的主图。它描述的是模块(Block)及其属性(Property)、端口(Port)、操作(Operation)和关联(Association)。BDD回答的问题是:系统由哪些模块组成?每个模块拥有什么属性?模块之间通过什么端口连接?
在BDD中,一个模块用矩形表示,矩形内通常分为三栏:名称、属性、操作。模块之间的整体—部分关系用组合关联(Composition)表示,即实心菱形指向整体;模块之间的引用关系用普通关联表示。端口则画在模块边界上,分为代理端口(Proxy Port)和全端口(Full Port),前者转发接口,后者直接定义接口。
以无人机飞控系统为例,BDD可以定义如下模块:
- FlightController:属性包括
cpu: Processor、imu: IMU、power: PowerModule;端口包括pMotor: MotorPort、pSensor: SensorPort。 - Motor:属性包括
maxThrust: N、responseTime: ms;端口为pControl: ControlPort。 - IMU:属性包括
sampleRate: Hz、range: deg/s;端口为pData: DataPort。
这些模块通过组合关系构成FlightController的整体结构,通过端口定义对外接口。BDD不描述时间顺序,也不描述消息交互,它只描述“静态结构”。
属性与端口:模块的细节定义
属性是模块的组成部分或值属性。在BDD中,属性可以有两种角色:一是部件属性(Part Property),表示该模块由另一个模块实例组成;二是值属性(Value Property),表示该模块拥有的数值或数据类型。例如FlightController中的cpu: Processor是部件属性,而Motor中的maxThrust: N是值属性。
端口是模块与外部交互的接入点。在SysML中,端口可以携带接口块(Interface Block),接口块中定义流属性(Flow Property)和操作。例如MotorPort可以定义in pwm: PWM和out rpm: RPM,表示该端口接收PWM信号并输出转速。端口与接口的分离,使得同一接口可以被多个模块复用,从而降低耦合。
架构分层与视图:从逻辑到物理
架构分层是组织复杂系统的核心手段。在SysML中,常见的分层包括:
- 逻辑层:描述系统功能与逻辑模块,不涉及具体实现技术。
- 物理层:描述实际硬件、软件部署与分配关系。
- 接口层:定义模块之间的交互契约,包括端口、接口块和流规范。
每一层都可以用BDD表达其结构,用包图表达其组织,用IBD表达其内部连接。分层的关键在于分配关系(Allocation):逻辑模块可以分配到物理模块上,需求可以分配到架构元素上。SysML通过<<allocate>>依赖关系表达这种映射。
例如,逻辑层的NavigationController可以分配到物理层的FlightController上,表示导航功能由飞控计算机实现。这种分配关系使得需求、逻辑、物理三者之间形成可追溯的链条。
从包图到BDD:一个可操作的建模顺序
在实际项目中,建议按以下顺序建立顶层架构模型:
- 先建包结构:根据项目分工和模型规模,建立需求包、架构包、参数包、验证包。包名使用英文,避免空格和特殊字符。
- 在架构包中建BDD:先定义顶层系统模块,再逐层分解出子系统模块。每个模块先写名称,再补属性,最后补端口。
- 定义接口块:为每个端口定义接口块,明确流属性的方向和类型。接口块放在接口层包中,供多个模块引用。
- 建立分配关系:用
<<allocate>>把逻辑模块分配到物理模块,把需求分配到架构元素。 - 检查一致性:确认包依赖无循环、端口方向匹配、分配关系完整。
以无人机飞控为例,完成上述步骤后,模型应能回答:飞控系统由哪些模块组成?每个模块的接口是什么?导航功能由哪个物理模块实现?需求“姿态控制周期≤5ms”由哪个模块的哪个属性满足?如果这些问题都能在模型中直接找到答案,说明顶层架构表达已经基本到位。
最后需要强调,架构分层不是越多越好。对于中小型系统,逻辑层与物理层两层通常足够;对于大型系统,可以在逻辑层内再分功能层与服务层,在物理层内再分硬件层与软件层。每一层都应有明确的建模目的和交付物,避免为了“看起来完整”而引入无实际用途的空层。