Files
comaps/map/extrapolation/extrapolator.hpp
Konstantin Pastbin e3e4a1985a Organic Maps sources as of 02.04.2025 (fad26bbf22ac3da75e01e62aa01e5c8e11861005)
To expand with full Organic Maps and Maps.ME commits history run:
  git remote add om-historic [om-historic.git repo url]
  git fetch --tags om-historic
  git replace squashed-history historic-commits
2025-05-08 21:10:51 +07:00

82 lines
3.8 KiB
C++

#pragma once
#include "platform/location.hpp"
#include <cstdint>
#include <functional>
#include <limits>
#include <mutex>
namespace extrapolation
{
/// \brief Returns extrapolated position after |point2| in |timeAfterPoint2Ms|.
/// \note |timeAfterPoint2Ms| should be reasonably small (several seconds maximum).
location::GpsInfo LinearExtrapolation(location::GpsInfo const & gpsInfo1,
location::GpsInfo const & gpsInfo2,
uint64_t timeAfterPoint2Ms);
/// \returns true if linear extrapolation based on |info1| and |info2| should be done.
/// \param info1 location information about point gotten before last one.
/// \param info2 the latest location information.
bool AreCoordsGoodForExtrapolation(location::GpsInfo const & info1,
location::GpsInfo const & info2);
/// \brief This class implements linear extrapolation based on methods LinearExtrapolation()
/// and AreCoordsGoodForExtrapolation(). The idea implemented in this class is
/// - OnLocationUpdate() should be called from gui thread when new data from gps is available.
/// - When OnLocationUpdate() was called twice so that AreCoordsGoodForExtrapolation()
/// returns true, extrapolation for this two location will be launched.
/// - That means all obsolete extrapolation calls in background thread will be canceled by
/// incrementing |m_locationUpdateMinValid|.
/// - Several new extrapolations based on two previous locations will be generated.
class Extrapolator
{
static uint64_t constexpr kExtrapolationCounterUndefined = std::numeric_limits<uint64_t>::max();
public:
using ExtrapolatedLocationUpdateFn = std::function<void(location::GpsInfo const &)>;
// |kMaxExtrapolationTimeMs| is time in milliseconds showing how long location will be
// extrapolated after last location gotten from GPS.
static uint64_t constexpr kMaxExtrapolationTimeMs = 2000;
// |kExtrapolationPeriodMs| is time in milliseconds showing how often location will be
// extrapolated. So if the last location was obtained from GPS at time X the next location
// will be emulated by Extrapolator at time X + kExtrapolationPeriodMs.
// Then X + 2 * kExtrapolationPeriodMs and so on till
// X + n * kExtrapolationPeriodMs <= kMaxExtrapolationTimeMs.
static uint64_t constexpr kExtrapolationPeriodMs = 200;
/// \param update is a function which is called with params according to extrapolated position.
/// |update| will be called on gui thread.
explicit Extrapolator(ExtrapolatedLocationUpdateFn const & update);
void OnLocationUpdate(location::GpsInfo const & gpsInfo);
// @TODO(bykoianko) Gyroscope information should be taken into account as well for calculation
// extrapolated position.
void Enable(bool enabled);
private:
/// \returns true if there's enough information for extrapolation and extrapolation is enabled.
/// \note This method should be called only when |m_mutex| is locked.
bool DoesExtrapolationWork() const;
void ExtrapolatedLocationUpdate(uint64_t locationUpdateCounter);
void RunTaskOnBackgroundThread(bool delayed);
bool m_isEnabled;
std::mutex m_mutex;
ExtrapolatedLocationUpdateFn m_extrapolatedLocationUpdate;
location::GpsInfo m_lastGpsInfo;
location::GpsInfo m_beforeLastGpsInfo;
uint64_t m_consecutiveRuns = kExtrapolationCounterUndefined;
// Number of calls Extrapolator::OnLocationUpdate() method. This way |m_locationUpdateCounter|
// reflects generation of extrapolations. That mean the next gps location is
// the next generation.
uint64_t m_locationUpdateCounter = 0;
// If |m_locationUpdateCounter| < |m_locationUpdateMinValid| when
// ExtrapolatedLocationUpdate() is called (on background thread)
// ExtrapolatedLocationUpdate() cancels its execution.
uint64_t m_locationUpdateMinValid = 0;
};
} // namespace extrapolation