[置顶] 【Apollo源码分析】系列的第四部分【decision】
2017-09-09 17:06
796 查看
【Apollo源码分析】系列的第四部分【decision】
decision模块目前依然处于待完善的状态,代码大概有500行左右。
decision的输入:
障碍物信息。包括障碍物位置(x,y,z),障碍物移动速度(v),障碍物加速度(av),预测的障碍物移动轨迹节点。车辆状态。包括车辆位置(x,y,z),车辆速度(v),加速度(v)
交通信号灯。状态(红/蓝/绿)
地图信息。
路径选择信息。
decision模块的主要作用是在上述的输入参数下根据决策算法产生decision 控制命令,向车辆发出控制命令。在可能的情况下,decision模块也会基于高精度地图,输出【预测障碍物移动】的结果。
decision的输出:
Decision command ,针对车辆的控制信息,(车辆本身速度等)virtual obstacles ,预测的障碍物
Decision command ,应付障碍物而发出的控制信息
decision/main.cc
先看main.cc的内容,只有一行代码。APOLLO_MAIN(apollo::decision::Decision);
注册decision模块,并执行该模块的内容。
[/code]
decision/decision.h
class Decision : public apollo::common::ApolloApp {
public:
std::string Name() const override;//模块名称
apollo::common::Status Init() override; //初始化操作
apollo::common::Status Start() override;//模块的内容
void Stop() override; //清理函数
virtual ~Decision() = default;
private:
void OnTimer(const ros::TimerEvent &event);//时间回调函数
void PublishDecision();//发布 Decision command 决策命令
private:
ros::Timer timer_;//时间
};
[/code]
.cc文件:
std::string Decision::Name() const { return FLAGS_decision_module_name; }
///模块名称
[/code]
// Decision command 模块的具体内容
common::Status Decision::Start() {
AdapterManager::Init();
const double duration = 1.0 / FLAGS_decision_publish_freq;// Decision command 模块发布决策的频率
timer_ = AdapterManager::CreateTimer(ros::Duration(duration), &Decision::OnTimer,this);
//定时回调Decision::OnTimer函数
return common::Status::OK();
}
[/code]
//回调函数,该模块会按照设定好的频率定时回调此函数。
void Decision::OnTimer(const ros::TimerEvent &) { PublishDecision(); }
[/code]
//发布决策命令Decision command
//通过下面可以看出,目前没有任何的命令发布出去。
void Decision::PublishDecision() {
DecisionResult decision_result;//空内容。
AdapterManager::FillDecisionHeader(Name(), decision_result.mutable_header());
AdapterManager::PublishDecision(decision_result);
//发布决策结果,但是并没有具体内容,还有待完善...
//也就是说目前只有一个框架,但是Decision command 是一片空白的。Apollo 1.0 目前的Decision 模块暂时没有发挥作用。
}
[/code]
decision/common/decision_gflags.h
DECLARE_string(decision_module_name);
DECLARE_double(decision_publish_freq);
[/code]
.cc文件
DEFINE_string(decision_module_name, "decision", "decision module name");//模块名称
DEFINE_double(decision_publish_freq, 10, "decision publishing frequency.");//决策频率
[/code]
decision.proto
决策内容。挺长的,建议直接看decision.proto源码。下面是简单的注释。syntax = "proto2";
package apollo.decision;
import "modules/common/proto/header.proto";
import "modules/common/proto/geometry.proto";
import "modules/prediction/proto/prediction_obstacle.proto";
import "modules/canbus/proto/chassis.proto";
//标识物体长度的2D数据。
message Range {
optional double start = 1;
optional double end = 2;
}
//理想化的车道线。车辆行驶起点+终点+行驶速度。 单位m
message TargetLane {
// lane id
optional string id = 1;
optional double start_s = 2; // in meters
optional double end_s = 3; // in meters
optional double speed_limit = 4; // in m/s
}
message ObjectIgnore {
}
//停车命令。停车理由状态码。
enum StopReasonCode {
STOP_REASON_HEAD_VEHICLE = 1; //有前车
STOP_REASON_DESTINATION = 2; //到达目的地
STOP_REASON_PEDESTRIAN = 3; //有行人
STOP_REASON_OBSTACLE = 4; //有障碍物体
STOP_REASON_PREPARKING = 5; //
STOP_REASON_SIGNAL = 100; //信号灯
STOP_REASON_STOP_SIGN = 101; //停车标识
STOP_REASON_YIELD_SIGN = 102;//让路标志
STOP_REASON_CLEAR_ZONE = 103;
STOP_REASON_CROSSWALK = 104; //人行横道
}
//停车目标。距离+停车理由code码+停车点
message ObjectStop {
// stop at least distance_s before the object
optional double distance_s = 1; // in meters
optional Range preferred_distance_s = 2; // NOT SUPPORTED FIELD
optional StopReasonCode reason_code = 3;
optional apollo.common.PointENU stop_point = 4;// stop point
}
//距离缓慢移动物体的最小距离
message ObjectNudge {
// minimum lateral distance with the object
optional double distance_l = 1; // in meters
enum Type {
LEFT_NUDGE = 1;
RIGHT_NUDGE = 2;
};
optional Type type = 2;
optional Range preferred_distance_l = 3; // NOT SUPPORTED FIELD
}
//车辆 礼让 命令状态。如校车/公交车/救护车
message ObjectYield {
// minimum longitutional distance with the object
optional double distance_s = 1; // in meters
optional Range preferred_distance_s = 2; // NOT SUPPORTED FIELD
optional apollo.common.PointENU yield_point = 3;
}
//车辆 跟随 目标
message ObjectFollow {
// minimum longitutional distance with the object
optional double distance_s = 1; // in meters
optional Range preferred_distance_s = 2; // NOT SUPPORTED FIELD
optional apollo.common.PointENU follow_point = 3;
}
//超车命令状态
message ObjectOvertake {
// minimum longitutional distance with the object
optional double distance_s = 1; // in meters
optional Range preferred_distance_s = 2; // NOT SUPPORTED FIELD
optional apollo.common.PointENU overtake_point = 3;
}
// 车辆侧面 物体/车辆 状态
message ObjectSidePass {
// Follow or lead the object from side lane keeping a longitutional distance
// to it.
// If you want to cut in the neighbored lane, you may need to sidepass a
// neighbored object first.
optional double distance_s = 1; // in meters
optional Range preferred_distance_s = 2; // in meters, relative to the object
enum Type {
FOLLOW = 1; // Follow the object from side lane
LEAD = 2; // Lead the object from side lane
};
optional Type type = 3;
}
message ObjectAvoid {
}
//因某物体而产生的决策类型
message ObjectDecisionType {
oneof object_tag {
ObjectIgnore ignore = 1; //忽略此物体
ObjectStop stop = 2; //停车
ObjectFollow follow = 3; //跟车
ObjectYield yield = 4; //礼让行人/车辆
ObjectOvertake overtake = 5;//超车
ObjectNudge nudge = 6; //缓慢移动
ObjectSidePass sidepass = 7; //侧方行驶
ObjectAvoid avoid = 8; //避开 unified object decision while estop
}
}
message ObjectDecision {
enum ObjectType {
PREDICTION = 1;
PERCEPTION = 2;
VIRTUAL = 3;
}
optional apollo.prediction.PredictionObstacle prediction = 1;
optional string id = 2;
optional ObjectType type = 3;
optional ObjectDecisionType decision = 4 [deprecated = true];
repeated ObjectDecisionType object_decision = 5;
}
//由该物体而产生的决策命令
message ObjectDecisions {
repeated ObjectDecision decision = 1;
}
//停车线
// stop at distance_s on lane
message StopLine {
optional string lane_id = 1;
optional double distance_s = 2;
}
//停车控制变量。
message MainStop {
// stop at or before distance_s relative to the lane_id
optional StopLine enforced_line = 1;
optional StopLine preferred_start = 2; // NOT SUPPORTED FIELD
optional StopLine preferred_end = 3; // NOT SUPPORTED FIELD
optional string reason = 4;
optional StopReasonCode reason_code = 5;
// When stopped, the front center of vehicle should be at this point.
optional apollo.common.PointENU stop_point = 6;
// When stopped, the heading of the vehicle should be stop_heading.
optional double stop_heading = 7;
}
message EmergencyStopHardBrake {
}
message EmergencyStopCruiseToStop {
}
//紧急停车
message MainEmergencyStop {
// Unexpected event happened, human driver is required to take over the
// vehicle.
optional string reason = 1;
enum ReasonCode {
ESTOP_REASON_INTERNAL_ERR = 1;
ESTOP_REASON_COLLISION = 2;
ESTOP_REASON_ST_FIND_PATH = 3;
ESTOP_REASON_ST_MAKE_DECISION = 4;
ESTOP_REASON_SENSOR_ERROR = 5;
}
optional ReasonCode reason_code = 2;
oneof task {
EmergencyStopHardBrake hard_brake = 3; // hard brake
EmergencyStopCruiseToStop cruise_to_stop = 4; // cruise to stop
}
}
// 巡航
message MainCruise {
// cruise current lane
}
message MainChangeLane {
enum Type {
LEFT = 1;
RIGHT = 2;
};
optional Type type = 1;
repeated TargetLane default_lane = 2;
optional MainStop default_lane_stop = 3;
optional MainStop target_lane_stop = 4;
}
message MainMissionComplete {
// arrived at routing destination
}
message MainNotReady {
// decision system is not ready.
// e.g. wait for routing data.
optional string reason = 1;
}
//停车
message MainParking {
enum Type {
FORWARD_PARKING = 1;
REVERSE_PARKING = 2;
};
optional Type type = 1;
// the heading of the final car position
optional double heading = 2;
// stop point
optional apollo.common.PointENU stop_point = 3;
// the polygon of the parking spot
repeated apollo.common.PointENU parking_polygon = 4;
}
//决策命令内容
message MainDecision {
oneof task {
MainCruise cruise = 1;
MainStop stop = 2;
MainEmergencyStop estop = 3;
MainChangeLane change_lane = 4;
MainMissionComplete mission_complete = 6;
MainNotReady not_ready = 7;
MainParking parking = 8;
}
repeated TargetLane target_lane = 5;
}
//控制车辆的方便debug信息
message MasterVehicleDebug {
optional apollo.common.PointENU position = 1;
optional string current_lane_id = 2;
optional double lane_s = 3;
optional double lane_l = 4;
optional double route_s = 5 [deprecated = true];
optional double route_l = 6 [deprecated = true];
optional double heading = 7;
optional double heading_speed = 8;
optional double heading_acceleration = 9;
optional Range route_s_range = 10;
optional Range route_l_range = 11;
}
message ObjectDebug {
optional string id = 1;
optional string path_id = 2;
optional Range route_s = 3;
optional Range route_l = 4;
optional bool on_route = 5;
optional string lane_id = 6;
optional double lane_s = 7;
optional bool on_lane = 8;
optional double path_speed = 9;
// x is time (t), y is s
repeated apollo.common.Point3D st_region = 10;
}
//潜在因素
message LatencyStats {
optional double total_time_ms = 1;
optional double sensor_read_time_ms = 2;
optional double adc_prepare_time_ms = 3;
optional double obj_prepare_time_ms = 4;
optional double world_rule_time_ms = 5;
optional double st_graph_time_ms = 6;
// time diff between gateway_msg_receive_timestamp and gateway_msg_timestamp
optional double gateway_receive_delay_ms = 8;
// time diff between perception_msg_receive_timestamp and
// perception_msg_timestamp
optional double perception_receive_delay_ms = 9;
// time diff between prediction_msg_receive_timestamp and
// prediction_msg_timestamp
optional double prediction_receive_delay_ms = 10;
// time diff between signal_msg_receive_timestamp and signal_msg_timestamp
optional double signal_receive_delay_ms = 11;
// time interval in ms between perception last and its previous msg
optional double perception_interval_ms = 12;
// time interval in ms between prediction last and its previous msg
optional double prediction_interval_ms = 13;
}
message Stats {
optional LatencyStats latency_stats = 1;
}
message ModuleDebug {
optional uint32 gateway_sequence_num = 1;
optional uint32 perception_sequence_num = 2;
optional uint32 prediction_sequence_num = 3;
optional uint32 signal_sequence_num = 4;
}
// next id: 8
message Debug {
optional MasterVehicleDebug master_vehicle = 1;
// Stores current frame's original decision when current decision has be
// modified.
// E.g., when current decision is the first encountered estop, we may use
// A valid history decision to replace current decision, but the estop
// decision will be stored in original_decision.
optional MainDecision original_decision = 2;
repeated ObjectDebug object = 3;
// some meta data will be dumped into debug per sample frequency:
// e.g. every 500 decision, meta data will be dumped once.
optional bytes map_version = 5;
optional bytes decision_version = 7;
// record per module debug info
optional ModuleDebug module_debug = 6;
}
//车载计算机控制的车灯信号
// The light signal of the adc
// naming reference https://en.wikipedia.org/wiki/Automotive_lighting[/code]message LightSignal {optional bool emergency = 1; // hazard signalenum TurnSignal {NO_TURN = 1;LEFT_TURN = 2;RIGHT_TURN = 3;};optional TurnSignal turn_signal = 2 [default = NO_TURN];}//决策结果message DecisionResult {optional apollo.common.Header header = 1;optional ObjectDecisions object_decision = 2;//由物体而产生的决策命令optional MainDecision main_decision = 3; //决策命令optional Debug debug = 4;optional Stats stats = 6;optional apollo.canbus.Signal signal = 7; //向底盘发送的信号内容optional LightSignal light_signal = 5 [deprecated = true];//车灯信号}
[/code]decision模块的内容就是上面这些。
总结
再次回顾一下decision模块的输入输出。
`障碍物信息。包括障碍物位置(x,y,z),障碍物移动速度(v),障碍物加速度(av),预测的障碍物移动轨迹节点。
decision的输入:
车辆状态。包括车辆位置(x,y,z),车辆速度(v),加速度(v)
交通信号灯。状态(红/蓝/绿)
地图信息。
路径选择信息。
decision模块的主要作用是在上述的输入参数下根据决策算法产生decision 控制命令,向车辆发出控制命令。在可能的情况下,decision模块也会基于高精度地图,输出【预测障碍物移动】的结果。Decision command ,针对车辆的控制信息,(车辆本身速度等)
decision的输出:
virtual obstacles ,预测的障碍物
Decision command ,针对障碍物而发出的控制信息
结合decision.proto,应该说目前decision模块的框架是搭好了的。但是很遗憾,目前本模块不能work。
山高水长,长路漫漫乎。
本文首发于微信公众号slamcode。
注释版源码:源码
相关文章推荐
- [置顶] 【Apollo源码分析】系列的第五部分【localization】
- [置顶] 【Apollo源码分析】系列的第六部分【planning】
- [置顶] 40-总结-【cartographer源码分析】系列的第四部分【io源码分析】
- [置顶] 【Apollo源码分析】系列的第三部分【prediction】
- [置顶] 【Apollo源码分析】系列的第二部分【perception】
- [置顶] 45-总结-【cartographer源码分析】系列的第五部分【kalman_filter】
- [置顶] 【Apollo源码分析】系列的第一部分【common】
- [置顶] 16 -总结-【cartographer源码分析】系列的第二部分【transform源码分析】
- [置顶] 58-总结-【cartographer源码分析】系列的第六部分【 mapping 】
- [置顶] 25-总结-【cartographer源码分析】系列的第三部分【sensor源码分析】
- [置顶] 自动驾驶框架 Apollo 1.0 -源码分析
- [置顶] 12-总结-【cartographer源码分析】系列的第一部分【common源码分析】
- SpringBoot-Loader源码分析系列2:启动 new JarLauncher().launch(args)的.launch(args)部分
- Android源码分析系列-整理篇 ------ 关于Vold 自动挂载部分
- [置顶] SpringMVC源码分析系列[转]
- [置顶] Spring Boot系列十二 通过redis实现Tomcat集群的Session同步及从源码分析其原理
- DPM中的HOG源码的Matlab版重写-《小超教你写论文》系列第四部分第一篇
- [置顶]【Spring源码分析系列】ApplicationContext 相关接口架构分析
- RocketMQ生产者消费者部分源码分析总结
- A Discriminative Feature Learning Approach for Deep Face Recognition 的源码部分分析