09.Monitor模块详解

第九部分:Monitor模块详解

免责声明

本文档仅供学习和技术研究使用,内容基于 Apollo 开源项目的公开资料和代码分析整理而成。文档中的技术实现细节、架构设计等内容可能随 Apollo 项目更新而变化。使用本文档所述技术方案时,请以 Apollo 官方最新文档为准。

声明事项:

  • 本文档不构成任何商业使用建议
  • 涉及自动驾驶技术的应用需遵守当地法律法规
  • 作者不对因使用本文档内容产生的任何后果承担责任
  • Apollo 为百度公司注册商标,本文档为非官方技术解析

1. Monitor模块概述

1.1 模块定位

Monitor模块是Apollo自动驾驶系统的健康监控中枢,负责实时监控所有模块、进程、通道和系统资源的状态,并在异常时触发Guardian安全模式。

核心职责:

  • 监控所有关键进程运行状态
  • 监控CyberRT消息通道更新频率
  • 监控系统资源(CPU/内存/磁盘)
  • 监控硬件设备(GPS/CAN/传感器)
  • 汇总状态并触发安全模式
  • 向HMI提供系统健康信息

关键特性:

  • 12个监控器并行运行
  • 1.5秒检测周期
  • 层级状态汇总: UNKNOWN < OK < WARN < ERROR < FATAL
  • 主动触发Guardian: 通过设置safety_mode_trigger_time
  • 实时HMI反馈: 向Dreamview提供状态信息

2. 系统架构设计

2.1 整体架构

复制代码
┌──────────────────────────────────────────────────────────┐
│                    Monitor Component                     │
│                  (100Hz TimerComponent)                  │
│                                                          │
│  ┌────────────────────────────────────────────────────┐ │
│  │ MonitorManager (Singleton)                         │ │
│  │  - SystemStatus管理                                │ │
│  │  - HMIMode配置                                     │ │
│  │  - Reader/Writer工厂                               │ │
│  └────────────────────────────────────────────────────┘ │
│                                                          │
│  ┌────────────────────────────────────────────────────┐ │
│  │ 12个RecurrentRunner (各自独立周期):                │ │
│  │                                                    │ │
│  │  1. ProcessMonitor (1.5s)    - 进程状态           │ │
│  │  2. ModuleMonitor (1.5s)     - 模块状态           │ │
│  │  3. ChannelMonitor (5s)      - 消息通道           │ │
│  │  4. LatencyMonitor (5s)      - 消息延迟           │ │
│  │  5. ResourceMonitor (5s)     - 系统资源           │ │
│  │  6. GpsMonitor (2s)          - GPS硬件            │ │
│  │  7. LocalizationMonitor (2s) - 定位质量           │ │
│  │  8. CameraMonitor (2s)       - 相机状态           │ │
│  │  9. EsdCanMonitor (1s)       - ESD CAN卡          │ │
│  │ 10. SocketCanMonitor (1s)    - Socket CAN         │ │
│  │ 11. SummaryMonitor (1s)      - 状态汇总           │ │
│  │ 12. FunctionalSafetyMonitor  - 功能安全检查       │ │
│  └────────────────────────────────────────────────────┘ │
└──────────────────────────┬───────────────────────────────┘
                           │ SystemStatus (10Hz)
                           ↓
                  ┌─────────────────┐
                  │    Guardian     │ ← 触发安全模式
                  └─────────────────┘
                           ↓
                  ┌─────────────────┐
                  │   Dreamview     │ ← 显示系统状态
                  └─────────────────┘

2.2 RecurrentRunner基类

所有监控器继承自RecurrentRunner:

cpp 复制代码
class RecurrentRunner {
 public:
  RecurrentRunner(const std::string &name, const double interval);

  // 每次Monitor::Proc()调用时执行
  void Tick(const double current_time) {
    if (current_time >= next_round_) {
      RunOnce(current_time);  // 到达间隔时间则执行
      next_round_ = current_time + interval_;
      round_count_++;
    }
  }

  // 子类实现具体监控逻辑
  virtual void RunOnce(const double current_time) = 0;

 private:
  std::string name_;
  double interval_;        // 执行间隔(秒)
  double next_round_;      // 下次执行时间
  unsigned int round_count_;
};

执行频率示例:

复制代码
Monitor Proc() @ 100Hz (每10ms)

t=0ms:    所有Runner初始化
t=10ms:   Tick() - 未到时间,跳过
...
t=1000ms: ProcessMonitor::RunOnce() (1.5s间隔,首次执行)
          EsdCanMonitor::RunOnce() (1s间隔)
          SummaryMonitor::RunOnce() (1s间隔)
t=2000ms: GpsMonitor::RunOnce() (2s间隔)
t=5000ms: ChannelMonitor::RunOnce() (5s间隔)
          ResourceMonitor::RunOnce() (5s间隔)

3. 核心监控器详解

3.1 监控器列表

监控器 检测周期 监控内容 失败影响
ProcessMonitor 1.5s 进程是否存在 FATAL → Guardian
ModuleMonitor 1.5s Cyber模块状态 FATAL → Guardian
ChannelMonitor 5s 消息更新频率 ERROR/WARN
LatencyMonitor 5s 消息端到端延迟 WARN
ResourceMonitor 5s CPU/内存/磁盘 WARN/ERROR
GpsMonitor 2s GPS信号质量 WARN/ERROR
LocalizationMonitor 2s 定位精度 ERROR
CameraMonitor 2s 相机帧率 WARN
EsdCanMonitor 1s ESD CAN卡状态 FATAL
SocketCanMonitor 1s Socket CAN状态 FATAL
SummaryMonitor 1s 汇总所有状态 -
FunctionalSafetyMonitor 1s 功能安全检查 触发Guardian

3.2 状态级别

cpp 复制代码
enum Status {
  UNKNOWN = 0;  // 未知(初始状态)
  OK = 1;       // 正常
  WARN = 2;     // 警告(可继续运行)
  ERROR = 3;    // 错误(功能受限)
  FATAL = 4;    // 致命(必须停止)
}

状态升级规则:

复制代码
UNKNOWN → OK → WARN → ERROR → FATAL
         ↑      ↑       ↑       ↑
      正常   轻微异常  严重异常  崩溃

4. 进程监控机制

4.1 ProcessMonitor实现

cpp 复制代码
class ProcessMonitor : public RecurrentRunner {
 public:
  ProcessMonitor()
      : RecurrentRunner("ProcessMonitor", 1.5) {}  // 1.5秒周期

  void RunOnce(const double current_time) override {
    // 1. 获取所有运行中的进程
    std::vector<std::string> running_processes;
    for (const auto& cmd_file : cyber::common::Glob("/proc/*/cmdline")) {
      std::string cmd_string;
      if (cyber::common::GetContent(cmd_file, &cmd_string)) {
        std::replace(cmd_string.begin(), cmd_string.end(), '\0', ' ');
        running_processes.push_back(cmd_string);
      }
    }

    // 2. 检查HMI模块进程
    auto* hmi_modules = MonitorManager::Instance()
                        ->GetStatus()->mutable_hmi_modules();
    for (const auto& iter : mode.modules()) {
      const std::string& module_name = iter.first;
      const auto& config = iter.second.process_monitor_config();
      UpdateStatus(running_processes, config,
                   &hmi_modules->at(module_name));
    }

    // 3. 检查其他组件进程
    // (类似逻辑检查monitored_components, other_components等)
  }

 private:
  static void UpdateStatus(
      const std::vector<std::string>& running_processes,
      const ProcessMonitorConfig& config,
      ComponentStatus* status) {

    // 遍历所有运行进程,查找匹配的进程
    for (const std::string& command : running_processes) {
      bool all_keywords_matched = true;

      // 检查所有关键字是否都在命令行中
      for (const std::string& keyword : config.command_keywords()) {
        if (command.find(keyword) == std::string::npos) {
          all_keywords_matched = false;
          break;
        }
      }

      if (all_keywords_matched) {
        // 找到匹配进程,状态设为OK
        SummaryMonitor::EscalateStatus(ComponentStatus::OK,
                                       command, status);
        return;
      }
    }

    // 未找到进程,状态设为FATAL
    SummaryMonitor::EscalateStatus(ComponentStatus::FATAL,
                                   "Process not found", status);
  }
};

4.2 进程匹配机制

配置示例 (HMI Mode):

yaml 复制代码
modules:
  planning:
    process_monitor_config:
      command_keywords:
        - "mainboard"
        - "planning"

匹配过程:

bash 复制代码
# 系统运行的进程:
/apollo/bazel-bin/cyber/mainboard -d modules/planning/dag/planning.dag

# 提取的命令行字符串:
"/apollo/bazel-bin/cyber/mainboard -d modules/planning/dag/planning.dag"

# 检查关键字:
  - "mainboard" ✓ (存在)
  - "planning"  ✓ (存在)

# 结果: 匹配成功,Planning进程正常运行

失败示例:

复制代码
Planning进程崩溃后:
  - 遍历所有/proc/*/cmdline
  - 找不到同时包含"mainboard"和"planning"的进程
  - 设置 hmi_modules["planning"].status = FATAL
  - SummaryMonitor汇总后触发safety_mode

5. 通道监控机制

5.1 ChannelMonitor实现

cpp 复制代码
class ChannelMonitor : public RecurrentRunner {
 public:
  explicit ChannelMonitor(
      const std::shared_ptr<LatencyMonitor>& latency_monitor)
      : RecurrentRunner("ChannelMonitor", 5.0),  // 5秒周期
        latency_monitor_(latency_monitor) {}

  void RunOnce(const double current_time) override {
    auto manager = MonitorManager::Instance();
    const auto& mode = manager->GetHMIMode();
    auto* components = manager->GetStatus()->mutable_components();

    // 检查每个组件的通道状态
    for (const auto& iter : mode.monitored_components()) {
      const std::string& name = iter.first;
      if (!iter.second.has_channel()) continue;

      const auto& config = iter.second.channel();
      auto* status = components->at(name).mutable_channel_status();

      // 从LatencyMonitor获取频率
      bool update_freq = false;
      double freq = 0.0;
      if (config.has_name()) {
        const auto freq_opt = latency_monitor_->GetFrequency(config.name());
        if (freq_opt) {
          update_freq = true;
          freq = *freq_opt;
        }
      }

      UpdateStatus(config, status, update_freq, freq);
    }
  }

 private:
  static void UpdateStatus(
      const ChannelMonitorConfig& config,
      ComponentStatus* status,
      const bool update_freq,
      const double freq) {

    if (!update_freq) {
      // 无法获取频率,标记为WARN
      status->set_status(ComponentStatus::WARN);
      status->set_message("Channel frequency not available");
      return;
    }

    // 检查频率是否在正常范围内
    if (freq < config.min_frequency_allowed()) {
      // 频率过低
      status->set_status(ComponentStatus::WARN);
      status->set_message(absl::StrCat("Frequency too low: ", freq,
                                       " < ", config.min_frequency_allowed()));
    } else {
      // 频率正常
      status->set_status(ComponentStatus::OK);
      status->set_message(absl::StrCat("Frequency: ", freq, " Hz"));
    }
  }

  std::shared_ptr<LatencyMonitor> latency_monitor_;
};

5.2 频率检测

LatencyMonitor计算频率:

cpp 复制代码
// LatencyMonitor内部维护消息时间戳队列
std::map<std::string, std::deque<double>> message_timestamps_;

void OnMessage(const std::string& channel, double timestamp) {
  auto& timestamps = message_timestamps_[channel];
  timestamps.push_back(timestamp);

  // 保留最近10秒的时间戳
  while (!timestamps.empty() &&
         timestamp - timestamps.front() > 10.0) {
    timestamps.pop_front();
  }
}

std::optional<double> GetFrequency(const std::string& channel) {
  if (!message_timestamps_.count(channel)) return {};

  const auto& timestamps = message_timestamps_[channel];
  if (timestamps.size() < 2) return {};

  // 频率 = 消息数 / 时间跨度
  double time_span = timestamps.back() - timestamps.front();
  if (time_span < 0.1) return {};

  return (timestamps.size() - 1) / time_span;
}

配置示例:

yaml 复制代码
monitored_components:
  perception:
    channel:
      name: "/apollo/perception/obstacles"
      min_frequency_allowed: 8.0  # 最低8Hz

6. 资源监控机制

6.1 ResourceMonitor实现

cpp 复制代码
class ResourceMonitor : public RecurrentRunner {
 public:
  ResourceMonitor()
      : RecurrentRunner("ResourceMonitor", 5.0) {}  // 5秒周期

  void RunOnce(const double current_time) override {
    const auto& mode = MonitorManager::Instance()->GetHMIMode();
    auto* components = MonitorManager::Instance()
                       ->GetStatus()->mutable_global_components();

    // 检查各项资源
    for (const auto& iter : mode.global_components()) {
      const std::string& name = iter.first;
      if (!iter.second.has_resource()) continue;

      const auto& config = iter.second.resource();
      auto* status = components->at(name).mutable_resource_status();

      UpdateStatus(config, status);
    }
  }

 private:
  static void UpdateStatus(
      const ResourceMonitorConfig& config,
      ComponentStatus* status) {

    // 1. 检查磁盘空间
    CheckDiskSpace(config, status);

    // 2. 检查CPU使用率
    CheckCPUUsage(config, status);

    // 3. 检查内存使用率
    CheckMemoryUsage(config, status);

    // 4. 检查磁盘I/O负载
    CheckDiskLoads(config, status);
  }

  static void CheckDiskSpace(
      const ResourceMonitorConfig& config,
      ComponentStatus* status) {

    for (const auto& disk_config : config.disks()) {
      struct statvfs stat;
      if (statvfs(disk_config.path().c_str(), &stat) != 0) {
        SummaryMonitor::EscalateStatus(
            ComponentStatus::ERROR,
            "Failed to get disk space: " + disk_config.path(),
            status);
        continue;
      }

      // 计算可用空间百分比
      const double available_percentage =
          static_cast<double>(stat.f_bavail) / stat.f_blocks * 100;

      // 检查是否低于阈值
      if (available_percentage <
          disk_config.min_available_gb() /
          (stat.f_blocks * stat.f_frsize / 1e9) * 100) {

        SummaryMonitor::EscalateStatus(
            ComponentStatus::WARN,
            absl::StrCat("Low disk space: ",
                        disk_config.path(), " ",
                        available_percentage, "%"),
            status);
      }
    }
  }

  static void CheckCPUUsage(
      const ResourceMonitorConfig& config,
      ComponentStatus* status) {

    if (!config.has_cpu_usage()) return;

    // 读取/proc/stat获取CPU使用率
    static unsigned long long prev_total = 0, prev_idle = 0;

    std::ifstream stat_file("/proc/stat");
    std::string line;
    std::getline(stat_file, line);

    unsigned long long user, nice, system, idle;
    sscanf(line.c_str(), "cpu %llu %llu %llu %llu",
           &user, &nice, &system, &idle);

    unsigned long long total = user + nice + system + idle;
    double cpu_usage = 100.0 * (1.0 -
        static_cast<double>(idle - prev_idle) / (total - prev_total));

    prev_total = total;
    prev_idle = idle;

    // 检查CPU使用率
    if (cpu_usage > config.cpu_usage().high_usage_percentage()) {
      SummaryMonitor::EscalateStatus(
          ComponentStatus::WARN,
          absl::StrCat("High CPU usage: ", cpu_usage, "%"),
          status);
    }
  }

  static void CheckMemoryUsage(
      const ResourceMonitorConfig& config,
      ComponentStatus* status) {

    if (!config.has_memory_usage()) return;

    // 读取/proc/meminfo
    std::ifstream meminfo("/proc/meminfo");
    std::string line;
    unsigned long long total_mem = 0, available_mem = 0;

    while (std::getline(meminfo, line)) {
      if (line.find("MemTotal:") == 0) {
        sscanf(line.c_str(), "MemTotal: %llu kB", &total_mem);
      } else if (line.find("MemAvailable:") == 0) {
        sscanf(line.c_str(), "MemAvailable: %llu kB", &available_mem);
      }
    }

    double used_percentage =
        100.0 * (1.0 - static_cast<double>(available_mem) / total_mem);

    if (used_percentage >
        config.memory_usage().high_usage_percentage()) {
      SummaryMonitor::EscalateStatus(
          ComponentStatus::WARN,
          absl::StrCat("High memory usage: ", used_percentage, "%"),
          status);
    }
  }
};

6.2 资源阈值配置

yaml 复制代码
global_components:
  resource:
    resource:
      # 磁盘空间
      disks:
        - path: "/apollo"
          min_available_gb: 10.0  # 最少10GB
        - path: "/apollo/data"
          min_available_gb: 50.0  # 最少50GB(录制数据)

      # CPU使用率
      cpu_usage:
        high_usage_percentage: 90.0  # CPU>90%警告

      # 内存使用率
      memory_usage:
        high_usage_percentage: 85.0  # 内存>85%警告

7. 状态汇总与决策

7.1 SummaryMonitor

SummaryMonitor负责汇总所有监控器的状态,并决定是否触发Guardian安全模式。

cpp 复制代码
class SummaryMonitor : public RecurrentRunner {
 public:
  SummaryMonitor()
      : RecurrentRunner("SummaryMonitor", 1.0) {}  // 1秒周期

  void RunOnce(const double current_time) override {
    auto manager = MonitorManager::Instance();
    auto* status = manager->GetStatus();

    // 汇总所有组件状态
    ComponentStatus::Status worst_status = ComponentStatus::OK;
    std::string worst_message;

    // 1. 检查HMI模块
    for (const auto& iter : status->hmi_modules()) {
      if (iter.second.status() > worst_status) {
        worst_status = iter.second.status();
        worst_message = iter.first + ": " + iter.second.message();
      }
    }

    // 2. 检查监控组件
    for (const auto& iter : status->components()) {
      UpdateWorstStatus(iter.second, &worst_status, &worst_message);
    }

    // 3. 检查全局组件
    for (const auto& iter : status->global_components()) {
      UpdateWorstStatus(iter.second, &worst_status, &worst_message);
    }

    // 4. 决定是否触发安全模式
    if (worst_status >= ComponentStatus::ERROR) {
      // 有ERROR或FATAL状态,触发安全模式
      status->set_safety_mode_trigger_time(current_time);
      status->set_passenger_msg(
          "系统异常: " + worst_message + ", 正在安全停车");

      // 如果是FATAL,需要紧急停车
      if (worst_status == ComponentStatus::FATAL) {
        status->set_require_emergency_stop(true);
      }
    } else {
      // 清除安全模式触发时间
      status->clear_safety_mode_trigger_time();
      status->clear_require_emergency_stop();
    }
  }

 private:
  static void UpdateWorstStatus(
      const Component& component,
      ComponentStatus::Status* worst_status,
      std::string* worst_message) {

    // 检查各个子状态
    const ComponentStatus* statuses[] = {
      &component.summary(),
      &component.process_status(),
      &component.channel_status(),
      &component.resource_status()
    };

    for (const auto* status : statuses) {
      if (status->status() > *worst_status) {
        *worst_status = status->status();
        *worst_message = status->message();
      }
    }
  }

 public:
  // 状态升级辅助函数
  static void EscalateStatus(
      const ComponentStatus::Status new_status,
      const std::string& message,
      ComponentStatus* status) {

    // 只有新状态更严重时才升级
    if (new_status > status->status()) {
      status->set_status(new_status);
      status->set_message(message);
    }
  }
};

7.2 FunctionalSafetyMonitor

功能安全监控器基于汇总状态做最终决策:

cpp 复制代码
class FunctionalSafetyMonitor : public RecurrentRunner {
 public:
  FunctionalSafetyMonitor()
      : RecurrentRunner("FunctionalSafetyMonitor", 1.0) {}

  void RunOnce(const double current_time) override {
    auto* status = MonitorManager::Instance()->GetStatus();

    // 检查是否在自动驾驶模式
    if (!MonitorManager::Instance()->IsInAutonomousMode()) {
      return;  // 非自动驾驶模式,不触发
    }

    // 检查是否有致命错误
    bool has_fatal_error = false;
    for (const auto& iter : status->hmi_modules()) {
      if (iter.second.status() == ComponentStatus::FATAL) {
        has_fatal_error = true;
        break;
      }
    }

    if (has_fatal_error &&
        !status->has_safety_mode_trigger_time()) {
      // 有致命错误但未触发安全模式,立即触发
      status->set_safety_mode_trigger_time(current_time);
      status->set_require_emergency_stop(true);
      status->set_passenger_msg("检测到致命错误,紧急停车");
    }
  }
};

8. 配置与部署

8.1 DAG配置

protobuf 复制代码
# modules/monitor/dag/monitor.dag
module_config {
    module_library : "modules/monitor/libmonitor_component.so"
    timer_components {
        class_name : "Monitor"
        config {
            name: "monitor"
            interval: 10  # 10ms = 100Hz
        }
    }
}

8.2 HMI Mode配置

yaml 复制代码
# modules/dreamview/conf/hmi_modes/default.pb.txt
modules:
  planning:
    process_monitor_config:
      command_keywords:
        - "mainboard"
        - "planning"

  control:
    process_monitor_config:
      command_keywords:
        - "mainboard"
        - "control"

monitored_components:
  perception:
    channel:
      name: "/apollo/perception/obstacles"
      min_frequency_allowed: 8.0
    process:
      command_keywords:
        - "perception"

global_components:
  resource:
    resource:
      disks:
        - path: "/apollo"
          min_available_gb: 10.0
      cpu_usage:
        high_usage_percentage: 90.0
      memory_usage:
        high_usage_percentage: 85.0

9. 实际应用场景

9.1 Planning崩溃检测

复制代码
t=0s:     Planning正常运行
t=10s:    Planning因bug崩溃,进程退出

t=11.5s:  ProcessMonitor::RunOnce() (1.5s周期)
          扫描/proc/*/cmdline
          未找到包含"mainboard"+"planning"的进程
          设置 hmi_modules["planning"].status = FATAL

t=12s:    SummaryMonitor::RunOnce() (1s周期)
          检测到Planning状态=FATAL
          设置 safety_mode_trigger_time = 12.0
          设置 require_emergency_stop = true

t=12.01s: Guardian收到SystemStatus
          检测到 has_safety_mode_trigger_time()
          触发安全模式,执行紧急停车

9.2 磁盘空间不足

复制代码
t=0s:     磁盘可用空间: 15GB

t=300s:   用户启动数据录制
t=600s:   磁盘可用空间: 8GB

t=605s:   ResourceMonitor::RunOnce() (5s周期)
          检测到 /apollo/data 可用空间 < 10GB
          设置 global_components["resource"].status = WARN

t=606s:   SummaryMonitor::RunOnce()
          汇总状态: WARN (不触发安全模式)
          设置 passenger_msg = "磁盘空间不足,请清理数据"

t=607s:   Dreamview显示警告
          HMI: "⚠️ 磁盘空间不足: 8GB < 10GB"

10. 调试与故障排查

10.1 查看SystemStatus

bash 复制代码
# 实时监控SystemStatus
cyber_monitor -c /apollo/monitor/system_status

# 查看字段:
# - hmi_modules: 各模块状态
# - components: 组件状态
# - global_components: 全局组件状态
# - safety_mode_trigger_time: 是否触发安全模式
# - passenger_msg: 给乘客的消息

10.2 常见问题

问题: 模块状态一直是FATAL

bash 复制代码
# 检查进程是否运行
ps aux | grep planning

# 检查关键字配置
# 确保process_monitor_config.command_keywords正确

# 查看Monitor日志
cat /apollo/data/log/monitor.INFO

问题: CPU使用率警告

bash 复制代码
# 查看CPU占用
top

# 调整阈值
# 编辑HMI mode配置,提高cpu_usage.high_usage_percentage

参考资料与引用

官方资源

  1. Apollo 官方 GitHub 仓库

    https://github.com/ApolloAuto/apollo

    • Apollo 开源项目主仓库,包含完整源代码
  2. Apollo 官方文档

    https://apollo.baidu.com/docs

    • 官方技术文档和开发指南
  3. Apollo 开发者社区

    https://apollo.baidu.com/community

    • 官方开发者论坛和技术交流平台

技术规范与标准

  1. ISO 26262 - 道路车辆功能安全标准

    https://www.iso.org/standard/68383.html

  2. ISO 21448 (SOTIF) - 预期功能安全标准

    https://www.iso.org/standard/77490.html

学术论文与技术资源

  1. CenterPoint: Center-based 3D Object Detection and Tracking

    Yin, T., Zhou, X., & Krähenbühl, P. (2021)

    https://arxiv.org/abs/2006.11275

  2. BEVFormer: Learning Bird's-Eye-View Representation from Multi-Camera Images

    Li, Z., et al. (2022)

    https://arxiv.org/abs/2203.17270

  3. OpenDRIVE 地图标准

    https://www.asam.net/standards/detail/opendrive/

开源工具与库

  1. Bazel 构建系统

    https://bazel.build/

  2. Fast-DDS (eProsima)

    https://www.eprosima.com/index.php/products-all/eprosima-fast-dds

  3. PROJ 坐标转换库

    https://proj.org/

  4. TensorRT 开发指南

    https://docs.nvidia.com/deeplearning/tensorrt/

  5. PCL 点云库文档

    https://pointclouds.org/

  6. IPOPT 优化求解器

    https://coin-or.github.io/Ipopt/

说明

本文档内容整理自上述官方资料、开源代码以及相关技术文档。所有代码示例和技术细节均基于 Apollo 9.0/10.0 版本。如需获取最新信息,请访问 Apollo 官方网站和 GitHub 仓库。

版权说明

Apollo® 是百度公司的注册商标。本文档为基于开源项目的非官方技术研究文档,仅供学习参考使用。

相关推荐
qq_317620317 小时前
13.Dreamview模块详解
apollo·dreamview
qq_317620319 小时前
14.Calibration模块详解
apollo·calibration
qq_3176203110 小时前
05.Transform模块详解
apollo·transform
Coder个人博客5 天前
Apollo VehicleState 车辆状态模块接口调用流程图与源码分析
人工智能·自动驾驶·apollo
程序员龙一5 天前
百度Apollo Cyber RT底层原理解析
自动驾驶·ros·apollo·cyber rt
Coder个人博客8 天前
Apollo Canbus 底盘通信模块接口调用流程图与源码分析
人工智能·自动驾驶·apollo
Coder个人博客8 天前
Apollo Prediction 预测模块接口调用流程图与源码分析
人工智能·自动驾驶·apollo
johnny_hhh15 天前
apollo配置环境
apollo
Hi202402174 个月前
使用 Apollo TransformWrapper 生成相机到各坐标系的变换矩阵
数码相机·线性代数·矩阵·自动驾驶·apollo