☰
智能驾驶功能软件平台架构设计:从分层到落地的关键实践
2026/10/4 1:01:06 网站建设 项目流程

做智能驾驶功能软件平台的第一件事,不是写代码,而是把系统架构定下来。这是我做了几个量产项目之后最大的体会。很多团队一上来就拆分模块、定义接口、搭通信框架,结果三个月后推倒重来,问题基本都出在架构层没想清楚。《智能驾驶功能软件平台设计规范 第一部分:系统架构》这份规范,解决的就是这个“最先要做又最容易糊弄过去”的问题。这篇内容我会结合自己在实际项目中踩过的坑,把架构设计的思路、模块划分的逻辑、接口和通信的关键设计点,以及落地时的避坑经验一次性讲透,给正在做架构评审、模块解耦和接口对齐的同行做个参考。

1. 为什么智能驾驶平台要先定系统架构

1.1 从项目痛点说起

智能驾驶功能软件的复杂度,这几年涨得离谱。一个L2+级别的基础功能,涉及感知、融合、预测、规划、控制、HMI提示,再加上高精地图、定位、云端交互,代码规模轻松到百万行级别。如果还沿用“每个功能一个工程、传感器数据直接灌给算法节点”的老做法,第一版Demo可能跑得很快,但到了量产阶段就全是坑。

我见过最典型的例子:某个泊车项目,感知团队写了一个视觉感知节点,直接把图像数据通过共享内存发给了规划团队,两边约定了一个私有结构体。结果感知算法要升级,换了新的输出格式,规划那边编译直接过不了,整个联调停了两周。这种问题归结起来只有一个原因——模块之间没有清晰的架构边界,接口没有规范约束。

系统架构规范要干的事情,就是把整个功能软件平台划分成职责清晰的层次和模块,规定好数据怎么流、服务怎么调用、故障怎么处理。它不关心某一个感知算法的具体实现,而是关心这些算法以什么形态挂在平台上,互相之间以什么方式协作。架构定了,后面写代码才是真正的“填砖头”,而不是边盖边拆。

1.2 这份规范到底在约束什么

《智能驾驶功能软件平台设计规范 第一部分:系统架构》这类文档,一般会覆盖几个核心方面:功能软件的层次划分、逻辑组件之间的交互关系、数据流和消息通信机制、系统资源的确定性调度,以及冗余和降级策略。

从工程落地角度看,它实际上在回答三个问题。第一,每个功能模块放在哪个层级,它的职责边界是什么,能调用哪些服务、不能直接碰哪些东西。第二,模块之间的接口长什么样,是同步调用还是异步消息,数据格式谁定义、怎么演进。第三,整个系统如何保证在算力有限的条件下稳定运行,极端场景下如何降级而不是直接崩溃。

这三个问题如果不在架构阶段讲清楚,后面每个迭代都会有人问“这个数据我该从哪里拿”“这个模块能不能直接访问传感器”“那个功能挂了我这边要不要一起降级”。每个问题都会变成一次跨团队扯皮,消耗的时间远超写代码本身。所以架构规范不是文档工作,它是在给所有开发人员划定一条公共的“交通规则”。

2. 架构设计的核心思路

2.1 分层架构,把职责切清楚

现在比较公认的做法,是把智能驾驶功能软件平台分成三层来设计:功能软件层、平台服务层、操作系统抽象层。对应到项目里,每一个模块都必须在其中找到属于自己的层级。

功能软件层是离业务最近的,感知、融合、预测、决策规划、控制都在这一层。这一层的特点是业务性强、迭代频繁,算法团队主要在这里工作。平台服务层是承上启下的,提供通信服务、数据管理、日志服务、诊断服务、健康管理、时间同步等公共能力。这一层更像是智能驾驶系统的“操作系统”,对上层提供稳定统一的API,屏蔽底层硬件差异。操作系统抽象层则负责封装不同的芯片平台、硬实时操作系统或者Linux发行版,让平台服务层不要被某个具体SoC绑定。

我理解的架构设计,第一原则就是严格禁止越层访问。功能软件层想拿传感器原始数据,必须通过平台服务层提供的数据访问接口,不能自己去读设备节点。这个约束在前期会觉得“多此一举”,但一旦芯片更换、驱动调整,只有数据访问被收敛了,才能把改动限制在一个很小的范围内。我在项目里见过最头疼的,就是某个感知模块直接依赖了摄像头驱动的私有格式,换了一个型号的摄像头之后,整个感知链路都要跟着改。

2.2 服务化拆解,不等于乱拆

分层之后,接下来是功能模块的拆分方式。这两年的主流方向是基于SOA(面向服务架构)的思路,把功能软件层的各个能力做成服务,服务之间通过接口进行调用和数据交互。

SOA落地的第一问题是服务粒度。拆太大了等于没拆,整个感知是一个服务,接口又粗又重,协作还是混乱。拆太细了又会产生大量通信开销和服务管理负担,一个感知服务拆成几十个子服务,光服务注册、发现、负载均衡就够喝一壶。我的经验是,按“可独立演进的业务能力”来切,一个服务应该对应一个相对完整且可独立迭代的功能域,比如目标感知、融合跟踪、行为预测、轨迹规划、车辆控制。每个服务内部的算法怎么改,其他服务不需要关心,只要接口协议不变就可以。

第二问题是服务之间怎么协作。大部分场景我倾向用异步消息机制,而不是同步RPC。感知结果以周期性的消息发布出去,规划模块订阅这些消息,两边通过话题解耦。这样感知的发布频率调整了,规划侧不需要改代码,只要配置订阅关系就行。但控制指令这类对时延敏感、需要确认的交互,用同步请求/响应模式会更容易保证时序关系。实际落地时,两种模式会共存,架构规范里必须把各自的适用场景界定清楚。

2.3 “感知—规划—控制—协同”四大功能簇

功能软件层内部的划分,我习惯先把它聚成四个功能簇,而不是一上来就拆到原子模块。感知功能簇负责环境感知和多传感器融合,对外输出目标列表、可行驶区域、交通标志等结构化信息。规划决策功能簇负责行为决策、轨迹规划和速度规划,告诉车辆接下来往哪走、怎么走。控制功能簇负责执行轨迹规划的结果,输出转向、加速、制动的控制指令。协同功能簇则分管人机交互、远程监控、云端交互等非驾驶主线但必须存在的功能。

分完这四个功能簇之后,再往里去定义模块。比如感知功能簇里可以拆出视觉感知、毫米波雷达感知、激光雷达感知、融合模块;决策规划里可以拆出场景理解、行为决策、运动规划、安全校验。每个模块的输入输出、周期、DDS(数据分发服务)主题都需要被明确定义。架构文档里把这一层画清楚,开发人员拿到手才知道自己该写什么、跟谁对接。这里有一个非常关键的细节,就是模块的“周期”必须写清楚,因为智能驾驶大多数处理是周期性的,视觉感知可能是30Hz到60Hz,毫米波雷达可能是20Hz到50Hz,融合模块一般用固定周期比如20Hz,规划控制通常是20Hz到50Hz。周期不一致导致的时序错乱,在架构层面就必须被识别出来。

3. 落地过程中最关键的几个细节

3.1 接口规范:架构的“语法”

架构光有分层和模块不够,接口规范才是保证大家协作顺畅的“语法”。接口设计里最容易犯的错误,是把接口协议直接和某个实现语言的数据结构绑定,比如用C++的struct,字段名、内存布局都和某一版代码强相关。第一版跑起来挺顺畅,等到对方升级版本、增加字段,问题就出来了。

我的做法是,所有跨模块接口用统一的接口描述语言来定义,然后自动生成各语言的代码骨架。这样接口一改,双方同步看到变更,编译期就能发现不兼容。字段命名也有约定,禁止用a、b、tmp这种无意义命名,单位必须写在字段名里或者定义明确的注释约束,比如速度字段要写清楚是m每s,角度字段要写清楚是rad还是deg。这个细节看起来小,我以前就遇到过一次,A模块输出的航向角单位是弧度,B模块默认用角度去算,结果车辆在高架弯道上直接偏了一个车道,排查了两天才发现是单位问题。

接口版本管理也特别重要。架构规范里要明确接口变更的流程,哪些改动是兼容的(新增字段、扩展枚举),哪些是不兼容的(删除字段、改变字段含义)。不兼容变更必须走评审流程,上下游模块统一迁移,禁止悄悄改。项目里最怕的就是有人“顺便把接口改了”,下游模块第二天跑起来发现数据对不上,还以为是自己的bug。

3.2 通信与数据流:时延和QoS是硬指标

功能软件平台的通信机制选型,很大程度上决定了系统的性能和稳定性。现在智能驾驶主流的通信中间件是DDS,它天然支持发布/订阅模式,QoS策略丰富,适合多传感器数据的实时分发。不过DDS的QoS配置是有讲究的,不是随便填个默认值就行。

可靠性策略上,感知数据这类周期性的、丢几帧可以容忍的消息,用BEST_EFFORT即可,也就是尽力传输。控制指令、状态切换这类必须确保送达的消息,用RELIABLE。如果反过来配,感知消息用可靠性传输,网络稍有抖动就会积累排队,时延持续增加,最后系统表现反而不稳定。我在项目里遇到的低概率“幽灵现象”,最后查下来就是某条感知消息被意外配置成RELIABLE,当网络出现瞬时拥塞时,消息积压,规划拿到的数据已经是一百多毫秒之前的了。

数据流设计还有一个容易忽略的点——大数据的传输路径。图像数据、点云数据动辄几十MB每秒,不适合走标准的DDS消息通道。我会单独规划共享内存通道,通过DDS只传递数据描述和共享内存的索引,真正的大块数据通过零拷贝方式读取。这样通信开销不会成为瓶颈,带宽留给控制消息和状态消息。同时要配套失效保护机制,共享内存通道异常了,接收方要能通过超时判断感知数据失效,并触发降级逻辑。

3.3 确定性调度与算力分配

智能驾驶是安全关键系统,处理的确定性非常关键。一个规划控制模块,如果运行时延忽高忽低,抖动超过几十毫秒,下游执行机构就会感到“车子一顿一顿的”。所以在平台服务层必须提供确定性调度能力,保证关键链路的处理周期可控。

最直接的做法,是为关键模块预留专用CPU核心或GPU算力分区。硬件上现在的智驾SoC普遍多核,把感知、融合、规划、控制分配到不同的核心,配置核心隔离,避免相互抢占。操作系统层采用硬实时或者配置高优先级抢占策略,确保关键任务不会被低优先级任务阻塞。非关键任务比如日志上传、远程诊断,放到低优先级或者独立核心上,绝不允许它们影响驾驶主链路。

算力的“余量”也要提前规划。架构阶段就得估算整个功能软件平台在峰值场景下的算力消耗,比如城市快速路上同时出现多目标、强光、雨雾天气,感知算力消耗会明显上涨。规划出峰值负载,建议预留不低于20%到30%的算力余量,给将来算法升级和新增功能留空间。有几个项目到后期算法精度提升需要增加算力,发现SoC已经满载,只能做裁减,是特别被动的事。

3.4 冗余与降级:L3以上绕不开的课题

系统架构设计中,冗余与降级是安全落地的保障。功能上,备份感知、备份规划甚至备份控制链路,是L3级及以上的常见要求。代价是算力成倍增长,功耗和成本都上去。架构上要做一个合理折中:关键模块做冗余,非关键模块做普通部署。

降级策略是我一直建议在架构阶段就要定义的。典型的分级降级模型可以这样划分:正常状态下,所有功能全开;检测到感知能力下降,比如摄像头被遮挡、雷达故障,系统进入“有限功能模式”,关闭依赖该传感器的功能,ACC自动退出或提醒接管;到了更严重的故障,比如定位失效,系统进入“最小风险策略”模式,靠道路模型和历史轨迹安全减速停车。每一级降级对应的触发条件、功能退出逻辑、HMI提示方式,都需要在架构文档里明确定义。

这个工作一定要前置。我见过不少项目,故障降级逻辑是在联调阶段才紧急补上的,结果没有统一的降级状态管理,一个模块一个想法,车辆遇到故障时的“反应”完全不可预测。等到整车安全评审时被提出一堆问题,再返工,代价非常大。

4. 架构落地避坑指南

4.1 接口风暴:大家各写各的,怎么收敛

架构规范发布之后,最常遇到的问题就是接口风暴。每个开发团队都觉得自己模块的输入输出是特殊的,不愿意按照公共接口规范来定义,结果审到后面接口五花八门。

我建议的做法是在项目启动时就搭一个接口评审组,任何跨模块接口变更必须过评审。评审的重点不是复杂度,而是接口设计是否符合几个原则:第一,字段是否真正必要,有些内部计算中间量不应该暴露给外部;第二,是同步还是异步,需要和调用场景匹配;第三,接口是否足够通用,比如目标列表数据,不应该绑定特定的传感器来源。评审组可以先用一个量化指标来盘点接口,比如每个接口被复用的次数,如果大量接口只被一个消费者用一次,说明模块划分或者接口设计出了偏差。

另外,接口文档和代码必须同步更新。我习惯把接口定义为代码仓库里的版本化文件,评审通过后自动生成文档,避免出现“文档一套、代码一套”的混乱。如果有人偷懒改了代码没更新接口文件,CI流程里加一道检查,编译不过,从源头堵住。

4.2 传感器配置变化,架构别跟着崩

智能驾驶系统的传感器配置,在开发过程中经常变。今天用三颗毫米波雷达,明天调整成五颗;摄像头从800万像素升级到1200万像素,测距能力变了。架构如果不能适应这种变化,每次配置调整都会带来一轮重构。

为了应对变化,架构上要把“传感器抽象”做成一个独立的接口层次。感知模块不直接订阅某个具体传感器的数据主题,而是订阅抽象过的感知输入接口,比如“前向感知目标列表”“环视感知目标列表”。具体哪颗传感器提供这个数据,由平台的传感器管理模块负责映射。这样调整传感器配置,只需要改平台层的映射关系,感知算法几乎不用动。

这个设计的额外好处是方便仿真测试。仿真环境里可以模拟任何传感器配置,只要配置映射到同一个抽象感知输入接口,算法不需要区分数据来自真实传感器还是仿真器。我们团队后来做仿真回归测试,就是靠这层抽象,每天可以自动跑上千个场景,效率提升非常明显。

4.3 仿真一致性问题:架构验证的试金石

架构设计得再漂亮,也要靠验证来兜底。这里最常见的问题是仿真结果和实车表现不一致。原因通常出在数据时间戳上。仿真环境里时间比较理想,实车上传感器数据、执行器反馈的时延是客观存在的。架构上如果对时间戳没有统一处理,仿真里能通过的算法,到实车就暴露时序问题。

所以架构规范里一定要定义统一的时间同步方案和时钟源。每个功能模块处理数据时,必须基于数据的采集时间戳,而不是模块本地收到数据的时刻。平台服务层要提供时间同步服务,把各个传感器、执行器的数据对齐到一个统一时间轴上。测试时,仿真环境要注入真实的时延分布,而不是理想化的零时延,这样仿真结果才有参考价值。

在验证环节我还建议搭一套“架构合规性检查工具”,用静态检查扫描代码,看有没有模块绕过平台服务层直接进行跨模块交互,有没有接口字段单位随便定义。这套东西写起来不复杂,但对维持架构规范的严肃性特别有帮助。规范的权威性不是靠文档贴出来,而是靠工具在开发流程里自动执行出来的。

5. 一些额外的想法

架构设计这个东西,最难的不是建立规范,而是在持续迭代中守住规范。功能软件平台只要还在演进,就会有各种各样的“特殊情况”跳出来,今天一个模块说“我这个场景必须突破架构”,明天另一个模块说“这个接口要加个临时字段”。守不住原则,架构很快就变成一张废纸。

我自己有两个小习惯,在几个项目里反复验证过有效。第一,代码评审里必须有一项是架构合规检查,哪怕多花二十分钟,也能拦住大部分跑偏的改动。第二,定期做一次架构review,不一定大张旗鼓,每个迭代结束复盘一下,看哪些模块开始变胖、哪些接口开始变多、哪些跨层访问“不小心”出现了,及时修正比年底统一治理省力得多。

后面有时间的话,我准备继续写设计规范系列的下一个部分,重点拆一下接口规范和数据定义,这块涉及的内容更细,踩过的坑也更多。如果你正在设计智能驾驶功能软件平台,或者正在为架构评审发愁,希望这篇内容的经验能让你少走一些弯路。说到底,架构规范是在为整个项目降低不确定性,把每个人的工作边界画清楚,才能让整个团队在一条稳定、可预期的轨道上高效推进。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询