24#include <boost/property_tree/json_parser.hpp>
25#include <boost/property_tree/ptree.hpp>
31 std::shared_ptr<JsonConf> sp_conf)
32 : poses_(poses), sp_conf_(sp_conf) {
33 laps_to_check_ = laps_to_check;
38 possible_max_laps_ = (laps_to_check_ + 1) * 10;
39 confidence_.resize(possible_max_laps_ + 1, 0.0);
42 AINFO <<
"instance has " << poses.size() <<
" poses";
43 AINFO <<
"confidence size: " << possible_max_laps_ + 1;
46int LapsChecker::SetProgress(
double p) {
57 lap_ = laps_to_check_;
58 for (
size_t i = 0; i < confidence_.size(); ++i) {
59 AINFO <<
"confidence[" << i <<
"]: " << confidence_[i];
61 AINFO <<
"laps to check: " << laps_to_check_;
62 for (
size_t i = laps_to_check_; i < confidence_.size(); ++i) {
63 res += confidence_[i];
65 AINFO <<
"current confidence: " << res
66 <<
",confidence thresh:" << sp_conf_->laps_rate_thresh;
67 if (res < sp_conf_->laps_rate_thresh) {
68 if (confidence_.empty()) {
69 AINFO <<
"some problems induce lap problem";
74 for (
size_t i = 1; i < confidence_.size(); ++i) {
75 if (i == laps_to_check_) {
78 if (confidence_[i] > res) {
97void LapsChecker::DoCheck() {
101 AINFO <<
"check->check_params";
104 AINFO <<
"check_params failed";
108 AINFO <<
"check->setup_grids_map";
109 ret = SetupGridsMap();
111 AINFO <<
"setup_grids_map failed";
114 AINFO <<
"check->setup_grids_map done";
116 AINFO <<
"check->check_laps";
119 AINFO <<
"check_laps failed";
122 AINFO <<
"check->check_laps done";
124 AINFO <<
"do_check done";
127int LapsChecker::CheckParams() {
128 int n_pose =
static_cast<int>(
poses_.size());
129 if (n_pose < sp_conf_->laps_frames_thresh) {
135int LapsChecker::SetupGridsMap() {
136 AINFO <<
"setup_grids_map->get_min_max";
138 AINFO <<
"setup_grids_map->do_setup_grids_map";
139 int ret = DoSetupGridsMap();
141 AINFO <<
"do_setup_grids_map failed";
144 AINFO <<
"setup_grids_map done";
148int LapsChecker::CheckLaps() {
150 if (height <= 2 || height > 1000000) {
151 AINFO <<
"grids_map_ size error. height = " <<
height;
156 if (width <= 2 || width >= 1000000) {
157 AINFO <<
"grids_map_ size error. width = " <<
width;
161 for (
int y = 0; y <
height; y++) {
162 for (
int x = 0; x <
width; x++) {
164 size_t t_size = grid.size();
168 for (
size_t i = 0; i < t_size; ++i) {
169 std::vector<double> stamps;
170 GatherTimestamps(&stamps, grid[i].alpha, x, y);
171 if (stamps.empty()) {
174 std::sort(stamps.begin(), stamps.end());
175 double thresh_in_sec = sp_conf_->laps_time_err_thresh * 60;
177 for (
size_t j = 1; j < stamps.size(); ++j) {
178 if (stamps[j] - stamps[j - 1] > thresh_in_sec) {
182 if (segment <= possible_max_laps_) {
183 confidence_[segment] += 1;
190 for (
size_t i = 0; i < confidence_.size(); ++i) {
191 all += confidence_[i];
194 AINFO <<
"there seems no poses";
197 AINFO <<
"confidence size: " << confidence_.size();
198 for (
size_t i = 0; i < confidence_.size(); ++i) {
199 confidence_[i] /= all;
205int LapsChecker::GatherTimestamps(std::vector<double> *sp_stamps,
double alpha,
206 int center_x,
int center_y) {
207 int search_d = sp_conf_->laps_search_diameter;
208 if ((search_d & 1) == 0) {
209 AINFO <<
"laps_search_diameter should be an odd";
212 int search_r = (search_d >> 1);
214 std::vector<double> &stamps = *sp_stamps;
216 const size_t start_y = std::max(0, center_y - search_r);
218 std::min(
static_cast<int>(height) - 1, center_y + search_r);
219 const size_t start_x = std::max(0, center_x - search_r);
221 std::min(
static_cast<int>(width) - 1, center_x + search_r);
222 for (
size_t y = start_y; y <= end_y; y++) {
223 for (
size_t x = start_x; x <= end_x; x++) {
225 for (
size_t i = 0; i < grid.size(); ++i) {
226 if (std::abs(alpha - grid[i].alpha) < sp_conf_->laps_alpha_err_thresh) {
227 std::vector<int> &idxs = grid[i].idxs;
228 for (
size_t j = 0; j < idxs.size(); ++j) {
229 if (idxs[j] >=
static_cast<int>(
poses_.size())) {
230 AINFO <<
"index error, index: " << idxs[j]
231 <<
", pose size: " <<
poses_.size();
233 stamps.push_back(
poses_[idxs[j]].time_stamp);
244int LapsChecker::GetMinMax() {
245 minx_ = std::numeric_limits<double>::max();
246 miny_ = std::numeric_limits<double>::max();
247 maxx_ = std::numeric_limits<double>::min();
248 maxy_ = std::numeric_limits<double>::min();
249 size_t size =
poses_.size();
250 AINFO <<
"get_min_max pose size: " << size;
251 for (
size_t i = 0; i < size; ++i) {
269int LapsChecker::DoSetupGridsMap() {
273 size_t size =
poses_.size();
274 if (1 >= size || 0 == height || 0 == width || height > 1000000 ||
276 AINFO <<
"pose size: " << size <<
", height: " <<
height
277 <<
", width: " <<
width;
278 AINFO <<
"pose size error or grid map size error";
283 for (
size_t i = 0; i <
height; ++i) {
287 for (
size_t i = 1; i < size; ++i) {
290 PutPoseToGrid(
static_cast<int>(i), y, x);
291 PutPoseToNeighborGrid(
static_cast<int>(i));
296double LapsChecker::CalcAlpha(
int pose_index) {
297 double vecx =
poses_[pose_index].tx -
poses_[pose_index - 1].tx;
298 double vecy =
poses_[pose_index].ty -
poses_[pose_index - 1].ty;
299 double alpha = acos(vecx / sqrt(vecx * vecx + vecy * vecy)) * 180 / M_PI;
306int LapsChecker::PutPoseToGrid(
int pose_index,
int grid_y,
int grid_x) {
307 if (pose_index <= 0) {
310 double alpha = CalcAlpha(pose_index);
311 if (std::isnan(alpha)) {
312 AERROR <<
"ignore static pose " << pose_index;
317 size_t t_size = grid.size();
318 for (
size_t j = 0; j < t_size; ++j) {
319 if (std::abs(alpha - grid[j].alpha) < sp_conf_->laps_alpha_err_thresh) {
320 grid[j].idxs.push_back(pose_index);
321 grid[j].alpha = (grid[j].alpha + alpha) / 2;
328 gm.idxs = {pose_index};
333int LapsChecker::PutPoseToNeighborGrid(
int pose_index) {
334 if (pose_index <= 0) {
337 std::vector<int> x, y;
338 GetPassedGrid(pose_index, &x, &y);
339 for (
size_t i = 0; i < x.size(); ++i) {
340 PutPoseToGrid(pose_index, y[i], x[i]);
345int LapsChecker::GetPassedGrid(
int pose_index, std::vector<int> *sp_grid_x,
346 std::vector<int> *sp_grid_y) {
347 if (pose_index <= 0) {
350 std::vector<int> &grid_x = *sp_grid_x;
351 std::vector<int> &grid_y = *sp_grid_y;
358 if (std::abs(x - last_x) < 1e-6) {
359 int start_y =
static_cast<int>(std::min(y, last_y)) + 1;
360 int end_y =
static_cast<int>(std::max(y, last_y));
361 int start_x =
static_cast<int>(x);
362 while ((start_y++) < end_y) {
363 grid_x.push_back(start_x);
364 grid_y.push_back(start_y);
366 }
else if (std::abs(y - last_y) < 1e-6) {
367 int start_x =
static_cast<int>(std::min(x, last_x));
368 int end_x =
static_cast<int>(std::max(x, last_x));
369 int start_y =
static_cast<int>(y);
370 while ((++start_x) < end_x) {
371 grid_x.push_back(start_x);
372 grid_y.push_back(start_y);
375 double k = Slope(last_x, last_y, x, y);
376 if (k > 99999999.0) {
380 int steps =
static_cast<int>(std::abs(last_x - x));
382 double xx = 0.0, yy = 0.0;
386 xx = last_x, yy = last_y;
388 while ((step++) < steps) {
391 grid_x.push_back(
static_cast<int>(xx));
392 grid_y.push_back(
static_cast<int>(yy));
398double LapsChecker::Slope(
double x1,
double y1,
double x2,
double y2) {
399 if (std::abs(x1 - x2) < 1e-6) {
400 return std::numeric_limits<double>::max();
402 if (std::abs(y1 - y2) < 1e-6) {
405 return (y2 - y1) / (x2 - x1);
std::vector< std::vector< Grid > > grids_map_
LapsChecker(const std::vector< FramePose > &poses, int laps_to_check, std::shared_ptr< JsonConf > sp_conf)
ErrorCode GetReturnState()
const std::vector< FramePose > & poses_
double GetProgress() const
uint32_t height
Height of point cloud
uint32_t width
Width of point cloud
@ ERROR_VERIFY_NO_GNSSPOS