Carma-platform v4.2.0
CARMA Platform is built on robot operating system (ROS) and utilizes open source software (OSS) that enables Cooperative Driving Automation (CDA) features to allow Automated Driving Systems to interact and cooperate with infrastructure and other vehicles through communication.
Geometry.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2022 LEIDOS.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License. You may obtain a copy of
6 * 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, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations under
14 * the License.
15 */
16
17#include <carma_wm/Geometry.hpp>
18#include <lanelet2_core/geometry/Point.h>
19#include <tf2/LinearMath/Transform.h>
20#include <tf2_geometry_msgs/tf2_geometry_msgs.h>
21#include <tf2/transform_datatypes.h>
22
23namespace carma_wm
24{
25namespace geometry
26{
27
28constexpr double SPATIAL_EPSILON_M = 0.05;
29
30// This safeAcos implementation is based on Stack Overflow answer: https://stackoverflow.com/questions/8489792/is-it-legal-to-take-acos-of-1-0f-or-1-0f
31// Asked by SirYakalot: https://stackoverflow.com/users/956689/siryakalot
32// Answered by TonyK: https://stackoverflow.com/users/428857/tonyk
33// Credited in accordance with Stack Overflow's CC-BY license
34double safeAcos (double x)
35{
36 if (x < -1.0) x = -1.0 ;
37 else if (x > 1.0) x = 1.0 ;
38 return std::acos(x) ;
39}
40
41// This safeAcos implementation is based on Stack Overflow answer: https://stackoverflow.com/questions/8489792/is-it-legal-to-take-acos-of-1-0f-or-1-0f
42// Asked by SirYakalot: https://stackoverflow.com/users/956689/siryakalot
43// Answered by TonyK: https://stackoverflow.com/users/428857/tonyk
44// Credited in accordance with Stack Overflow's CC-BY license
45double safeAsin (double x)
46{
47 if (x < -1.0) x = -1.0 ;
48 else if (x > 1.0) x = 1.0 ;
49 return std::asin(x) ;
50}
51
52void rpyFromQuaternion(const tf2::Quaternion& q, double& roll, double& pitch, double& yaw)
53{
54 tf2::Matrix3x3 mat(q);
55 mat.getRPY(roll, pitch, yaw);
56}
57
58void rpyFromQuaternion(const geometry_msgs::msg::Quaternion& q_msg, double& roll, double& pitch, double& yaw)
59{
60 tf2::Quaternion quat;
61 tf2::convert(q_msg, quat);
62 rpyFromQuaternion(quat, roll, pitch, yaw);
63}
64
65double getAngleBetweenVectors(const Eigen::Vector2d& vec1, const Eigen::Vector2d& vec2)
66{
67 double vec1Mag = vec1.norm();
68 double vec2Mag = vec2.norm();
69 if (vec1Mag == 0.0 || vec2Mag == 0.0)
70 {
71 return 0;
72 }
73 return safeAcos(vec1.dot(vec2) / (vec1Mag * vec2Mag));
74}
75
76TrackPos trackPos(const lanelet::BasicPoint2d& p, const lanelet::BasicPoint2d& seg_start,
77 const lanelet::BasicPoint2d& seg_end)
78{
79 Eigen::Vector2d vec_to_p(p);
80 Eigen::Vector2d vec_to_start(seg_start);
81 Eigen::Vector2d vec_to_end(seg_end);
82
83 // Get vector from start to external point
84 Eigen::Vector2d start_to_p = vec_to_p - vec_to_start;
85
86 // Get vector from start to end point
87 Eigen::Vector2d start_to_end = vec_to_end - vec_to_start;
88
89 // Get angle between both vectors
90 double interior_angle = getAngleBetweenVectors(start_to_p, start_to_end);
91
92 // Calculate downtrack distance
93 double start_to_p_mag = start_to_p.norm();
94 double downtrack_dist = start_to_p_mag * std::cos(interior_angle);
95
111 double d = (start_to_p[0] * start_to_end[1]) - (start_to_p[1] * start_to_end[0]);
112 double sign = d >= 0 ? 1.0 : -1.0; // If d is positive then the point is to the right if it is negative the point is
113 // to the left
114
115 double crosstrack = start_to_p_mag * std::sin(interior_angle) * sign;
116
117 return TrackPos(downtrack_dist, crosstrack);
118}
119
120TrackPos trackPos(const lanelet::ConstLanelet& lanelet, const lanelet::BasicPoint2d& point)
121{
122 auto center_line = lanelet::utils::to2D(lanelet.centerline());
123
124 if (center_line.numSegments() < 1)
125 {
126 throw std::invalid_argument("Provided lanelet has invalid centerline containing no points");
127 }
128 auto tuple = matchSegment(point, center_line.basicLineString());
129
130 return std::get<0>(tuple);
131}
132
156bool selectFirstSegment(const TrackPos& first_seg_trackPos, const TrackPos& second_seg_trackPos,
157 double first_seg_length, double second_seg_length)
158{
159 const bool first_seg_in_downtrack =
160 (0 <= first_seg_trackPos.downtrack && first_seg_trackPos.downtrack < first_seg_length);
161 const bool second_seg_in_downtrack =
162 (0 <= second_seg_trackPos.downtrack && second_seg_trackPos.downtrack < second_seg_length);
163
164 if (first_seg_in_downtrack && !second_seg_in_downtrack)
165 { // If in the first segment but not the last segment
166
167 return true; // First segment is better
168 }
169 else if (second_seg_in_downtrack && !first_seg_in_downtrack)
170 {
171 return false; // Second segment is better
172 }
173 else if (first_seg_in_downtrack && second_seg_in_downtrack)
174 {
175 return first_seg_trackPos.crosstrack <=
176 second_seg_trackPos.crosstrack; // Pick the first segment if the crosstrack values are equal or the first
177 // segment is closer
178 }
179 else
180 { // Point lies outside the downtrack bounds of both segments (Remember According to function contract the nearest
181 // point to external point is the midpoint of the two segments)
182 return true; // Choose first segment as it will always have positive downtrack in this case while the second
183 // segment will always have negative downtrack
184 }
185}
186
187std::tuple<TrackPos, lanelet::BasicSegment2d> matchSegment(const lanelet::BasicPoint2d& p,
188 const lanelet::BasicLineString2d& line_string)
189{
190 if (line_string.size() < 2)
191 {
192 throw std::invalid_argument("Provided with linestring containing fewer than 2 points");
193 }
194
195 lanelet::BasicSegment2d best_segment =
196 std::make_pair(line_string[0], line_string[1]); // Default to starting segment if no match is found
197 auto point_2d = lanelet::utils::to2D(p);
198
199 double min_distance = lanelet::geometry::distance2d(point_2d, line_string[0]);
200 size_t best_point_index = 0;
201 double best_accumulated_length = 0;
202 double best_last_accumulated_length = 0;
203 double best_seg_length = 0;
204 double best_last_seg_length = 0;
205 double last_seg_length = 0;
206
207 double accumulated_length = 0;
208 double last_accumulated_length = 0;
209 for (size_t i = 0; i < line_string.size(); i++)
210 { // Iterate over line string to find nearest point
211 double seg_length = 0;
212 if (i < line_string.size() - 1)
213 {
214 seg_length = lanelet::geometry::distance2d(line_string[i], line_string[i + 1]); // Compute segment length
215 }
216
217 double distance = lanelet::geometry::distance2d(p, line_string[i]); // Compute from current point to external point
218 if (distance < min_distance)
219 { // If this distance is below minimum discovered so far then update minimum
220 min_distance = distance;
221 best_point_index = i;
222 best_accumulated_length = accumulated_length;
223 best_last_accumulated_length = last_accumulated_length; // Record accumulated lengths to each segment
224 best_seg_length = seg_length;
225 best_last_seg_length = last_seg_length;
226 }
227
228 last_accumulated_length = accumulated_length; // Update accumulated lenths
229 accumulated_length += seg_length;
230 last_seg_length = seg_length;
231 }
232
233 // Minimum point has been found next step is to determine which segment it should go with using the following rules.
234 // If the minimum point is the first point then use the first segment
235 // If the minimum point is the last point then use the last segment
236 // If the minimum point is within the downtrack bounds of one segment but not the other then use the one it is within
237 // If the minimum point is within the downtrack bounds of both segments then use the one with the smallest crosstrack
238 // distance If the minimum point is within the downtrack bounds of both segments and has exactly equal crosstrack
239 // bounds with each segment then use the first one
240 TrackPos best_pos(0, 0);
241 if (best_point_index == 0)
242 {
243 best_pos = trackPos(p, line_string[0], line_string[1]);
244 best_segment = std::make_pair(line_string[0], line_string[1]);
245 }
246 else if (best_point_index == line_string.size() - 1)
247 {
248 best_pos = trackPos(p, line_string[line_string.size() - 2], line_string[line_string.size() - 1]);
249 best_pos.downtrack += best_last_accumulated_length;
250 best_segment = std::make_pair(line_string[line_string.size() - 2], line_string[line_string.size() - 1]);
251 }
252 else
253 {
254 TrackPos first_seg_trackPos = trackPos(p, line_string[best_point_index - 1], line_string[best_point_index]);
255 TrackPos second_seg_trackPos = trackPos(p, line_string[best_point_index], line_string[best_point_index + 1]);
256 if (selectFirstSegment(first_seg_trackPos, second_seg_trackPos, best_last_seg_length, best_seg_length))
257 {
258 best_pos = first_seg_trackPos;
259 best_pos.downtrack += best_last_accumulated_length;
260 best_segment = std::make_pair(line_string[best_point_index - 1], line_string[best_point_index]);
261 }
262 else
263 {
264 best_pos = second_seg_trackPos;
265 best_pos.downtrack += best_accumulated_length;
266 best_segment = std::make_pair(line_string[best_point_index], line_string[best_point_index + 1]);
267 }
268 }
269
270 // couldn't find a matching segment, so use the first segment within the downtrack range of.
271 // Or the starting segment assuming we are before the route
272 return std::make_tuple(best_pos, best_segment);
273}
274
275// NOTE: See Geometry.h header file for details on source of logic in this function
276double computeCurvature(const lanelet::BasicPoint2d& p1, const lanelet::BasicPoint2d& p2,
277 const lanelet::BasicPoint2d& p3)
278{
279 auto dp = 0.5 * (p3 - p1);
280 auto ddp = p3 - 2.0 * p2 + p1;
281 auto denom = std::pow(dp.x() * dp.x() + dp.y() * dp.y(), 3.0 / 2.0);
282 if (std::fabs(denom) < 1e-20)
283 {
284 denom = 1e-20;
285 }
286 return static_cast<double>((ddp.y() * dp.x() - dp.y() * ddp.x()) / denom);
287}
288
289lanelet::BasicPolygon2d objectToMapPolygon(const geometry_msgs::msg::Pose& pose, const geometry_msgs::msg::Vector3& size)
290{
291 tf2::Transform object_tf;
292 tf2::fromMsg(pose, object_tf);
293
294 double half_x_bound = size.x / 2;
295 double half_y_bound = size.y / 2;
296
297 // 4 corners of the object starting with upper left and moving in clockwise direction in pose frame
298 tf2::Vector3 obj_p1(half_x_bound, half_y_bound, 0);
299 tf2::Vector3 obj_p2(half_x_bound, -half_y_bound, 0);
300 tf2::Vector3 obj_p3(-half_x_bound, -half_y_bound, 0);
301 tf2::Vector3 obj_p4(-half_x_bound, half_y_bound, 0);
302
303 tf2::Vector3 obj_p1_map = object_tf * obj_p1;
304 tf2::Vector3 obj_p2_map = object_tf * obj_p2;
305 tf2::Vector3 obj_p3_map = object_tf * obj_p3;
306 tf2::Vector3 obj_p4_map = object_tf * obj_p4;
307
308 lanelet::BasicPoint2d p1(obj_p1_map.getX(), obj_p1_map.getY());
309 lanelet::BasicPoint2d p2(obj_p2_map.getX(), obj_p2_map.getY());
310 lanelet::BasicPoint2d p3(obj_p3_map.getX(), obj_p3_map.getY());
311 lanelet::BasicPoint2d p4(obj_p4_map.getX(), obj_p4_map.getY());
312
313 return { p1, p2, p3, p4 };
314}
315
316lanelet::BasicLineString2d concatenate_lanelets(const std::vector<lanelet::ConstLanelet>& lanelets)
317{
318 if (lanelets.empty()) {
319 return lanelet::BasicLineString2d();
320 }
321 lanelet::BasicLineString2d centerline_points = lanelets[0].centerline2d().basicLineString();
322 lanelet::BasicLineString2d new_points;
323 for (size_t i = 1; i < lanelets.size(); i++) {
324 new_points = lanelets[i].centerline2d().basicLineString();
325 centerline_points = concatenate_line_strings(centerline_points, new_points);
326 }
327
328 return centerline_points;
329}
330
331template <class P, class A>
332std::vector<double>
333templated_local_curvatures(const std::vector<P, A>& centerline_points)
334{
335
336 if (centerline_points.empty()) {
337 throw std::invalid_argument("No points in centerline for curvature calculation");
338 }
339
340 std::vector<Eigen::Vector2d> spatial_derivative = compute_finite_differences(centerline_points);
341 std::vector<Eigen::Vector2d> normalized_tangent_vectors = normalize_vectors(spatial_derivative);
342
343 std::vector<double> arc_lengths = compute_arc_lengths(centerline_points);
344
345 std::vector<Eigen::Vector2d> tangent_derivative =
347 normalized_tangent_vectors,
348 arc_lengths);
349
350 std::vector<double> curvature = compute_magnitude_of_vectors(tangent_derivative);
351
352 return curvature;
353}
354
355std::vector<double>
356local_curvatures(const lanelet::BasicLineString2d& centerline_points)
357{
358 return templated_local_curvatures(centerline_points);
359}
360
361std::vector<double>
362local_curvatures(const std::vector<lanelet::BasicPoint2d>& centerline_points)
363{
364 return templated_local_curvatures(centerline_points);
365}
366
367std::vector<double>
368local_curvatures(const std::vector<lanelet::ConstLanelet>& lanelets) {
369 return local_curvatures(concatenate_lanelets(lanelets));
370}
371
372lanelet::BasicLineString2d
373concatenate_line_strings(const lanelet::BasicLineString2d& a,
374 const lanelet::BasicLineString2d& b)
375{
376 lanelet::BasicLineString2d out;
377
378 int start_offset = 0;
379 if (!a.empty() && !b.empty() && compute_euclidean_distance(a.back(), b.front()) < SPATIAL_EPSILON_M) {
380 start_offset = 1;
381 }
382
383 out.insert(out.end(), a.begin(), a.end());
384 out.insert(out.end(), b.begin() + start_offset, b.end());
385
386 return out;
387}
388
389template <class P, class A>
390std::vector<Eigen::Vector2d>
392{
393 std::vector<Eigen::Vector2d> out;
394 Eigen::Vector2d diff;
395 Eigen::Vector2d vec_i_plus_1;
396 Eigen::Vector2d vec_i_minus_1;
397
398 for (size_t i = 0; i < data.size(); i++) {
399 if (i == 0) {
400 // Compute forward derivative
401 diff = (data[i + 1] - data[i]);
402 } else if (i == data.size() - 1) {
403 // Compute backward derivative
404 diff = (data[i] - data[i - 1]);
405 } else {
406 // Else, compute centered derivative
407 vec_i_plus_1 = data[i + 1];
408 vec_i_minus_1 = data[i - 1];
409 diff = (vec_i_plus_1 - vec_i_minus_1)/2.0;
410 }
411
412 out.push_back(diff);
413 }
414
415 return out;
416}
417
418std::vector<Eigen::Vector2d>
419compute_finite_differences(const lanelet::BasicLineString2d& data)
420{
422}
423
424std::vector<Eigen::Vector2d> compute_finite_differences(const std::vector<lanelet::BasicPoint2d>& data) {
426}
427
428std::vector<double>
429compute_finite_differences(const std::vector<double>& data)
430{
431 std::vector<double> out;
432 double diff;
433 for (size_t i = 0; i < data.size(); i++) {
434
435 if (i == 0) {
436 diff = data[i + 1] - data[i];
437 } else if (i == data.size() - 1) {
438 diff = data[i] - data[i - 1];
439 } else {
440 diff = (data[i + 1] - data[i - 1])/2.0;
441 }
442
443 out.push_back(diff);
444 }
445
446 return out;
447}
448
449std::vector<Eigen::Vector2d>
450compute_finite_differences(const std::vector<Eigen::Vector2d>& x,const std::vector<double>& y)
451{
452 if (x.size() != y.size()) {
453 throw std::invalid_argument("Attempting to differentiate two unequal sized lists!");
454 }
455
456 std::vector<Eigen::Vector2d> out;
457 Eigen::Vector2d diff;
458 for (size_t i = 0; i < x.size(); i++) {
459 if (i == 0) {
460 diff = (x[i + 1] - x[i])/(y[i + 1] - y[i]);
461 } else if (i == x.size() - 1) {
462 diff = (x[i] - x[i - 1])/(y[i] - y[i - 1]);
463 } else {
464 diff = (x[i + 1] - x[i - 1])/(y[i + 1] - y[i - 1]);
465 }
466
467 out.push_back(diff);
468 }
469
470 return out;
471}
472
473template <class P, class A>
474std::vector<double>
475compute_templated_arc_lengths(const std::vector<P, A>& data) {
476 std::vector<double> out;
477 double total = 0;
478 double diff = 0;
479 for (size_t i = 0; i < data.size(); i++) {
480 if (i == 0) {
481 out.push_back(0);
482 } else {
483 diff = compute_euclidean_distance(data[i - 1], data[i]);
484 total += diff;
485 out.push_back(total);
486 }
487 }
488
489 return out;
490}
491
492std::vector<double>
493compute_arc_lengths(const lanelet::BasicLineString2d& data) {
495}
496
497std::vector<double>
498compute_arc_lengths(const std::vector<lanelet::BasicPoint2d>& data)
499{
501}
502
503double
504compute_euclidean_distance(const Eigen::Vector2d& a, const Eigen::Vector2d& b)
505{
506 return std::sqrt(std::pow(b[0] - a[0], 2) + std::pow(b[1] - a[1], 2));
507}
508
509std::vector<Eigen::Vector2d>
510normalize_vectors(const std::vector<Eigen::Vector2d>& vectors)
511{
512 std::vector<Eigen::Vector2d> out;
513 for (auto vec : vectors) {
514 out.push_back(vec.normalized());
515 }
516 return out;
517}
518
519std::vector<double>
520compute_magnitude_of_vectors(const std::vector<Eigen::Vector2d>& vectors)
521{
522 std::vector<double> out;
523 for (auto vec : vectors) {
524 out.push_back(vec.norm());
525 }
526
527 return out;
528}
529
530template<class P, class A>
531std::vector<double>
532compute_templated_tangent_orientations(const std::vector<P,A>& centerline)
533{
534 std::vector<double> out;
535 if (centerline.empty())
536 return out;
537
538 std::vector<Eigen::Vector2d> tangents = carma_wm::geometry::compute_templated_finite_differences(centerline);
539
540 for (auto tangent : tangents)
541 {
542 geometry_msgs::msg::Quaternion q;
543
544 // Derive angle by cos theta = (u . v)/(||u| * ||v||)
545 double yaw = 0;
546 double norm = tangent.norm();
547 if (norm != 0.0) {
548 auto normalized_tanged = tangent / norm;
549 yaw = atan2(normalized_tanged[1], normalized_tanged[0]);
550 }
551
552 out.push_back(yaw);
553 }
554
555 return out;
556}
557
558std::vector<double>
559compute_tangent_orientations(const lanelet::BasicLineString2d& centerline)
560{
562}
563
564std::vector<double>
565compute_tangent_orientations(const std::vector<lanelet::BasicPoint2d>& centerline)
566{
568}
569
570Eigen::Isometry2d build2dEigenTransform(const Eigen::Vector2d& position, const Eigen::Rotation2Dd& rotation) {
571 Eigen::Vector2d scale(1.0, 1.0);
572 Eigen::Isometry2d tf;
573 return tf.fromPositionOrientationScale(position, rotation, scale);
574}
575
576Eigen::Isometry3d build3dEigenTransform(const Eigen::Vector3d& position, const Eigen::Quaterniond& rotation) {
577 Eigen::Vector3d scale(1.0, 1.0, 1.0);
578 Eigen::Isometry3d tf;
579 return tf.fromPositionOrientationScale(position, rotation, scale);
580}
581
582Eigen::Isometry3d build3dEigenTransform(const Eigen::Vector3d& position, const Eigen::AngleAxisd& rotation) {
583 Eigen::Vector3d scale(1.0, 1.0, 1.0);
584 Eigen::Isometry3d tf;
585 return tf.fromPositionOrientationScale(position, rotation, scale);
586}
587
588double point_to_point_yaw(const lanelet::BasicPoint2d& cur_point, const lanelet::BasicPoint2d& next_point)
589{
590 double dx = next_point[0] - cur_point[0];
591 double dy = next_point[1] - cur_point[1];
592 double yaw = atan2(dy, dx);
593 return yaw;
594}
595
596double circular_arc_curvature(const lanelet::BasicPoint2d& cur_point, const lanelet::BasicPoint2d& next_point)
597{
598 double dist = sqrt(pow(cur_point[0] - next_point[0], 2) + pow(cur_point[1] - next_point[1], 2));
599
600 double angle = point_to_point_yaw(cur_point, next_point);
601
602 double r = 0.5 * (dist / std::sin(angle));
603
604 double max_curvature = 100000;
605 double curvature = std::min(1 / r, max_curvature);
606
607 return curvature;
608}
609
610std::vector<double> local_circular_arc_curvatures(const std::vector<lanelet::BasicPoint2d>& points, int lookahead) {
611 std::vector<double> curvatures;
612 curvatures.reserve(points.size());
613
614 if (lookahead <= 0) {
615 throw std::invalid_argument("local_circular_arc_curvatures lookahead must be greater than 0");
616 }
617
618 if (points.empty()) {
619 return curvatures;
620 }
621 else if (points.size() == 1) {
622 curvatures.push_back(0.0);
623 return curvatures;
624 }
625
626 for (size_t i = 0; i < points.size() - 1; i++)
627 {
628 size_t next_point_index = i + lookahead;
629 if (next_point_index >= points.size()) {
630 next_point_index = points.size() - 1;
631 }
632 double cur = circular_arc_curvature(points[i], points[next_point_index]);
633 curvatures.push_back(fabs(cur));
634 }
635 curvatures.push_back(curvatures.back());
636 return curvatures;
637}
638
639
640} // namespace geometry
641
642} // namespace carma_wm
Position in a track based coordinate system where the axis are downtrack and crosstrack....
Definition: TrackPos.hpp:35
Eigen::Isometry3d build3dEigenTransform(const Eigen::Vector3d &position, const Eigen::Quaterniond &rotation)
Builds a 3D Eigen coordinate frame transform with not applied scaling (only translation and rotation)...
Definition: Geometry.cpp:576
std::vector< double > compute_templated_tangent_orientations(const std::vector< P, A > &centerline)
Definition: Geometry.cpp:532
lanelet::BasicPolygon2d objectToMapPolygon(const geometry_msgs::msg::Pose &pose, const geometry_msgs::msg::Vector3 &size)
Uses the provided pose and size vector of an ExternalObject to compute what the polygon would be of t...
Definition: Geometry.cpp:289
std::vector< double > local_curvatures(const lanelet::BasicLineString2d &centerline_points)
Returns a list of local (computed by discrete derivative) curvatures for the input centerlines....
Definition: Geometry.cpp:356
constexpr double SPATIAL_EPSILON_M
Definition: Geometry.cpp:28
void rpyFromQuaternion(const tf2::Quaternion &q, double &roll, double &pitch, double &yaw)
Extract extrinsic roll-pitch-yaw from quaternion.
Definition: Geometry.cpp:52
std::vector< double > compute_templated_arc_lengths(const std::vector< P, A > &data)
Definition: Geometry.cpp:475
double safeAcos(double x)
acos method that caps the input x value for 1 or -1 to avoid undefined output. This is meant to preve...
Definition: Geometry.cpp:34
std::vector< Eigen::Vector2d > normalize_vectors(const std::vector< Eigen::Vector2d > &vectors)
Normalize the vectors in the input list such that their magnitudes = 1.
Definition: Geometry.cpp:510
double point_to_point_yaw(const lanelet::BasicPoint2d &cur_point, const lanelet::BasicPoint2d &next_point)
Computes the 2d orientation of the vector from the provided start point to end point.
Definition: Geometry.cpp:588
double circular_arc_curvature(const lanelet::BasicPoint2d &cur_point, const lanelet::BasicPoint2d &next_point)
Computes the curvature of a circular arc that passes through the two provided points....
Definition: Geometry.cpp:596
double compute_euclidean_distance(const Eigen::Vector2d &a, const Eigen::Vector2d &b)
Compute the Euclidean distance between the two points.
Definition: Geometry.cpp:504
Eigen::Isometry2d build2dEigenTransform(const Eigen::Vector2d &position, const Eigen::Rotation2Dd &rotation)
Builds a 2D Eigen coordinate frame transform with not applied scaling (only translation and rotation)...
Definition: Geometry.cpp:570
std::tuple< TrackPos, lanelet::BasicSegment2d > matchSegment(const lanelet::BasicPoint2d &p, const lanelet::BasicLineString2d &line_string)
Get the TrackPos of the provided point along the linestring and the segment of the line string which ...
Definition: Geometry.cpp:187
double safeAsin(double x)
asin method that caps the input x value for 1 or -1 to avoid undefined output. This is meant to preve...
Definition: Geometry.cpp:45
double getAngleBetweenVectors(const Eigen::Vector2d &vec1, const Eigen::Vector2d &vec2)
Calculates the angle between two vectors.
Definition: Geometry.cpp:65
std::vector< double > compute_tangent_orientations(const lanelet::BasicLineString2d &centerline)
Compute an approximate orientation for the vehicle at each point along the provided centerline.
Definition: Geometry.cpp:559
lanelet::BasicLineString2d concatenate_lanelets(const std::vector< lanelet::ConstLanelet > &lanelets)
Helper function to a list of lanelets together and return the result. Neither LineString is modified ...
Definition: Geometry.cpp:316
std::vector< double > templated_local_curvatures(const std::vector< P, A > &centerline_points)
Definition: Geometry.cpp:333
std::vector< double > compute_arc_lengths(const std::vector< lanelet::BasicPoint2d > &data)
Compute the arc length at each point around the curve.
Definition: Geometry.cpp:498
bool selectFirstSegment(const TrackPos &first_seg_trackPos, const TrackPos &second_seg_trackPos, double first_seg_length, double second_seg_length)
Helper function to identify whether to select the preceeding or succeeding segment of a linstring poi...
Definition: Geometry.cpp:156
lanelet::BasicLineString2d concatenate_line_strings(const lanelet::BasicLineString2d &l1, const lanelet::BasicLineString2d &l2)
Helper function to concatenate 2 linestrings together and return the result. Neither LineString is mo...
Definition: Geometry.cpp:373
std::vector< Eigen::Vector2d > compute_templated_finite_differences(const std::vector< P, A > &data)
Definition: Geometry.cpp:391
double computeCurvature(const lanelet::BasicPoint2d &p1, const lanelet::BasicPoint2d &p2, const lanelet::BasicPoint2d &p3)
Function for computing curvature from 3 points.
Definition: Geometry.cpp:276
TrackPos trackPos(const lanelet::ConstLanelet &lanelet, const lanelet::BasicPoint2d &point)
Returns the TrackPos, computed in 2d, of the provided point relative to the centerline of the provide...
Definition: Geometry.cpp:120
std::vector< double > local_circular_arc_curvatures(const std::vector< lanelet::BasicPoint2d > &points, int lookahead)
Computes the curvature of each point in the provided list by calling circular_arc_curvature using tha...
Definition: Geometry.cpp:610
std::vector< Eigen::Vector2d > compute_finite_differences(const lanelet::BasicLineString2d &data)
Use finite differences methods to compute the derivative of the input data set with respect to index ...
Definition: Geometry.cpp:419
std::vector< double > compute_magnitude_of_vectors(const std::vector< Eigen::Vector2d > &vectors)
Compute the magnitude of each vector in the input list.
Definition: Geometry.cpp:520
void convert(const carma_v2x_msgs::msg::PSM &in_msg, carma_perception_msgs::msg::ExternalObject &out_msg, const std::string &map_frame_id, double pred_period, double pred_step_size, const lanelet::projection::LocalFrameProjector &map_projector, const tf2::Quaternion &ned_in_map_rotation, rclcpp::node_interfaces::NodeClockInterface::SharedPtr node_clock)