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 cTraceAllowableError = 0.47 * units::si::meter;
11const units::Length cTraceMaxDeltaDistance = 22.5 * units::si::meter;
12const units::Angle cTraceDeltaPhi = units::Angle(1.0 * units::degree);
13
14PathHistory::PathHistory() : PathHistory(Parameters{})
15{
16}
17
18PathHistory::PathHistory(const Parameters& params) :
19 m_params(params), m_samples(3)
20{
21}
22
23const PathPoint& PathHistory::starting() const
24{
25 assert(!m_concise.empty());
26 return m_concise.front();
27}
28
29const PathPoint& PathHistory::previous() const
30{
31 assert(m_samples.size() > 1);
32 return m_samples[1];
33}
34
35const PathPoint& PathHistory::next() const
36{
37 assert(!m_samples.empty());
38 return m_samples.front();
39}
40
41void PathHistory::addSample(const PathPoint& point)
42{
43 m_samples.push_front(point);
44 if (m_concise.empty()) {
45 m_concise.push_front(m_samples.front());
46 }
47
48 updateConcisePoints();
49 truncateConcisePoints();
50}
51
53{
54 m_samples.clear();
55 m_concise.clear();
56}
57
59{
60 static const PathPoint scDefaultPathPoint = PathPoint();
61
62 if (m_samples.empty()) {
63 return scDefaultPathPoint;
64 } else {
65 return m_samples.front();
66 }
67}
68
69void PathHistory::updateConcisePoints()
70{
71 if (m_samples.full()) {
72 const auto actual_chord_length = chord_length(starting(), next());
73 units::Length actual_error;
74 if (actual_chord_length > m_params.chord_length_threshold) {
75 actual_error = m_params.allowable_error + 1.0 * units::si::meter;
76 } else {
77 const units::Angle delta_phi = next().heading - starting().heading;
78 if (abs(delta_phi) < m_params.small_delta_phi) {
79 actual_error = 0.0 * units::si::meter;
80 } else {
81 const units::Length estimated_radius = actual_chord_length / (2 * sin(delta_phi * 0.5));
82 const units::Length d = estimated_radius * cos(0.5 * delta_phi);
83 actual_error = estimated_radius - d;
84 }
85 }
86
87 if (actual_error > m_params.allowable_error) {
88 m_concise.push_front(previous());
89 }
90 }
91}
92
93void PathHistory::truncateConcisePoints()
94{
95 units::Length distance = 0.0 * units::si::meter;
96 if (m_concise.size() > 2) {
97 auto previous = m_concise.begin();
98 auto current = ++m_concise.begin();
99 for (; current != m_concise.end(); ++previous, ++current) {
100 distance += chord_length(*previous, *current);
101 if (distance >= m_params.retention_distance) {
102 m_concise.erase(++current, m_concise.end());
103 break;
104 }
105 }
106 }
107}
108
110PathHistory::getConcisePointsMinLength(units::Length distance) const
111{
112 return getConcisePointsMinLength(distance, m_concise.size());
113}
114
116PathHistory::getConcisePointsMinLength(units::Length distance, std::size_t max_points) const
117{
118 units::Length covered = 0.0 * units::si::meter;
119 std::size_t count = 0;
120 const PathPoint* previous = nullptr;
121 auto cut = m_concise.begin();
122 for (; cut != m_concise.end() && count < max_points; ++cut, ++count) {
123 if (previous != nullptr) {
124 covered += chord_length(*previous, *cut);
125 }
126 previous = &*cut;
127 if (covered >= distance) {
128 ++cut; // include the point reaching the distance
129 break;
130 }
131 }
132 return { m_concise.begin(), cut };
133}
134
136PathHistory::getConcisePointsMaxLength(units::Length distance) const
137{
138 return getConcisePointsMaxLength(distance, m_concise.size());
139}
140
142PathHistory::getConcisePointsMaxLength(units::Length distance, std::size_t max_points) const
143{
144 units::Length covered = 0.0 * units::si::meter;
145 std::size_t count = 0;
146 const PathPoint* previous = nullptr;
147 auto cut = m_concise.begin();
148 for (; cut != m_concise.end() && count < max_points; ++cut, ++count) {
149 if (previous != nullptr) {
150 covered += chord_length(*previous, *cut);
151 if (covered > distance) {
152 break; // exclude the point beyond the distance
153 }
154 }
155 previous = &*cut;
156 }
157 return { m_concise.begin(), cut };
158}
159
160} // namespace facilities
161} // namespace vanetza
void addSample(const PathPoint &)
const PathPoint & getReferencePoint() const
boost::iterator_range< std::list< PathPoint >::const_iterator > getConcisePointsMinLength(units::Length distance, std::size_t max_points) const
As above but capped at max_points.
boost::iterator_range< std::list< PathPoint >::const_iterator > getConcisePointsMaxLength(units::Length distance, std::size_t max_points) const
As above but capped at max_points.
boost::iterator_range< std::list< PathPoint >::const_iterator > getConcisePointsMinLength(units::Length distance) const
boost::iterator_range< std::list< PathPoint >::const_iterator > getConcisePointsMaxLength(units::Length distance) const