Apollo 10.0
自动驾驶开放平台
hermite_spline.h
浏览该文件的文档.
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
21#pragma once
22
23#include <array>
24#include <utility>
25
26#include "cyber/common/log.h"
27
28namespace apollo {
29namespace common {
30namespace math {
31
32// Hermite spline implementation that works for 1d and 2d space interpolation.
33// Valid input type T: double, Eigen::Vector2d
34template <typename T, std::size_t N>
36 public:
37 HermiteSpline(std::array<T, (N + 1) / 2> x0, std::array<T, (N + 1) / 2> x1,
38 const double z0 = 0.0, const double z1 = 1.0);
39
40 virtual ~HermiteSpline() = default;
41
42 virtual T Evaluate(const std::uint32_t order, const double z) const;
43
44 private:
45 std::array<T, (N + 1) / 2> x0_;
46
47 std::array<T, (N + 1) / 2> x1_;
48
49 double z0_ = 0.0;
50
51 double delta_z_ = 0.0;
52};
53
54template <typename T, std::size_t N>
55inline HermiteSpline<T, N>::HermiteSpline(std::array<T, (N + 1) / 2> x0,
56 std::array<T, (N + 1) / 2> x1,
57 const double z0, const double z1)
58 : x0_(std::move(x0)), x1_(std::move(x1)), z0_(z0), delta_z_(z1 - z0) {
59 ACHECK(N == 3 || N == 5)
60 << "Error: currently we only support cubic and quintic hermite splines!";
61}
62
63template <typename T, std::size_t N>
64inline T HermiteSpline<T, N>::Evaluate(const std::uint32_t order,
65 const double z) const {
66 CHECK_LE(z0_, z);
67 CHECK_LE(z, z0_ + delta_z_);
68
69 // if N == 3, cubic hermite spline, N == 5, quintic hermite spline
70 if (N == 3) {
71 const T& p0 = x0_[0];
72 const T& v0 = x0_[1];
73 const T& p1 = x1_[0];
74 const T& v1 = x1_[1];
75 switch (order) {
76 case 0: {
77 const double t = (z - z0_) / delta_z_;
78 const double t2 = t * t;
79 const double t3 = t2 * t;
80
81 return (2.0 * t3 - 3.0 * t2 + 1.0) * p0 + (t3 - 2 * t2 + t) * v0 +
82 (-2.0 * t3 + 3.0 * t2) * p1 + (t3 - t2) * v1;
83 }
84 case 1: {
85 const double t = (z - z0_) / delta_z_;
86 const double t2 = t * t;
87
88 return (6.0 * t2 - 6.0 * t) * p0 + (3.0 * t2 - 4 * t + 1.0) * v0 +
89 (-6.0 * t2 + 6.0 * t) * p1 + (3.0 * t2 - 2.0 * t) * v1;
90 }
91 case 2: {
92 const double t = (z - z0_) / delta_z_;
93 return (12.0 * t - 6.0) * p0 + (6.0 * t - 4.0) * v0 +
94 (-12.0 * t + 6.0) * p1 + (6.0 * t - 2.0) * v1;
95 }
96 case 3: {
97 return 12.0 * p0 + 6.0 * v0 - 12.0 * p1 + 6.0 * v1;
98 }
99 default: { break; }
100 }
101 } else {
102 CHECK_EQ(5, N);
103 const T& p0 = x0_[0];
104 const T& v0 = x0_[1];
105 const T& a0 = x0_[2];
106 const T& p1 = x1_[0];
107 const T& v1 = x1_[1];
108 const T& a1 = x1_[2];
109
110 switch (order) {
111 case 0: {
112 const double t = (z - z0_) / delta_z_;
113 const double t2 = t * t;
114 const double t3 = t * t2;
115 const double t4 = t2 * t2;
116 const double t5 = t2 * t3;
117 const double det0 = t3 - t4;
118 const double det1 = t4 - t5;
119 const double h0 = 1.0 - 10.0 * t3 + 15.0 * t4 - 6.0 * t5;
120 const double h1 = t - 6.0 * t3 + 8.0 * t4 - 3.0 * t5;
121 const double h2 = 0.5 * (t2 - t5) - 1.5 * det0;
122 const double h3 = 10.0 * t3 - 15.0 * t4 + 6.0 * t5;
123 const double h4 = -4.0 * det0 + 3.0 * det1;
124 const double h5 = 0.5 * (det0 - det1);
125
126 return h0 * p0 + h1 * v0 + h2 * a0 + h3 * p1 + h4 * v1 + h5 * a1;
127 }
128 case 1: {
129 const double t = (z - z0_) / delta_z_;
130 const double t2 = t * t;
131 const double t3 = t * t2;
132 const double t4 = t2 * t2;
133 const double det0 = t2 - t3;
134 const double det1 = t3 - t4;
135 const double dh0 = -30.0 * det0 + 30.0 * det1;
136 const double dh1 = 1 - 18.0 * t2 + 32.0 * t3 - 15.0 * t4;
137 const double dh2 = t - 4.5 * t2 + 6.0 * t3 - 2.5 * t4;
138 const double dh3 = 30.0 * det0 - 30.0 * det1;
139 const double dh4 = -12.0 * t2 + 28.0 * t3 - 15.0 * t4;
140 const double dh5 = 1.5 * det0 - 2.5 * det1;
141
142 return dh0 * p0 + dh1 * v0 + dh2 * a0 + dh3 * p1 + dh4 * v1 + dh5 * a1;
143 }
144 case 2: {
145 const double t = (z - z0_) / delta_z_;
146 const double t2 = t * t;
147 const double t3 = t * t2;
148 const double det0 = t - t2;
149 const double det1 = t2 - t3;
150 const double ddh0 = -60.0 * det0 + 120.0 * det1;
151 const double ddh1 = -36.0 * det0 + 60.0 * det1;
152 const double ddh2 = 1.0 - 9.0 * t + 18.0 * t2 - 10.0 * t3;
153 const double ddh3 = 60.0 * det0 - 120.0 * det1;
154 const double ddh4 = -24.0 * det0 + 60.0 * det1;
155 const double ddh5 = 3.0 * t - 12.0 * t2 + 10.0 * t3;
156
157 return ddh0 * p0 + ddh1 * v0 + ddh2 * a0 + ddh3 * p1 + ddh4 * v1 +
158 ddh5 * a1;
159 }
160 case 3: {
161 const double t = (z - z0_) / delta_z_;
162 const double t2 = t * t;
163 const double det = t - t2;
164 const double dddh0 = -60.0 + 360.0 * det;
165 const double dddh1 = -36.0 + 192.0 * t - 180.0 * t2;
166 const double dddh2 = -9.0 + 36.0 * t - 30.0 * t2;
167 const double dddh3 = 60.0 - 360.0 * det;
168 const double dddh4 = -24.0 + 168.0 * t - 180.0 * t2;
169 const double dddh5 = 3.0 - 24.0 * t + 30.0 * t2;
170
171 return dddh0 * p0 + dddh1 * v0 + dddh2 * a0 + dddh3 * p1 + dddh4 * v1 +
172 dddh5 * a1;
173 }
174 case 4: {
175 const double t = (z - z0_) / delta_z_;
176 const double d4h0 = 360.0 - 720.0 * t;
177 const double d4h1 = 192.0 - 360.0 * t;
178 const double d4h2 = 36.0 - 60.0 * t;
179 const double d4h3 = -360.0 + 720.0 * t;
180 const double d4h4 = 168.0 - 360.0 * t;
181 const double d4h5 = -24.0 + 60.0 * t;
182
183 return d4h0 * p0 + d4h1 * v0 + d4h2 * a0 + d4h3 * p1 + d4h4 * v1 +
184 d4h5 * a1;
185 }
186 case 5: {
187 const double d5h0 = -720.0;
188 const double d5h1 = -360.0;
189 const double d5h2 = -60.0;
190 const double d5h3 = 720.0;
191 const double d5h4 = -360.0;
192 const double d5h5 = 60.0;
193
194 return d5h0 * p0 + d5h1 * v0 + d5h2 * a0 + d5h3 * p1 + d5h4 * v1 +
195 d5h5 * a1;
196 }
197 default: { break; }
198 }
199 }
200 return T();
201}
202
203} // namespace math
204} // namespace common
205} // namespace apollo
HermiteSpline(std::array< T,(N+1)/2 > x0, std::array< T,(N+1)/2 > x1, const double z0=0.0, const double z1=1.0)
virtual T Evaluate(const std::uint32_t order, const double z) const
#define ACHECK(cond)
Definition log.h:80
class register implement
Definition arena_queue.h:37
Definition future.h:29