Fixed filter

This commit is contained in:
Constantin Shalnev 2015-12-17 16:00:57 +03:00
parent 2fca519d21
commit 48722e99ff
2 changed files with 42 additions and 13 deletions

View file

@ -10,11 +10,18 @@ namespace
char const kMinHorizontalAccuracyKey[] = "GpsTrackingMinAccuracy";
// Minimal horizontal accuracy is required to skip 'bad' points.
// Use 250 meters to allow points from a pure GPS + GPS through wifi.
double constexpr kMinHorizontalAccuracyMeters = 250;
// Required for points decimation to reduce number of close points.
double constexpr kClosePointDistanceMeters = 15;
inline bool IsRealGpsPoint(location::GpsInfo const & info)
{
// we guess real gps says speed and bearing other than zero
return info.m_speed > 0 && info.m_bearing > 0;
}
} // namespace
void GpsTrackNullFilter::Process(vector<location::GpsInfo> const & inPoints,
@ -38,21 +45,28 @@ GpsTrackFilter::GpsTrackFilter()
void GpsTrackFilter::Process(vector<location::GpsInfo> const & inPoints,
vector<location::GpsTrackInfo> & outPoints)
{
steady_clock::time_point const timeNow = steady_clock::now();
outPoints.reserve(inPoints.size());
for (location::GpsInfo const & currInfo : inPoints)
{
if (!m_hasLastInfo)
{
// Accept first point
m_hasLastInfo = true;
m_lastInfo = currInfo;
m_lastGoodGpsTime = timeNow;
outPoints.emplace_back(currInfo);
continue;
}
// Filter points which happens earlier than first point
if (currInfo.m_timestamp <= m_lastInfo.m_timestamp)
continue;
bool const lastRealGps = IsRealGpsPoint(m_lastInfo);
bool const currRealGps = IsRealGpsPoint(currInfo);
bool const gpsToWifi = lastRealGps && !currRealGps;
bool const wifiToWifi = !lastRealGps && !currRealGps;
bool const wifiToGps = !lastRealGps && currRealGps;
// Distance in meters between last and current point is, meters:
double const distance = ms::DistanceOnEarth(m_lastInfo.m_latitude, m_lastInfo.m_longitude,
@ -62,6 +76,15 @@ void GpsTrackFilter::Process(vector<location::GpsInfo> const & inPoints,
if (distance < kClosePointDistanceMeters)
continue;
// If gps appears after wifi then accept gps point
if (wifiToGps)
{
m_lastGoodGpsTime = timeNow;
m_lastInfo = currInfo;
outPoints.emplace_back(currInfo);
continue;
}
// Filter point if accuracy areas are intersected
if (distance < m_lastInfo.m_horizontalAccuracy && distance < currInfo.m_horizontalAccuracy)
continue;
@ -70,18 +93,21 @@ void GpsTrackFilter::Process(vector<location::GpsInfo> const & inPoints,
if (currInfo.m_horizontalAccuracy > m_minAccuracy)
continue;
// Time elapsed since last info is, sec:
double const elapsedTime = currInfo.m_timestamp - m_lastInfo.m_speed;
// Prevent jumping between wifi points
// We use following heuristics: if suddenly point jumps over long
// distance in short time then we skip point
if (m_lastInfo.m_speed == 0 && currInfo.m_speed == 0)
if (gpsToWifi || wifiToWifi)
{
if (distance > 25 && elapsedTime < 10)
continue; // we guess it is jump between wifi points
auto const elapsedTimeSinceGoodGps = duration_cast<seconds>(timeNow - m_lastGoodGpsTime);
// Wait before switch gps to wifi or switch between wifi points
if (elapsedTimeSinceGoodGps.count() < 30 /* seconds */)
continue;
// For wifi we expect pedestrian walker with average speed 5 km/h or 1.4 m/s.
double const speed = distance / elapsedTimeSinceGoodGps.count();
if (speed > 3 /* m/s */)
continue; // we guess it is jump to another gps
}
m_lastGoodGpsTime = timeNow;
m_lastInfo = currInfo;
outPoints.emplace_back(currInfo);
}

View file

@ -4,6 +4,7 @@
#include "geometry/latlon.hpp"
#include "std/chrono.hpp"
#include "std/vector.hpp"
class IGpsTrackFilter
@ -37,7 +38,9 @@ public:
private:
double m_minAccuracy;
location::GpsInfo m_lastInfo;
bool m_hasLastInfo;
location::GpsInfo m_lastInfo;
steady_clock::time_point m_lastGoodGpsTime;
};