Planning-Apollo 6.0 Planning模块pipeline

Planning模块包括决策和运动规划,Apollo6.0使用的主要规划方法为PublicRoadPlanner,划分了场景状态机(scenarios),在每个场景下依次运行stage,在每个stage下依次执行task,通过可配置的stagetask实现程序的扩展性。

1 planning模块的主要类成员

planning模块内部类成员关系
PlanningComponent继承于cyber::Component,是事件触发机制,即当同时收到预测、底盘和定位信息时,planning模块才会运行。PredictionLocalization同样是事件触发的,Chassis模块是时间触发的。预测模块的频率是10Hz,因此规划模块的频率也是10Hz。

class PlanningComponent final
    : public cyber::Component<prediction::PredictionObstacles, canbus::Chassis,
                              localization::LocalizationEstimate> {
 public:
  PlanningComponent() = default;

  ~PlanningComponent() = default;

 public:
  bool Init() override;

  bool Proc(const std::shared_ptr<prediction::PredictionObstacles>&
                prediction_obstacles,
            const std::shared_ptr<canbus::Chassis>& chassis,
            const std::shared_ptr<localization::LocalizationEstimate>&
                localization_estimate) override;

 private:
  void CheckRerouting();
  bool CheckInput();
  ...
}

通过PlannerDispatcher的配置来选择是OnLanPlanning还是NaviPlanning,在Apollo6.0NaviPlanning已经被摒弃了。OnLanPlanning是基于参考线在规划的,Apollo6.0中默认的是PublicRoadPlanner,是由EM Planner演变而来。

2 planning模块主要的计算流程

在这里插入图片描述
PlanningComponent继承于cyber::Component,重载了Init()Proc()函数。

2.1 Init()初始化函数

Init()函数中,会根据flags配置来选择OnLanPlanning还是NaviPlanning,在两者构造时,会分别构造NaviPlannerDispatcherOnLanePlannerDispatcher,在OnLanePlannerDispatcher的构造中会通过载参来选择具体是哪一个Planner(RTKReplayPlannerNaviPlannerLatticePlannerPublicRoadPlanner)。在Apollo6.0中,NaviPlanning已经被摒弃,因此planning_base_会实例化为其基类的对象OnLanePlanning,在其初始化函数中,会进行一些载参和状态变量的初始化工作,获取HD Map,开启参考线的多线程计算等。此外,设置各种readerwriter,类似于ROS中的subscriberpublisher

## palnning_component.cc
bool PlanningComponent::Init() {
  injector_ = std::make_shared<DependencyInjector>();
  // default: FLAGS_use_navigation_mode = false
  // 此flags的设置在modules/coomon/configs/config_flags.h中
  if (FLAGS_use_navigation_mode) {
    planning_base_ = std::make_unique<NaviPlanning>(injector_);
  } else {
    // 在显式构造时planner_dispatcher_指向OnLanePlannerDispatcher
    planning_base_ = std::make_unique<OnLanePlanning>(injector_);
  }
  // 在其父类Component::Initialize中会调用LoadConfigFiles(config),会根据ComponentConfig中
  // 配置的config_file_path和flag_file_path进行载参
  // 配置文件在 modules/planning/dag/planning.dag
  // GetProtoConfig函数将config_file_path设置的文件赋值给config_
  ACHECK(ComponentBase::GetProtoConfig(&config_))
      << "failed to load planning config file "
      << ComponentBase::ConfigFilePath();
  // default: FLAGS_planning_offline_learning = false
  if (FLAGS_planning_offline_learning ||
      config_.learning_mode() != PlanningConfig::NO_LEARNING) {
    if (!message_process_.Init(config_, injector_)) {
      AERROR << "failed to init MessageProcess";
      return false;
    }
  }

  planning_base_->Init(config_);

  routing_reader_ = node_->CreateReader<RoutingResponse>(
      config_.topic_config().routing_response_topic(),
      [this](const std::shared_ptr<RoutingResponse>& routing) {
        AINFO << "Received routing data: run routing callback."
              << routing->header().DebugString();
        std::lock_guard<std::mutex> lock(mutex_);
        routing_.CopyFrom(*routing);
      });
  ...
  planning_writer_ = node_->CreateWriter<ADCTrajectory>(
      config_.topic_config().planning_trajectory_topic());
..
  return true;
}

2.2 Proc()计算函数

在此函数中,会进行输入数据的检查,主要的作用是进行决策规划,运行planning_base_->RunOnce(local_view_, &adc_trajectory_pb)。如图2所示,会进行规划前数据的准备,比如参考线计算、时间戳对齐、航迹推算、轨迹拼接、障碍物处理、交通规则处理等等,然后进行规划,包括场景状态机跳转、stagetask的执行等等,在后续详细介绍。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值