91 if (track_data->age_ > 0) {
92 if (new_object->direction.dot(latest_object->output_direction) < 0) {
93 new_object->direction *= -1;
96 double time_diff = new_object->timestamp - latest_object->timestamp;
98 double direction_measurement_variance = variance_bound_;
99 double angular_measurement_variance = variance_bound_;
101 &direction_measurement_variance,
102 &angular_measurement_variance, &angular);
104 Eigen::Vector2d direction_measurement;
105 direction_measurement(0) =
Vec2Angle(new_object->direction);
106 direction_measurement(1) = angular;
108 const auto& last_direction_state = latest_object->direction_state;
109 const auto& last_direction_state_covariance =
110 latest_object->direction_state_covariance;
112 Eigen::Matrix3d transition = Eigen::Matrix3d::Identity();
113 transition(0, 1) = time_diff;
114 transition(0, 2) = 0.5 * time_diff * time_diff;
115 transition(1, 2) = time_diff;
116 double direction_predict_noise =
117 variance_bound_ * (1e-1 * time_diff * time_diff);
119 auto& direction_state = new_object->direction_state;
120 auto& direction_state_covariance =
121 new_object->direction_state_covariance;
122 Eigen::Matrix3d predict_noise = Eigen::Matrix3d::Identity() *
123 predict_noise_per_sqrsec_ * time_diff;
124 predict_noise(0, 0) = direction_predict_noise;
126 direction_state = transition * last_direction_state;
128 direction_state_covariance =
129 transition * last_direction_state_covariance *
130 transition.transpose() + predict_noise;
133 Eigen::Matrix<double, 2, 3> observation_transform;
134 observation_transform.block<2, 2>(0, 0).setIdentity();
135 observation_transform.block<2, 1>(0, 2).setZero();
136 Eigen::Matrix2d measurement_covariance = Eigen::Matrix2d::Identity();
137 measurement_covariance(0, 0) = direction_measurement_variance;
138 measurement_covariance(1, 1) = angular_measurement_variance;
139 Eigen::Matrix<double, 3, 2> kalman_gain_matrix =
140 direction_state_covariance * observation_transform.transpose() *
141 (observation_transform * direction_state_covariance *
142 observation_transform.transpose() + measurement_covariance).inverse();
143 Eigen::Vector2d observation_transform_state =
144 observation_transform * direction_state;
145 Eigen::Vector2d measurement_residual;
146 measurement_residual(0) =
LegalizeAngle(direction_measurement(0) -
147 observation_transform_state(0));
148 measurement_residual(1) = direction_measurement(1) -
149 observation_transform_state(1);
152 Eigen::Vector3d direction_state_gain =
153 kalman_gain_matrix * measurement_residual;
156 direction_state(1) = direction_state(1) + direction_state_gain(1);
157 direction_state(2) = (direction_state(2) + direction_state_gain(2));
159 direction_state_covariance =
160 (Eigen::Matrix3d::Identity() - kalman_gain_matrix *
161 observation_transform) * direction_state_covariance;
163 double filter_theta =
Degree2Radian(new_object->direction_state(0));
164 double filter_angular =
Degree2Radian(new_object->direction_state(1));
165 new_object->output_direction(0) = std::cos(filter_theta);
166 new_object->output_direction(1) = std::sin(filter_theta);
167 new_object->output_direction(2) = 0.0;
168 new_object->output_angular(0) = std::cos(filter_angular);
169 new_object->output_angular(1) = std::sin(filter_angular);
170 new_object->output_angular(2) = 0.0;
176 double* direction_measurement_variance,
177 double* angular_measurement_variance,
180 std::vector<TrackedObjectConstPtr> history_objects;
181 track_data->GetObjectsInInterval(
182 new_object->timestamp - 2.0, &history_objects);
183 if (history_objects.size() == 0) {
186 history_objects.insert(history_objects.begin(), new_object);
187 size_t object_num = history_objects.size();
188 size_t history_start_interval = 5;
189 size_t history_end_interval = 15;
190 size_t angular_window_end = std::min(angular_window_size_, object_num - 1);
192 double window_time_diff = history_objects[0]->timestamp -
193 history_objects[angular_window_end]->timestamp;
194 *angular = angular_scale_ *
VecDiffAngle(history_objects[0]->direction,
195 history_objects[angular_window_end]->direction) / window_time_diff;
198 double time_diff = history_objects[0]->timestamp -
199 history_objects[1]->timestamp;
200 double latest_adjacent_frame_angular =
202 history_objects[1]->direction)) / time_diff;
205 double direction_confidence = 0.0;
207 *direction_measurement_variance =
208 std::pow((1.0 - direction_confidence) * 45.0, 2.0) + 1.0;
211 if (latest_adjacent_frame_angular > 3.0 * max_angular_thresh_) {
212 *direction_measurement_variance = variance_bound_ * variance_bound_;
213 *angular_measurement_variance = variance_bound_ * variance_bound_;;
219 std::vector<size_t> angular_vec;
220 double agreed_dir_num = 0.0;
221 for (
size_t i = 0; i < angular_window_end; ++i) {
222 double cur_time_diff = history_objects[i]->timestamp -
223 history_objects[i + 1]->timestamp;
224 double cur_angular =
VecDiffAngle(history_objects[i]->direction,
225 history_objects[i + 1]->direction) / cur_time_diff;
226 *angular_measurement_variance +=
227 (*angular - cur_angular) * (*angular - cur_angular);
229 size_t start = std::min(object_num - 1, i + history_start_interval);
230 size_t end = std::min(object_num - 1, i + history_end_interval);
231 for (
size_t j = start; j < end; ++j) {
235 double angle_change = algorithm::CalculateTheta2DXY<double>(
236 history_objects[i]->direction.head(2),
237 history_objects[j]->direction.head(2));
238 if (angle_change >= 0.0) {
239 angular_vec.push_back(1);
240 agreed_dir_num += 1.0;
242 angular_vec.push_back(-1);
247 *angular_measurement_variance /= (angular_window_end * 10.0);
251 agreed_dir_num = agreed_dir_num > 0.5 * angular_vec.size() ?
252 agreed_dir_num : angular_vec.size() - agreed_dir_num;
253 double agreed_dir_ratio = (agreed_dir_num + 1.0) / (angular_vec.size() + 1.0);
254 double angular_confidence = agreed_dir_ratio * agreed_dir_ratio;
255 if (angular_confidence < angular_confidence_thresh_) {
257 *angular_measurement_variance = 1.0;
280 Eigen::Vector3f polygon_direction = Eigen::Vector3f::Zero();
281 Eigen::Vector3d ref_center = Eigen::Vector3d::Zero();
284 (new_object->sensor_to_local_pose.rotation()).cast<float>()
286 double direction_diff = std::fabs(
287 algorithm::CalculateTheta2DXY<double>(new_object->direction.head(2),
288 polygon_direction.head(2).cast<
double>()));
289 direction_diff = direction_diff > M_PI / 2.0 ?
290 M_PI - direction_diff : direction_diff;
291 direction_diff = direction_diff > M_PI / 4.0 ?
292 M_PI / 2.0 - direction_diff : direction_diff;
293 *confidence = 1.0 - direction_diff / (0.25 * M_PI);