diff --git a/libosmscout/include/osmscout/navigation/VoiceInstructionAgent.h b/libosmscout/include/osmscout/navigation/VoiceInstructionAgent.h index f4d6829f3..1c1a8a985 100644 --- a/libosmscout/include/osmscout/navigation/VoiceInstructionAgent.h +++ b/libosmscout/include/osmscout/navigation/VoiceInstructionAgent.h @@ -118,8 +118,8 @@ class OSMSCOUT_API VoiceInstructionAgent CLASS_FINAL : public NavigationAgent { public: - enum class MessageType { - NoMessage, + enum class MessageType: int { + NoMessage = 0, LeaveRbExit1, LeaveRbExit2, @@ -138,7 +138,9 @@ class OSMSCOUT_API VoiceInstructionAgent CLASS_FINAL : public NavigationAgent LeaveMotorway, LeaveMotorwayRight, - LeaveMotorwayLeft + LeaveMotorwayLeft, + + Silent }; struct MessageStruct { @@ -175,6 +177,7 @@ class OSMSCOUT_API VoiceInstructionAgent CLASS_FINAL : public NavigationAgent private: DistanceUnitSystem units{DistanceUnitSystem::Metrics}; + Vehicle vehicle{vehicleCar}; // state used for triggering GpsFound / GpsLost messages bool prevGpsSignal{true}; @@ -194,7 +197,8 @@ class OSMSCOUT_API VoiceInstructionAgent CLASS_FINAL : public NavigationAgent private: void toSamples(std::vector &samples, - const MessageType &messageType); + const MessageType &messageType, + bool shortRoundaboutMessage); std::vector toSamples(const Distance &distanceFromStart, const MessageStruct &message, diff --git a/libosmscout/src/osmscout/navigation/VoiceInstructionAgent.cpp b/libosmscout/src/osmscout/navigation/VoiceInstructionAgent.cpp index a71f8e63d..7f3b2c87d 100644 --- a/libosmscout/src/osmscout/navigation/VoiceInstructionAgent.cpp +++ b/libosmscout/src/osmscout/navigation/VoiceInstructionAgent.cpp @@ -32,6 +32,7 @@ struct PostprocessorCallback : public RouteDescriptionPostprocessor::Callback Distance distanceFromStart; Distance stopAfter; Distance distance; + std::optional roundaboutEnter; //GetExitCount()){ case 1: @@ -120,11 +137,13 @@ struct PostprocessorCallback : public RouteDescriptionPostprocessor::Callback // it is not correct, but what else we may say? type = MessageType::LeaveRbExit6; } + // say the message before entering the roundabout if (!nextMessage){ - nextMessage = VoiceInstructionAgent::MessageStruct{type, distance}; + nextMessage = VoiceInstructionAgent::MessageStruct{type, *roundaboutEnter}; } else if (!thenMessage){ - thenMessage = VoiceInstructionAgent::MessageStruct{type, distance}; + thenMessage = VoiceInstructionAgent::MessageStruct{type, *roundaboutEnter}; } + roundaboutEnter = std::nullopt; } void OnTargetReached(const osmscout::RouteDescription::TargetDescriptionRef& /*targetDescription*/) override @@ -188,33 +207,32 @@ struct PostprocessorCallback : public RouteDescriptionPostprocessor::Callback } }; -void VoiceInstructionAgent::toSamples(std::vector &samples, const MessageType &type) +void VoiceInstructionAgent::toSamples(std::vector &samples, const MessageType &type, bool shortRoundaboutMessage) { using VoiceSample = VoiceInstructionMessage::VoiceSample; + + if (!shortRoundaboutMessage && type>=MessageType::LeaveRbExit1 && type<=MessageType::LeaveRbExit6) { + samples.push_back(VoiceSample::RbCross); + } + switch (type) { case MessageType::LeaveRbExit1: - samples.push_back(VoiceSample::RbCross); samples.push_back(VoiceSample::RbExit1); break; case MessageType::LeaveRbExit2: - samples.push_back(VoiceSample::RbCross); samples.push_back(VoiceSample::RbExit2); break; case MessageType::LeaveRbExit3: - samples.push_back(VoiceSample::RbCross); samples.push_back(VoiceSample::RbExit3); break; case MessageType::LeaveRbExit4: - samples.push_back(VoiceSample::RbCross); samples.push_back(VoiceSample::RbExit4); break; case MessageType::LeaveRbExit5: - samples.push_back(VoiceSample::RbCross); samples.push_back(VoiceSample::RbExit5); break; case MessageType::LeaveRbExit6: - samples.push_back(VoiceSample::RbCross); samples.push_back(VoiceSample::RbExit6); break; @@ -262,6 +280,11 @@ std::vector VoiceInstructionAgent::toSampl std::vector samples; assert(message); + + if (message.type == MessageType::Silent) { + return samples; + } + // distance from our position to next message Distance nextMessageDistance = (message.distance - distanceFromStart); double distanceInUnits = (units == DistanceUnitSystem::Metrics) ? nextMessageDistance.AsMeter() : nextMessageDistance.As(); @@ -270,7 +293,13 @@ std::vector VoiceInstructionAgent::toSampl return samples; } - if (distanceInUnits > 50){ + // We are close to roundabout, we will use short roundabout message in such case. + bool shortRoundaboutMessage = message.type >= MessageType::LeaveRbExit1 && message.type <= MessageType::LeaveRbExit6 && + distanceInUnits < 120; + + if (bool skipDistanceInformation = (distanceInUnits < 80 && vehicle == vehicleCar); + !skipDistanceInformation){ + samples.push_back(VoiceSample::After); if (distanceInUnits > 800){ samples.push_back(VoiceSample::Distance800); @@ -296,12 +325,12 @@ std::vector VoiceInstructionAgent::toSampl samples.push_back(units == DistanceUnitSystem::Metrics ? VoiceSample::Meters : VoiceSample::Yards); } - toSamples(samples, message.type); + toSamples(samples, message.type, shortRoundaboutMessage); if (then){ auto thenDistance = then.distance - message.distance; - if (thenDistance <= Meters(200)) { // ignore then messsage otherwise + if (thenDistance <= Meters(200)) { // ignore then message otherwise samples.push_back(VoiceSample::Then); - toSamples(samples, then.type); + toSamples(samples, then.type, true); } } return samples; @@ -316,6 +345,7 @@ std::list VoiceInstructionAgent::Process(const NavigationM // reset state lastMessage.type=MessageType::NoMessage; lastMessagePosition=Distance::Zero(); + vehicle=routeUpdateMessage->vehicle; return result; }