# 功能安全介绍 ## 目录 - [功能安全介绍](#功能安全介绍) - [目录](#目录) - [功能安全框架](#功能安全框架) - [模块说明](#模块说明) - [1. statistics(数据统计)](#1-statistics数据统计) - [2. safety\_manager(功能安全模块)](#2-safety_manager功能安全模块) - [功能安全配置](#功能安全配置) - [statistics 配置](#statistics-配置) - [resource statistics 配置](#resource-statistics-配置) - [process statistics 配置](#process-statistics-配置) - [latency statistics 配置](#latency-statistics-配置) - [checker 配置](#checker-配置) - [channel\_freq\_checker 配置](#channel_freq_checker-配置) - [collision\_checker 配置](#collision_checker-配置) - [control\_checker 配置](#control_checker-配置) - [file\_exist\_checker 配置](#file_exist_checker-配置) - [latency\_checker 配置](#latency_checker-配置) - [localization\_checker 配置](#localization_checker-配置) - [process\_checker 配置](#process_checker-配置) - [resource\_checker 配置](#resource_checker-配置) - [analyzer 配置](#analyzer-配置) - [功能安全自定义添加](#功能安全自定义添加) - [代码示例](#代码示例) - [功能安全使用方法](#功能安全使用方法) - [功能安全现有配置项](#功能安全现有配置项) - [配置项总览表](#配置项总览表) --- ## 功能安全框架 开源 Apollo 主要面向学习型开发者使用,不能提供实车场景安全保障。园区版新增了**功能安全模块**,用于检测系统的异常情况并执行风险规避措施,整体架构如下: ![功能安全整体架构](img/功能安全框架.png) 文本架构说明: ``` ┌─────────────────────────────────────────────────┐ │ 功能安全整体架构 │ ├─────────────────────────────────────────────────┤ │ ┌─────────────┐ ┌─────────────────────┐ │ │ │ statistics │────▶│ safety_manager │ │ │ │ (数据统计) │ │ (功能安全核心模块) │ │ │ └─────────────┘ └─────────────────────┘ │ │ │ │ │ ┌───────────────┼───────────────┐ │ │ ▼ ▼ ▼ │ │ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │ │ │ checker │ │ exporter │ │ analyzer │ │ │ │ (异常检测)│ │(信息输出)│ │ (状态解析) │ │ │ └──────────┘ └──────────┘ └──────────────┘ │ │ │ │ │ ┌───────────────┼───────────────┐ │ │ ▼ ▼ ▼ │ │ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │ │ │aggregator│ │ decider │ │ guardian │ │ │ │(消息聚合)│ │(策略生成)│ │ (指令输出) │ │ │ └──────────┘ └──────────┘ └──────────────┘ │ └─────────────────────────────────────────────────┘ ``` ### 模块说明 **整体分为两部分:** #### 1. statistics(数据统计) 负责完成一些信息数据统计,包括: - 资源使用信息(CPU/GPU/MEM/Disk) - 进程存在信息 - 模块间消息延迟信息等 #### 2. safety_manager(功能安全模块) 负责检测是否存在异常,并触发安全风险规避指令。执行流程: ``` 状态检测 → 发送 → 聚合决策 → 执行 ``` | 组件 | 职责说明 | |------|----------| | **checker 模块** | 负责异常检测,每种 checker 是个独立的 cyber 组件 | | **exporter 库** | 基础类库,checker 调用 exporter 输出零散的异常信息 | | **analyzer 组件** | 解析 exporter 的输出信息,根据策略判断每个检测项的实时状态 | | **aggregator 库** | 用于消息聚合,输出聚合消息 | | **decider 库** | 根据所有检测项结果生成刹停策略(缓刹/急刹) | | **guardian** | 读取刹停策略,输出最终的 control 指令 | --- ## 功能安全配置 ### statistics 配置 主要是配置统计的信息,通常情况下使用默认配置即可。 #### resource statistics 配置 **文件路径**:`modules/statistics/resource/conf/resource_statistic_conf.pb.txt` **配置说明**:cpu、gpu、mem 会自动检测,主要是配置检测的磁盘对象。 ```protobuf disk_conf { # 配置一个检测的磁盘,支持标准的正则表达式匹配 # sda1, nvme0n1 and etc device: ["sd[a-z][0-9]*", "nvme[\\w]*", "ssd[\\w]*"] } ``` **输出说明**:channel `/apollo/statistics/resources` | 资源类型 | 监控指标 | |----------|----------| | **cpu** | 使用率、温度 | | **gpu** | 使用率、温度 | | **mem** | 使用量、总量、空闲量、使用率 | | **disk** | 使用量、总量、空闲量、使用率、负载(Orin 上暂未支持) | --- #### process statistics 配置 **文件路径**:`modules/statistics/process/conf/process_statistic_conf.pb.txt` **配置说明**:mainboard 启动的 cyber 组件会自行检测,主要是配置其他程序。 ```protobuf general_process { # 支持正则表达式配置 regex: [".*/apollo/scripts/.*", "cyber_recorder record .*"] } ``` **输出说明**:channel `/apollo/statistics/process` | 输出项 | 说明 | |--------|------| | `mainboard_dag` | 列出所有的用 mainboard 启动的 dag | | `mainboard_process_group` | 列出所有 mainboard 的 group 组(即 `-p` 指定的参数) | | `general_process` | 用户自定义的程序状态 | --- #### latency statistics 配置 **文件路径**:`modules/statistics/latency/conf/latency_statistic_gflags.conf` **配置说明**:主要是配置指定融合点云的 channel(因为每个用户输出的 channel 名可能不一致)。 ```bash # set your lidar compensator topic, default use FLAGS_pointcloud_16_topic #--compensator_topic= ``` **输出说明**:channel `/apollo/statistics/latency` 包括补偿点云、perception、prediction、planning、control 多个模块的延迟信息,每个延迟项包括: | 指标 | 说明 | |------|------| | `proc_ms` | 处理耗时毫秒数,包括 min/max/avg 及计算采用的样本数量 | | `chain_ms` | 主 lidar 读取时间到当前模块的延迟,包括 min/max/avg 及计算采用的样本数量 | --- ### checker 配置 checker 的一些通用配置,在各个 checker 的 `conf` 目录 `gflags` 文件中,主要包括: | 配置项 | 说明 | |--------|------| | `report_interval` | 检查结果输出频率 | | `filter_required_cycles` / `filter_total_cycles` | 过滤策略,如 `3/5` 表示 5 个周期内 3 次异常才计算为异常 | | `duration_ms` | 异常信息持续多长时间才会判定为异常 | | `status_timeout` | 异常消息经过多久会置为正常 | | **报警级别** | `WARN`=只发送警告,`ERROR`=执行缓刹,`FATAL`=执行急刹 | > 📌 所有 checker 的最终结果都会输出到 `/apollo/safety/status` channel。 --- #### channel_freq_checker 配置 **功能**:检测 channel 频率是否有异常。 **文件路径**:`modules/safety_manager/checker/channel_freq_checker/conf/channel_freq_checker_conf.pb.txt` **配置说明**:主要是指定要检查的 channel 阈值以及报警级别。 ```protobuf # 每个 item 一行,指定 channel 名称,异常级别,以及频率下限和上限 item { name: "/apollo/perception/obstacles", level: ERROR, expect_freq: 10, lower_limit: 6, upper_limit: 15 } ``` --- #### collision_checker 配置 **功能**:检测是否存在碰撞风险。 **文件路径**:`modules/safety_manager/checker/collision_checker/conf/collision_checker_conf.pb.txt` **配置说明**:主要是配置警告、缓刹、急刹的阈值,以及选取的策略。 ```protobuf # The seconds time to collision in different level warn_sec: 5.0 # Do nothing, just sending a warning status error_sec: 4.0 # Comfortable brake fatal_sec: 3.0 # Emergency brake # strategy type: # SENSITIVE: 保守策略,低风险也可能报警,召回率高 # ACCURATE: 仅通过 prediction 计算 TTC,报警较少,准确率高 # NORMAL: 中性策略,默认配置 type: NORMAL # sensitive strategy 详细配置 sensitive_strategy_conf { collision_check_angle: 90.0 # 前向碰撞检测角度 collision_check_distance: 100.0 # 前向碰撞检测距离 predict_adc_by_acc: true # 是否通过加速度预测 ADC 轨迹 acc_calculate_sec: 3.0 # 加速度计算时间,之后速度视为恒定 predict_obs_by_perception: true # 障碍物预测方法:感知 predict_obs_by_prediction: true # 障碍物预测方法:预测 predict_obs_by_stationary: true # 障碍物预测方法:静止 adc_front_extended_len: 0.2 # ADC 前向扩展长度 (米) adc_lateral_extended_len: 0.2 # ADC 横向扩展长度 (米) adc_back_extended_len: 0.2 # ADC 后向扩展长度 (米) speed_threshold_mps: 0.01 # 低速不检测阈值 steering_threshold_percentage: 50 # 转向不检测阈值 } ``` --- #### control_checker 配置 **功能**:检测自动驾驶控制指令和车体实际控制情况的偏差。 **文件路径**:`modules/safety_manager/checker/control_checker/conf/control_checker_conf.pb.txt` **配置说明**:conf 文件中主要定义每种偏差类型的报警级别,gflags 文件中给了默认的偏差检查阈值,通常不需要修改。 --- #### file_exist_checker 配置 **功能**:检测指定路径文件是否存在。 **文件路径**:`modules/safety_manager/checker/file_exist_checker/conf/file_exist_checker_conf.pb.txt` **配置说明**:指定文件路径和报警级别。 ```protobuf # file name: file alias or short name. # file path: absolute path or relative path base on current directory, usually in "/apollo/". # risk level: WARN, ERROR, FATAL. item { name: "novatel_localization_extrinsics.yaml" path: "./modules/localization/msf/params/novatel_localization_extrinsics.yaml" level: FATAL } ``` --- #### latency_checker 配置 **功能**:检查模块是否有处理耗时、延迟异常。 **文件路径**:`modules/safety_manager/checker/latency_checker/conf/latency_checker_conf.pb.txt` **配置说明**:配置指定模块耗时或者延迟阈值,模块包括补偿点云、感知、预测、规划、控制。 ```protobuf # item config # name: unique check name # module enums: LIDAR_COMPENSATOR,PERCEPTION,PREDICTION,PLANNING,CONTROL # type enums: PROC_MS, CHAIN_MS # level: alarm level, enums WARN,ERROR,FATAL # avg: avg latency condition, in milliseconds # min: min latency condition, in milliseconds # max: max latency condition, in milliseconds # sample_size_lower_limit: sample_size less than the limit will be ignored # lidar compensator item { name: "lidar compensator proc time", module: LIDAR_COMPENSATOR, type: PROC_MS, level: ERROR, avg: 150, sample_size_lower_limit: 10 } item { name: "lidar compensator chain time", module: LIDAR_COMPENSATOR, type: CHAIN_MS, level: ERROR, avg: 150, sample_size_lower_limit: 10 } # perception item { name: "perception proc time", module: PERCEPTION, type: PROC_MS, level: ERROR, avg: 200, sample_size_lower_limit: 10 } item { name: "perception chain time", module: PERCEPTION, type: CHAIN_MS, level: ERROR, avg: 250, sample_size_lower_limit: 10 } ``` --- #### localization_checker 配置 **功能**:检查定位信息是否存在异常。 **文件路径**:`modules/safety_manager/checker/localization_checker/conf/localization_checker_gflags.conf` **配置说明**:主要是读取 localization status channel 状态返回,gflags 文件中可以配置等级映射关系。 ```bash # localization checker name #--localization_checker_name="Localization" # The safety status fatal threshold, when the localization status value is # greater than the threshold, set safety status to fatal. # MeasureState::ERROR: 1 # MeasureState::CRITICAL_ERROR: 2 # MeasureState::FATAL_ERROR: 3 # default fatal threshold: 3 #--safety_status_fatal_threshold=3 ``` > 📌 配置成 `3` 表示 status 中的 `ERROR` 会触发急刹,`2` 表示会触发缓刹。 --- #### process_checker 配置 **功能**:检查指定进程是否存在。 **文件路径**:`modules/safety_manager/checker/process_checker/conf/process_checker_conf.pb.txt` **配置说明**:检测 dag、mainboard 进程组、普通进程是否存在。 ```protobuf item { name: "Perception Process Group", type: MAINBOARD_PROCESS_GROUP, value: "perception", level: FATAL } item { name: "Guardian Components", type: DAG, value: "guardian.dag", level: FATAL } item { name: "Recorder Process", type: GENERAL_PROCESS, value: "cyber_recorder record -all", level: WARN } ``` --- #### resource_checker 配置 **功能**:检查资源使用是否存在异常。 **文件路径**:`modules/safety_manager/checker/resource_checker/conf/resource_checker_conf.pb.txt` **配置说明**:主要是配置 cpu、gpu、mem、disk 的使用上限阈值。 ```protobuf # CPU 配置 cpu { usage_warning: 80 usage_error: 90 temperature_warning: 75 temperature_error: 90 } # GPU 配置 gpu { usage_warning: 80 usage_error: 90 temperature_warning: 75 temperature_error: 90 } # Memory 配置 memory { usage_warning: 80 usage_error: 90 used_warning: 20000 # MB used_error: 30000 # MB available_warning: 2000 # MB available_error: 1000 # MB } # Disk 配置 disk { name: "Data DisK" device: "sda1" usage_warning: 80 usage_error: 90 used_warning: 400 # GB used_error: 500 # GB available_warning: 50 # GB available_error: 10 # GB load_warning: 10 load_error: 20 } ``` --- ### analyzer 配置 **功能**:analyzer 主要是规则匹配的配置,对某些检测项添加自定义配置时使用,用户通常不需要关注。 **文件路径**:`modules/safety_manager/analyzer/conf/rule_matcher_conf.pb.txt` **配置说明**:主要是 `rule` 和 `matcher` 的配置,`rule` 决定匹配哪些检查项,`matcher` 决定使用什么样的规则。 ```protobuf rule_matcher { matcher { # full name match list #name: Memory # or #name: ["CPU", "Memory"] # name contains match list #contains: ["Mem"] # name prefix match list #prefix: ["Mem"] # name regex match list #regex: ["Mem.*"] # tags contains one match list #tags_contains_one: ["resource", "load"] # contain resource or load # tags contains many match list #tags_contains_many: ["resource", "load"] # contain resource and load } rule { # note: at most one rule can be configured at the same time # timeout seconds #timeout: 3.0 # duration rule in seconds #duration: 10.0 # filter rule #filter { # required_cycles: 3 # total_cycles: 5 #} } } ``` --- ## 功能安全自定义添加 功能安全的 `exporter` 库对外提供了函数 `callback` 和主动发送两种接口,消息会统一输出到 `/apollo/safety/status` channel。 📚 具体说明参考 `exporter` 目录下 `README.md`,使用样例参考 `examples` 目录下的 `example.cc`。 ### 代码示例 ```cpp #include #include "cyber/cyber.h" #include "modules/safety_manager/exporter/exporter.h" namespace safety_ns = apollo::safety_manager; /** * @brief A sample of how to use safety exporter in class. */ class GnssChecker { public: explicit GnssChecker(const std::shared_ptr& node) : node_(node) { // set period: 1s exporter_ = std::make_shared(node_, 1000); // set default filter condition exporter_->SetDefaultFilter(3, 3); /* // set default status timeout seconds exporter_->SetDefaultTimeout(2.0); // set default duration condition exporter_->SetDefaultDuration(3.0); */ } /** * @brief Adding safety exporter callback tasks. */ void Run() { exporter_->Add("Gnss Status", this, &GnssChecker::check); } protected: /** * @brief The exporter callback function. * * @param status_wrapper A SafetyStatusWrapper reference. */ virtual void check(safety_ns::SafetyStatusWrapper* status_wrapper) { { // do some gnss status check } // writer status status_wrapper->Summary(safety_ns::SafetyStatus_Status_OK, "OK"); } private: std::shared_ptr node_; std::shared_ptr exporter_; }; int main(int argc, char** argv) { // init cyber framework apollo::cyber::Init(argv[0]); // create node std::shared_ptr node = apollo::cyber::CreateNode("safety_exporter_example"); // create reader AINFO << "begin create safety status reader."; apollo::cyber::ReaderConfig reader_cfg; reader_cfg.channel_name = SAFETY_EXPORTER_TOPIC; reader_cfg.pending_queue_size = 10; node->CreateReader( reader_cfg, [](const std::shared_ptr& safety_status) { AINFO << "recvieve safety status message: \n" << safety_status->DebugString(); }); AINFO << "begin write safety status info."; // create exporter instance auto exporter = std::make_shared(node); // report status directly exporter->Report("CPU Usage", safety_ns::SafetyStatus_Status_WARN, "value 75%, threshold 70%"); // report add detail values exporter->Report("CPU Temp", safety_ns::SafetyStatus_Status_OK, "OK", {{"cpu1", "40"}, {"cpu2", "40"}}); // report by StatusWrapper auto status_wrapper = std::make_shared("MEM Usage"); status_wrapper->SetTags({"resource"}); status_wrapper->Summary(safety_ns::SafetyStatus_Status_OK, "value: 30%"); exporter->Report(status_wrapper); // add exporter task GnssChecker gnss_checker(node); gnss_checker.Run(); apollo::cyber::WaitForShutdown(); } ``` --- ## 功能安全使用方法 1. 修改 `/apollo/modules/canbus/conf/canbus.conf` 配置 2. 注释掉最后一行 `–noreceive_guardian`,改成 `#–noreceive_guardian` ```bash # 原配置 –noreceive_guardian # 修改后 #–noreceive_guardian ``` --- ## 功能安全现有配置项 > ⚠️ **报警级别说明**:`WARN`=只警告,`ERROR`=缓刹,`FATAL`=急刹 > 📁 刹停阈值配置文件:`/apollo/modules/safety_manager/guardian/conf/guardian_conf.pb.txt` > 🔧 默认缓刹阈值:25,急刹阈值:50(可修改) ### 配置项总览表 | 类别 | 配置文件 | 检查项 | 说明 | 级别 | 阈值/配置 | |------|----------|--------|------|------|-----------| | **channel 频率** | `/apollo/modules/safety_manager/checker/channel_freq_checker/conf/channel_freq_checker_conf.pb.txt` | `/apollo/sensor/lidar16/back/PointCloud2` | 顶 lidar 频率 | `ERROR` | `lower_limit: 6, upper_limit: 15` | | | | `/apollo/sensor/lidar16/left/PointCloud2` | 左 lidar 频率 | `ERROR` | `lower_limit: 6, upper_limit: 15` | | | | `/apollo/sensor/lidar16/right/PointCloud2` | 右 lidar 频率 | `ERROR` | `lower_limit: 6, upper_limit: 15` | | | | `/apollo/sensor/lidar16/compensator/PointCloud2` | 运动补偿 lidar 频率 | `ERROR` | `lower_limit: 6, upper_limit: 15` | | | | `/apollo/perception/obstacles` | 感知输出频率 | `ERROR` | `lower_limit: 6, upper_limit: 15` | | | | `/apollo/prediction` | 预测输出频率 | `ERROR` | `lower_limit: 6, upper_limit: 15` | | | | `/apollo/planning` | 规划输出频率 | `ERROR` | `lower_limit: 6, upper_limit: 15` | | | | `/apollo/control` | 控制输出频率 | `ERROR` | `lower_limit: 80, upper_limit: 150` | | | | `/apollo/canbus/chassis` | 底盘输出频率 | `ERROR` | `lower_limit: 80, upper_limit: 150` | | | | `/apollo/canbus/chassis_detail` | 底盘详情输出频率 | `ERROR` | `lower_limit: 80, upper_limit: 150` | | | | `/apollo/guardian` | 功能安全控制输出频率 | `ERROR` | `lower_limit: 80, upper_limit: 150` | | | | `/apollo/sensor/gnss/best_pose` | gnss 驱动 best pos 频率 | `ERROR` | `lower_limit: 0.3, upper_limit: 3` | | | | `/apollo/sensor/gnss/imu` | gnss 驱动 imu 输出频率 | `ERROR` | `lower_limit: 60, upper_limit: 150` | | | | `/apollo/localization/pose` | 定位输出频率 | `ERROR` | `lower_limit: 80, upper_limit: 150` | | | | `/tf` | tf 输出频率 | `ERROR` | `lower_limit: 80, upper_limit: 150` | | **文件存在性** | `/apollo/modules/safety_manager/checker/file_exist_checker/conf/file_exist_checker_conf.pb.txt` | `novatel_localization_extrinsics.yaml` | imu 外参配置文件是否存在 | `FATAL` | - | | | | `static_transform_conf.pb.txt` | 静态 tf 配置文件是否存在 | `FATAL` | - | | **延迟检查** | `/apollo/modules/safety_manager/checker/latency_checker/conf/latency_checker_conf.pb.txt` | `lidar compensator proc time` | lidar 驱动处理耗时 | `ERROR` | `avg: 150, sample_size_lower_limit: 10` | | | | `lidar compensator chain time` | lidar 点云输入到运动补偿输出耗时 | `ERROR` | `avg: 150, sample_size_lower_limit: 10` | | | | `perception proc time` | 感知程序处理耗时(点云→障碍物) | `ERROR` | `avg: 200, sample_size_lower_limit: 10` | | | | `perception chain time` | lidar 点云输入到感知障碍物输出耗时 | `ERROR` | `avg: 250, sample_size_lower_limit: 10` | | | | `prediction proc time` | 预测程序处理耗时 | `ERROR` | `avg: 100, sample_size_lower_limit: 10` | | | | `prediction chain time` | lidar 点云输入到预测障碍物输出耗时 | `ERROR` | `avg: 350, sample_size_lower_limit: 10` | | | | `planning proc time` | 规划程序处理耗时 | `ERROR` | `avg: 100, sample_size_lower_limit: 10` | | | | `planning chain time` | lidar 点云输入到规划结果输出耗时 | `ERROR` | `avg: 450, sample_size_lower_limit: 10` | | | | `control proc time` | 控制程序处理耗时 | `ERROR` | `avg: 100, sample_size_lower_limit: 10` | | | | `control chain time` | lidar 点云输入到控制结果输出耗时 | `ERROR` | `avg: 500, sample_size_lower_limit: 10` | | **定位状态** | `/apollo/modules/safety_manager/checker/localization_checker/conf/localization_checker_gflags.conf` | `Localization` | 定位状态 | 根据 `msf_status` 状态判断 | - | | **进程存在性** | `/apollo/modules/safety_manager/checker/process_checker/conf/process_checker_conf.pb.txt` | `Perception Process Group` | 感知进程 | `FATAL` | - | | | | `Static Transform` | tf 进程 | `FATAL` | - | | | | `Localization Process Group` | 定位进程 | `FATAL` | - | | | | `Planning` | 规划进程 | `FATAL` | - | | | | `Control` | 控制进程 | `FATAL` | - | | | | `Canbus` | canbus 进程 | `FATAL` | - | | | | `Statistics Process Group` | 资源统计进程 | `ERROR` | - | | | | `Recorder Process` | 落盘进程 | `ERROR` | - | | | | `Data Clean Process` | 数据清理进程 | `WARN` | - | | **资源占用** | `/apollo/modules/safety_manager/checker/resource_checker/conf/resource_checker_conf.pb.txt` | `CPU` | CPU 资源占用 | 根据阈值确定 | `usage_warning: 80`
`usage_error: 90`
`temperature_warning: 75`
`temperature_error: 85` | | | | `memory` | 内存资源占用 | 根据阈值确定 | `usage_warning: 80`
`usage_error: 90`
`available_warning: 2000`
`available_error: 1000` | | | | `disk` | 磁盘资源占用 | 根据阈值确定 | `device: "nvme0n1p1"`
`usage_warning: 80`
`usage_error: 90` | | **碰撞检测** | `/apollo/modules/safety_manager/checker/collision_checker/conf/collision_checker_conf.pb.txt` | `Collision` | 碰撞检测 | 根据阈值确定 | `warn_sec: 5.0` (警告)
`error_sec: 4.0` (缓刹)
`fatal_sec: 3.0` (急刹) | | **控制一致性** | `/apollo/modules/safety_manager/checker/control_checker/conf/control_checker_conf.pb.txt` | `Control` | 控制一致性检测 | 根据配置项确定 | 参考配置文件,通常用默认配置 | --- > 💡 **提示**:以上配置项可根据实际项目需求进行调整,修改配置后需重启相关模块生效。建议在生产环境部署前进行充分的测试验证。