Apollo  6.0
Open source self driving car software
polygon_mask.h
Go to the documentation of this file.
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 #pragma once
17 
18 #include <algorithm>
19 #include <limits>
20 #include <vector>
21 
25 
26 namespace apollo {
27 namespace perception {
28 namespace lidar {
29 
30 template <typename T>
31 bool DrawPolygonMask(const typename PolygonScanCvter<T>::Polygon& polygon,
32  Bitmap2D* bitmap, const double extend_dist = 0.0,
33  const bool no_edge_table = false);
34 
35 template <typename T>
36 bool DrawPolygonsMask(
37  const std::vector<typename PolygonScanCvter<T>::Polygon>& polygons,
38  Bitmap2D* bitmap, const double extend_dist = 0.0,
39  const bool no_edge_table = false);
40 
41 template <typename T>
42 bool DrawPolygonMask(const typename PolygonScanCvter<T>::Polygon& polygon,
43  Bitmap2D* bitmap, const double extend_dist,
44  const bool no_edge_table) {
45  typedef typename PolygonScanCvter<T>::IntervalIn IntervalIn;
46  typedef typename PolygonScanCvter<T>::IntervalOut IntervalOut;
47  typedef typename PolygonScanCvter<T>::DirectionMajor PolyDirMajor;
48  if (bitmap->Empty()) {
49  AERROR << "bitmap is empty";
50  return false;
51  }
52  Eigen::Vector2d poly_min_p, poly_max_p;
53  poly_min_p.setConstant(std::numeric_limits<double>::max());
54  poly_max_p = -poly_min_p;
55  for (const auto& pt : polygon) {
56  poly_min_p.x() = std::min(pt.x(), poly_min_p.x());
57  poly_min_p.y() = std::min(pt.y(), poly_min_p.y());
58 
59  poly_max_p.x() = std::max(pt.x(), poly_max_p.x());
60  poly_max_p.y() = std::max(pt.y(), poly_max_p.y());
61  }
62  if (poly_max_p.x() <= poly_min_p.x()) {
63  AERROR << "Invalid polygon";
64  return false;
65  }
66  if (poly_max_p.y() <= poly_min_p.y()) {
67  AERROR << "Invalid polygon";
68  return false;
69  }
70  const Eigen::Vector2d& bitmap_min_range = bitmap->min_range();
71  const Eigen::Vector2d& bitmap_max_range = bitmap->max_range();
72  const Eigen::Vector2d& cell_size = bitmap->cell_size();
73  const int major_dir = bitmap->dir_major();
74  const int op_major_dir = bitmap->op_dir_major();
75 
76  // check major x range
77  IntervalIn valid_range;
78  valid_range.first =
79  std::max(poly_min_p[major_dir], bitmap_min_range[major_dir]);
80  valid_range.second =
81  std::min(poly_max_p[major_dir], bitmap_max_range[major_dir]);
82 
83  // for numerical stability
84  valid_range.first =
85  (static_cast<int>((valid_range.first - bitmap_min_range[major_dir]) /
86  cell_size[major_dir]) +
87  0.5) *
88  cell_size[major_dir] +
89  bitmap_min_range[major_dir];
90 
91  if (valid_range.second < valid_range.first + cell_size[major_dir]) {
92  AWARN << "Invalid range: " << valid_range.first << " " << valid_range.second
93  << ". polygon major directory range: " << poly_min_p[major_dir] << " "
94  << poly_max_p[major_dir] << ". cell size: " << cell_size[major_dir];
95  return true;
96  }
97 
98  // start calculating intervals of scans
99  PolygonScanCvter<T> poly_scan_cvter;
100  poly_scan_cvter.Init(polygon);
101  std::vector<std::vector<IntervalOut>> scans_intervals;
102  if (no_edge_table) {
103  size_t scans_size = static_cast<size_t>(
104  (valid_range.second - valid_range.first) / cell_size[major_dir]);
105  scans_intervals.resize(scans_size);
106  for (size_t i = 0; i < scans_size; ++i) {
107  double scan_loc = valid_range.first + i * cell_size[major_dir];
108  poly_scan_cvter.ScanCvt(scan_loc, static_cast<PolyDirMajor>(major_dir),
109  &(scans_intervals[i]));
110  }
111  } else {
112  poly_scan_cvter.ScansCvt(valid_range, static_cast<PolyDirMajor>(major_dir),
113  cell_size[major_dir], &(scans_intervals));
114  }
115  // start to draw
116  double x = valid_range.first;
117  for (size_t i = 0; i < scans_intervals.size();
118  x += cell_size[major_dir], ++i) {
119  for (auto scan_interval : scans_intervals[i]) {
120  if (scan_interval.first > scan_interval.second) {
121  AERROR << "The input polygon is illegal(complex polygon)";
122  return false;
123  }
124 
125  // extend
126  scan_interval.first -= extend_dist;
127  scan_interval.second += extend_dist;
128 
129  IntervalOut valid_y_range;
130  valid_y_range.first =
131  std::max(bitmap_min_range[op_major_dir], scan_interval.first);
132  valid_y_range.second =
133  std::min(bitmap_max_range[op_major_dir], scan_interval.second);
134  if (valid_y_range.first > valid_y_range.second) {
135  continue;
136  }
137  bitmap->Set(x, valid_y_range.first, valid_y_range.second);
138  }
139  }
140  return true;
141 }
142 
143 template <typename T>
145  const std::vector<typename PolygonScanCvter<T>::Polygon>& polygons,
146  Bitmap2D* bitmap, const double extend_dist, const bool no_edge_table) {
147  for (const auto& polygon : polygons) {
148  bool flag = DrawPolygonMask<T>(polygon, bitmap, extend_dist, no_edge_table);
149  if (!flag) {
150  return false;
151  }
152  }
153  return true;
154 }
155 
156 } // namespace lidar
157 } // namespace perception
158 } // namespace apollo
int op_dir_major() const
Definition: bitmap2d.h:47
PlanningContext is the runtime context in planning. It is persistent across multiple frames...
Definition: atomic_hash_map.h:25
const Eigen::Vector2d & cell_size() const
Definition: bitmap2d.h:42
Definition: bitmap2d.h:28
Eigen::Vector2d Vector2d
Definition: base_map_fwd.h:36
DirectionMajor
Definition: polygon_scan_cvter.h:75
void ScansCvt(const IntervalIn &scans_interval, const DirectionMajor dir_major, const T &step, std::vector< std::vector< IntervalOut >> *scans_intervals)
Definition: polygon_scan_cvter.h:206
bool DrawPolygonsMask(const std::vector< typename PolygonScanCvter< T >::Polygon > &polygons, Bitmap2D *bitmap, const double extend_dist=0.0, const bool no_edge_table=false)
Definition: polygon_mask.h:144
bool DrawPolygonMask(const typename PolygonScanCvter< T >::Polygon &polygon, Bitmap2D *bitmap, const double extend_dist=0.0, const bool no_edge_table=false)
Definition: polygon_mask.h:42
Definition: polygon_scan_cvter.h:33
bool Empty() const
Definition: bitmap2d.h:55
std::vector< Point, Eigen::aligned_allocator< Point > > Polygon
Definition: polygon_scan_cvter.h:36
void Set(const Eigen::Vector2d &p)
void ScanCvt(const T &scan_loc, DirectionMajor dir_major, std::vector< IntervalOut > *scan_intervals)
Definition: polygon_scan_cvter.h:153
std::pair< T, T > IntervalIn
Definition: polygon_scan_cvter.h:37
int dir_major() const
Definition: bitmap2d.h:46
std::pair< double, double > IntervalOut
Definition: polygon_scan_cvter.h:38
#define AERROR
Definition: log.h:44
void Init(const Polygon &polygon)
Definition: polygon_scan_cvter.h:136
#define AWARN
Definition: log.h:43
const Eigen::Vector2d & max_range() const
Definition: bitmap2d.h:41
const Eigen::Vector2d & min_range() const
Definition: bitmap2d.h:40