自动驾驶软件开发中的 DevOps

自动驾驶软件开发中的 DevOps

[TOC]

由于我有幸参加过自动驾驶软件开发的 DevOps 平台的搭建与优化, 在实践中有些感触, 在本文总结一下, 也算是对过去将近一年的软件集成测试工作经验的心得总结.

什么是 DevOps ?

DevOps(Development 和 Operations 的组合词)是一组过程、方法与系统的统称,用于促进开发(应用程序/软件工程)、技术运营和质量保障部门之间的沟通、协作与整合。之前参加过 DevOps的极客时间的教程(DevOps 实战笔记), 老师讲的很不错, 把我的学习笔记贴在这里. 这个课程对于其全面的理解很有帮助, 推荐给感兴趣的各位.

为什么在自动驾驶软件开发中应用 DevOps?

DevOps 这个火于互联网软件的开发思想, 已经在很多领域有了不错的实践. 自动驾驶软件相比于传统的汽车软件相比有如下特点使得其可以被考虑借鉴 DevOps 的思想.

  • 车联网, 5G 的兴起使得 FOTA 这种在线升级汽车软件成了可能, 而不是像之前汽车软件, 如果要更新 bug 只能通过召回的形式, 让车主开到 4S 店手动刷写升级. 这种特性带来的结果, 汽车成了与手机一样的软件载体. 也就是可以根据多变以及可定制化的软件设计满足不同用户以及软件不同开发阶段的需求. 这与互联网产品的开发有异曲同工之妙. 互联网开发的思想之一的 DevOps 也因此可以应用在汽车软件开发上.
  • 自动驾驶软件的开发更倾向于 C++ python 这些”较高级”编程语言, 应用的算法也在从前算法的基础上增加了深度学习, 强化学习, 众包地图理解等更加复杂的算法. 传统的汽车软件一般都是基于 MDB(matlab/simulink) 以及 C 语言开发的. 开发, 验证, 仿真等配套的工具链成熟(有时候是第三方的专业工具公司, 有时候是供应商通过把工具打包到产品中提供给 OEM). 但是这些工具在自动驾驶领域不太够用, 不管是感知的学习网络还是决策规划等行为端, C++ 给了更多的灵活性以及性能可操控性(这对实时性要求极高的系统而言非常重要). 传统的工具链不可用, 需要借助同样依赖 C++ python 等语言的互联网开发工具与思路. DevOps 是其中的集大成者.
  • 自动驾驶软件的开发是个非常复杂的体系. 从独立的芯片设计, 运算平台到各式各样的传感器, 再到复杂的功能需求实现, 这些很多时候都是需要慢慢摸索的. 再加上与传统汽车软硬件还有配合地方, 让其开发显得很像一个缝合怪. 自动驾驶软件的开发还没有步入成熟阶段, 需要试错的地方很多. 能够提供组合持续优化以及最初如何开始的思路的, DevOps 可以算一个很不错的候选.
  • 当前很热的自动驾驶技术的发展需要跑步式前进, 传统的瀑布式开发流程, 不够灵活束缚了开发的速度. DevOps 与敏捷开发思想类似的是, 可以通过小步快跑的形式加快开发节奏, 适应市场对技术发展的需求(卷起来!).

自动驾驶软件开发无法照搬互联网 DevOps 的原因

  • 实时性安全性要求较高. 大部分互联网产品可以推行小步快走的原因是它们可以在一定范围内犯错, 例如访问延迟, 客户访问产品卡顿严重, 但很多情况下不会影响客户的生命危险, 带来例如剁手爽感降低的不好体验. 自动驾驶则不然, 100km/h 下的汽车在 100ms 时间内(规划的一帧, 一般而言)行驶距离 2.78m 已经有半个车身的距离了, 一旦出现碰撞事故, 可能带来的是车上人员甚至是连环相撞下的多车人员生命风险. 尤其是大多数时间下驾驶员觉得自动驾驶系统足够安全, 对自动驾驶系统产生了依赖, 这种情况下, 驾驶员对风险场景的反应反而还不如不使用不依赖自动驾驶的驾驶员(想起了自己的硕士课题, shared control). 因此, 自动驾驶软件的开发需要严谨再严谨. 不管是特斯拉还是国内的某新势力都出现过导致驾驶员丧生的案例, 并且由于对自动驾驶技术的法规以及检测技术还没有成熟, 很多时候自动驾驶软件并没有最终的验证方式.

  • 场景复杂. 互联网软件, 如电商, 社交软件, 功能服务等, 它们通过手机, 电脑端, 网页端与用户交互, 这些功能场景以及交互方式在于自动驾驶相比, 复杂度是小巫见大巫. 即便是老司机在很多场景下都是 hold 不住的, 更何况是开发还未成熟的软件算法. 场景的复杂性的一个直接后果便是仿真验证的几乎不可能. 很多自动驾驶算法的仿真验证甚至是在 GTA 这种沙盒世界中进行, 但也很难保证验证精度, 更不用说制造所有场景的高昂成本了. 与之相对的是互联网产品, 很多领域内有比较成熟的工具框架, 例如 Android 下的 Appium 框架. 作为 DevOps 非常重要的一环, 自动化测试, 可以在互联网产品上蓬勃发展, 但是在自动驾驶软件开发上很难得到贯彻. 如果考虑到系统架构(计算平台, 传感器配置), 系统需求定义等各家都不同的背景下, 想要有一个统一的自动化测试框架, 简直是不可能.

    即便不说自动化测试, 开发也受到场景复杂的限制. 例如, 利用学习算法学习场景, 抽出 features 很多时候需要进行标注. 由于现实场景的几乎无限性, 对场景的标注也是很大的课题.

  • 与传统汽车开发思想藕断丝连. 既然是汽车开发, 自动驾驶软件的开发需要整车的开发流程相嵌合. 下面是整车开发过程的示例.

    同时与 EPS 等传统软件功能有联系的自动驾驶软件也必须考虑与它们的开发流程相配合(例如 ASPICE).

    即便在车辆电子电气架构面临变革的现在(例如域功能化, SOA等), 自动驾驶软件也很难像互联网软件一样能够较快较灵活地改变开发流程, 切换到 DevOps 的开发思想上来.

在这些不同下, 摸索出的将 DevOps 与 ASPICE 流程相结合下的尝试思路.

ASPICE 下的 DevOps

整体架构如下:

总体的思路是: 在 ASPICE 架构下, 进行流程的安排, 通过 CI CD 等技术手段打通自动化集成, 测试, 数据反馈, 项目管理等流程, 以实现 DevOps 开发思想.

诚然这是一个妥协后的缝合怪. 但是探索期间, 也是一个很好的尝试.

分工

按照 ASPICE 流程的分工, 分为项目, 系统, 开发, 集成, 测试等职能. 具体这里不展开, 可以直接参考 ASPICE 手册.

持续集成 CI

大概有如下指导性原则:

  • 所有环节关键产出均持续优化为代码, 不仅包含软件实现本身的代码, 配置文件等, 也包括规则化的需求文档, 测试代码, 测试用例, 集成 pipeline 脚本, 测试调试工具, 制品的元数据等等.

  • 系统性记录制品每次更新细节. 按照 ASPICE 流程, 集成与模块开发都是共同的输入, 然而考虑到需求的灵活, 阶段性的开发过程等等, 每次的集成内容不会完全按照既定的需求来实现, 因此为了保证集成后版本的可控性, 需要将每次集成的细节格式化记录下来. 同时为了确保收集到的细节是被大家理解正确的, 集成人员需要在 scrum 站会上逐条对照确认. 信息使用规范化的格式, 方便后期管理(代码化).

  • 把问题阻隔在上游. 例如, 如果代码编译不通过或者静态检查不达标, 代码无法被 merge 到 git 公共开发 branch 上. 模块无法通过其单元测试, 该模块无法参与版本构建, 在与其他模块接口不变的情况下, 使用之前集成已经构建的制品参与本次集成, 并通知相关人员. 如果无法通过 SIL/HIL 上的版本冒烟测试测试用例集, 版本集成失败, 记录数据与测试结果, 上传数据到专用的问题管理平台(例如 Jira), 直到问题解决或者项目达成某种共识, 集成出版本. 这也是”集成地狱”说法的由来, 只要有一个模块出现了问题, 集成就得陪着直到解决为止.

  • 状态即反馈. CI 的 pipeline 出现了任何问题, 会通过邮件/ Jira 通知对应的模块负责人. 每次集成的信息(release note 等)可以轻易查询获取到. 测试用例, 测试结果以及数据会通知相关人员分析处理, 并且能够轻易访问获取.

  • 测试自动化, 放入 pipeline 中. 无论是代码静态检查, 单元测试(可能涉及到交叉编译, 使用到虚拟化容器), 接口测试, 覆盖率测试, 桩点测试, 还是数据回灌, SIL 仿真测试, 在每次版本构建过程中必须达到既定的要求才能继续下去. 考虑到软件最终运行的硬件平台以及中间件环境(QNX ROS等)也许无法进行深层次的 SIL, 这时候可以借助 HIL 实现测试的自动化.

  • 版本配置化. 为了方便差异化调试/测试需求, 通过制品的元数据管理, 配置文件的规范化, 通过修改参数一键构建出满足特定需求的版本. 例如 AB 测试的版本构建, 模块的回退与不同版本下各模块的组合, 不同测试车辆的传感器标定参数/与其他特异软件版本相适配等场景.

使用的工具, 主要是开源工具以及自制的脚本:

  • 代码管理: Gitlab
  • pipeline: Jenkins
  • 制品库: Artifactory
  • 元数据管理 : Conan
  • 容器化: Docker, K8s
  • 代码检查: QAC
  • 问题管理: Jira
  • 以及一些其他测试用的商业工具.

持续部署 CD

分为 2 个阶段: 开发初期, FOTA 期.

开发初期

主要靠手动刷写的方式实现软件的部署. 这涉及到部署工具的开发以及控制器存储空间的管理.

FOTA 期

借助车载联网系统, 将差异化版本推送到控制器内.

这涉及到通信安全, 车辆自检等很多技术.

推荐资料

一个 DevOps 方面很棒的网站: https://devops.phodal.com/home

其中比较帅的工具元素周期表:

参考链接:

https://clicccar.com/2020/03/07/958117/glossary_developing_method_01/

作者

cx

发布于

2022-05-07

更新于

2022-07-16

许可协议