osmandapp / OsmAnd

OsmAnd
https://osmand.net
Other
4.68k stars 1.02k forks source link

Voice navigation could be smarter about what names/numbers to use for street #7289

Open somasis opened 5 years ago

somasis commented 5 years ago

In my town (Boone, NC), there are multiple highway concurrencies that run through the town.

https://commons.wikimedia.org/wiki/File:NC_105_with_Truck_Signs.jpg

This leads to OsmAnd spitting out a lot of text just to say the street name, when it could instead just say the highway that most of the route would be taken on. Truck routes could also be eliminated from names that are said, for example, if the vehicle being used is not a truck/heavy goods vehicle (though I imagine that'd need an additional navigation profile...). Either way, as it stands now, OsmAnd can be annoyingly long-winded when saying highway numbers because of concurrency.

vshcherb commented 5 years ago

We would need some local knowledge and expert who can adjust it properly

sonora commented 5 years ago

I think the intriguing idea here is to "just say the highway that most of the route would be taken on". That requires an algorithm to discover that route, not sure how involved this is to code.

In any case, concurrence of 4 routes seems a rather rare occurrence, though? Is this perhaps a one-off example? I do drive a lot around the US, and yes, concurrence of e.g. an Interstate and a US Highway are quite frequent, but I find 3 or more concurrences rather rare. Normally, I would say it suffices to announce the highest-hierarchy route only (e.g. the Interstate over the US Hwy), but in your case there would be 3 US Hwys so it would not solve the issue...

somasis commented 5 years ago

It is pretty unusual, admittedly; in part just because Boone is in the perfect spot for all the highways to have an easy path through the mountains.

Perhaps repurposing this issue a little might be useful. There are some other problems I should of mentioned that I've noticed since I started using OsmAnd to get around, since this is ultimately a "improve voice navigation awkwardness" issue.

It seems to me like OsmAnd might just be entirely ignoring the road number when deduplicating ways, actually.

Imagine you have a new way for when the speed limit changes on the current road, but it's the same road number, not even a fork on it or anything that might make any voice instructions useful or necessary. Yet OsmAnd keeps telling me to stay on the new way, failing to understand it's not a new road, but the same way with some different attributes.

I think it already does this for when road names are the same across way objects, but not for roads with numbers but no names. I've noticed this mostly when driving on highways (notably US 421, one of the ones I take leaving Boone generally) that I've split up myself to add speed limits to. When I then navigate with OsmAnd on these roads, what was once a single contiguous instruction to get on 421 and keep straight is now split up, and now OsmAnd constantly keeps telling me to keep left/right onto US 421.

sonora commented 5 years ago

Here is the logic of what I think you are talking about, I had authored the original PROLOG code (the one now commented out behind //). I I think it has been captured ok in the easier to read if ...else if js code:, but am not 100% sure, we may have to verify/revisit:

function turn_street(streetName) {
    // turn_street("", []).
// turn_street(voice(["","",""],_), []).
// turn_street(voice(["", "", D], _), ["toward", D]) :- tts.
// turn_street(Street, ["on", SName]) :- tts, Street = voice([R, S, _],[R, S, _]), assemble_street_name(Street, SName).
// turn_street(Street, ["on", SName]) :- tts, Street = voice([R, "", _],[R, _, _]), assemble_street_name(Street, SName).
// turn_street(Street, ["onto", SName]) :- tts, not(Street = voice([R, S, _],[R, S, _])), assemble_street_name(Street, SName).
    if (Object.keys(streetName).length == 0 || (streetName["toDest"] === "" && streetName["toStreetName"] === "" && streetName["toRef"] === "") || !tts) {
        return "";
    } else if (streetName["toStreetName"] === "" && streetName["toRef"] === "") {
        return dictionary["toward"] + " " + streetName["toDest"];
    } else if (streetName["toRef"] === streetName["fromRef"] && streetName["toStreetName"] === streetName["fromStreetName"]) {
        return dictionary["on"] + " " + assemble_street_name(streetName);
    } else if ((streetName["toRef"] === streetName["fromRef"] && streetName["toStreetName"] === streetName["fromStreetName"]) 
        || (streetName["toStreetName"] === "" && streetName["toRef"] === streetName["fromRef"])) {
        return dictionary["on"] + " " + assemble_street_name(streetName);
    } else if (!(streetName["toRef"] === streetName["fromRef"] && streetName["toStreetName"] === streetName["fromStreetName"])) {
        return dictionary["onto"] + " " + assemble_street_name(streetName);
    }
    return "";

As you can see, whether a segment is detected as "the same" or "something new" is derived from different combinations of when the street name and/or the associated reference (I guess in the concurrence case the sum of all refs) change or not, or vanish/appear. Most easily to verify in the lines defining if we use "on" (indicating you stay on the same street) or "onto" (instructing you to turn onto a new street.

Maybe you find an error, I have not checked the js code ever, or maybe you have an improvement idea for the "awkwardness"example cases you observe.

It would also help to look at one concrete set of coordinates where you observe something could be improved, then we could check why and what kind of turn OsmAnd detects and announces.

somasis commented 5 years ago

At the moment I'm not actually in Boone (on vacation) but I just simulated navigation on OsmAnd and it did indeed reproduce the issue a few times. Here's a few coordinates of when I noticed it.

However, now I'm actually kinda confused. It doesn't seem like these match up the spots where a way object connects to another way object...

sonora commented 5 years ago

I assume you're talking westbound?

Obviously this is not only a voice issue, we need to look at this in light of our rules when to detect a valid turn at all and when not, we have some evaluation rules there I have not looked at in years, hope someone in the team can help out.

But one thing I do notice voice-related is that at least some voice engines pronounce all US highways as "United States 123" instead of "U S 123", which makes this particularly clumsy. I guess this is also part of your experience, and may be a big portion of the issue? I can seen that it makes sense for TTS engines in some context to make that replacement, but for repeated highway ref announcements it seems certainly not advantageous?

sonora commented 3 years ago

The only viable strategies I see here are:

  1. "Evaluate the route ahead, and from the multiple possible refs only announce the one which the route will follow for the longest stretch".

Possible side effects are

Or

  1. we somehow resort to always announce only one ref, figuring out which one is the overall 'most prominent' one, e.g. by its overall lenght on the map.

In light of these remarks I would hand it over to product development @vshcherb, probably with the recommendation that I think we should likely take no action here for now, unless we receive more feedback indicating that the issue is more common than we think now.

vshcherb commented 3 years ago

@sonora Sounds complicated but we have some similar code where we detect ref for next road segments cause there is an issue on road intersections, refs are not mapped correctly. So it's somewhere when calculate the route itself and where we could augment / change names / refs.