NASA Astrobee Robot Software  0.19.1
Flight software for the Astrobee robots operating inside the International Space Station.
linear_algebra.h
Go to the documentation of this file.
1 /* Copyright (c) 2017, United States Government, as represented by the
2  * Administrator of the National Aeronautics and Space Administration.
3  *
4  * All rights reserved.
5  *
6  * The Astrobee platform is licensed under the Apache License, Version 2.0
7  * (the "License"); you may not use this file except in compliance with the
8  * License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15  * License for the specific language governing permissions and limitations
16  * under the License.
17  */
18 
19 #ifndef MAPPER_LINEAR_ALGEBRA_H_
20 #define MAPPER_LINEAR_ALGEBRA_H_
21 
23 #include <vector>
24 #include <string>
26 
27 namespace algebra_3d {
28 
29 // Line parameterized as l = p0 + t.vec, t belongs to (-inf,inf)
30 // This class is used in point compression algorithms
31 class Line3d{
32  public:
35 
36  // Constructor: returns line that goes through two points p1, p2
37  Line3d(const Eigen::Vector3d &p1, const Eigen::Vector3d &p2) {
38  p0_ = p1;
39  vec_ = p1 - p2;
40  }
41 
42  // Methods
43  // Calculate the distance between one point and the line
44  void DistancePoint2Line(const Eigen::Vector3d &point, double *dist) {
45  // Two points on the line
46  const Eigen::Vector3d x1 = p0_;
47  const Eigen::Vector3d x2 = p0_ + vec_;
48 
49  // Optimal t is the t at which the point is closest to the line
50  // t_opt = (x1-x2)'*(x1-p)/norm(x1-x2)^2;
51  static double t_opt;
52  if (x1 == x2) {
53  t_opt = 0;
54  } else {
55  const double gain = 1.0 / (pow((x1 - x2).norm(), 2.0));
56  t_opt = gain*(x1 - x2).transpose()*(x1 - point);
57  }
58 
59  // p_opt is the closest point between the point and the line
60  const Eigen::Vector3d p_opt = x1 + t_opt * vec_;
61  *dist = (point - p_opt).norm();
62  }
63 };
64 
65 class Plane3d{
66  public:
69 
70  // Constructor: plane given by an origin and a normal
71  Plane3d(const Eigen::Vector3d &origin,
72  const Eigen::Vector3d &normal) {
73  origin_ = origin;
74  normal_ = normal;
75  if (normal_.norm() == 0) {
76  std::cout << "Warning: plane ill-defined: "
77  << "zero-norm normal vector!"
78  << std::endl;
79  }
80  }
81  // Plane given by three points.
82  // Normal is in the direction of (p2 - p1) x (p3 - p1)
84  const Eigen::Vector3d &p2,
85  const Eigen::Vector3d &p3) {
86  const Eigen::Vector3d v1 = p2 - p1;
87  const Eigen::Vector3d v2 = p3 - p1;
88  // const Eigen::Vector3d v3 = (p1 + p2 + p3)/3.0;
89  if ((v1.norm() == 0) || (v2.norm() == 0) || ((p2-p3).norm() == 0)) {
90  std::cout << "Warning: plane ill-defined: "
91  << "three distinct points are needed!"
92  << std::endl;
93  origin_ = p1;
94  normal_ << 0.0, 0.0, 0.0;
95  } else {
96  origin_ = p1;
97  normal_ = v1.cross(v2).normalized();
98  }
99  }
100 
101  Plane3d() {}
102 
103  void transformPlane(const Eigen::Affine3d &transform,
104  Plane3d *transformedPlane) {
105  transformedPlane->origin_ = transform*origin_;
106  transformedPlane->normal_ = (transform.linear()*normal_).normalized();
107  }
108 };
109 
111  public:
117 
118  FrustumPlanes(const double fov,
119  const double aspectRatio) {
120  double znear = 1.0;
121  double hh = tan(fov/2.0);
122  double hw = -hh*aspectRatio;
123  double normalize = 1.0/Eigen::Vector3d(hw, hh, znear).norm();
124  UL_ = normalize*Eigen::Vector3d(-hw, hh, znear);
125  UR_ = normalize*Eigen::Vector3d(hw, hh, znear);
126  DL_ = normalize*Eigen::Vector3d(-hw, -hh, znear);
127  DR_ = normalize*Eigen::Vector3d(hw, -hh, znear);
128  origin_ = Eigen::Vector3d(0.0, 0.0, 0.0);
133  }
134 
135  FrustumPlanes(const double fx,
136  const double fy,
137  const double cx,
138  const double cy,
139  const uint32_t width,
140  const uint32_t height) {
141  double znear = 1.0;
142  double x0 = 0.0, y0 = 0.0;
143  double xf = static_cast<float>(width) - 1;
144  double yf = static_cast<float>(height) - 1;
145  double XL = -znear*(x0-cx)/fx; // X left
146  double XR = -znear*(xf-cx)/fx; // X right
147  double YU = -znear*(y0-cy)/fy; // Y up
148  double YD = -znear*(yf-cy)/fy; // Y down
149  UL_ = Eigen::Vector3d(XL, YU, znear).normalized();
150  UR_ = Eigen::Vector3d(XR, YU, znear).normalized();
151  DL_ = Eigen::Vector3d(XL, YD, znear).normalized();
152  DR_ = Eigen::Vector3d(XR, YD, znear).normalized();
153  origin_ = Eigen::Vector3d(0.0, 0.0, 0.0);
158  }
159 
161 
162  void TransformFrustum(const Eigen::Affine3d &transform,
163  FrustumPlanes *transformed_frustum) {
164  left_plane_.transformPlane(transform, &transformed_frustum->left_plane_);
165  right_plane_.transformPlane(transform, &transformed_frustum->right_plane_);
166  up_plane_.transformPlane(transform, &transformed_frustum->up_plane_);
167  down_plane_.transformPlane(transform, &transformed_frustum->down_plane_);
168  transformed_frustum->origin_ = transform*origin_;
169  transformed_frustum->UL_ = transform*UL_;
170  transformed_frustum->UR_ = transform*UR_;
171  transformed_frustum->DL_ = transform*DL_;
172  transformed_frustum->DR_ = transform*DR_;
173  }
174 
175  bool IsPointWithinFrustum(const Eigen::Vector3d &pt) const {
176  if ((pt - left_plane_.origin_).dot(left_plane_.normal_) < 0)
177  return false;
178  else if ((pt - right_plane_.origin_).dot(right_plane_.normal_) < 0)
179  return false;
180  else if ((pt - up_plane_.origin_).dot(up_plane_.normal_) < 0)
181  return false;
182  else if ((pt - down_plane_.origin_).dot(down_plane_.normal_) < 0)
183  return false;
184  else
185  return true;
186  }
187 
188  // Return visualization markers frustum visualization
189  void VisualizeFrustum(const std::string &frame_id,
190  visualization_msgs::Marker *line_list) {
191  // Initialize array
192  line_list->header.frame_id = frame_id;
193  line_list->header.stamp = ros::Time::now();
194  line_list->ns = "fustrum/" + frame_id;
195  line_list->action = visualization_msgs::Marker::ADD;
196  line_list->pose.orientation.w = 1.0;
197  line_list->type = visualization_msgs::Marker::LINE_LIST;
198  line_list->id = 0;
199  line_list->scale.x = 0.01; // Line width
200  line_list->color = visualization_functions::Color::Red();
201  line_list->lifetime = ros::Duration(1); // Disappears in 1 second
202 
203  std::vector<Eigen::Vector3d> points;
204  points.push_back(origin_);
205  points.push_back(UL_);
206  points.push_back(UR_);
207  points.push_back(DL_);
208  points.push_back(DR_);
209 
210  geometry_msgs::Point node1, node2;
211  for (uint i = 0; i < points.size(); i++) {
212  for (uint j = 0; j < points.size(); j++) {
213  if (i == j)
214  continue;
215  node1 = msg_conversions::eigen_to_ros_point(points[i]);
216  node2 = msg_conversions::eigen_to_ros_point(points[j]);
217  line_list->points.push_back(node1);
218  line_list->points.push_back(node2);
219  }
220  }
221  }
222 };
223 
224 } // namespace algebra_3d
225 
226 #endif // MAPPER_LINEAR_ALGEBRA_H_
visualization_functions.h
visualization_functions::Color::Red
static const Color Red()
Definition: visualization_functions.h:52
algebra_3d::Line3d::p0_
Eigen::Vector3d p0_
Definition: linear_algebra.h:33
algebra_3d::Line3d::Line3d
Line3d(const Eigen::Vector3d &p1, const Eigen::Vector3d &p2)
Definition: linear_algebra.h:37
algebra_3d::FrustumPlanes
Definition: linear_algebra.h:110
algebra_3d::FrustumPlanes::UL_
Eigen::Vector3d UL_
Definition: linear_algebra.h:116
algebra_3d::FrustumPlanes::UR_
Eigen::Vector3d UR_
Definition: linear_algebra.h:116
algebra_3d::Plane3d::Plane3d
Plane3d(const Eigen::Vector3d &origin, const Eigen::Vector3d &normal)
Definition: linear_algebra.h:71
algebra_3d::FrustumPlanes::DR_
Eigen::Vector3d DR_
Definition: linear_algebra.h:116
algebra_3d::FrustumPlanes::IsPointWithinFrustum
bool IsPointWithinFrustum(const Eigen::Vector3d &pt) const
Definition: linear_algebra.h:175
point_cloud_common::Vector3d
Eigen::Vector3d Vector3d(const PointType &point)
Definition: utilities.h:328
algebra_3d::FrustumPlanes::VisualizeFrustum
void VisualizeFrustum(const std::string &frame_id, visualization_msgs::Marker *line_list)
Definition: linear_algebra.h:189
algebra_3d::FrustumPlanes::FrustumPlanes
FrustumPlanes(const double fx, const double fy, const double cx, const double cy, const uint32_t width, const uint32_t height)
Definition: linear_algebra.h:135
algebra_3d
Definition: linear_algebra.h:27
algebra_3d::Plane3d::origin_
Eigen::Vector3d origin_
Definition: linear_algebra.h:67
algebra_3d::FrustumPlanes::down_plane_
Plane3d down_plane_
Definition: linear_algebra.h:115
algebra_3d::Plane3d
Definition: linear_algebra.h:65
algebra_3d::Line3d
Definition: linear_algebra.h:31
algebra_3d::FrustumPlanes::FrustumPlanes
FrustumPlanes()
Definition: linear_algebra.h:160
algebra_3d::FrustumPlanes::origin_
Eigen::Vector3d origin_
Definition: linear_algebra.h:116
algebra_3d::FrustumPlanes::up_plane_
Plane3d up_plane_
Definition: linear_algebra.h:114
algebra_3d::FrustumPlanes::right_plane_
Plane3d right_plane_
Definition: linear_algebra.h:113
algebra_3d::Line3d::vec_
Eigen::Vector3d vec_
Definition: linear_algebra.h:34
optimization_common::Affine3d
Eigen::Affine3d Affine3d(const Eigen::Matrix< double, 7, 1 > &affine_vector)
Definition: utilities.cc:43
algebra_3d::Plane3d::Plane3d
Plane3d()
Definition: linear_algebra.h:101
algebra_3d::Plane3d::Plane3d
Plane3d(const Eigen::Vector3d &p1, const Eigen::Vector3d &p2, const Eigen::Vector3d &p3)
Definition: linear_algebra.h:83
algebra_3d::Plane3d::normal_
Eigen::Vector3d normal_
Definition: linear_algebra.h:68
algebra_3d::FrustumPlanes::DL_
Eigen::Vector3d DL_
Definition: linear_algebra.h:116
msg_conversions.h
algebra_3d::Line3d::DistancePoint2Line
void DistancePoint2Line(const Eigen::Vector3d &point, double *dist)
Definition: linear_algebra.h:44
algebra_3d::FrustumPlanes::FrustumPlanes
FrustumPlanes(const double fov, const double aspectRatio)
Definition: linear_algebra.h:118
algebra_3d::FrustumPlanes::left_plane_
Plane3d left_plane_
Definition: linear_algebra.h:112
algebra_3d::Plane3d::transformPlane
void transformPlane(const Eigen::Affine3d &transform, Plane3d *transformedPlane)
Definition: linear_algebra.h:103
msg_conversions::eigen_to_ros_point
geometry_msgs::Point eigen_to_ros_point(const Eigen::Vector3d &v)
Definition: msg_conversions.cc:37
algebra_3d::FrustumPlanes::TransformFrustum
void TransformFrustum(const Eigen::Affine3d &transform, FrustumPlanes *transformed_frustum)
Definition: linear_algebra.h:162