35double ComputeMean(
const std::vector<double>& nums,
size_t start,
size_t end) {
38 for (
size_t i = start; i <= end && i < nums.size(); i++) {
42 return (count == 0) ? 0.0 : sum / count;
49 LoadModel(FLAGS_evaluator_vehicle_mlp_file);
57 CHECK_NOTNULL(obstacle_ptr);
58 CHECK_LE(LANE_FEATURE_SIZE, 4 * FLAGS_max_num_lane_point);
62 int id = obstacle_ptr->
id();
64 AERROR <<
"Obstacle [" <<
id <<
"] has no latest feature.";
69 CHECK_NOTNULL(latest_feature_ptr);
70 if (!latest_feature_ptr->has_lane() ||
71 !latest_feature_ptr->
lane().has_lane_graph()) {
72 ADEBUG <<
"Obstacle [" <<
id <<
"] has no lane graph.";
76 double speed = latest_feature_ptr->
speed();
79 latest_feature_ptr->mutable_lane()->mutable_lane_graph();
80 CHECK_NOTNULL(lane_graph_ptr);
82 AERROR <<
"Obstacle [" <<
id <<
"] has no lane sequences.";
86 std::vector<double> obstacle_feature_values;
87 SetObstacleFeatureValues(obstacle_ptr, &obstacle_feature_values);
88 if (obstacle_feature_values.size() != OBSTACLE_FEATURE_SIZE) {
89 ADEBUG <<
"Obstacle [" <<
id <<
"] has fewer than "
90 <<
"expected obstacle feature_values "
91 << obstacle_feature_values.size() <<
".";
95 for (
int i = 0; i < lane_graph_ptr->lane_sequence_size(); ++i) {
96 LaneSequence* lane_sequence_ptr = lane_graph_ptr->mutable_lane_sequence(i);
97 ACHECK(lane_sequence_ptr !=
nullptr);
98 std::vector<double> lane_feature_values;
99 SetLaneFeatureValues(obstacle_ptr, lane_sequence_ptr, &lane_feature_values);
100 if (lane_feature_values.size() != LANE_FEATURE_SIZE) {
101 ADEBUG <<
"Obstacle [" <<
id <<
"] has fewer than "
102 <<
"expected lane feature_values" << lane_feature_values.size()
107 std::vector<double> feature_values;
108 feature_values.insert(feature_values.end(), obstacle_feature_values.begin(),
109 obstacle_feature_values.end());
110 feature_values.insert(feature_values.end(), lane_feature_values.begin(),
111 lane_feature_values.end());
114 if (FLAGS_prediction_offline_mode ==
118 "mlp", lane_sequence_ptr);
119 ADEBUG <<
"Save extracted features for learning locally.";
122 double probability = ComputeProbability(feature_values);
124 double centripetal_acc_probability =
126 *lane_sequence_ptr, speed);
127 probability *= centripetal_acc_probability;
128 lane_sequence_ptr->set_probability(probability);
135 std::vector<double>* feature_values) {
136 int id = obstacle_ptr->
id();
137 std::vector<double> obstacle_feature_values;
139 SetObstacleFeatureValues(obstacle_ptr, &obstacle_feature_values);
141 if (obstacle_feature_values.size() != OBSTACLE_FEATURE_SIZE) {
142 ADEBUG <<
"Obstacle [" <<
id <<
"] has fewer than "
143 <<
"expected obstacle feature_values "
144 << obstacle_feature_values.size() <<
".";
148 std::vector<double> lane_feature_values;
149 SetLaneFeatureValues(obstacle_ptr, lane_sequence_ptr, &lane_feature_values);
150 if (lane_feature_values.size() != LANE_FEATURE_SIZE) {
151 ADEBUG <<
"Obstacle [" <<
id <<
"] has fewer than "
152 <<
"expected lane feature_values" << lane_feature_values.size()
157 feature_values->insert(feature_values->end(), obstacle_feature_values.begin(),
158 obstacle_feature_values.end());
159 feature_values->insert(feature_values->end(), lane_feature_values.begin(),
160 lane_feature_values.end());
163void MLPEvaluator::SaveOfflineFeatures(
164 LaneSequence* sequence,
const std::vector<double>& feature_values) {
165 for (
double feature_value : feature_values) {
166 sequence->mutable_features()->add_mlp_features(feature_value);
170void MLPEvaluator::SetObstacleFeatureValues(
171 Obstacle* obstacle_ptr, std::vector<double>* feature_values) {
172 feature_values->clear();
173 feature_values->reserve(OBSTACLE_FEATURE_SIZE);
175 std::vector<double> thetas;
176 std::vector<double> lane_ls;
177 std::vector<double> dist_lbs;
178 std::vector<double> dist_rbs;
179 std::vector<int> lane_types;
180 std::vector<double> speeds;
181 std::vector<double> timestamps;
184 obstacle_ptr->timestamp() - FLAGS_prediction_trajectory_time_length;
186 for (std::size_t i = 0; i < obstacle_ptr->history_size(); ++i) {
187 const Feature& feature = obstacle_ptr->feature(i);
188 if (!feature.IsInitialized()) {
191 if (feature.timestamp() < duration) {
194 if (feature.has_lane() && feature.lane().has_lane_feature()) {
195 thetas.push_back(feature.lane().lane_feature().angle_diff());
196 lane_ls.push_back(feature.lane().lane_feature().lane_l());
197 dist_lbs.push_back(feature.lane().lane_feature().dist_to_left_boundary());
199 feature.lane().lane_feature().dist_to_right_boundary());
200 lane_types.push_back(feature.lane().lane_feature().lane_turn_type());
201 timestamps.push_back(feature.timestamp());
202 speeds.push_back(feature.speed());
209 size_t curr_size = 5;
210 size_t hist_size = obstacle_ptr->history_size();
211 double theta_mean =
ComputeMean(thetas, 0, hist_size - 1);
212 double theta_filtered =
ComputeMean(thetas, 0, curr_size - 1);
213 double lane_l_mean =
ComputeMean(lane_ls, 0, hist_size - 1);
214 double lane_l_filtered =
ComputeMean(lane_ls, 0, curr_size - 1);
215 double speed_mean =
ComputeMean(speeds, 0, hist_size - 1);
217 double time_diff = timestamps.front() - timestamps.back();
218 double dist_lb_rate = (timestamps.size() > 1)
219 ? (dist_lbs.front() - dist_lbs.back()) / time_diff
221 double dist_rb_rate = (timestamps.size() > 1)
222 ? (dist_rbs.front() - dist_rbs.back()) / time_diff
225 double delta_t = 0.0;
226 if (timestamps.size() > 1) {
227 delta_t = (timestamps.front() - timestamps.back()) /
228 static_cast<double>(timestamps.size() - 1);
230 double angle_curr =
ComputeMean(thetas, 0, curr_size - 1);
231 double angle_prev =
ComputeMean(thetas, curr_size, 2 * curr_size - 1);
233 (hist_size >= 2 * curr_size) ? angle_curr - angle_prev : 0.0;
235 double lane_l_curr =
ComputeMean(lane_ls, 0, curr_size - 1);
236 double lane_l_prev =
ComputeMean(lane_ls, curr_size, 2 * curr_size - 1);
238 (hist_size >= 2 * curr_size) ? lane_l_curr - lane_l_prev : 0.0;
240 double angle_diff_rate = 0.0;
241 double lane_l_diff_rate = 0.0;
242 if (delta_t > std::numeric_limits<double>::epsilon()) {
243 angle_diff_rate = angle_diff / (delta_t *
static_cast<double>(curr_size));
244 lane_l_diff_rate = lane_l_diff / (delta_t *
static_cast<float>(curr_size));
248 if (speeds.size() >= 3 * curr_size &&
249 delta_t > std::numeric_limits<double>::epsilon()) {
250 double speed_1 =
ComputeMean(speeds, 0, curr_size - 1);
251 double speed_2 =
ComputeMean(speeds, curr_size, 2 * curr_size - 1);
252 double speed_3 =
ComputeMean(speeds, 2 * curr_size, 3 * curr_size - 1);
253 acc = (speed_1 - 2 * speed_2 + speed_3) /
254 (
static_cast<float>(curr_size) *
static_cast<float>(curr_size) *
258 double dist_lb_rate_curr = 0.0;
259 if (hist_size >= 2 * curr_size &&
260 delta_t > std::numeric_limits<double>::epsilon()) {
261 double dist_lb_curr =
ComputeMean(dist_lbs, 0, curr_size - 1);
262 double dist_lb_prev =
ComputeMean(dist_lbs, curr_size, 2 * curr_size - 1);
263 dist_lb_rate_curr = (dist_lb_curr - dist_lb_prev) /
264 (
static_cast<float>(curr_size) * delta_t);
267 double dist_rb_rate_curr = 0.0;
268 if (hist_size >= 2 * curr_size &&
269 delta_t > std::numeric_limits<double>::epsilon()) {
270 double dist_rb_curr =
ComputeMean(dist_rbs, 0, curr_size - 1);
271 double dist_rb_prev =
ComputeMean(dist_rbs, curr_size, 2 * curr_size - 1);
272 dist_rb_rate_curr = (dist_rb_curr - dist_rb_prev) /
273 (
static_cast<float>(curr_size) * delta_t);
277 feature_values->push_back(theta_filtered);
278 feature_values->push_back(theta_mean);
279 feature_values->push_back(theta_filtered - theta_mean);
280 feature_values->push_back(angle_diff);
281 feature_values->push_back(angle_diff_rate);
283 feature_values->push_back(lane_l_filtered);
284 feature_values->push_back(lane_l_mean);
285 feature_values->push_back(lane_l_filtered - lane_l_mean);
286 feature_values->push_back(lane_l_diff);
287 feature_values->push_back(lane_l_diff_rate);
289 feature_values->push_back(speed_mean);
290 feature_values->push_back(acc);
292 feature_values->push_back(dist_lbs.front());
293 feature_values->push_back(dist_lb_rate);
294 feature_values->push_back(dist_lb_rate_curr);
296 feature_values->push_back(dist_rbs.front());
297 feature_values->push_back(dist_rb_rate);
298 feature_values->push_back(dist_rb_rate_curr);
300 feature_values->push_back(lane_types.front() == 0 ? 1.0 : 0.0);
301 feature_values->push_back(lane_types.front() == 1 ? 1.0 : 0.0);
302 feature_values->push_back(lane_types.front() == 2 ? 1.0 : 0.0);
303 feature_values->push_back(lane_types.front() == 3 ? 1.0 : 0.0);
306void MLPEvaluator::SetLaneFeatureValues(Obstacle* obstacle_ptr,
307 LaneSequence* lane_sequence_ptr,
308 std::vector<double>* feature_values) {
309 feature_values->clear();
310 feature_values->reserve(LANE_FEATURE_SIZE);
311 const Feature& feature = obstacle_ptr->latest_feature();
312 if (!feature.IsInitialized()) {
313 ADEBUG <<
"Obstacle [" << obstacle_ptr->id() <<
"] has no latest feature.";
315 }
else if (!feature.has_position()) {
316 ADEBUG <<
"Obstacle [" << obstacle_ptr->id() <<
"] has no position.";
320 double heading = feature.velocity_heading();
321 for (
int i = 0; i < lane_sequence_ptr->lane_segment_size(); ++i) {
322 if (feature_values->size() >= LANE_FEATURE_SIZE) {
325 const LaneSegment& lane_segment = lane_sequence_ptr->lane_segment(i);
326 for (
int j = 0; j < lane_segment.lane_point_size(); ++j) {
327 if (feature_values->size() >= LANE_FEATURE_SIZE) {
330 const LanePoint& lane_point = lane_segment.lane_point(j);
331 if (!lane_point.has_position()) {
332 AERROR <<
"Lane point has no position.";
335 double diff_x = lane_point.position().x() - feature.position().x();
336 double diff_y = lane_point.position().y() - feature.position().y();
337 double angle = std::atan2(diff_y, diff_x);
338 feature_values->push_back(std::sin(angle - heading));
339 feature_values->push_back(lane_point.relative_l());
340 feature_values->push_back(lane_point.heading());
341 feature_values->push_back(lane_point.angle_diff());
345 std::size_t size = feature_values->size();
346 while (size >= 4 && size < LANE_FEATURE_SIZE) {
347 double heading_diff = feature_values->operator[](size - 4);
348 double lane_l_diff = feature_values->operator[](size - 3);
349 double heading = feature_values->operator[](size - 2);
350 double angle_diff = feature_values->operator[](size - 1);
351 feature_values->push_back(heading_diff);
352 feature_values->push_back(lane_l_diff);
353 feature_values->push_back(heading);
354 feature_values->push_back(angle_diff);
355 size = feature_values->size();
359void MLPEvaluator::LoadModel(
const std::string& model_file) {
360 model_ptr_.reset(
new FnnVehicleModel());
361 ACHECK(model_ptr_ !=
nullptr);
363 <<
"Unable to load model file: " << model_file <<
".";
365 AINFO <<
"Succeeded in loading the model file: " << model_file <<
".";
368double MLPEvaluator::ComputeProbability(
369 const std::vector<double>& feature_values) {
370 CHECK_NOTNULL(model_ptr_.get());
371 double probability = 0.0;
373 if (model_ptr_->dim_input() !=
static_cast<int>(feature_values.size())) {
374 ADEBUG <<
"Model feature size not consistent with model proto definition. "
375 <<
"model input dim = " << model_ptr_->dim_input()
376 <<
"; feature value size = " << feature_values.size();
379 std::vector<double> layer_input;
380 layer_input.reserve(model_ptr_->dim_input());
381 std::vector<double> layer_output;
384 for (
int i = 0; i < model_ptr_->dim_input(); ++i) {
385 double mean = model_ptr_->samples_mean().columns(i);
386 double std = model_ptr_->samples_std().columns(i);
387 layer_input.push_back(
391 for (
int i = 0; i < model_ptr_->num_layer(); ++i) {
393 layer_input.swap(layer_output);
394 layer_output.clear();
396 const Layer& layer = model_ptr_->layer(i);
401 neuron_output += (layer_input[row] * weight);
406 neuron_output =
Sigmoid(neuron_output);
408 neuron_output = std::tanh(neuron_output);
410 AERROR <<
"Undefined activation function ["
412 <<
"]. A default sigmoid will be used instead.";
413 neuron_output =
Sigmoid(neuron_output);
415 layer_output.push_back(neuron_output);
419 if (layer_output.size() != 1) {
420 AERROR <<
"Model output layer has incorrect # outputs: "
421 << layer_output.size();
423 probability = layer_output[0];
ObstacleConf::EvaluatorType evaluator_type_
static void InsertDataForLearning(const Feature &feature, const std::vector< double > &feature_values, const std::string &category, const LaneSequence *lane_sequence_ptr)
Insert a data_for_learning
MLPEvaluator()
Constructor
void Clear()
Clear obstacle feature map
bool Evaluate(Obstacle *obstacle_ptr, ObstaclesContainer *obstacles_container) override
Override Evaluate
void ExtractFeatureValues(Obstacle *obstacle_ptr, LaneSequence *lane_sequence_ptr, std::vector< double > *feature_values)
Extract feature vector
bool IsNearJunction()
Check if the obstacle is near a junction.
Feature * mutable_latest_feature()
Get a pointer to the latest feature.
int id() const
Get the obstacle's ID.
void SetEvaluatorType(const ObstacleConf::EvaluatorType &evaluator_type)
const Feature & latest_feature() const
Get the latest feature.
static const int kDumpDataForLearning
static double ProbabilityByCentripetalAcceleration(const LaneSequence &lane_sequence, const double speed)
Compute the probability by centripetal acceleration
double Sigmoid(const double x)
bool GetProtoFromFile(const std::string &file_name, google::protobuf::Message *message)
Parses the content of the file specified by the file_name as a representation of protobufs,...
double Relu(const double value)
RELU function used in neural networks as an activation function.
double Normalize(const double value, const double mean, const double std)
Normalize the value by specified mean and standard deviation.
double ComputeMean(const std::vector< double > &nums, size_t start, size_t end)
Holds all global constants for the prediction module.
optional int32 layer_input_dim
optional Matrix layer_input_weight
optional ActivationFunc layer_activation_func
optional Vector layer_bias
optional int32 layer_output_dim
repeated LaneSequence lane_sequence