Apollo 10.0
自动驾驶开放平台
cartesian_frenet_conversion.cc
浏览该文件的文档.
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
18
19#include <cmath>
20
21#include "cyber/common/log.h"
23
24namespace apollo {
25namespace common {
26namespace math {
27
29 const double rs, const double rx, const double ry, const double rtheta,
30 const double rkappa, const double rdkappa, const double x, const double y,
31 const double v, const double a, const double theta, const double kappa,
32 std::array<double, 3>* const ptr_s_condition,
33 std::array<double, 3>* const ptr_d_condition) {
34 const double dx = x - rx;
35 const double dy = y - ry;
36
37 const double cos_theta_r = std::cos(rtheta);
38 const double sin_theta_r = std::sin(rtheta);
39
40 const double cross_rd_nd = cos_theta_r * dy - sin_theta_r * dx;
41 ptr_d_condition->at(0) =
42 std::copysign(std::sqrt(dx * dx + dy * dy), cross_rd_nd);
43
44 const double delta_theta = theta - rtheta;
45 const double tan_delta_theta = std::tan(delta_theta);
46 const double cos_delta_theta = std::cos(delta_theta);
47
48 const double one_minus_kappa_r_d = 1 - rkappa * ptr_d_condition->at(0);
49 ptr_d_condition->at(1) = one_minus_kappa_r_d * tan_delta_theta;
50
51 const double kappa_r_d_prime =
52 rdkappa * ptr_d_condition->at(0) + rkappa * ptr_d_condition->at(1);
53
54 ptr_d_condition->at(2) =
55 -kappa_r_d_prime * tan_delta_theta +
56 one_minus_kappa_r_d / cos_delta_theta / cos_delta_theta *
57 (kappa * one_minus_kappa_r_d / cos_delta_theta - rkappa);
58
59 ptr_s_condition->at(0) = rs;
60
61 ptr_s_condition->at(1) = v * cos_delta_theta / one_minus_kappa_r_d;
62
63 const double delta_theta_prime =
64 one_minus_kappa_r_d / cos_delta_theta * kappa - rkappa;
65 ptr_s_condition->at(2) =
66 (a * cos_delta_theta -
67 ptr_s_condition->at(1) * ptr_s_condition->at(1) *
68 (ptr_d_condition->at(1) * delta_theta_prime - kappa_r_d_prime)) /
69 one_minus_kappa_r_d;
70}
71
73 const double rs, const double rx, const double ry, const double rtheta,
74 const double x, const double y, double* ptr_s, double* ptr_d) {
75 const double dx = x - rx;
76 const double dy = y - ry;
77
78 const double cos_theta_r = std::cos(rtheta);
79 const double sin_theta_r = std::sin(rtheta);
80
81 const double cross_rd_nd = cos_theta_r * dy - sin_theta_r * dx;
82 *ptr_d = std::copysign(std::sqrt(dx * dx + dy * dy), cross_rd_nd);
83 *ptr_s = rs;
84}
85
87 const double rs, const double rx, const double ry, const double rtheta,
88 const double rkappa, const double rdkappa,
89 const std::array<double, 3>& s_condition,
90 const std::array<double, 3>& d_condition, double* const ptr_x,
91 double* const ptr_y, double* const ptr_theta, double* const ptr_kappa,
92 double* const ptr_v, double* const ptr_a) {
93 ACHECK(std::abs(rs - s_condition[0]) < 1.0e-6)
94 << "The reference point s and s_condition[0] don't match";
95
96 const double cos_theta_r = std::cos(rtheta);
97 const double sin_theta_r = std::sin(rtheta);
98
99 *ptr_x = rx - sin_theta_r * d_condition[0];
100 *ptr_y = ry + cos_theta_r * d_condition[0];
101
102 const double one_minus_kappa_r_d = 1 - rkappa * d_condition[0];
103
104 const double tan_delta_theta = d_condition[1] / one_minus_kappa_r_d;
105 const double delta_theta = std::atan2(d_condition[1], one_minus_kappa_r_d);
106 const double cos_delta_theta = std::cos(delta_theta);
107
108 *ptr_theta = NormalizeAngle(delta_theta + rtheta);
109
110 const double kappa_r_d_prime =
111 rdkappa * d_condition[0] + rkappa * d_condition[1];
112 *ptr_kappa = (((d_condition[2] + kappa_r_d_prime * tan_delta_theta) *
113 cos_delta_theta * cos_delta_theta) /
114 (one_minus_kappa_r_d) +
115 rkappa) *
116 cos_delta_theta / (one_minus_kappa_r_d);
117
118 const double d_dot = d_condition[1] * s_condition[1];
119 *ptr_v = std::sqrt(one_minus_kappa_r_d * one_minus_kappa_r_d *
120 s_condition[1] * s_condition[1] +
121 d_dot * d_dot);
122
123 const double delta_theta_prime =
124 one_minus_kappa_r_d / cos_delta_theta * (*ptr_kappa) - rkappa;
125
126 *ptr_a = s_condition[2] * one_minus_kappa_r_d / cos_delta_theta +
127 s_condition[1] * s_condition[1] / cos_delta_theta *
128 (d_condition[1] * delta_theta_prime - kappa_r_d_prime);
129}
130
132 const double rkappa,
133 const double l,
134 const double dl) {
135 return NormalizeAngle(rtheta + std::atan2(dl, 1 - l * rkappa));
136}
137
139 const double rdkappa,
140 const double l, const double dl,
141 const double ddl) {
142 double denominator = (dl * dl + (1 - l * rkappa) * (1 - l * rkappa));
143 if (std::fabs(denominator) < 1e-8) {
144 return 0.0;
145 }
146 denominator = std::pow(denominator, 1.5);
147 const double numerator = rkappa + ddl - 2 * l * rkappa * rkappa -
148 l * ddl * rkappa + l * l * rkappa * rkappa * rkappa +
149 l * dl * rdkappa + 2 * dl * dl * rkappa;
150 return numerator / denominator;
151}
152
154 const Vec2d& rpoint,
155 const double l) {
156 const double x = rpoint.x() - l * std::sin(rtheta);
157 const double y = rpoint.y() + l * std::cos(rtheta);
158 return Vec2d(x, y);
159}
160
162 const double rtheta, const double theta, const double l,
163 const double rkappa) {
164 return (1 - rkappa * l) * std::tan(theta - rtheta);
165}
166
168 const double rtheta, const double theta, const double rkappa,
169 const double kappa, const double rdkappa, const double l) {
170 const double dl = CalculateLateralDerivative(rtheta, theta, l, rkappa);
171 const double theta_diff = theta - rtheta;
172 const double cos_theta_diff = std::cos(theta_diff);
173 const double res = -(rdkappa * l + rkappa * dl) * std::tan(theta - rtheta) +
174 (1 - rkappa * l) / (cos_theta_diff * cos_theta_diff) *
175 (kappa * (1 - rkappa * l) / cos_theta_diff - rkappa);
176 if (std::isinf(res)) {
177 AWARN << "result is inf when calculate second order lateral "
178 "derivative. input values are rtheta:"
179 << rtheta << " theta: " << theta << ", rkappa: " << rkappa
180 << ", kappa: " << kappa << ", rdkappa: " << rdkappa << ", l: " << l
181 << std::endl;
182 }
183 return res;
184}
185
186} // namespace math
187} // namespace common
188} // namespace apollo
static void frenet_to_cartesian(const double rs, const double rx, const double ry, const double rtheta, const double rkappa, const double rdkappa, const std::array< double, 3 > &s_condition, const std::array< double, 3 > &d_condition, double *const ptr_x, double *const ptr_y, double *const ptr_theta, double *const ptr_kappa, double *const ptr_v, double *const ptr_a)
Convert a vehicle state in Frenet frame to Cartesian frame.
static void cartesian_to_frenet(const double rs, const double rx, const double ry, const double rtheta, const double rkappa, const double rdkappa, const double x, const double y, const double v, const double a, const double theta, const double kappa, std::array< double, 3 > *const ptr_s_condition, std::array< double, 3 > *const ptr_d_condition)
Convert a vehicle state in Cartesian frame to Frenet frame.
static Vec2d CalculateCartesianPoint(const double rtheta, const Vec2d &rpoint, const double l)
static double CalculateSecondOrderLateralDerivative(const double theta_ref, const double theta, const double kappa_ref, const double kappa, const double dkappa_ref, const double l)
static double CalculateTheta(const double rtheta, const double rkappa, const double l, const double dl)
static double CalculateLateralDerivative(const double theta_ref, const double theta, const double l, const double kappa_ref)
: given sl, theta, and road's theta, kappa, extract derivative l, second order derivative l:
static double CalculateKappa(const double rkappa, const double rdkappa, const double l, const double dl, const double ddl)
Implements a class of 2-dimensional vectors.
Definition vec2d.h:42
double y() const
Getter for y component
Definition vec2d.h:57
double x() const
Getter for x component
Definition vec2d.h:54
#define ACHECK(cond)
Definition log.h:80
#define AWARN
Definition log.h:43
Math-related util functions.
double NormalizeAngle(const double angle)
Normalize angle to [-PI, PI).
Definition math_utils.cc:53
class register implement
Definition arena_queue.h:37