1. 添加场景的基本步骤
1.1 步骤
- 添加scenario
- 新增相关scenario的文件夹及相关文件:
BUILD
,***(scenario name)_scenario.h/.cc
,***(scenario name)_scenario_test.cc
,***(stage name)_stage.h/.cc
- 在
scenario_manager.h/.cc
中添加相关注册信息以及相关函数:CreateScenario()
,RegisterScenarios()
,Select***(scenario name)Scenario()
,ScenarioDispatch()
,Is***(scenario name)Scenario()
,UpdatePlanningContext***(scenario name)Scenario()
,同时修改BUILD
文件 - 在相关proto中添加scenario/stage的信息:
planning_config.proto
- 新增相关scenario的文件夹及相关文件:
- 添加task
- 新增相关task的文件夹及相关文件:
BUILD
,***(task name).h/.cc
,test.cc
- 在
task_factory.cc
中添加相关注册信息以及相关函数:Init()
,同时修改BUILD
文件 - 在相关proto中添加task的信息:
BUILD
,planning_config.proto
,***(task name)_config.proto
- 添加相关配置信息:
planning_config_navi.pb.txt
(保存了planning所包括的planner配置信息以及planner所包含的task的配置信息,以及其他task的默认配置,格式由planning_config.proto
决定,由planning_navi.conf
决定使用该配置文件),***(scenario name)_conf.pb.txt
(scenario所包括的stage及stage所包括的task的配置信息均在此处,格式由planning_config.proto
决定) - 在
planning_gflags.h/.cc
中添加配置文件***(scenario name)_conf.pb.txt
路径的宏(在scenario_manager.cc
的RegisterScenario()
中使用)
- 新增相关task的文件夹及相关文件:
- 添加
planning_status.proto
中的相关信息- 添加scenario相关的status信息,用于上下文、场景切换(见
UpdatePlanningContext***(scenario name)Scenario()
)
- 添加scenario相关的status信息,用于上下文、场景切换(见
- 将新增的相关.h/.cc文件中的基本信息写入,并进行编译以检查proto设置是否成功
- 进行功能开发,并根据需求动态修改proto及相关配置文件
1.2 详解
1.2.1 添加scenario
1.2.1.1 新增相关scenario的文件夹及相关文件
假设目前要创建一个名为supervised_bypass的scenario,其中包含forward_stage、supervised_bypass_stage两个stage,则需要创建:
-
一个名为supervised_bypass的文件夹
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vvMrU2in-1629511083672)(HowToAddScenario.assets/Screenshot from 2021-04-12 15-33-24.png)] -
BUILD文件,中间包含各文件之间的依赖信息(对照.h/.cc文件的依赖)
load("//tools:cpplint.bzl", "cpplint") package(default_visibility = ["//visibility:public"]) cc_library( name = "supervised_bypass", copts = ["-DMODULE_NAME=\\\"planning\\\""], deps = [ ":supervised_bypass_scenario", ":supervised_bypass_stage", ":forward_stage", ], ) cc_library( name = "supervised_bypass_stage", srcs = ["supervised_bypass_stage.cc"], hdrs = ["supervised_bypass_stage.h"], copts = ["-DMODULE_NAME=\\\"planning\\\""], deps = [ "//cyber/common:log", "//external:gflags", "//modules/common/proto:pnc_point_proto", "//modules/common/status", "//modules/common/time", "//modules/common/util", "//modules/common/util:factory", "//modules/common/vehicle_state:vehicle_state_provider", "//modules/map/hdmap", "//modules/planning/common:planning_common", "//modules/planning/common:speed_profile_generator", "//modules/planning/constraint_checker", "//modules/planning/math/curve1d:quartic_polynomial_curve1d", "//modules/planning/proto:planning_proto", "//modules/planning/reference_line", "//modules/planning/reference_line:qp_spline_reference_line_smoother", "//modules/planning/scenarios:scenario", "//modules/planning/tasks/generators/supervised_bypass_path_generator:supervised_bypass_path_generator", "//modules/planning/tasks/generators/st_speed_generator:st_speed_generator", "@eigen", "//modules/planning/common:planning_context", ], ) cc_library( name = "forward_stage", srcs = ["forward_stage.cc"], hdrs = ["forward_stage.h"], copts = ["-DMODULE_NAME=\\\"planning\\\""], deps = [ "//cyber/common:log", "//external:gflags", "//modules/common/proto:pnc_point_proto", "//modules/common/status", "//modules/common/time", "//modules/common/util", "//modules/common/util:factory", "//modules/common/vehicle_state:vehicle_state_provider", "//modules/map/hdmap", "//modules/planning/common:planning_common", "//modules/planning/common:speed_profile_generator", "//modules/planning/constraint_checker", "//modules/planning/math/curve1d:quartic_polynomial_curve1d", "//modules/planning/proto:planning_proto", "//modules/planning/reference_line", "//modules/planning/reference_line:qp_spline_reference_line_smoother", "//modules/planning/scenarios:scenario", "//modules/planning/tasks/generators/supervised_bypass_path_generator:supervised_bypass_path_generator", "//modules/planning/tasks/generators/st_speed_generator:st_speed_generator", "@eigen", "//modules/planning/common:planning_context", ], ) cc_library( name = "supervised_bypass_scenario", srcs = ["supervised_bypass_scenario.cc"], hdrs = ["supervised_bypass_scenario.h"], copts = ["-DMODULE_NAME=\\\"planning\\\""], deps = [ ":supervised_bypass_stage", ":forward_stage", "//cyber/common:log", "//external:gflags", "//modules/common/proto:pnc_point_proto", "//modules/common/status", "//modules/common/time", "//modules/common/util", "//modules/common/util:factory", "//modules/common/vehicle_state:vehicle_state_provider", "//modules/map/hdmap", "//modules/planning/common:planning_common", "//modules/planning/common:speed_profile_generator", "//modules/planning/constraint_checker", "//modules/planning/math/curve1d:quartic_polynomial_curve1d", "//modules/planning/proto:planning_proto", "//modules/planning/reference_line", "//modules/planning/reference_line:qp_spline_reference_line_smoother", "//modules/planning/scenarios:scenario", "//modules/planning/tasks/generators/supervised_bypass_path_generator:supervised_bypass_path_generator", "//modules/planning/tasks/generators/st_speed_generator:st_speed_generator", "@eigen", ], ) cc_test( name = "supervised_bypass_scenario_test", size = "small", srcs = ["supervised_bypass_scenario_test.cc"], data = [ "//modules/planning:planning_conf", ], deps = [ ":supervised_bypass", "@gtest//:main", ], ) cpplint()
-
supervised_bypass_scenario.h/.cc以及对应的test文件,其中应包含的重要函数:
-
RegisterStages()
,用于注册如上所述的两个stagevoid SupervisedBypassScenario::RegisterStages() { if (!s_stage_factory_.Empty()) { s_stage_factory_.Clear(); } s_stage_factory_.Register( ScenarioConfig::FORWARD_STAGE, [](const ScenarioConfig::StageConfig& config) -> Stage* { return new ForwardStage(config); }); s_stage_factory_.Register( ScenarioConfig::SUPERVISED_BYPASS_STAGE, [](const ScenarioConfig::StageConfig& config) -> Stage* { return new SupervisedBypassStage(config); }); }
-
apollo::common::util::Factory<...>::Register()
中的第一个参数需在planning_config.proto中添加
-
-
forward_stage.h/.cc、supervised_bypass.h/.cc,其中应包含的重要函数:
-
Process()
,内部调用FinishStage()
判断stage结束和切换,内部调用PlanOnReferenceLine()
执行task(Process()
在planner层Plan()
函数调用的Scenario::Process()
中调用)Stage::StageStatus ForwardStage::Process( const TrajectoryPoint& planning_start_point, Frame* frame) { bool has_drivable_reference_line = false; ... auto result = CheckForwardFinish(frame); if (result) { return FinishStage(frame); } const auto start_lane_id = PlanningContext::Instance() ->planning_status() .supervised_bypass() .start_lane_id(); for (auto& reference_line_info : *ref_line_info_group) { // start_lane is the only drivable reference_line_info if (reference_line_info.Lanes().Id() == start_lane_id) { auto status = PlanOnReferenceLine
-