-
Notifications
You must be signed in to change notification settings - Fork 658
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve voice instructions #4696
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It just a draft right now. Even if it works fine in my case it should be tested by somebody else to verify if it works in reality on the road.
@@ -12,6 +12,8 @@ | |||
#include "midgard/util.h" | |||
#include "odin/enhancedtrippath.h" | |||
#include "odin/util.h" | |||
#include "odin/narrative_builder_factory.h" | |||
#include "odin/narrativebuilder.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having these here is ofc debatable. We have following problem here: Currently we only build instructions during building the maneuver. But we decide the distance when a maneuver is played in the osrm_serializer and the instructions do depend on the distance (e.g. In 200 meter do XY). So the two options in my mind are:
- Calculate the distances here and add the 'IN 200 meters' information here. This needs the dependency and that's how I did it.
- Inject the distance information during maneuver building. So we later on just call here e.g.
verbal_transition_alert_instruction()
and we also get the distance when to play it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah i think the long term way we should do it is the second way primarily because it is odins main function, deciding where maneuvers are. deciding when to warn about them is very closely related in my opinion.
having said that, you already did all the work and there has been slow progress on this effort in the past so i think it could stay this way until someone has time for a larger refactor. i would wager that others would agree especially because there are other odin deps mixed in here as well (which was already not great and was for the same reason).
as an aside.. maybe we should have had the actor stuff that tyr provides be part of the valhalla namespace exposed in the main valhalla header and then just have odin subsume all the serialization stuff (essentially dividing up tyrs parts and then removing tyr completely). i think it would be reasonably appropriate for odin to generate maneuvers narrative and do serialization. its essentially serializing the path into maneuvers and then serializing maneuvers into narrative. may as well do the final serialization into json or pbf bytes. this of course ignores that there are some endpoints that have no directions or narrative and maybe those would seem strange calling into odin.. meh just some thoughts 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for having a look! I completely agree. The second way feels more correct, but would need some more time. Would also be better so the normal valhalla json answer could be enhanced by the same distance information which might be helpful.
But then let me clean up this one and write some test. I'll also open a cleanup issue for doing it the second way. Maybe I'll have some time in the future to clean it up.
const constexpr double SECONDS_BEFORE_VERBAL_TRANSITION_ALERT_INSTRUCTION = 15.0; | ||
const constexpr double SECONDS_BEFORE_VERBAL_PRE_TRANSITION_INSTRUCTION = 5.0; | ||
const constexpr double SECONDS_BEFORE_VERBAL_TRANSITION_ALERT_INSTRUCTION = 35.0; | ||
const constexpr double SECONDS_BEFORE_VERBAL_PRE_TRANSITION_INSTRUCTION = 10.0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just increased those values. 5 and 15 seconds sound nice in theory but on the road I experienced that this is way too late. Would be cool to get some feedback of somebody else on this
Also 35 seconds is the way better option for alert instructions when enhancing it by the 'IN 200 meters ...' information.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, these are much better values.
I think that longer term (maybe not this PR), these values be tunable at request time. We can set sensible defaults, but different people / use cases may have different preferences.
const constexpr double SECONDS_BEFORE_VERBAL_PRE_TRANSITION_INSTRUCTION = 5.0; | ||
const constexpr double SECONDS_BEFORE_VERBAL_TRANSITION_ALERT_INSTRUCTION = 35.0; | ||
const constexpr double SECONDS_BEFORE_VERBAL_PRE_TRANSITION_INSTRUCTION = 10.0; | ||
const constexpr double MIN_DISTANCE_VERBAL_PRE_TRANSITION_INSTRUCTION = 40; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding a minimum distance for the pre transition alert here. I experienced that on low speed roads we will just announce right before the turn due to the low speed. That also often feels way too late. On such low speed roads its even fine to announce 30 seconds before the transition if you can already can see it.
One thing to take into account here is that a routing graph only reflects (ideally) the center of the road and doesn't represent the width of a road.
I'm not sure if I 100% like this concept, but it helped in my case
src/tyr/route_serializer_osrm.cc
Outdated
const valhalla::Options& options) { | ||
// narrative builder for custom pre alert instructions | ||
MarkupFormatter nullFormatter; | ||
std::unique_ptr<NarrativeBuilder> narrative_builder = NarrativeBuilderFactory::Create(options, etp, nullFormatter); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also not 100% happy with this. The functions which we need don't use the markup formatter, so I'm just passing a null formatter.
@@ -1494,65 +1503,94 @@ json::ArrayPtr voice_instructions(const valhalla::DirectionsLeg::Maneuver* prev_ | |||
// shortly (10 meters at the given speed) after the maneuver has started. | |||
// The voice_instruction_beginning starts shortly after the beginning of the step. | |||
// The voice_instruction_end starts shortly before the end of the step. | |||
float distance_before_verbal_transition_alert_instruction = -1; | |||
float distance_before_verbal_pre_transition_instruction = -1; | |||
if (prev_maneuver) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just moved this if(prev_maneuver)
out of the function. We should always have it.
src/tyr/route_serializer_osrm.cc
Outdated
// TODO: don't add alert instruction if there was already a pre/post transition aleart which is close by | ||
if (!maneuver.verbal_transition_alert_instruction().empty() | ||
&& distance_before_verbal_transition_alert_instruction > -1.0 | ||
&& prev_maneuver->time() > SECONDS_BEFORE_VERBAL_TRANSITION_ALERT_INSTRUCTION + APPROXIMATE_VERBAL_PRERANSITION_SECONDS) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is one of the most important changes. We will not have the alert instructions for short maneuvers. Doesn't make sense in my mind to alert something on a 50 meter road. Just play the transition instruction in that case is fine enough. Two instructions on that small maneuver are way too much.
Actually we should even go further and collapse multiple maneuver into a single one if the maneuver itself is too short
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, this is the exact approach I took in a hacked up previous implementation.
src/tyr/route_serializer_osrm.cc
Outdated
voice_instruction_end->emplace("announcement", maneuver.verbal_transition_alert_instruction()); | ||
//building voice instructions for the alert | ||
float distance_km = (float) distance_along_geometry / 1000.0f; | ||
std::string instruction = narrative_builder->FormVerbalAlertApproachInstruction(distance_km, maneuver.verbal_transition_alert_instruction()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here is the part where I'm enhancing the alert instruction by the distance information. This needs the narrative_builder. In english language it will add some prefix like 'In x meters ...'
@@ -1832,29 +1871,28 @@ json::ArrayPtr serialize_legs(const google::protobuf::RepeatedPtrField<valhalla: | |||
|
|||
// Add banner instructions if the user requested them | |||
if (options.banner_instructions()) { | |||
if (prev_step) { | |||
if (prev_step && prev_maneuver) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just ensuring here that we have the prev_maneuver, since I moved it out of the build voice instruction function. Actually it should always be present
…la#4698) Co-authored-by: Michael Kirk <michael.code@endoftheworl.de>
…ections_type is set to none (valhalla#4706)
Co-authored-by: Christian <58629404+chrstnbwnkl@users.noreply.github.com>
…alhalla#4710) Co-authored-by: Christian <58629404+chrstnbwnkl@users.noreply.github.com>
Co-authored-by: Christian <58629404+chrstnbwnkl@users.noreply.github.com>
Co-authored-by: Martin Schlossarek <martin.schlossarek@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll need a review from one of the core maintainers to comment on the parts that you flagged as needing a design review, but throwing in my 2 cents, this 1) does appear to work (running it on some servers now after some local testing), and 2) is a significant improvement.
I'd suggest marking this ready for review @Trietes unless you're still waiting on something I missed.
const constexpr double SECONDS_BEFORE_VERBAL_TRANSITION_ALERT_INSTRUCTION = 15.0; | ||
const constexpr double SECONDS_BEFORE_VERBAL_PRE_TRANSITION_INSTRUCTION = 5.0; | ||
const constexpr double SECONDS_BEFORE_VERBAL_TRANSITION_ALERT_INSTRUCTION = 35.0; | ||
const constexpr double SECONDS_BEFORE_VERBAL_PRE_TRANSITION_INSTRUCTION = 10.0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, these are much better values.
I think that longer term (maybe not this PR), these values be tunable at request time. We can set sensible defaults, but different people / use cases may have different preferences.
src/tyr/route_serializer_osrm.cc
Outdated
// TODO: don't add alert instruction if there was already a pre/post transition aleart which is close by | ||
if (!maneuver.verbal_transition_alert_instruction().empty() | ||
&& distance_before_verbal_transition_alert_instruction > -1.0 | ||
&& prev_maneuver->time() > SECONDS_BEFORE_VERBAL_TRANSITION_ALERT_INSTRUCTION + APPROXIMATE_VERBAL_PRERANSITION_SECONDS) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, this is the exact approach I took in a hacked up previous implementation.
Thanks for checking it out and giving it a test. I've been waiting for somebody to test it out and saying it is at least better than before :D |
…uncements (valhalla#4644) Co-authored-by: Christian <58629404+chrstnbwnkl@users.noreply.github.com>
…es/valhalla into improve-voice-instructions
Seems like GitHub doesn't like my rebase. I'm just done with adapting the tests and cleaning the stuff up. I'll open a clean new pull request now |
Issue
Trying to do more work on #4640.
Tasklist
Requirements / Relations
Also contains the changes made in #4644. So we can either skip #4644 and wait for this one or quickly merge as soon as we know that it works with Maplibre and later on merge this one.