软件定义汽车,那谁来定义软件?
2024-06-12
来源:智车科技
软件定义汽车(Software Defined Vehicles, SDV)这个话题,已经算是老生常谈了。尤其是汽车新四化技术不断发展的这几年,软件定义汽车这个话题在不同的场合被人们提及和重申。当然,也有一些文章、一些人群表示了不同的观点,认为该表述有些以偏概全、夸大其词的意味。那实际情况又是什么样的呢?可能很多人是会有一些疑问,比如:为什么是软件定义汽车?软件如何定义汽车?谁来定义软件?
其实对于前两个问题业内已经有较为普遍的共识:汽车产业经过上百年的发展,发动机、底盘、悬架、座椅、车身这些传统的部分已经很难在做出什么新花样了,与之对应的投入也逐渐减少。而在软件相关开发成本上加大投入,需求量也在不断扩大。决定未来汽车的是以人工智能为核心的软件技术,而不再是汽车的马力大小,是否真皮沙发座椅,机械性能好坏。因此,软件定义汽车是大势所趋,即通过软件来表达汽车这一产品的很多特性、功能、服务成为一种趋势。
图 单车平均代码长度变化
今天笔者最想分享的是前面提到的第三个问题:既然软件定义汽车,那究竟谁来定义软件?
这里不卖关子,先直接亮明笔者的观点:软件定义汽车,需求定义软件。为什么呢?下面是笔者的一些拙见。
为什么是“需求”?
在这里先讲一个笔者亲历的故事:在笔者从业的最开始几年一直埋头研究算法,然后搭建模型(主要基于simulink),最后基于快速原型系统上车验证。当时的工作状态是真的好:自己搞算法调研、自己设计算法、用simulink搭建模型实现、再通过快速原型设备上车进行验证……实现自己想要功能时,真的是发自内心的自豪和开心。每天早上上班真的想赶紧去公司向领导汇报昨天的成果,那种状态真的是好极了!但是这种状态有一天被改变了。
一次团队从GM挖来一位资深的汽车动力学控制的专家,当时笔者负责运动控制模块的算法出现了一点棘手的问题需要解决。那位专家刚来的第一天领导便安排这位专家与我进行了沟通,简单的寒暄之后我们的聊天进入正题。那位专家问出了第一个问题:咱们现在的需求是什么,有文档吗?面对这个问题有些不知所措,因为当时我们的开发似乎没有什么明确的需求,只是想到哪做到哪。
其实在此之前看到过一篇mathwork高级应用工程师董淑成的文章,是关于MBD(基于模型的开发)开发的,里面讲到汽车的“V”流程开发,讲到了系统需求、软件需求,如何进行单元测试、集成测试以及如何形成开发工作的闭环反馈。
展开来说,如果你的团队完全是严格按照“V”进行正向开发的话,当系统需求分析没有完成或没有通过集体评审的话,是无法进行系统架构设计的。但是,实际中真的是这样吗?当然不是,这种完全一步一个脚印,按部就班的开发过程在实际中几乎是不存在的,受到项目周期的约束和版本快速迭代的压力,很多工作往往都是同步进行,交叉开展的。举个例子:当系统工程师把系统需求分析搞完并编写出初版“***系统需求文档”时,即便这个时候文档并未完成评审和释放,架构师也可以开始进行架构设计了,在后面需求评审中如有某些变化架构设计可以基于变化进行相应的微调即可,这样不断迭代循环完成设计。这是需求的在”V”流程中左侧过程的意义,当然也是对于软件开发的意义。
再来看”V”流程右侧的测试过程,在这一过程中是对左侧工作成果的确认和验证,也就是保证“开发做了正确的事和正确的做了事”。对于不同层级的测试过程,都需要基于需求去展开测试,测试工程师的测试用例不是凭空捏造和主观臆断的,而是有理有据的。有多少条需求,就要针对这些需求设计相应的测试用例来验证它。当然,并不是有N条需求就对应N条测试用例,有可能一个需求需要多个测试用力来验证,这就是测试覆盖度。因此,在“V”流程的右侧工作过程中仍然离不开“需求”,软件开发正确与否测试人员直接是看不出来的,必须要基于你的需求文档来逐条验证才行。所以有的时候工程师往往会出现“补文档”的情况。单从“补文档”这一非正规操作来看,就足以说明需求必不可少,就更不要说严格按照正向研发流程展开的软件产品开发工作了。所以,当上面那位专家提出那个问题的时候,我再一次意识到了需求的重要性。
随着对”V”流程的不断理解,加之在后面的工作、培训以及与不同层次的人的沟通中对需求这一概念的不断理解,慢慢认识到需求才是开发的源头、边界、目标,需求才是核心。因此,才有了我开始的回答。在产品开发中,很多时候会忽略需求的重要性而过于强调某项技术。实际技术是为产品服务的,而产品又是由需求来定义的。回到我们的问题:谁来定义软件?如果回答不是需求那还能是什么呢?在汽车嵌入式系统开发流程中,从系统需求到子系统需求到硬件需求、软件需求,这一过程既是设计与开发的过程,又是需求不断细化和深入的过程。任何一个工作过程都是在上一层需求的基础上展开开发,如果某一工作过程偏离、超出甚至脱离了上一层的需求,哪这一工作将出现极大风险并失去意义,进而对整个产品开发造成巨大损失。
以上是笔者一些粗浅的观点和认识。既然需求如此之重要,那如何进行需求开发呢?
需求怎么定义
谈到到需求开发,笔者立马想起自己在工作中认识的一位外国朋友Chakri。他是一位来自印度的软件工程专家,是他让笔者第一次较为系统的了解需求开发。第一次与他交流时,我用极其贫瘠的英文词汇和他展开对话。但我令我惊奇的是他总能第一时间理解我想表达的内容,并给与回答和补充。那次交流使我对需求开发有了全面且系统的认识,并从此开启了我的“正规”开发之路。
说到需求开发,就必须了解需求工程。需求工程包括两部分工作过程:需求开发和需求管理。
需求工程是指应用已证实有效的技术、方法进行需求分析,确定客户需求,帮助分析人员理解问题并定义目标系统的所有外部特征的一门学科。它通过合适的工具和记号系统地描述待开发系统及其行为特征和相关约束,形成需求文档(需求规格说明书),并对用户不断变化的需求演进给予支持。
对于需求管理我们先不展开,因为它涉及到一些项目管理的内容,这里主要讲需求开发。
在进行需求开发时,对于一个产品或系统而言,需求是分不同层级的。一般来说分:业务需求、用户需求和系统需求,系统需求往下细分又可以分为不同的子系统需求。对于自动驾驶系统开发来说,子系统需求一般包含:硬件需求和软件(应用软件)需求。硬件需求通常指的是对域控制器的需求,用于指导、约束、定义控制器的开发;软件需求指的是对感知、定位、预测、规划、控制等模块整体的需求,用于指导、约束、定义软件系统的开发。
这里的软件需求一定是对于整个系统的需求而不是对某个模块而言的。为什么去这样强调,原因是在需求开发时需求工程时很容易混淆需求边界,导致将系统需求、子系统需求、模块需求混为一谈。理解需求层级边界的一个很好理解解释就是在定义某一层需求时将这个系统或模块看作是一个黑盒子,只关心它对外提供什么功能或服务,而不要关心它是如何实现的。拿系统需求开发中的简单例子,如:“在不具备换道条件时,系统应控制车辆保持在车道中心行驶”。这里我们暂且不去细究这条需求描述的准确性,单从“黑盒”理念(暂且这儿叫)来看,这条需求是符合的。到这里我们可以得出一个结论:在不同层级需求开发的过程中其实就是在定义这个系统(子系统、模块)的功能、特性、边界。
说完了需求分层理论,这里再聊一个更重要的东西:需求的特性。换句话说就是什么样的需求才是规范的需求,优秀的需求。这一点对于需求开发者、对于研发工程师,甚至对于每一个产品相关的人员来说都很重要。通常来说需求应具备以下特性:
① 完整性:完整描述每项需求的功能
② 正确性:经过用户和用户代理人的审阅
③ 可行性:在已知能力和约束条件中实现
④ 必要性:每项需求功能都隐私用户正真需要的
⑤ 无歧义:对所有读者只有一种一致的解释
⑥ 无交叉重叠:在不同的需求功能中没有重复的内容
⑦ 可验证性:可以设计测试方法来监察
⑧ 正确的详细层次:不同需求层次的结构要清晰
⑨ 划分优先级 :提供了实现优先的次序
⑩ 与实现无关性:与后续的设计开发如何实现无关
用来自GM专家的话说:需求开发的精细程度要达到每条需求对应这一行代码。这句话我仍然记忆犹新。
说了这么多,我们拿两个常见的feature来看一下需求是如何定义的。
从以上的需求列表中我们可以看到,虽然这是系统级的需求,但很大程度上这些需求已经对软件的设计进行一定程度定义和约束。那进一步的如果到达模块级的需求讲把软件模块的功能和边界定义的很清楚。我们再来再来看几个软件模块的需求:
Req1:横向控制模块应输出目标方向盘转角作为控制量。
Req2:横向控制模块应将最终输出的目标转角值限制在[-500,500]度以内。
Req3:横向控制模块应将目标转角的变化率限制在[-300,300]度每秒以内。
Req4:横向控制模块应对目标转角进行低通滤波处理以消除信号抖动。
看到上面的这几条需求是不是已经很细化了,基本上达到了需求的最理想状态:每一条需求可以对应一行代码。没错,需求写到这个程度已经很不错了,这样软件代码是不会存在无缘无故的多写和少写的。这就是需求定义软件的真谛!
换句话说,只要需求写清楚了,那么产品也就清楚了、软件也就清楚了,最终不管是用什么算法、什么语言去开发其结果都是可预见的。