Apollo 9.0
自动驾驶开放平台
mlf_motion_refiner.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2018 The Apollo Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
16
18
19#include <algorithm>
20#include <limits>
21
22#include "cyber/common/file.h"
25
26namespace apollo {
27namespace perception {
28namespace lidar {
29
31 std::string config_file = "mlf_motion_refiner.conf";
32 if (!options.config_file.empty()) {
33 config_file = options.config_file;
34 }
35 config_file = GetConfigFile(options.config_path, config_file);
38 // read from proto config
43 return true;
44}
45
47 TrackedObjectPtr new_object) {
48 auto latest_object_pair = track_data->GetLatestObject();
49 const TrackedObjectConstPtr& latest_object = latest_object_pair.second;
50
51 // 1. keep motion if acceleration of filter is greater than a threshold
52 double time_diff = new_object->object_ptr->latest_tracked_time -
53 latest_object->object_ptr->latest_tracked_time;
54 Eigen::Vector3d filter_velocity_gain = new_object->belief_velocity_gain;
55 double filter_acceleration_gain = 0.0;
56 if (fabs(time_diff) < EPSION_TIME) {
57 filter_acceleration_gain = 0.0;
58 } else {
59 filter_acceleration_gain = filter_velocity_gain.norm() / time_diff;
60 }
61 bool need_keep_motion =
62 filter_acceleration_gain > claping_acceleration_threshold_;
63 // use tighter threshold for pedestrian
64 if (filter_acceleration_gain > claping_acceleration_threshold_ / 2 &&
65 new_object->type == base::ObjectType::PEDESTRIAN) {
66 need_keep_motion = true;
67 }
68
69 if (need_keep_motion && (!new_object->converged)) {
70 Eigen::Vector3d current_velocity = Eigen::Vector3d::Zero();
71 current_velocity = latest_object->output_velocity;
72 new_object->output_velocity = current_velocity;
73 // new_object->output_velocity = Eigen::Vector3d::Zero();
74 // new_object->state.tail<2>().setZero();
75 // new_object->belief_velocity = Eigen::Vector3d::Zero();
76 // new_object->state.head<2>().setZero();
77 AINFO << "[Velocity-Refine] track_id: " << track_data->track_id_
78 << " KEEP MOTION because of extraodinary acceleration.";
79 return true;
80 }
81 // 2. static hypothesis check
82 bool is_static_hypothesis =
83 CheckStaticHypothesisByState(latest_object, new_object);
84
85 if (is_static_hypothesis) {
86 new_object->output_velocity = Eigen::Vector3d::Zero();
87 new_object->state.tail<2>().setZero();
88 AINFO << "[Velocity-Refine] track_id: " << track_data->track_id_
89 << " set velocity to zero because of static_hypothesis.";
90 return true;
91 }
92 return false;
93}
94
96 const TrackedObjectConstPtr& latest_object,
97 const TrackedObjectConstPtr& new_object) const {
98 // Check whether track is static or not
99 // evaluate speed noise level, the less the level is the
100 // greater the probability of noise is
101 double speed = new_object->output_velocity.head(2).norm();
102
103 // TypeBasedThreshold
104 bool velocity_noise_level_0 = false;
105 bool velocity_noise_level_1 = false;
106 bool velocity_noise_level_2 = false;
107 auto type_select = new_object->type;
108 // for pedestrian we give loose threshold
109 if (type_select == base::ObjectType::PEDESTRIAN ||
110 type_select == base::ObjectType::UNKNOWN) {
111 velocity_noise_level_0 = speed < (claping_speed_threshold_ / 4.0);
112 velocity_noise_level_1 = speed < (claping_speed_threshold_ / 2.0);
113 velocity_noise_level_2 = speed < (claping_speed_threshold_ / 1.0);
114 } else if (type_select == base::ObjectType::BICYCLE) {
115 velocity_noise_level_0 = speed < (cyc_refine_speed_ / 6.0);
116 velocity_noise_level_1 = speed < (cyc_refine_speed_ / 4.0);
117 velocity_noise_level_2 = speed < (cyc_refine_speed_ / 2.0);
118 } else if (type_select == base::ObjectType::VEHICLE) {
119 velocity_noise_level_0 = speed < (car_refine_speed_ / 8.0);
120 velocity_noise_level_1 = speed < (car_refine_speed_ / 4.0);
121 velocity_noise_level_2 = speed < (car_refine_speed_ / 2.0);
122 }
123
124 // believe track is static if speed_level 0 is so small
125 if (velocity_noise_level_0) {
126 ADEBUG << "type: " << static_cast<size_t>(type_select)
127 << " speed is " << speed << " so small";
128 return true;
129 }
130
131 double velocity_change_angle = M_PI, velocity_heading_angle = M_PI;
132 if (CalculateVelocityAngleChange(latest_object, new_object,
133 &velocity_change_angle, &velocity_heading_angle)) {
134 ADEBUG << " velocity_change_angle: " << velocity_change_angle
135 << " velocity_heading_angle: " << velocity_heading_angle;
136 }
137
138 // believe track is static
139 // speed_level 1 and velocity-change or velocity-heading change > PI/6
140 bool dir_change_level_0 = (fabs(velocity_change_angle) > M_PI / 6 ||
141 fabs(velocity_heading_angle) > M_PI / 6);
142 if (velocity_noise_level_1 && dir_change_level_0) {
143 ADEBUG << "type: " << static_cast<size_t>(type_select) << " speed is "
144 << speed << " velocity_change is " << velocity_change_angle
145 << " velocity_heading is " << velocity_heading_angle
146 << " bigger than PI/6";
147 return true;
148 }
149
150 // believe track is static
151 // speed_level 2 and velocity-change or velocity-heading change is > PI/4
152 bool dir_change_level_1 = (fabs(velocity_change_angle) > M_PI / 4 ||
153 fabs(velocity_heading_angle) > M_PI / 4);
154 if (velocity_noise_level_2 && dir_change_level_1) {
155 ADEBUG << "type: " << static_cast<size_t>(type_select) << " speed is "
156 << speed << " velocity_change is " << velocity_change_angle
157 << " velocity_heading is " << velocity_heading_angle
158 << " bigger than PI/4";
159 return true;
160 }
161 return false;
162}
163
165 const TrackedObjectConstPtr& latest_object,
166 const TrackedObjectConstPtr& new_object,
167 double* vel_change_angle,
168 double* velocity_heading_angle) const {
169 Eigen::Vector3d pre_velocity = latest_object->output_velocity;
170 Eigen::Vector3d cur_velocity = new_object->output_velocity;
171 Eigen::Vector3d pre_direction = latest_object->output_direction;
172 constexpr double kEpsilon = std::numeric_limits<double>::epsilon();
173
174 if (pre_velocity.norm() < kEpsilon || cur_velocity.norm() < kEpsilon) {
175 return false;
176 }
177 *vel_change_angle = algorithm::CalculateTheta2DXY<double>(
178 pre_velocity, cur_velocity);
179
180 double velocity_heading_angle_1 = algorithm::CalculateTheta2DXY<double>(
181 pre_direction, cur_velocity);
182 pre_direction *= -1;
183 double velocity_heading_angle_2 = algorithm::CalculateTheta2DXY<double>(
184 pre_direction, cur_velocity);
185 *velocity_heading_angle = std::min(fabs(velocity_heading_angle_1),
186 fabs(velocity_heading_angle_2));
187 return true;
188}
189
191 const TrackedObjectConstPtr& latest_object,
192 const TrackedObjectConstPtr& new_object,
193 double reasonable_angle_change_maximum) const {
194 // note reasonable_angle_change_maximum should be within [0, M_PI]
195 // believe angle change is obvious if one of estimation pair is
196 // extrodinary small
197 Eigen::Vector3d previous_velocity = latest_object->output_velocity;
198 Eigen::Vector3d current_velocity = new_object->output_velocity;
199 constexpr double kEpsilon = std::numeric_limits<double>::epsilon();
200 if (previous_velocity.norm() < kEpsilon) {
201 // return false; // without motion score, this should be true
202 return true;
203 }
204 if (current_velocity.norm() < kEpsilon) {
205 return true;
206 }
207 // believe angle change is obvious if it is greater than threshold
208
209 double velocity_angle_change =
210 algorithm::CalculateTheta2DXY(previous_velocity, current_velocity);
211 if (fabs(velocity_angle_change) > reasonable_angle_change_maximum) {
212 return true;
213 }
214 // Let track be static if angle change of current velocity
215 // & previous heading is larger
216 // than given reasonable maximum.
217 Eigen::Vector3d previous_direction = latest_object->output_direction;
218 double velocity_heading_angle_change_1 =
219 algorithm::CalculateTheta2DXY(previous_direction, current_velocity);
220 previous_direction *= -1;
221 double velocity_heading_angle_change_2 =
222 algorithm::CalculateTheta2DXY<double>(
223 previous_direction, current_velocity);
224 velocity_angle_change = std::min(fabs(velocity_heading_angle_change_1),
225 fabs(velocity_heading_angle_change_2));
226 if (fabs(velocity_angle_change) > reasonable_angle_change_maximum) {
227 return true;
228 }
229 return false;
230}
231
232} // namespace lidar
233} // namespace perception
234} // namespace apollo
bool CheckStaticHypothesisByState(const TrackedObjectConstPtr &latest_object, const TrackedObjectConstPtr &new_object) const
Check whether new observed object is static or not
bool Init(const MlfMotionRefinerInitOptions &options=MlfMotionRefinerInitOptions())
Init motion refiner
bool Refine(const MlfTrackDataConstPtr &track_data, TrackedObjectPtr new_object)
Refine velocity of new object
bool CheckStaticHypothesisByVelocityAngleChange(const TrackedObjectConstPtr &latest_object, const TrackedObjectConstPtr &new_object, double reasonable_angle_change_maximum) const
Check whether new observed object is static or not via considering the angle velocity change
bool CalculateVelocityAngleChange(const TrackedObjectConstPtr &latest_object, const TrackedObjectConstPtr &new_object, double *vel_change_angle, double *velocity_heading_angle) const
#define ACHECK(cond)
Definition log.h:80
#define ADEBUG
Definition log.h:41
#define AINFO
Definition log.h:42
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,...
Definition file.cc:132
T CalculateTheta2DXY(const Eigen::Matrix< T, 3, 1 > &v1, const Eigen::Matrix< T, 3, 1 > &v2)
Definition basic.h:92
std::shared_ptr< const MlfTrackData > MlfTrackDataConstPtr
std::shared_ptr< const TrackedObject > TrackedObjectConstPtr
std::shared_ptr< TrackedObject > TrackedObjectPtr
std::string GetConfigFile(const std::string &config_path, const std::string &config_file)
Definition util.cc:80
class register implement