Plan a route somewhere, and in the Location panel set "Position Tracking" to "Current Route". You now have a GPS simulation where the position is reported along the planned route. Note how the position is exactly on the planned route. In this task you change the simulation to behave more like a real GPS device would report the position: Add noise to the position such that the reported position is a bit off the route.
The noise should stay roughly in the bounds of what RouteSimulationPositionProviderPlugin::accuracy() reports. Currently it reports result.horizontal = 10.0; i.e. an expected deviation of 10 meter to the real position.
- Introduce a new member variable `GeoDataCoordinates m_currentPositionWithNoise`
- Change RouteSimulationPositionProviderPlugin::position() to `return m_currentPositionWithNoise;`
- When `RouteSimulationPositionProviderPlugin::update()` calls `m_currentPosition = newPosition;` add a line that sets `m_currentPositionWithNoise` based on newPosition. Introduce a new method `GeoDataCoordinates addNoise(const GeoDataCoordinates &position) const`
- See below how to implement that method
How to generate noise:
- use the passed position as base, but walk away from it in a random direction for a random distance: `return currentPosition.moveByBearing(randomBearing, randomDistance);`
- use random numbers for randomBearing and randomDistance. Limit their range to sane values (randomBearing: 0.. 2 * M_PI, randomDistance: 0..`accuracy().horizontal / m_marbleModel->planetRadius()`)
- use qrand to generate random numbers, see https://doc.qt.io/qt-5/qtglobal.html#qrand
Make sure to understand how GeoDataCoordinates::moveByBearing works. In particular, it takes a position and returns a new one. The first parameter is the bearing (direction) in radians, and the second is the distance to walk away from the position. Note that the distance has no unit! It is not meters or kilometers, but the calculation works on a unit sphere. You have to relate it to the radius of the planet (earth) to be able to pass a value in meters. E.g. to walk a distance of 25 meters, pass distance = `25.0 / m_marbleModel->planetRadius()`;
Test your implementation and submit a review request using Differential here in phabricator.kde.org