1#include <vanetza/facilities/path_history.hpp>
2#include <vanetza/units/angle.hpp>
3#include <vanetza/units/length.hpp>
4#include <boost/units/cmath.hpp>
10const units::Length cAllowableError = 0.47 * units::si::meter;
11const units::Length cChordLengthThreshold = 22.5 * units::si::meters;
12const units::Length cDistance = 200.0 * units::si::meters;
13const units::Length cMaxEstimatedRadius = cREarthMeridian;
14const units::Angle cSmallDeltaPhi = units::Angle(1.0 * units::degree);
16PathHistory::PathHistory() :
21const PathPoint& PathHistory::starting()
const
23 assert(!m_concise.empty());
24 return m_concise.front();
27const PathPoint& PathHistory::previous()
const
29 assert(m_samples.size() > 1);
33const PathPoint& PathHistory::next()
const
35 assert(!m_samples.empty());
36 return m_samples.front();
41 m_samples.push_front(point);
42 if (m_concise.empty()) {
43 m_concise.push_front(m_samples.front());
46 updateConcisePoints();
47 truncateConcisePoints();
50const PathPoint& PathHistory::getReferencePoint()
const
54 if (m_samples.empty()) {
55 return scDefaultPathPoint;
57 return m_samples.front();
61void PathHistory::updateConcisePoints()
63 if (m_samples.full()) {
64 const auto actual_chord_length = chord_length(starting(), next());
65 units::Length actual_error;
66 if (actual_chord_length > cChordLengthThreshold) {
67 actual_error = cAllowableError + 1.0 * units::si::meter;
69 const units::Angle delta_phi = next().heading - starting().heading;
70 units::Length estimated_radius;
71 if (abs(delta_phi) < cSmallDeltaPhi) {
72 actual_error = 0.0 * units::si::meter;
73 estimated_radius = cMaxEstimatedRadius;
75 estimated_radius = actual_chord_length / (2 * sin(delta_phi * 0.5));
76 const units::Length d = estimated_radius * cos(0.5 * delta_phi);
77 actual_error = estimated_radius - d;
81 if (actual_error > cAllowableError) {
82 m_concise.push_front(previous());
87void PathHistory::truncateConcisePoints()
89 units::Length distance = 0.0 * units::si::meter;
90 if (m_concise.size() > 2) {
91 auto previous = m_concise.begin();
92 auto current = ++m_concise.begin();
93 for (; current != m_concise.end(); ++previous, ++current) {
94 distance += chord_length(*previous, *current);
95 if (distance >= cDistance) {
96 m_concise.erase(++current, m_concise.end());