Apollo 10.0
自动驾驶开放平台
interpolation_2d.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2017 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 <cmath>
20
21#include "cyber/common/log.h"
23
24namespace {
25
26const double kDoubleEpsilon = 1.0e-6;
27
28} // namespace
29
30namespace apollo {
31namespace control {
32
34 if (xyz.empty()) {
35 AERROR << "empty input.";
36 return false;
37 }
38 for (const auto &t : xyz) {
39 xyz_[std::get<0>(t)][std::get<1>(t)] = std::get<2>(t);
40 }
41
42 if (!CheckMap()) {
43 AERROR << "calibration map is not correct.";
44 return false;
45 }
46
47 return true;
48}
49
51 double keysize = xyz_.begin()->second.size();
52 auto itr_ = xyz_.begin();
53 for (; itr_ != xyz_.end(); itr_++) {
54 if (FLAGS_use_calibration_dimension_equal_check) {
55 if (keysize != itr_->second.size()) {
56 AERROR << "calibration map dimension is not equal.";
57 AERROR << "first value: " << keysize
58 << ", second value: " << itr_->second.size();
59 return false;
60 }
61 }
62
63 int pos_count = 0;
64 int nag_count = 0;
65 auto inner_itr_ = itr_->second.begin();
66 for (; inner_itr_ != itr_->second.end(); inner_itr_++) {
67 if (inner_itr_->first > 0) {
68 pos_count++;
69 } else if (inner_itr_->first < 0) {
70 nag_count++;
71 }
72 }
73 if (nag_count == 0) {
74 AERROR << "calibration has all pos map";
75 return false;
76 }
77 if (pos_count == 0) {
78 AERROR << "calibration has all nag map";
79 return false;
80 }
81 }
82 return true;
83}
84
85double Interpolation2D::Interpolate(const KeyType &xy) const {
86 double max_x = xyz_.rbegin()->first;
87 double min_x = xyz_.begin()->first;
88 if (xy.first >= max_x - kDoubleEpsilon) {
89 return InterpolateYz(xyz_.rbegin()->second, xy.second);
90 }
91 if (xy.first <= min_x + kDoubleEpsilon) {
92 return InterpolateYz(xyz_.begin()->second, xy.second);
93 }
94
95 auto itr_after = xyz_.lower_bound(xy.first);
96 auto itr_before = itr_after;
97 if (itr_before != xyz_.begin()) {
98 --itr_before;
99 }
100
101 double x_before = itr_before->first;
102 double z_before = InterpolateYz(itr_before->second, xy.second);
103 double x_after = itr_after->first;
104 double z_after = InterpolateYz(itr_after->second, xy.second);
105
106 double x_diff_before = std::fabs(xy.first - x_before);
107 double x_diff_after = std::fabs(xy.first - x_after);
108
109 return InterpolateValue(z_before, x_diff_before, z_after, x_diff_after);
110}
111
112double Interpolation2D::InterpolateYz(const std::map<double, double> &yz_table,
113 double y) const {
114 if (yz_table.empty()) {
115 AERROR << "Unable to interpolateYz because yz_table is empty.";
116 return y;
117 }
118 double max_y = yz_table.rbegin()->first;
119 double min_y = yz_table.begin()->first;
120 if (y >= max_y - kDoubleEpsilon) {
121 return yz_table.rbegin()->second;
122 }
123 if (y <= min_y + kDoubleEpsilon) {
124 return yz_table.begin()->second;
125 }
126
127 auto itr_after = yz_table.lower_bound(y);
128 auto itr_before = itr_after;
129
130 if (itr_before != yz_table.begin()) {
131 --itr_before;
132 }
133
134 double y_before = itr_before->first;
135 double z_before = itr_before->second;
136 double y_after = itr_after->first;
137 double z_after = itr_after->second;
138
139 double y_diff_before = std::fabs(y - y_before);
140 double y_diff_after = std::fabs(y - y_after);
141
142 return InterpolateValue(z_before, y_diff_before, z_after, y_diff_after);
143}
144
145double Interpolation2D::InterpolateValue(const double value_before,
146 const double dist_before,
147 const double value_after,
148 const double dist_after) const {
149 if (dist_before < kDoubleEpsilon) {
150 return value_before;
151 }
152 if (dist_after < kDoubleEpsilon) {
153 return value_after;
154 }
155 double value_gap = value_after - value_before;
156 double value_buff = value_gap * dist_before / (dist_before + dist_after);
157 return value_before + value_buff;
158}
159
160} // namespace control
161} // namespace apollo
bool Init(const DataType &xyz)
initialize Interpolation2D internal table
std::pair< double, double > KeyType
std::vector< std::tuple< double, double, double > > DataType
double Interpolate(const KeyType &xy) const
linear interpolate from 2D key (double, double) to one double value.
#define AERROR
Definition log.h:44
const double kDoubleEpsilon
class register implement
Definition arena_queue.h:37