apollo_logo
16
0

星火自动驾驶大赛赛事集锦--红绿灯路口减速慢行(方法一)

交通灯场景(TRAFFIC_LIGHT)

场景描述:

当主车在监测到前方的红灯时, 主车停车在停止线前1.5-2.0米处,不得超过停止线。当红灯变为绿灯后,主车可以通过该路段,在通过交通灯区域时,主车的速度不得超过 6 m/s。

场景图示:

在交通规则中,当我们的车辆遇到红灯或者黄灯时就需要停车等待。在Apollo中设置的交通规则中也满足了这点。当我们的主车检测到前方为红或者黄灯时 (代码如下),在dreamview中的会显示以下界面:如图1 所示;同时也会在实线前多少米(看具体设置的距离,默认值为1米)外生成一道停止墙如图2所示:

图1:红灯显示 图2:停止墙

评判标准

主车未停车在停止线1.5-2.0米之间, 本场景分扣20分; 速度每超速1m/s, 本场景分扣20分, 超过停止线或者红灯状态未停止, 本场景计0分;

运行视频回放

【百度Apollo星火自动驾驶大赛城市道路预选赛——交通灯路口赛题】 https://www.bilibili.com/video/BV1Ez4y187hG/?share_source=copy_web&vd_source=c5757152d93e2f5dba69049264ebea4e

实验流程:

实验流程大纲

  1. 默认配置参数规划效果
  • 启动dreamview并观察默认配置参数下车辆遇到交通灯的仿真效果。
  1. 红绿灯场景实践:
  • a. 找到planning2.0中Traffic Rules配置的相关文件。
  • b. 根据要求,调整Traffic Rules配置参数,确保车辆停车在距离停止线2米至2.5米的位置停车。
  • c. 调整通过交叉路口的速度
  • d.保存修改后的配置参数,并重新启动planning模块。
  • e. 运行车辆规划模块,并在dreamview上观察车辆遇到红绿灯场景的停车变化和通过交叉路口速度

使用插件配置参数流程

生成和使用traffic light插件

输入配置参数同步指令,系统将自动将全局配置参数复制到profile的default目录中,然后就可以在profile目录上轻松修改配置参数。

buildtool profile config init --package planning-traffic-rules-traffic-light --profile=default

使用目录名为default的这份配置参数

aem profile use defaul

查看profile插件目录结构:

tree profiles/default/modules/planning/traffic_rules/

目录结构:

profiles/default/modules/planning/traffic_rules/
`-- traffic_light
`-- conf
`-- default_conf.pb.txt//traffic_light插件参数配置文件

修改插件配置参数

在工作apollo_workspace工作目录找到profiles/default/modules/planning/traffic_rules/traffic_light/conf/default_conf.pb.txt配置文件,调整红绿灯场景停止配置参数,达到我们期望路径规划效果。

(1) 使用在线编辑工具修改profiles/default/modules/planning/traffic_rules/traffic_light/conf/default_conf.pb.txt配置文件,将stop_distance 参数

在全局配置参数中找到红绿灯场景停止配置参数:

stop_distance: 1.0

将配置参数的值修改为:

stop_distance: 2.0

仿真对比:

原始

修改后

绕行距离配置实践


云实验链接:

该实践内容已经上线Apollo云实验室,开快速启动进行实践体验: https://apollo.baidu.com/community/course/9

技术详解

交通灯场景运行流程框图

一、进入TRAFFIC_LIGHT_PROTECTED场景

代码以及代码路径(节选):

.aem/envroot/opt/apollo/neo/src/modules/planning/scenarios/traffic_light_protected/conf/scenario_conf.pb.txt

start_traffic_light_scenario_distance: 5.0
#当距离红绿灯的停车道5.0米时进入TRAFFIC_LIGHT_PROTECTED场景

代码以及代码路径(节选):

.aem/envroot/opt/apollo/neo/src/modules/planning/scenarios/traffic_light_protected/traffic_light_protected_scenario.cc

如果 adc_distance_to_traffic_light 小于等于0(表示车辆已经过了交通信号灯)或者大于起始检查距离(start_check_distance),
那么就不进入交通信号灯场景,继续下一个信号灯的判断。否则进入交通信号灯场景
// enter traffic-light scenarios: based on distance only
if (adc_distance_to_traffic_light <= 0.0 ||
adc_distance_to_traffic_light > start_check_distance) {
continue;
}

交通灯场景TRAFFIC_LIGHT_PROTECTED定义了两个stage

.aem/envroot/opt/apollo/neo/share/modules/planning/scenarios/traffic_light_protected/conf/pipeline.pb.txt

stage: {
name: "TRAFFIC_LIGHT_PROTECTED_APPROACH"
type: "TrafficLightProtectedStageApproach"
enabled: true
…
}
stage: {
name: "TRAFFIC_LIGHT_PROTECTED_INTERSECTION_CRUISE"
type: "TrafficLightProtectedStageIntersectionCruise"
enabled: true
…
}

TRAFFIC_LIGHT_PROTECTED_APPROACH和TRAFFIC_LIGHT_PROTECTED_INTERSECTION_CRUISE的注册

代码以及代码路径(节选):

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 TrafficLightProtectedStageIntersectionCruise(config,
injector);
});

如果自动驾驶车辆遇到交通灯为红灯

二、红绿灯检测:

代码以及代码路径(节选):

.aem/envroot/opt/apollo/neo/src/modules/planning/traffic_rules/traffic_light/traffic_light.cc

这段代码的作用是检查交通灯是否已经完成。它遍历已完成的交通灯重叠区域的ID列表,
然后将当前交通灯的ID与这些ID进行比较。如果当前交通灯的ID在已完成的交通灯重叠区域的ID列表中,
那么设置变量traffic_light_done为true,然后退出循环。
bool traffic_light_done = false;
for (const auto& done_traffic_light_overlap_id :
traffic_light_status.done_traffic_light_overlap_id()) {
if (traffic_light_overlap.object_id == done_traffic_light_overlap_id) {
traffic_light_done = true;
break;
}
}
if (traffic_light_done) {
continue;
}

2.1停止墙生成源码:

可能有小伙伴会问停止墙是如何生成的呢?停止墙的标志是什么?

首先当我们的主车确认前方交通灯不为绿灯时时,会生成停止墙,停止原因为黄/红信号灯,

代码以及代码路径(节选):

.aem/envroot/opt/apollo/neo/src/modules/planning/traffic_rules/traffic_light/traffic_light.cc

/*
函数的作用是生成一条停车决策,并将其添加到参考线信息中。当交通规则需要控制车辆停止时,
例如信号灯指示红灯时,就会生成这样的停车决策。
*/
util::BuildStopDecision(
virtual_obstacle_id, traffic_light_overlap.start_s,
config_.stop_distance(), StopReasonCode::STOP_REASON_SIGNAL,
wait_for_obstacles, Getname(), frame, reference_line_info);

2.2信号灯停止源码:

代码以及代码路径(节选):

/*
这段代码是一个交通灯保护阶段(TrafficLightProtectedStage)中的交通灯靠近阶段
(TrafficLightProtectedStageApproach)的处理函数(Process)。
首先,它遍历当前交通灯重叠区域的ID列表,并检查每个交通灯的颜色是否为绿灯。
如果存在任何一个交通灯不是绿灯,那么设置变量traffic_light_all_done为false,然后退出循环。
否则,将变量traffic_light_all_done设置为true。
如果所有交通灯都是绿灯,那么函数调用FinishStage()来结束该阶段,然后返回Stage::FINISHED状态。
否则,返回Stage::RUNNING状态,表示该阶段仍在运行中。
*/
StageResult TrafficLightProtectedStageApproach::Process(
const TrajectoryPoint& planning_init_point, Frame* frame) {
// traffic_light_all_done 用于标记是否所有交通信号灯都已处理完毕
bool traffic_light_all_done = true;
// 遍历当前交通信号灯的重叠区域
for (const auto& traffic_light_overlap_id :
context->current_traffic_light_overlap_ids) {
// 获取交通信号灯在参考线上的重叠信息
PathOverlap* current_traffic_light_overlap =
reference_line_info.GetOverlapOnReferenceLine(
traffic_light_overlap_id, ReferenceLineInfo::SIGNAL);
if (!current_traffic_light_overlap) {
continue;
}
// 设置交通信号灯不具备交通优先权
reference_line_info.SetJunctionRightOfWay(
current_traffic_light_overlap->start_s, false);
// 获取车辆前沿位置相对于交通信号灯停车线的距离
const double adc_front_edge_s = reference_line_info.AdcSlBoundary().end_s();
const double distance_adc_to_stop_line =
current_traffic_light_overlap->start_s - adc_front_edge_s;
auto signal_color = frame->GetSignal(traffic_light_overlap_id).color();
// 检查车辆到停车线的距离是否小于最大有效停车距离
if (distance_adc_to_stop_line > scenario_config.max_valid_stop_distance()) {
traffic_light_all_done = false;
break;
}
// 检查交通信号灯的颜色是否为绿色
if (signal_color != TrafficLight::GREEN) {
traffic_light_all_done = false;
break;
}
}
// 如果所有交通信号灯都已经处理完毕,则返回 FinishStage() 表示阶段已完成
if (traffic_light_all_done) {
return FinishStage();
}
// 否则,返回 result.SetStageStatus(StageStatusType::RUNNING) 表示阶段仍在运行中
return result.SetStageStatus(StageStatusType::RUNNING);
}

当主车靠近红绿灯场景时,会进入Scenario 为TRAFFIC_LIGHT_PROTECTED的红绿灯场景

自动驾驶车辆接近交通信号灯

三、进入APPROACH的stage定义

代码以及代码路径(节选):

/*
这段代码是交通灯保护阶段(TrafficLightProtectedStage)中的交通灯靠近阶段(TrafficLightProtectedStageApproach)的处理函数(Process)
*/
StageResult TrafficLightProtectedStageApproach::Process(
const TrajectoryPoint& planning_init_point, Frame* frame)
//APPROACHstage 正在运行
{
return result.SetStageStatus(StageStatusType::RUNNING);
}
/*
这段代码是交通灯保护阶段(TrafficLightProtectedStage)中的交通灯靠近阶段(TrafficLightProtectedStageApproach)的结束函数(FinishStage)。
当交通灯靠近阶段的任务完成后,该函数会将next_stage_
设置为ScenarioConfig::TRAFFIC_LIGHT_PROTECTED_INTERSECTION_CRUISE,
表示进入交通灯保护阶段的下一个阶段TRAFFIC_LIGHT_PROTECTED_INTERSECTION_CRUISE。
然后,它返回Stage::FINISHED状态,表示该阶段已经完成。
*/
Stage::StageStatus TrafficLightProtectedStageApproach::FinishStage()
//APPROACHstage 正在完成
{
//省略
next_stage_ = "TRAFFIC_LIGHT_PROTECTED_INTERSECTION_CRUISE";
//进入下一个stage TRAFFIC_LIGHT_PROTECTED_INTERSECTION_CRUISE
return StageResult(StageStatusType::FINISHED);
//APPROACH的stage完成
}

自动驾驶车辆进入红绿灯交叉路口区域

四、进入INTERSECTION_CRUISE的stage定义

代码以及代码路径(节选):

这段代码是交通灯保护阶段(TrafficLightProtectedStage)中的交通灯保护交叉路口阶段(TrafficLightProtectedStageIntersectionCruise)的处理函数(Process)。
首先,它调用stage_impl_.CheckDone()函数,检查是否已经通过了交叉路口。如果已经通过了交叉路口,那么将返回true,表示该阶段已经完成。
如果该阶段已经完成,那么函数调用FinishStage()来结束该阶段,然后返回Stage::FINISHED状态。
否则,返回Stage::RUNNING状态,表示该阶段仍在运行中。
StageResult TrafficLightProtectedStageIntersectionCruise::Process(
const common::TrajectoryPoint& planning_init_point, Frame* frame) {
bool stage_done = CheckDone(*frame, injector_->planning_context(), true);
//定义交叉路口
if (stage_done)
//如果通过交叉路口
{
return FinishStage();
//INTERSECTION_CRUISE的stage完成
}
return result.SetStageStatus(StageStatusType::RUNNING);
//进入INTERSECTION_CRUISE的RUNNING
}
该函数调用FinishScenario()函数,结束整个交通灯保护阶段(TrafficLightProtectedStage),并返回Stage::FINISHED状态,表示该阶段已经完成。
StageResult TrafficLightProtectedStageIntersectionCruise::FinishStage() {
return FinishScenario();
//INTERSECTION_CRUISE的stage完成
}

交通灯场景代码修改部分

任务实现:

停车距离:

输入traffic_rules参数同步指令,系统将自动将traffic_light的配置参数复制到profile的default目录中,然后就可以在profile目录上轻松修改配置参数。

buildtool profile config init --package planning-traffic-rules-traffic-light --profile=default && aem profile use default

profiles/default/modules/planning/traffic_rules/traffic_light/conf/default_conf.pb.txt

stop_distance: 1.0
#停止距离为1.0 单位 m

代码实现(节选):

.aem/envroot/opt/apollo/neo/src/modules/planning/planning_base/common/util/common.cc

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决策的停车安全距离

实现场景代码(修改参数的部分):

我们仅仅需要将配置文件TRAFFIC_LIGHT的stop_distance值改为1.5-2.0即可。

因为存在误差值,尽量取中间值。

stop_distance: 1.7
#停止距离为1.0 单位 m

红绿灯路口限速:

可通过修改加速度实现

buildtool install planning-task-piecewise-jerk-speed

修改源码

piecewise_jerk_problem.set_ddx_bounds(veh_param.max_deceleration(),
veh_param.max_acceleration());

调整最大加速度的大小,具体范围,需要调参解决

piecewise_jerk_problem.set_ddx_bounds(veh_param.max_deceleration(),
1.0);

原创声明,本文由作者授权发布于Apollo开发者社区,未经许可,不得转载。
发表评论已发表 0 条评论
登录后可评论,请前往 登录
暂无评论~快去发表自己的独特见解吧!
目录
交通灯场景(TRAFFIC_LIGHT)
场景描述:
场景图示:
评判标准
运行视频回放
实验流程:
实验流程大纲
使用插件配置参数流程
云实验链接:
技术详解
交通灯场景运行流程框图
任务实现:
红绿灯路口限速: