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 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);
19 m_params(params), m_samples(3)
25 assert(!m_concise.empty());
26 return m_concise.front();
31 assert(m_samples.size() > 1);
37 assert(!m_samples.empty());
38 return m_samples.front();
43 m_samples.push_front(point);
44 if (m_concise.empty()) {
45 m_concise.push_front(m_samples.front());
48 updateConcisePoints();
49 truncateConcisePoints();
62 if (m_samples.empty()) {
63 return scDefaultPathPoint;
65 return m_samples.front();
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;
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;
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;
87 if (actual_error > m_params.allowable_error) {
88 m_concise.push_front(previous());
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());
112 return getConcisePointsMinLength(distance, m_concise.size());
118 units::Length covered = 0.0 * units::si::meter;
119 std::size_t count = 0;
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);
127 if (covered >= distance) {
132 return { m_concise.begin(), cut };
138 return getConcisePointsMaxLength(distance, m_concise.size());
144 units::Length covered = 0.0 * units::si::meter;
145 std::size_t count = 0;
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) {
157 return { m_concise.begin(), cut };
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