Vanetza
 
Loading...
Searching...
No Matches
path_history.cpp
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>
5#include <cassert>
6
7namespace vanetza {
8namespace facilities {
9
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);
15
16PathHistory::PathHistory() :
17 m_samples(3)
18{
19}
20
21const PathPoint& PathHistory::starting() const
22{
23 assert(!m_concise.empty());
24 return m_concise.front();
25}
26
27const PathPoint& PathHistory::previous() const
28{
29 assert(m_samples.size() > 1);
30 return m_samples[1];
31}
32
33const PathPoint& PathHistory::next() const
34{
35 assert(!m_samples.empty());
36 return m_samples.front();
37}
38
39void PathHistory::addSample(const PathPoint& point)
40{
41 m_samples.push_front(point);
42 if (m_concise.empty()) {
43 m_concise.push_front(m_samples.front());
44 }
45
46 updateConcisePoints();
47 truncateConcisePoints();
48}
49
50const PathPoint& PathHistory::getReferencePoint() const
51{
52 static const PathPoint scDefaultPathPoint = PathPoint();
53
54 if (m_samples.empty()) {
55 return scDefaultPathPoint;
56 } else {
57 return m_samples.front();
58 }
59}
60
61void PathHistory::updateConcisePoints()
62{
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;
68 } else {
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;
74 } else {
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;
78 }
79 }
80
81 if (actual_error > cAllowableError) {
82 m_concise.push_front(previous());
83 }
84 }
85}
86
87void PathHistory::truncateConcisePoints()
88{
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());
97 break;
98 }
99 }
100 }
101}
102
103} // namespace facilities
104} // namespace vanetza