Apollo  6.0
Open source self driving car software
basic.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 
17 #pragma once
18 
19 #include <limits>
20 
21 #include "Eigen/Core"
23 
24 namespace apollo {
25 namespace perception {
26 namespace common {
27 
28 // @brief cross production on two vectors
29 // one is from pt1 to pt2, another is from pt1 to pt3
30 // the type of points could be double or float
31 // old name: cross_prod
32 template <typename Type>
33 inline Type CrossProduct(const Eigen::Matrix<Type, 2, 1> &point1,
34  const Eigen::Matrix<Type, 2, 1> &point2,
35  const Eigen::Matrix<Type, 2, 1> &point3) {
36  return (point2.x() - point1.x()) * (point3.y() - point1.y()) -
37  (point3.x() - point1.x()) * (point2.y() - point1.y());
38 }
39 
40 // @brief cross production on two vectors
41 // one is from pt1 to pt2, another is from pt1 to pt3
42 // the type of points could be double or float
43 // old name: cross_prod
44 template <typename PointT>
45 inline typename PointT::Type CrossProduct(const PointT &point1,
46  const PointT &point2,
47  const PointT &point3) {
48  return (point2.x - point1.x) * (point3.y - point1.y) -
49  (point3.x - point1.x) * (point2.y - point1.y);
50 }
51 
52 // @brief calculate the Eucliden distance between two points
53 // old name: euclidean_dist
54 template <typename PointT>
55 inline typename PointT::Type CalculateEuclidenDist(const PointT &pt1,
56  const PointT &pt2) {
57  typename PointT::Type dist = (pt1.x - pt2.x) * (pt1.x - pt2.x);
58  dist += (pt1.y - pt2.y) * (pt1.y - pt2.y);
59  dist += (pt1.z - pt2.z) * (pt1.z - pt2.z);
60  return static_cast<typename PointT::Type>(sqrt(dist));
61 }
62 
63 // @brief calculate the Euclidean distance between two points in X-Y plane
64 // old name: euclidean_dist_2d_xy
65 template <typename PointT>
66 inline typename PointT::Type CalculateEuclidenDist2DXY(const PointT &pt1,
67  const PointT &pt2) {
68  typename PointT::Type dist = (pt1.x - pt2.x) * (pt1.x - pt2.x);
69  dist += (pt1.y - pt2.y) * (pt1.y - pt2.y);
70  return static_cast<typename PointT::Type>(sqrt(dist));
71 }
72 
73 // @brief calculate cos value of the rotation angle
74 // between two vectors in X-Y plane
75 // old name: vector_cos_theta_2d_xy
76 template <typename T>
77 T CalculateCosTheta2DXY(const Eigen::Matrix<T, 3, 1> &v1,
78  const Eigen::Matrix<T, 3, 1> &v2) {
79  T v1_len = static_cast<T>(sqrt((v1.head(2).cwiseProduct(v1.head(2))).sum()));
80  T v2_len = static_cast<T>(sqrt((v2.head(2).cwiseProduct(v2.head(2))).sum()));
81  if (v1_len < std::numeric_limits<T>::epsilon() ||
82  v2_len < std::numeric_limits<T>::epsilon()) {
83  return 0.0;
84  }
85  T cos_theta = (v1.head(2).cwiseProduct(v2.head(2))).sum() / (v1_len * v2_len);
86  return cos_theta;
87 }
88 
89 // @brief calculate the rotation angle between two vectors in X-Y plane
90 // old name: vector_theta_2d_xy
91 template <typename T>
92 T CalculateTheta2DXY(const Eigen::Matrix<T, 3, 1> &v1,
93  const Eigen::Matrix<T, 3, 1> &v2) {
94  T v1_len = static_cast<T>(sqrt((v1.head(2).cwiseProduct(v1.head(2))).sum()));
95  T v2_len = static_cast<T>(sqrt((v2.head(2).cwiseProduct(v2.head(2))).sum()));
96  if (v1_len < std::numeric_limits<T>::epsilon() ||
97  v2_len < std::numeric_limits<T>::epsilon()) {
98  return 0.0;
99  }
100  const T cos_theta =
101  (v1.head(2).cwiseProduct(v2.head(2))).sum() / (v1_len * v2_len);
102  const T sin_theta = (v1(0) * v2(1) - v1(1) * v2(0)) / (v1_len * v2_len);
103  T theta = std::acos(cos_theta);
104  if (sin_theta < 0.0) {
105  theta = -theta;
106  }
107  return theta;
108 }
109 
110 // @brief calculate the rotation matrix
111 // transform from v1 axis coordinate to v2 axis coordinate
112 // old name: vector_rot_mat_2d_xy
113 template <typename T>
114 Eigen::Matrix<T, 3, 3> CalculateRotationMat2DXY(
115  const Eigen::Matrix<T, 3, 1> &v1, const Eigen::Matrix<T, 3, 1> &v2) {
116  T v1_len = static_cast<T>(sqrt((v1.head(2).cwiseProduct(v1.head(2))).sum()));
117  T v2_len = static_cast<T>(sqrt((v2.head(2).cwiseProduct(v2.head(2))).sum()));
118  if (v1_len < std::numeric_limits<T>::epsilon() ||
119  v2_len < std::numeric_limits<T>::epsilon()) {
120  return Eigen::Matrix<T, 3, 3>::Zero(3, 3);
121  }
122 
123  const T cos_theta =
124  (v1.head(2).cwiseProduct(v2.head(2))).sum() / (v1_len * v2_len);
125  const T sin_theta = (v1(0) * v2(1) - v1(1) * v2(0)) / (v1_len * v2_len);
126 
127  Eigen::Matrix<T, 3, 3> rot_mat;
128  rot_mat << cos_theta, sin_theta, 0, -sin_theta, cos_theta, 0, 0, 0, 1;
129  return rot_mat;
130 }
131 
132 // @brief calculate the project vector from one vector to another
133 // old name: compute_2d_xy_project_vector
134 template <typename T>
135 Eigen::Matrix<T, 3, 1> Calculate2DXYProjectVector(
136  const Eigen::Matrix<T, 3, 1> &projected_vector,
137  const Eigen::Matrix<T, 3, 1> &project_vector) {
138  if (projected_vector.head(2).norm() < std::numeric_limits<T>::epsilon() ||
139  project_vector.head(2).norm() < std::numeric_limits<T>::epsilon()) {
140  return Eigen::Matrix<T, 3, 1>::Zero(3, 1);
141  }
142  Eigen::Matrix<T, 3, 1> project_dir = project_vector;
143  project_dir(2) = 0.0;
144  project_dir.normalize();
145 
146  const T projected_vector_project_dir_inner_product =
147  projected_vector(0) * project_dir(0) +
148  projected_vector(1) * project_dir(1);
149  const T projected_vector_project_dir_angle_cos =
150  projected_vector_project_dir_inner_product /
151  (projected_vector.head(2).norm() * project_dir.head(2).norm());
152  const T projected_vector_norm_on_project_dir =
153  projected_vector.head(2).norm() * projected_vector_project_dir_angle_cos;
154  return project_dir * projected_vector_norm_on_project_dir;
155 }
156 
157 // @brief convert point xyz in Cartesian coordinate to polar coordinate
158 // old name: xyz_to_polar_coordinate
159 template <typename PointT>
160 void ConvertCartesiantoPolarCoordinate(const PointT &xyz,
161  typename PointT::Type *h_angle_in_degree,
162  typename PointT::Type *v_angle_in_degree,
163  typename PointT::Type *dist) {
164  using T = typename PointT::Type;
165  const T radian_to_degree = 180.0 / M_PI;
166  const T x = xyz.x;
167  const T y = xyz.y;
168  const T z = xyz.z;
169 
170  (*dist) = static_cast<T>(sqrt(x * x + y * y + z * z));
171  T dist_xy = static_cast<T>(sqrt(x * x + y * y));
172 
173  (*h_angle_in_degree) = std::acos(x / dist_xy) * radian_to_degree;
174  if (y < 0.0) {
175  (*h_angle_in_degree) = static_cast<T>(360.0) - (*h_angle_in_degree);
176  }
177 
178  (*v_angle_in_degree) = std::acos(dist_xy / (*dist)) * radian_to_degree;
179  if (z < 0.0) {
180  (*v_angle_in_degree) = -(*v_angle_in_degree);
181  }
182 }
183 
184 } // namespace common
185 } // namespace perception
186 } // namespace apollo
Eigen::Matrix< T, 3, 3 > CalculateRotationMat2DXY(const Eigen::Matrix< T, 3, 1 > &v1, const Eigen::Matrix< T, 3, 1 > &v2)
Definition: basic.h:114
T CalculateTheta2DXY(const Eigen::Matrix< T, 3, 1 > &v1, const Eigen::Matrix< T, 3, 1 > &v2)
Definition: basic.h:92
Eigen::Matrix< T, 3, 1 > Calculate2DXYProjectVector(const Eigen::Matrix< T, 3, 1 > &projected_vector, const Eigen::Matrix< T, 3, 1 > &project_vector)
Definition: basic.h:135
PlanningContext is the runtime context in planning. It is persistent across multiple frames...
Definition: atomic_hash_map.h:25
Type CrossProduct(const Eigen::Matrix< Type, 2, 1 > &point1, const Eigen::Matrix< Type, 2, 1 > &point2, const Eigen::Matrix< Type, 2, 1 > &point3)
Definition: basic.h:33
void ConvertCartesiantoPolarCoordinate(const PointT &xyz, typename PointT::Type *h_angle_in_degree, typename PointT::Type *v_angle_in_degree, typename PointT::Type *dist)
Definition: basic.h:160
T CalculateCosTheta2DXY(const Eigen::Matrix< T, 3, 1 > &v1, const Eigen::Matrix< T, 3, 1 > &v2)
Definition: basic.h:77
PointT::Type CalculateEuclidenDist2DXY(const PointT &pt1, const PointT &pt2)
Definition: basic.h:66
PointT::Type CalculateEuclidenDist(const PointT &pt1, const PointT &pt2)
Definition: basic.h:55