Apollo planning之交规决策技术

欢迎大家关注我的B站:

偷吃薯片的Zheng同学的个人空间-偷吃薯片的Zheng同学个人主页-哔哩哔哩视频 (bilibili.com)

目录

1 双层状态机

2 决策模块的解析 

2.1 参考路径

2.2 交规决策 

2.3 路径决策 

2.4 速度决策

2.5 场景的调度与管理

3 交规决策实现代码解读 

3.1 遍历交规配置文件,存储信息

3.2 交规决策的运行流程 

3.3 场景框架代码

3.3.1 Traffic Light 场景的进入

3.3.2 Traffic Light 场景的 stage

3.3.3 Approach阶段

3.3.4 Cruise阶段

3.3.5 交通灯通过检测与停止墙生成


1 双层状态机

  •  Apollo主要是通过状态机进行决策,不熟悉状态机的读者请参考【自动驾驶决策算法之有限状态机】_有限状态机 自动驾驶_无意2121的博客-CSDN博客
  • 有限状态机不适用于比较复杂的自动驾驶车辆,于是Apollo选择用Top Layer+Bottom Layer的方式,将类似的状态集合到一个底层的状态机中,于是就形成了双层状态机
  • 同时Apollo通过对scenario进行分类,每个scenario又分为一个或多个stage,每个stage又是由不同的task组成。整体流程图如上图所示

2 决策模块的解析 

这里介绍了决策模块的目的与作用

  • 安全性
  • 遵守交规
  • 为平滑器提供信息 

决策模块的上游有Routing、Prediction、Location、Perception等等module,这作为决策模块的输入。最终的输出则是路径、速度、位置的边界,为优化器提供条件 

2.1 参考路径

  • 没有障碍物情况下的默认行车路径
    • 参考路径需要保证连续和平滑(参考线平滑算法,Apollo中默认离散点平滑)
  • 参考路径也用于表达换道需求(在Routing模块已经通过A*算法完成了车道级别的搜索
    • 目标参考路径(优先级高
    • 当前参考路径
  • 参考路径的一种实现方法
    • 根据Routing结果找对对应的道路的中心线
    • 对道路中心线进行平滑

2.2 交规决策 

  • 主要作用
    • 处理红绿灯、Stop Sign,人行横道等交通规则
  • 输入信息
    • 参考路径
    • 高精地图
    • 信号灯状态
  • 输出
    • 虚拟墙(通过对当前交通状态的判断进行是否需要停车的决策

2.3 路径决策 

通过一系列类似决策树的是否判断决定当前要生成哪种路径边界输送到优化器中

各种Path Bound的举例如下

2.4 速度决策

在speed decider中需要通过以下各种各样的判断来生成一个最终的speed bound 

  • 道路限速
  • 路径周边行人,自行车等
  • 通过人行横道时
  • 减速带
  • 路径上过近的车辆,较为拥挤的道路
  • 借道避让时
  •  换道时

 整个 planning 模块的运行流程就如上图所示

2.5 场景的调度与管理

依据场景来做决策规划有以下两个优点
  • 场景之间互不干扰,有利于场景并行开发和独立调参,利于维护与开发
  • 功能之间相互解耦,开发者可以开发自己的特有场景,但定制化的好处背后就是普遍性的不足

3 交规决策实现代码解读 

3.1 遍历交规配置文件,存储信息

场景分类解释
Backside_Vehicle主车后方来车
Crosswalk人行横道
Destination主车前往的目的地
Keep_Clear禁停区
Reference_Line_End参考线结束
Rerouting重新全局规划
Stop_Sign停车
Traffic_Light交通灯
Yield_sign让行

A p o l l o 对 交 通 规 则 的 处 理 是 通 过 f o r 循 环 来 遍 历 traffic_rule_config.pb.txt 中设置的交通规则,处理后相关信息存入 ReferenceLineInfo 

//modules\planning\traffic_rules\traffic_decider.cc
Status TrafficDecider::Execute(
    Frame *frame, ReferenceLineInfo *reference_line_info,
    const std::shared_ptr<DependencyInjector> &injector) {
  CHECK_NOTNULL(frame);
  CHECK_NOTNULL(reference_line_info);
  
  //遍历配置文件
  for (const auto &rule_config : rule_configs_.config()) {
    if (!rule_config.enabled()) {
      ADEBUG << "Rule " << rule_config.rule_id() << " not enabled";
      continue;
    }
    auto rule = s_rule_factory.CreateObject(rule_config.rule_id(), rule_config,
                                            injector);
    if (!rule) {
      AERROR << "Could not find rule " << rule_config.DebugString();
      continue;
    }
    rule->ApplyRule(frame, reference_line_info);
    ADEBUG << "Applied rule "
           << TrafficRuleConfig::RuleId_Name(rule_config.rule_id());
  }
  //处理信息保存在reference_line_info中,作为输入,提供给后续模块。
  BuildPlanningTarget(reference_line_info);
  return Status::OK();
}

3.2 交规决策的运行流程 

前面遍历配置的信息都存储到ReferenceLineInfo中,通过overlap判断与什么场景重叠,通过交通规则判断需要进入哪个场景,再进行一系列stage,stage中又包含很多task

3.3 场景框架代码

3.3.1 Traffic Light 场景的进入

modules/planning/common/reference_line_info.cc
// signal
hdmap::PathOverlap signal_overlap;
if(GetFirstOverlap(map_path.signal_overlaps(),
&signal_overlap)) {
first_encounter_overlaps_.emplace_back(
SIGNAL, signal_overlap);
}

通过overlap重叠进入Traffic Light 场景

modules/planning/scenarios/scenario_manager.cc
if (right_turn && red_light) {
//进入红绿灯无保护右转
const auto& scenario_config =
config_map_[ScenarioConfig::TRAFFIC_LIGHT_UNPROTECTED_RIGHT_TURN]
.traffic_light_unprotected_right_turn_config();
} else if (left_turn) {
//进入红绿灯无保护左转
const auto& scenario_config =
config_map_[ScenarioConfig::TRAFFIC_LIGHT_UNPROTECTED_LEFT_TURN]
.traffic_light_unprotected_left_turn_config();
} else {
//红绿灯有保护
const auto& scenario_config =
config_map_[ScenarioConfig::TRAFFIC_LIGHT_PROTECTED]
.traffic_light_protected_config();
}

根据车道信息与交通信号灯的情况进入不同的Scenario

3.3.2 Traffic Light 场景的 stage

stage_type:
TRAFFIC_LIGHT_PROTECTED_APPROACH 
#靠近阶段
stage_type:
TRAFFIC_LIGHT_PROTECTED_INTERSECTION_CRUISE
#进入交叉路口阶段

Traffic Light 场景有两个stage,stage_type在配置文件modules/planning/conf/scenario/traffic_light_protected_ config.pb.txt中进行定义

// traffic_light_protected scenario
TRAFFIC_LIGHT_PROTECTED_APPROACH = 400;
TRAFFIC_LIGHT_PROTECTED_INTERSECTION_CRUISE = 401;

这是stage优先级的定义,相当于进入一个scenario会有一个stage执行的顺序

s_stage_factory_.Register(
ScenarioConfig::TRAFFIC_LIGHT_PROTECTED_APPROACH,
[](const ScenarioConfig::StageConfig& config,
const std::shared_ptr<DependencyInjector>&
injector) -> Stage* {
return new
TrafficLightProtectedStageApproach(config, injector);
});
s_stage_factory_.Register(
ScenarioConfig::TRAFFIC_LIGHT_PROTECTED_INTERSECTION_CRUISE,
[](const ScenarioConfig::StageConfig& config,
const std::shared_ptr<DependencyInjector>&
injector) -> Stage* {
return new (config, injector);
});

这里stage进行了注册

3.3.3 Approach阶段

//modules\planning\scenarios\scenario.cc
const auto& scenario_config =
  config_map_[ScenarioConfig::TRAFFIC_LIGHT_PROTECTED]
      .traffic_light_protected_config();
// 距离判断:主车离停车小于start_traffic_light_scenario_distance时
// 进入TRAFFIC_LIGHT_PROTECTED场景
if (adc_distance_to_traffic_light < 
    scenario_config.start_traffic_light_scenario_distance()) 
{
    traffic_light_protected_scenario = true;
}

在approach阶段需要进行了距离判断,若距离满足要求就进入traffic_light_protected场景

//modules\planning\conf\scenario\traffic_light_protected_config.pb.txt
scenario_type: TRAFFIC_LIGHT_PROTECTED
traffic_light_protected_config: {
  start_traffic_light_scenario_distance: 5.0
}

这是配置文件 

//modules\planning\scenarios\traffic_light\protected\stage_approach.cc
Stage::StageStatus TrafficLightProtectedStageApproach::Process(
    const TrajectoryPoint& planning_init_point, Frame* frame) {
    ADEBUG << "stage: Approach";
    //APPROACH 正在运行
    CHECK_NOTNULL(frame);
    if (traffic_light_all_done) {
        return FinishStage();
  }
  return Stage::RUNNING;
}

//modules\planning\scenarios\traffic_light\protected\stage_approach.cc
Stage::StageStatus TrafficLightProtectedStageApproach::FinishStage() {
  auto* traffic_light = injector_->planning_context()
                            ->mutable_planning_status()
                            ->mutable_traffic_light();
  traffic_light->clear_done_traffic_light_overlap_id();
  for (const auto& traffic_light_overlap_id :
       GetContext()->current_traffic_light_overlap_ids) {
    traffic_light->add_done_traffic_light_overlap_id(traffic_light_overlap_id);
  }
  //进入下一个Stage:TRAFFIC_LIGHT_PROTECTED_INTERSECTION_CRUISE
  next_stage_ = ScenarioConfig::TRAFFIC_LIGHT_PROTECTED_INTERSECTION_CRUISE;
  return Stage::FINISHED;
  //APPROACH的Stage完成
}

Approach阶段的定义如上

3.3.4 Cruise阶段

Stage::StageStatus TrafficLightProtectedStageIntersectionCruise::Process(
const common::TrajectoryPoint& planning_init_point, Frame* frame) {
bool stage_done =
stage_impl_.CheckDone(*frame, ScenarioConfig::TRAFFIC_LIGHT_PROTECTED,
config_, injector_->planning_context(), true);
//定义交叉路口
if (stage_done)
//如果通过交叉路口
{ return FinishStage();
//INTERSECTION_CRUISE的stage完成
}
return Stage::RUNNING;
//进入INTERSECTION_CRUISE的RUNNING
}
Stage::StageStatus TrafficLightProtectedStageIntersectionCruise::FinishStage() {
return FinishScenario();
//INTERSECTION_CRUISE的stage完成
}

3.3.5 交通灯通过检测与停止墙生成

ObjectDecisionType stop;
//定义一个停止墙
auto* stop_decision = stop.mutable_stop();
//stop决策的停车原因
stop_decision->set_reason_code(stop_reason_code);
stop_decision->set_distance_s(-stop_distance);
//stop决策的停车安全距离
util::BuildStopDecision(virtual_obstacle_id,
traffic_light_overlap.start_s,
config_.traffic_light().stop_distance(),
StopReasonCode::STOP_REASON_SIGNAL,
wait_for_obstacles,TrafficRuleConfig::RuleId_Name(config_.rule_id()),
config: {
rule_id: TRAFFIC_LIGHT
enabled: true
traffic_light {
stop_distance: 1.0 #停止距离为1.0 单位 m
max_stop_deceleration: 4.0
}
}

配置文件中可以修改停止距离 

  • 4
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
### 回答1: Apollo Planning决策规划算法在无人驾驶领域中被广泛应用,在自动驾驶车辆中起着至关重要的作用。该算法主要通过对车辆周围环境的感知和分析,实现智能驾驶路线的规划和决策,确保车辆安全行驶。 该算法的代码主要包含三个部分:感知模块、规划模块和控制模块。其中感知模块主要负责采集车辆周围的环境信息,包括车辆所处的位置、路况、障碍物等。规划模块通过对这些信息的分析,提出一系列可能的驾驶路线,并通过评估这些路线的优劣来选择最佳驾驶路线。控制模块负责实现规划模块中选择的最佳驾驶路线,并控制车辆按照路线行驶。 在Apollo Planning决策规划算法中,规划模块是实现驾驶决策的最重要模块,也是最具技术难度的模块。规划模块通过对车辆当前状态和环境信息的分析,提出一系列汽车驾驶路线。该算法采用在线生成路线方案的方法,路线生成的步骤如下: 1. 动态路径规划:根据车辆的位置和行驶状态,实时选择当前最佳的驾驶路线。 2. 静态路线生成:基于当前车辆所处的环境信息,生成固定的驾驶路线。 3. 组合路径规划:将动态路径规划和静态路线生成相结合,生成最终的驾驶路线。 除此之外,Apollo Planning决策规划算法还包括计算机视觉、机器学习、深度学习和人工智能技术,这些技术的综合应用使得Apollo Planning决策规划算法成为无人驾驶领域中应用最广泛的决策规划算法。 ### 回答2: Apollo Planning决策规划算法是一种用于自动驾驶系统的规划算法。该算法的主要作用是实时生成安全、有效且符合路况的路径以实现自动驾驶功能。本文将对该算法进行详细解析。 Apollo Planning决策规划算法主要包括三个步骤:路线规划、运动规划和决策规划。具体代码如下: 1. 路线规划 ```c++ bool Planning::PlanOnReferenceLine() { std::vector<const hdmap::HDMap*> hdmap_vec; hdmap_vec.reserve(1); if (!GetHdmapOnRouting(current_routing_, &hdmap_vec)) { AERROR << "Failed to get hdmap on current routing with " << current_routing_.ShortDebugString(); return false; } const auto& reference_line_info = reference_line_infos_.front(); std::vector<ReferencePoint> ref_points; if (!CreateReferenceLineInfo(hdmap_vec.front(), reference_line_info, &ref_points)) { AERROR << "Failed to create reference line from routing"; return false; } // Smooth reference line Spline2d smoothed_ref_line; std::vector<double> s_refs; std::vector<double> l_refs; std::vector<double> headings; std::vector<double> kappas; std::vector<double> dkappas; if (!SmoothReferenceLine(ref_points, &smoothed_ref_line, &s_refs, &l_refs, &headings, &kappas, &dkappas)) { AERROR << "Failed to smooth reference line"; return false; } reference_line_info.SetTrajectory(&smoothed_ref_line); reference_line_info.SetReferenceLine(&ref_points); // set origin point if (!reference_line_info.SLToXY(s_refs.front(), 0.0, &origin_point_)) { AERROR << "Failed to get origin point on reference line"; return false; } return true; } ``` 在路线规划阶段中,Apollo Planning决策规划算法首先获取当前行驶路线和高精度地图数据。然后根据行驶路线和地图数据构建参考线,对参考线进行平滑处理,得到平滑后的参考线。此时我们可以得到平滑后的参考线的位置、方向和曲率等信息,这些信息将作为后面的运动和决策规划的输入。 2. 运动规划 ```c++ bool Planning::PlanOnPrediction() { PredictionObstacles prediction_obstacles; if (!GetPrediction(&prediction_obstacles)) { AERROR << "Prediction failed"; return false; } std::vector<Obstacle> obstacles; if (!BuildObstacle(prediction_obstacles, &obstacles)) { AERROR << "Unable to build obstacle"; return false; } const auto& reference_line_info = reference_line_infos_.front(); const auto& reference_line = reference_line_info.reference_line(); SpeedData speed_data; Cruiser::PlanningTarget planning_target; Status status = cruiser_->Plan(reference_line_info, obstacles, 0.0, reference_line.Length(), &speed_data, &planning_target); if (status != Status::OK()) { AERROR << "Failed to plan path with status: " << status; return false; } RecordDebugInfo(reference_line_info, obstacles, speed_data); return true; } ``` 运动规划主要用于生成车辆在参考线上的运行轨迹。在运动规划阶段,Apollo Planning决策规划算法首先获取预测障碍物信息,将预测的障碍物转化为Obstacle对象。然后根据当前平滑后的参考线、障碍物等信息进行运动规划。运动规划的目标是生成符合规划目标的速度曲线。最后,Apollo Planning决策规划算法记录调试信息,以便后续分析调试。 3. 决策规划 ```c++ bool Planning::MakeDecision() { const auto& reference_line_info = reference_line_infos_.front(); const auto& reference_line = reference_line_info.reference_line(); std::vector<const Obstacle*> obstacles; if (!Obstacle::CreateObstacleRegions(FLAGS_max_distance_obstacle, reference_line_info, &obstacles)) { AERROR << "Failed to create obstacle regions"; return false; } for (auto obstacle_ptr : obstacles) { const auto& obstacle = *obstacle_ptr; if (obstacle.IsVirtual()) { continue; } if (obstacle.IsStatic()) { continue; } if (obstacle.type() == PerceptionObstacle::BICYCLE || obstacle.type() == PerceptionObstacle::PEDESTRIAN) { continue; } const auto& nearest_path_point = obstacle.nearest_point(); const SLPoint obstacle_sl = reference_line_info.xy_to_sl(nearest_path_point); if (obstacle_sl.s() < -FLAGS_max_distance_obstacle || obstacle_sl.s() > reference_line.Length() + FLAGS_max_distance_obstacle) { continue; } ObjectDecisionType decision; decision.mutable_avoid(); decision.mutable_avoid()->set_distance_s(-obstacle_sl.s()); reference_line_info.AddCost(&obstacle, &decision); } std::vector<ObjectDecisionType> decisions; if (!traffic_rule_manager_.ApplyRule(reference_line_info, &decisions)) { AERROR << "Failed to apply traffic rule manager"; return false; } reference_line_info.SetDecision(decisions); return true; } ``` 决策规划是基于当前环境信息和规划的路径等输入信息,实时生成控制命令的过程。在Apollo Planning决策规划算法中,决策规划阶段根据当前参考线、障碍物等信息生成决策。该算法根据不同的规则和策略,生成不同的控制命令,以保证车辆安全、有效地运行。 综上,Apollo Planning决策规划算法是自动驾驶系统中重要的规划算法之一,它通过路线规划、运动规划和决策规划三个步骤,实现了安全、有效和符合路况的路径规划,为自动驾驶车辆的控制提供了重要的支持。 ### 回答3: Apollo Planning(阿波罗规划)是百度自动驾驶平台Apollo中的一种决策规划算法,主要用于规划车辆的驾驶行为。该算法基于深度强化学习,使用了运动学模型和环境感知技术,可以根据车辆当前位置和目的地,生成一条最优的行驶路径,包括车辆的控制指令和行驶速度等。 该算法的核心技术是深度强化学习,它通过对驾驶过程进行大量的仿真,让计算机通过自我学习得到驾驶规则,使车辆能够根据不同的场景做出最优的决策。具体而言,算法先通过神经网络生成一系列潜在的行动策略,然后通过与环境进行交互、执行行动并接收环境反馈来评估每个策略的优劣,最终选取最优策略进行执行。 在实现上,Apollo Planning算法主要由四个模块构成:感知模块、规划模块、执行模块和控制模块。感知模块主要用于获取车辆周围环境的信息,包括车辆位置、速度、道路情况、交通灯等;规划模块根据感知模块提供的信息和车辆的目的地,生成一条最优的行驶路径;执行模块则根据规划模块生成的路径信息,实现车辆的自主驾驶;控制模块则根据执行模块生成的控制指令,控制车辆的加速、刹车、转向等行为。 在算法实现上,Apollo Planning采用了C++编程语言,结合ROS框架实现各模块之间的数据交互和代码复用,保证了算法的高效性和可维护性。算法代码实现方面还采用了许多优化技术,包括多线程并发执行、高效的数据结构和算法等,以提升算法的运行效率和稳定性。 总之,Apollo Planning是一种基于深度强化学习的决策规划算法,具有高效、自主、可靠等特点,在智能驾驶领域具有广泛应用前景。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无意2121

创作不易,多多支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值