• Apollo 应用与源码分析:guardian 紧急处置


    目录

    概念

    代码

    分析


    概念

    Guardian模块的主要作用是监控自动驾驶系统状态,当出现模块为失败状态的时候,会主动切断控制命令输出,并且刹车。

    有点像是保险丝,有一个fallback机制。

    guardian模块的触发条件主要有2个。

    1. 上报模块状态的消息间隔超过kSecondsTillTimeout(2.5秒)
    2. 上报的状态消息中有safety_mode_trigger_time字段 这时候就会触发进入接管。

    安全模式的步骤分为2步骤,第一步状态消息中需要紧急刹车或者超声波检测到障碍物,如果检测到障碍物则说明车已经非常接近障碍物了,该检测被称为硬件触发的检测,因为已经发现模块故障,也非常接近障碍物所以刹车会加急。第二步是普通刹车,刹车没有那么急。

    guardian为定时模块,所以该过程中会一直发送消息,直到车辆停车。

    当前版本代码屏蔽了上述超声波检测。

    guardian模块的频率是10ms,因此最大会增加control命令的延时10ms。

    代码

    1. class GuardianComponent : public apollo::cyber::TimerComponent {
    2. public:
    3. bool Init() override;
    4. bool Proc() override;
    5. private:
    6. void PassThroughControlCommand();
    7. void TriggerSafetyMode();
    8. apollo::guardian::GuardianConf guardian_conf_;
    9. apollo::canbus::Chassis chassis_;
    10. apollo::monitor::SystemStatus system_status_;
    11. apollo::control::ControlCommand control_cmd_;
    12. apollo::guardian::GuardianCommand guardian_cmd_;
    13. double last_status_received_s_{};
    14. std::shared_ptr>
    15. chassis_reader_;
    16. std::shared_ptr>
    17. control_cmd_reader_;
    18. std::shared_ptr>
    19. system_status_reader_;
    20. std::shared_ptr>
    21. guardian_writer_;
    22. std::mutex mutex_;
    23. };
    24. bool GuardianComponent::Proc() {
    25. constexpr double kSecondsTillTimeout(2.5);
    26. bool safety_mode_triggered = false;
    27. if (guardian_conf_.guardian_enable()) {
    28. std::lock_guard lock(mutex_);
    29. if (Time::Now().ToSecond() - last_status_received_s_ >
    30. kSecondsTillTimeout) {
    31. safety_mode_triggered = true;
    32. }
    33. safety_mode_triggered =
    34. safety_mode_triggered || system_status_.has_safety_mode_trigger_time();
    35. }
    36. if (safety_mode_triggered) {
    37. ADEBUG << "Safety mode triggered, enable safety mode";
    38. TriggerSafetyMode();
    39. } else {
    40. ADEBUG << "Safety mode not triggered, bypass control command";
    41. PassThroughControlCommand();
    42. }
    43. common::util::FillHeader(node_->Name(), &guardian_cmd_);
    44. guardian_writer_->Write(guardian_cmd_);
    45. return true;
    46. }

    分析

    核心函数就是Proc。

    可以看到

    1. if (Time::Now().ToSecond() - last_status_received_s_ >
    2. kSecondsTillTimeout) {
    3. safety_mode_triggered = true;
    4. }

    会判断monitor 是不是超时了,如果monitor 超时就直接刹车。

    另外就是判断monitor 中summary_monitor 上报的system_state中是不是有safety_mode_trigger_time字段,如果有safety_mode_triggered 就设置True,调用安全模式接管。

    这里的安全模式就是由TriggerSafetyMode函数调用的。

    最终会调用set_brake执行guardian_cmd_emergency_stop_percentage模式停车或者guardian_cmd_soft_stop_percentage停车。

    这俩中停车模式的区别就是配置的停车力度不同,所以用舒适度进行了命名。

     

  • 相关阅读:
    [ElasticSearch]-初识Elastic Stack
    浅谈SparkSQL基本概念和原理
    系统篇: uboot 启动流程
    学习如何在 Vue.js 中实现车牌号校验
    L2-022 重排链表
    HTML5:七天学会基础动画网页6
    人工智能优势
    (一)docker:建立oracle数据库
    WebDAV之π-Disk派盘 + 天天
    你真的会使用PDF注释功能吗?PDF注释功能正确使用方法
  • 原文地址:https://blog.csdn.net/qq_32378713/article/details/128126473