bmwcarit / barefoot

Java map matching library for integrating the map into software and services with state-of-the-art online and offline map matching that can be used stand-alone and in the cloud.
Apache License 2.0
671 stars 183 forks source link

Real-time matching imprecise #36

Closed sergyv closed 7 years ago

sergyv commented 7 years ago

Hello,

We are trying to use online mapmatching, but unfortunately we see a lot of problems. If you look at the attached picture on the right you will see raw positions - driver went back and forth on the main road, but on the matched picture on the left there is a lot of strange movements. May be we are missing some settings? Have you seen such a behavior? Basically what happens if the speed slows down matcher starts making "loops" using nearby small roads. Hope you can clear this mystery for us.

Thanks!

bf_problem

smattheis commented 7 years ago

I've indeed seen this behavior in the past. Without a detailed check of your data I guess that the loops are caused by position measurements that are (if we consider movement only along the road) behind an already matched position which, in turn, is very likely due to measurement errors of GPS. It's as if the object moves a very little bit backwards on the road. The problem is that the matcher then thinks that the object IS moving back and tries to find a reasonable route, which is a u-turn or some loop. (Note that (1) most bigger roads in OSM are modelled as one-ways and (2) the matcher never does a u-turn on the road, but only at the end of a road.) To avoid this behavior, try setting the matcher.distance.min in the config/tracker.properties to some value greater than zero, e.g. 5. This will cause the tracker to skip matching position measurements that are below 5 meters apart from any previous matched position and, hence, avoids in most cases the appearance of backwards movements and, consequently, the loops and u-turns, see https://github.com/bmwcarit/barefoot/wiki#parameters . This, however, decreases the position sampling rate in scenarios of slow movement. The alternative is to do data cleaning yourself if you have more knowledge to correct (and filter) backwards movements. I hope this helps! If not, let me know and providing the trace would give me the opportunity to check for bugs.

sergyv commented 7 years ago

Hi Sebastian, thanks for the quick reply. Indeed we were thinking about increasing this parameter, but thought would consult you first. The problem is that we dont really have backward movements in the data I believe. Im attaching geojson of this route for you to have a look. Thanks a lot! data.txt

smattheis commented 7 years ago

Do you use something like Android SDK to record the trace? What is your current tracker configuration? What's the use case you need the map matched information? Of course, online map matching and considering only the most recent position is less accurate than offline map matching and/or considering the full path, but your deviations are quite significant.

sergyv commented 7 years ago

Its a hardware device, sends position every 12-15 seconds. We are using it to display busses in the transportation network. And currently with the trace I showed you when you watch it realtime it doesnt look good at all. So of course for later reviews we will postprocess it, but for real-time inspection it would be nice to get it fixed.

smattheis commented 7 years ago

I just wanted reconstruct the issue and saw that in your data, you use for each position measurement a new ID. If this id is sent to the matcher, it actually thinks that each position measurement is a new object, because the semantics for the matcher/tracker is to use the id for identifying the object. (Usually the tracker is able to the tracking for multiple objects that are identified with this id.) This would then explain a confuse map matching. Can you check that you do that right in your application? If this is not the problem, I will continue reconstructing the problem.

PaulChipault commented 7 years ago

Hi,

@smattheis First I'd like to thank you for this amazing piece of software. To help with what @sergyv explained I'd like to give a few more details.

We are not using the standalone barefoot server, we are using the barefoot java library to have scalable online map matching. (We are using the mapwithstate feature of Apache Spark to keep track of our assets K-States and share it across cluster nodes).

Here is how we instantiate the sample :

val sample: MatcherSample = new MatcherSample(<uuid>, <timestamp>, <position measure>)

Is the id attribute of the MatcherSample class the id you are referring to ?

In the meantime, I'll make some more online matching simulation with an increased min distance value. (10 meters).

smattheis commented 7 years ago

Exactly, I just checked the Javadoc for potential misunderstanding and found a bug in the Javadoc: The description of the id for MatcherSample is wrong, i.e., it should be an identifier of the object that produces the sample.

That you're using the library programmatically makes things a little bit more clear and we can check it on a different level. If you maintain an instance of the Matcher and issue the execute method on your own, and make sure that you use the same MatcherKState instance (you must issue the update method manually and also note that the MatcherKState is not thread-safe by default) for samples of the same object, then everything should be fine. The question is then, which information of the state do you use as the result (showed in the screenshot).

To help you out, I suggest that you try out the stand-alone tracker with your data and see if it produces weird results too. If yes, just send me the input for the tracker and I can see if a parameter tuning helps. If not, and the tracker produces better results, there is very likely a bug in your implementation which I could check back, if you provide the respective code snippet.

PaulChipault commented 7 years ago

Thanks a lot for this feedback.

We do use MatcherKState, and we use the MatcherKState to json method to share the k-state across the cluster nodes. The MatcherKState instance is recreated from the json representation for each position measure.

The information we use as a result is the transition of the candidate.

Another interesting thing : at the end of the asset's trip we use the MatcherKState.toGeoJSON() , and the outputted route is perfectly matched.

Like you said, I'll make some more tests with the standalone tracker first before I start bothering you with my messy code :)

smattheis commented 7 years ago

Okay. Note that in real-time map matching, i.e., you want some result after processing of each sample (iteratively), you should use the estimate's transition: MatcherKState.estimate().transition(). The estimate is also what the tracker uses and forwards (with some additional stuff) to the monitor.

PaulChipault commented 7 years ago

Yup that's how we do it.

val snappedPoint: Point = newState.estimate().point().geometry() val transition = newState.estimate().transition()

I'll let you know how the test goes.

PaulChipault commented 7 years ago

Hi,

Sorry to get back to you so late, I got burried under assignments for University. So I made some test with the barefoot Tracker Server and I got the same result.

I made a short video of the route running on the TrackerServer when it occurs. There goes the link

I've also attached a file containing the route data , in case you might need it. Let me know if you need anymore details. broken_route_barefoot.txt

smattheis commented 7 years ago

Fixed in commit https://github.com/bmwcarit/barefoot/commit/952e63f620fa1dba82eb33865be4b130c86e3334 and released in https://github.com/bmwcarit/barefoot/releases/tag/0.1.1 and tested with trace and map of Ile-de-France provided with comment https://github.com/bmwcarit/barefoot/issues/36#issuecomment-275733572 The bug seems to be fixed for that case and originated from an errorneous emission probability. It was related to issue #27 .

ZhiWeiCui commented 4 years ago

@PaulChipault I'm using spark to deploy this service, I'm having some troubles, I want to know the details of

We are not using the standalone barefoot server, we are using the barefoot java library to have scalable online map matching. (We are using the mapwithstate feature of Apache Spark to keep track of our assets K-States and share it across cluster nodes).

Looking forward to your reply.