Open aerostitch opened 14 years ago
I think maneuver should also be announced if another road of the same or better grade require to turn at similar or smaller angle in the junction. i.e. abs(angle[route]) + 15degrees > abs(angle[alternative]).
I was traveling on 108 from SE and needed to continue on 108 to SW. Turn in this junction was not announced. Ok, I knew the route, road signs show that "main road" makes a turn. But, if traveling in unknown place, it's easy to become confused or miss a turn if not glimpsing at the map periodically.
Another one is here: http://www.openstreetmap.org/?lat=54.3455&lon=24.6964&zoom=13&layers=M
No turn is announced when following A4 from east to west; however, the route graph shows the correct route (turning slightly left to stay on A4, rather than proceeding straight onto 128). I've seen similar behavior in many places, not just Lithuania ;-)
It seems that Navit does not produce turn instructions when the same road is followed, even if this road turns right or left and another one branches off, going straight (or to the other side). "Same road" apparently gets decided based on highway=*, ref and/or name.
When roads split, it is not immediately apparent to the driver which of the two roads ahead is the continuation of the road he is currently on. Directions like "go straight", "turn left", "keep right" are more intuitive. Also, I would expect most drivers to intuitively go straight unless they are getting different instructions.
Suggestion: At each junction, analyze the geometry of the roads. When the road to be followed deviates from the "straight" direction and there's another road that's going more "straight", generate a turn instruction.
Consider also #921, which discusses the contrary case for motorways: the motorway turns slightly while an off-ramp goes straight; here turn instructions are not needed as it's usually obvious where the continuation of the road is.
Can any cardriver please tell, if this is still an issue?
Yes, it is still an issue, and I just ran into it again.
Does anybody have a pointer to the part of the code where Navit decides whether or not to announce a maneuver? Then I might be able to get my build environment up and running again and experiment with a few rules.
I have a first solution approach for motorways: Assume each point on the route has an "entry" and one or more potential "exits". The route approaches the point over the entry and leaves it through one of the exit.
Then rules for announcing a maneuver are:
- When there is only one exit, make no announcement. (This one is so obvious that it might be forgotten in code.)
- When the entry is a motorway and the exit on the route is a ramp, make an announcement.
- When the entry is a motorway and more than one exit is a motorway, make an announcement.
Trunk roads are a bit more difficult. Some have motorway-like characteristics while others are just major urban or country roads.
Motorway-like trunk roads have the
oneway=yes
tag, hence we can apply the above rules tohighway=trunk;oneway=yes
just likehighway=motorway
.Not every trunk road with this tag is motorway-like, so we need an extra rule to sort out such cases:
- When the entry is a one-way trunk road and at least one exit is neither a motorway, trunk road or ramp, use the old logic, i.e. decide whether or not to announce a maneuver based on the same criteria as before.
I expect that this will solve quite a few issues, including those that I encountered over the course of the past week (mostly motorway junctions). The bad news is that the two cases in Lithuania which Monas and I encountered before were on single-carriageway roads. (Monas's example has since been converted to a roundabout, so we'll need to find another test case here.)
We might be able to catch these with the following extra rules:
- When the exit is a ramp, make an annonucement.
- When two or more exits have the same rank as the entry (i.e. trunk, primary, secondary) and the route takes a turn, make an announcement. Specifically, do not suppress announcements based on the road number alone.
For the purposes of this rule, we will consider a route to take a turn based on the bearings of entry and route exit. When the exit with the bearing closest to the entry is not on the route, or when the bearings of entry and route exit differ by more than a certain threshold (some 22.5°), we consider this a turn in the route.
The last rule may need some extra tweaking: it will not catch my case (entry is trunk, exit is either slightly left onto the trunk road or straight onto a primary road). One possibility would be to change the "same rank as entry" criterion to "same rank as or one rank lower than entry".
I've found something in /trunk/navit/navit/navigation.c,
maneuver_required2(struct navigation *, struct navigation_itm *, struct navigation_itm *, int *, char **)
, which seems to hold the code we need to touch. I'm currently cloning the repo, and if I get it to build, I'll prepare a patch and submit it here.
Navit builds, I'll try to get a patch ready over the next few days
Looking at it again, I see that my earlier example (near Naujieji Valkininkai, Lithuania) is a particularly mean one. It is a single-carriageway trunk road that turns left, and a primary going off it. However, the links between the primary and the trunk road are mapped as ramps. In OSM they are
primary_ramp
roads, but Navit uses a single ramp type and thus cannot tell if it is atrunk_ramp
or aprimary_ramp
.I could modify the logic to generate turn instructions when the entry and exit is a single-carriageway trunk road, which would give us an instruction here. However, it might generate superfluous instructions on certain single-carriageway trunk roads with no level crossings. (These are single-carriageway roads but have ramps like motorways, and if one of the ramps is in a left turn, we'd get a "turn left" to stay on the road.) I'll try to find a few test cases where we don't want a turn instruction and then try implementing the ruleset I described above.
Just noticed that I still have an old map file where Monas's example is still a T junction rather than a roundabout. He was going from Maišiagala to Vievis and the left turn near Airėnai I/II to stay on 108 was not announced. However, 5899 does announce a left turn here. On the other hand, the turn before, in Dūkštos (turn right to stay on 108) is not announced. The only difference I can see is that the turn in Dūkstos has a bearing change of about 60° while the one in Airėnai is close to 90°. In any case this should get caught by the rules I proposed.
I've found two stretches of single-carriageway trunk roads with no level crossings: in Switzerland, the Rongellen–San Bernardino and Lostallo–Bellinzona stretches of the A13. With 5899 routing is OK: exits are announced, going past an exit is not.
I've implemented and tested the above rules. Results:
- Maišiagala–Vievis: OK – announcements in Dūkštos and Airėnai.
- Naujieji Valkininkai–Senoji Varėna: NOK – still no announcement after Naujieji Valkininkai.
- Rongellen–San Bernardino: OK – no announcements when going past an exit
- San Bernardino–Rongellen: OK – no announcements when going past an exit
- Lostallo–Arbedo-Castione: OK – no announcements when going past an exit
- Bellinzona–Lostallo: OK – no announcements when going past an exit
Still need to do some work work on Senoji Varėna without breaking San Bernardino.
Looking at aerial imagery of Naujieji Valkininkai, the road markings at the junction make it pretty clear that the trunk road goes left while the road that continues straight is a smaller road. We might even be able to live with cases like that one – I'll make a patch of what I have now and submit it.
trac660.patch
(3.8 KiB)Patch above.
If somebody would like to try the patch, a prebuilt Android package is available at: http://mvglasow.github.io/navit/Navit.5899-trac660.apk
A binary for Linux (x86) is available at: http://mvglasow.github.io/navit/linux_x86/navit.5899-trac660
-*Edit: These versions are outdated and have been removed. See later comment for current versions.**
I also have compiled a test version for win32 and wince platforms, you may download it from http://www.navit-project.org/~tryagain/navit_win32_5899_trac660.exe and http://www.navit-project.org/~tryagain/navit_wince_5899_trac660.exe
Currently testing the patched version.
The patch just adds announcements and doesn't suppress any, hence watch out for superfluous announcements.
- I got one strange maneuver, which I still need to sort out by replaying a GPX trace against both a patched and a vanilla build and comparing differences.
- There are some cases which will not get caught. Most notably, these are motorway interchanges where one of the two possible ways after the maneuver is a motorway and the other is a ramp (and the maneuver is to follow the motorway). This is indistinguishable from a regular exit, thus going on the ramp will create a maneuver, staying on the motorway will not. (Same goes for oneway trunk roads.)
- Occasionally I will get told to "turn left" when it should be "keep right" and vice versa. This is a separate issue (#694, #795) and not addressed by this patch.
- Apart from that I did not notice any superfluous maneuvers.
The strange maneuver was a "turn left" just prior to entering a roundabout which is part of a ramp. Without cross-checking against a vanilla build, I suspect it has to do with the rule to always generate a maneuver for ramps. I'll move the "no maneuver to enter roundabout" rule higher up and see what happens.
Rearranging the rules to evaluate roundabouts first did the trick and eleminated the strange maneuver I'd observed before. Updated test versions:
Another test today brought about two more odd maneuvers:
- Turning left from a dual-carriageway primary road onto a motorway ramp, I was first instructed to keep left, then to turn left right after that. This needs further investigation.
- When going past a highway service area, connected via
highway=service
ways, I got an instruction to go straight – this is probably an error that can be fixed by not generating a maneuver when the only other options are service roads.
I am definitely interested into an updated version of your patch. Highways are quite dense around where I live ( or where I usually drive ) and splits are very common, and Navit should make better announcements for them. I'll try your patch meanwhile.
I did some testing, and the navigation instructions are indeed a bit better. It does a better job at announcing a highway split for example.
Patch applied in 5911.
We could still enhance the navigation tho, especially for highways :
- when there is a ramp between the two highways, navit will say "turn right into the ramp". It would be useful to announce the next highway name / number : " ... towards
". For that we probably need to announce item[2] instead of item[1] - same applies for highway entries actually : sometimes you have two ramps leading to two different highways. Knowing toward which highway you should be headed would actually be helpful
- we should probably replace the "turn <right|left> into the ramp" by "take the exit on your <left|right>" ( announcing exit number when available is yet another topic). Can a ramp be something else than an exit or a merge towards another highway?
I'm keeping this ticket open for now in case we can enhance these issues soon.
Anyway, your patch does actually improve navigation a lot, so thanks mvglasow!
I'll post the updated patch soon, I realize I should have made that available along with the compiled versions.
I'll need to do some more research into the cases which I encountered this weekend. Turns out the service area had ramps going off the motorway which then turned into service roads, thus it got treated like a normal exit or interchange. There were two further cases in which I got an announcement to stay on the motorway and not take a normal exit – I'll need to investigate into why that happened. Neither of these cases should be generating an announcement.
(This should also answer the question what else ramps can be used for – a ramp may also lead towards a service area, though mapping on OSM is somewhat inconsistent here.)
As for announcing ramps – I have had this idea as well, but this is really a separate issue. I've opened #1265 for it. The issue here is about whether or not to create a maneuver, #1265 is about the name to be used in announcements. There's also #694/#795, which is about the type of maneuver...
The above patch fixes the roundabout/ramp case. Be sure to get the latest version as I've uploaded a few buggy versions of it, due to the fact that merging 5911 back into my git branch messed up things.
Some news on the "don't take the ramp" maneuvers: apparently the rule that triggers those maneuvers is somewhere in the block that checks for same street and angles. I have to dig my way through it to understand what it is meant to do...
I still don't fully understand the whole steering angle magic, but essentially the code boils down to checking two things:
- Ambiguity: A maneuver is considered ambiguous if there is more than one candidate road within a certain range of steering angles.
- Same street: The route is assumed to follow the same street if the name stays the same and there are no other candidate roads with the same name. An exception is made for motorways (which can split temporarily): if the route follows a motorway and all other roads with the same name are also motorways, the same street criterion is still met.
A maneuver is created when the maneuver is ambiguous AND the same street criterion is not met.
Due to the rules for steering angles, an exit off a relatively straight motorway is easily considered ambiguous. However, the same street criterion will usually be met, thus following a motorway going past an exit will usually not create a maneuver.
However, there are cases in which zealous mappers have tagged ramps with the name of the motorway they lead away from. This would violate the "same street" criterion (more than one candidate way with the same name as the old way, one of which is not a motorway) and thus create an unnecessary maneuver.
After analyzing the data, this has caused all of the superfluous maneuvers I encountered last weekend.
IMHO the tagging is broken. But I doubt I'll live long enough to convince each and every mapper out there of my point – so the only other option is to modify Navit to handle such cases. Should be fairly straightforward...
trac660_r5911.patch
(5.6 KiB)Third version of patch, applies on top of r5911 (replaces second version)
Here's the patch. It applies on top of 5911 and fixes the following:
- Only exit from roundabout (not entry or staying in it) is announced, even on ramps
- New helper function to determine if a way is "motorway-like" (i.e. motorway or one-way trunk road)
- Exceptions to same-street criterion apply to all motorway-like roads, as well as ramps going off motorway-like roads
- Removed (now obsolete) check for ramps in same-street criterion (going on a ramp is already caught by a separate rule added in 5911)
I've briefly tested the code against one of last weekend's test cases and the superfluous maneuvers are gone. I'll do some more extensive testing and then update the prebuilt versions. As always, additional testers are welcome :-)
highway.png
(176.3 KiB)Highway routing comparison
missing_maeuver.png
(125.9 KiB)Missing maneuver
I did some tests and this patch really enhance navigation on highways.
Here is an example: [[Image(highway.png)]]
In blue, the route before the patches from this ticket. In red, the route after. This highway has 6 lanes and splits in 3, and if you're in the wrong lane ( or if you don't know which split you should follow) you can end up having to pay a toll. We can see that the patch adds 3 announcements along the way which are really helping staying on the right route. It could still be a bit better, for example announcing "stay on your left" instead of "turn left" but it's already a big improvement.
There is still a missing maneuver, tho: [[Image(missing_maeuver.png)]] Here, if you are coming from Powell Street, you are supposed to turn right into Frontage road then enter the highway, but currently the announcement for Frontage road is skipped, and Navit will only say "Turn right into the ramp", with the distance between the two red markers. It can be easily confusing and one could be tempted to continue on Powell Street looking for the ramp instead of going right into Frontage road and then right again into the ramp.
One last thing : to better investigate routing changes, I added a new dbus call : http://sourceforge.net/p/navit/code/5912/
You can now compare the effect of a routing change using for example:
dbus-send --print-reply --session --dest=org.navit_project.navit /org/navit_project/navit/default_navit org.navit_project.navit.navit.set_position string:"geo: $lng $lat" dbus-send --print-reply --session --dest=org.navit_project.navit /org/navit_project/navit/default_navit org.navit_project.navit.navit.set_destination string:"geo: $dlng $dlat" string:"dbus" dbus-send --session --type=method_call --print-reply --dest=org.navit_project.navit /org/navit_project/navit/default_navit org.navit_project.navit.navit.export_as_gpx string:/tmp/660.gpx
It will generate a gpx dump of the route like this one :
<?xml version='1.0' encoding='UTF-8'?> <gpx version='1.1' creator='Navit http://navit.sourceforge.net' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:navit='http://www.navit-project.org/schema/navit' xmlns='http://www.topografix.com/GPX/1/1' xsi:schemaLocation='http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd'> <rte> <rtept lon='-122.2937179811110866' lat='37.8439930619099130'><name>Turn right in 50 meters into the street Shellmound Street</name></rtept> <rtept lon='-122.2934481846293124' lat='37.8393554404405563'><name>Turn right in 500 meters into the street Shellmound Way</name></rtept> <rtept lon='-122.2949230720629998' lat='37.8392631111721158'><name>Turn left in 125 meters into the street Christie Avenue</name></rtept> <rtept lon='-122.2947072348775919' lat='37.8385173705367208'><name>Turn right in 80 meters into the street Powell Street</name></rtept> <rtept lon='-122.2977829147698259' lat='37.8396182231104490'><name>Turn easily right in 400 meters into the ramp</name></rtept> <rtept lon='-122.2960292376382938' lat='37.8362587957613954'><name>Turn right in 450 meters into the street Eastshore Freeway I 80;I 580</name></rtept> <rtept lon='-122.2948151534702959' lat='37.8335739848470212'><name>Turn left in 300 meters into the I 580</name></rtept> <rtept lon='-122.2938708657841005' lat='37.8293263860142446'><name>Turn left in 500 meters into the I 580</name></rtept> <rtept lon='-122.2736631092990933' lat='37.8254763443810305'><name>Turn right in 2 kilometers into the ramp</name></rtept> <rtept lon='-122.2701197821717756' lat='37.8193385933242894'><name>Turn right in 900 meters</name></rtept> <rtept lon='-122.2710370902098020' lat='37.8168449861608025'><name>Turn left in 300 meters into the street 27th Street</name></rtept> <rtept lon='-122.2698319992578746' lat='37.8164613468129716'><name>Turn left in 125 meters into the street Northgate Avenue</name></rtept> <rtept lon='-122.2697960263936494' lat='37.8166602711681179'><name>Turn easily right in 20 meters into the ramp</name></rtept> <rtept lon='-122.2696701213688186' lat='37.8171291621701187'><name>Turn left in 50 meters</name></rtept> <rtept lon='-122.2688607319234961' lat='37.8208091426765094'><name>Turn right in 400 meters</name></rtept> <rtept lon='-122.2647238525362638' lat='37.8233168235070281'><name>You have reached your destination in 600 meters</name></rtept> </rte> </gpx>
And you can easily use that to diff two gpx outputs ( or plot the route on a map). It's a quick hack but was helpful in reviewing patches in this ticket. One gotcha : the marker is where you are supposed to perform the maneuver, but the distance in the announcement is the distance from the previous maneuver (because it is what is used to build the announcement)
I forgot to say that the patch trac660_r5911.patch was applied in 5913.
@kazer: Thanks! About your example: is the link from Powell Street to Frontage road a ramp or a secondary road in the map data you used in this test? This would make a difference in routing.
If it were all secondary (no ramps), I can explain why no maneuver is generated: at the point of the maneuver, there is only one possible way of the same category as the way leading towards it (secondary). All other ways are tertiary – thus Navit assumes that the user would follow the secondary road unless instructed otherwise.
I've had the opposite example: at http://www.openstreetmap.org/node/536468708#map=15/48.2265/11.5879&layers=N, coming from Munich on the primary road and going straight, I get an instruction to "keep left". Note that in the map data I used, the short stretch of primary between the two motorway ramps is mapped as secondary.
I have already given this some thought and one idea I had was to change the "only one street in same category" criterion to "only one street in same or next lower category". This would have given you a maneuver in your example – I have to see what it would do in my example.
Good catch mvglasow.
Powell and Frontage road are both secondary, and Powell becomes tertiary after this split, so it makes sense.
About your test case, I've put some ideas in #1268
Probably not the best way of mapping it (I would've made it a ramp), but I won't manage to convince every mapper of that. Let's see what I can do.
One thing that's odd is that I've run my test case (the one mentioned above) on Linux with the demo vehicle, and I don't get the "keep left" instruction which I got on my phone. Map data is the exact same though... will try replaying a recorded trace and see what happens...
The mapping seems ok to me, because Frontage roads actually continues past the ramp : OSM
One step further on the Emeryville test case: the "more than one similar road and delta over 22" criterion does not fire because the difference between old and new bearing at the split is 19° for the maneuver.
For going straight the delta is 13°, hence the "not same street or ambiguous" criterion does not fire either because dlim is too low: Since both the old and new way are in a higher category than any other way at that position, dlim is set to one half the delta of the maneuver (which is 19°/2, rounded to 9°). I think I need to fiddle with the dlim calculations here...
That did the trick! I introduced an extra criterion: if the category of the old way, the category of the new way and the highest category of any other way differ by no more than 1,
dlim
is set so that any other way with same or lower delta as the maneuver will be considered ambiguous and trigger an announcement. Specifically,dlim = abs(d) + 1
. (Adding 1 is needed because comparison is<
/>
rather than<=
/>=
).I'm not committing this yet because I can't really tell how likely this change is to have any regressions (in the form of superfluous anouncements).
I'll attach a patch as well as links to prebuilt binaries so that people can test it. I'll run my own test cases against it, in the lab and (if I can) in real life, and commit after successful testing.
And prebuilt binaries are here:
I've found another issue in 5917:
http://www.openstreetmap.org/node/564869
When following Ammerseestraße to join the motorway, I get told to "keep left" here when there are no other allowed maneuvers (the only physically possible one would be to make a sharp right turn and go the wrong way into Senftenauerstraße). More testing revealed that this happens in other positions as well. I'll take a look at why this happens.
Turns out the maneuver here was generated because we're going from a secondary to a ramp (and the particular check fails to verify whether any other options are permitted).
I'm refactoring the code to have only one loop going over the entire set of available ways and analyze only those which are permitted. Furthermore I'm adding a check that suppresses maneuvers when there is only one permitted option.
The code changes have fixed the case. Running my suite of tests, I found three more interesting cases:
In one case I get an announcement on a ramp where two split carriageways join, despite there being a turn restriction (the other, forbidden option being a U-turn).
Another issue I found, which is even more complicated, involves T-junctions with dual-carriageway roads. Example:
http://www.openstreetmap.org/node/493880718 http://www.openstreetmap.org/#map=19/46.22227/9.04440
When I come in from the ramp, I don't get an instruction to turn left since that's the only possible maneuver at that point.
- At the same junction, since the road coming in is a ramp, I get a "turn easily left" announcement (telling me to stay on the ramp) at the point where I am crossing the opposite carriageway, just before the point at which I would turn left.
This is where things get interesting.
Case 1 is probably caused by the fact that
is_way_allowed
does not take turn restrictions into account. I'll need to dig into that more deeply to find out how Navit deals with turn restrictions in general.Case 3 could probably be resolved by relaxing/refining the "always announce ramps" criterion: when one of the eligible ways is neither a ramp or motorway-like AND the maneuver is to go straight AND all other maneuvers involve a turn, do not announce the maneuver. I'll need to analyze the case further to see the reason for the maneuver here.
Case 2 is the really tricky one: we're not on a motorway-like road, so we expect the driver to follow the road, follow all access restrictions and go straight otherwise. We first cross the carriageway for the opposite direction (no maneuver needed since we're going straight), and once we've crossed it, turning left is the only option available, thus it is not announced.
However, drivers almost certainly expect to get told "turn left" at this point, and will get confused when they're getting near the end of the road and don't see a maneuver (or get told to go straight until shortly before the actual maneuver, and then suddenly get the nex maneuver, which may be at the other end of town).
So the rule is: when turning into a dual-carriageway road, announce the maneuver. The problem is how to detect a dual-carriageway road: we have to analyze not just a single maneuver, but also the one preceding it. This will need some more research...
Turns out analyzing previous maneuvers for case 2 is not quite as tricky as I thought. I've successfully tackled the respective test case. Currently running the test suite...
Patch attached (which fixes case 2). 5917 plus this patch fixes the Emeryville test case and the Munich-Ammerseestraße test case with no known regressions (compared to 5917) so far. (Case 1 and 3 have been around since at least 5917).
As always, if no major regressions are found, I'll commit this code in a few days. For those who can't wait, here are the attached binaries:
Issue migrated from trac ticket # 660
component: core | priority: major | keywords: patches
2010-09-10 08:23:57: polarbear_n created the issue