Skip to content

Commit

Permalink
Merge pull request #1435 from Karry/brief-voice-instructions
Browse files Browse the repository at this point in the history
Brief voice instructions
  • Loading branch information
Framstag committed May 28, 2023
2 parents 7aebbc7 + b69c13b commit 7bed716
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 18 deletions.
12 changes: 8 additions & 4 deletions libosmscout/include/osmscout/navigation/VoiceInstructionAgent.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -138,7 +138,9 @@ class OSMSCOUT_API VoiceInstructionAgent CLASS_FINAL : public NavigationAgent

LeaveMotorway,
LeaveMotorwayRight,
LeaveMotorwayLeft
LeaveMotorwayLeft,

Silent
};

struct MessageStruct {
Expand Down Expand Up @@ -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};
Expand All @@ -194,7 +197,8 @@ class OSMSCOUT_API VoiceInstructionAgent CLASS_FINAL : public NavigationAgent

private:
void toSamples(std::vector<VoiceInstructionMessage::VoiceSample> &samples,
const MessageType &messageType);
const MessageType &messageType,
bool shortRoundaboutMessage);

std::vector<VoiceInstructionMessage::VoiceSample> toSamples(const Distance &distanceFromStart,
const MessageStruct &message,
Expand Down
58 changes: 44 additions & 14 deletions libosmscout/src/osmscout/navigation/VoiceInstructionAgent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ struct PostprocessorCallback : public RouteDescriptionPostprocessor::Callback
Distance distanceFromStart;
Distance stopAfter;
Distance distance;
std::optional<Distance> roundaboutEnter; //<! distance of roundabout enter before nextMessage

public:
VoiceInstructionAgent::MessageStruct nextMessage;
Expand Down Expand Up @@ -90,12 +91,28 @@ struct PostprocessorCallback : public RouteDescriptionPostprocessor::Callback
OnMotorwayLeave(directionDescription);
}

void OnRoundaboutEnter([[maybe_unused]] const RouteDescription::RoundaboutEnterDescriptionRef &roundaboutEnterDescription,
[[maybe_unused]] const RouteDescription::CrossingWaysDescriptionRef &crossingWaysDescription) override
{
if (!roundaboutEnter) {
roundaboutEnter = distance;
}
}

void OnRoundaboutLeave(const osmscout::RouteDescription::RoundaboutLeaveDescriptionRef& roundaboutLeaveDescription,
[[maybe_unused]] const osmscout::RouteDescription::NameDescriptionRef& nameDescription) override
{
assert(roundaboutLeaveDescription);

using MessageType = VoiceInstructionAgent::MessageType;

if (!roundaboutEnter) {
if (!nextMessage) {
// we are on the roundabout right now, be silent until we leave it
nextMessage = VoiceInstructionAgent::MessageStruct{MessageType::Silent, distance};
}
return;
}

MessageType type = MessageType::NoMessage;
switch (roundaboutLeaveDescription->GetExitCount()){
case 1:
Expand All @@ -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
Expand Down Expand Up @@ -188,33 +207,32 @@ struct PostprocessorCallback : public RouteDescriptionPostprocessor::Callback
}
};

void VoiceInstructionAgent::toSamples(std::vector<VoiceInstructionMessage::VoiceSample> &samples, const MessageType &type)
void VoiceInstructionAgent::toSamples(std::vector<VoiceInstructionMessage::VoiceSample> &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;

Expand Down Expand Up @@ -262,6 +280,11 @@ std::vector<VoiceInstructionMessage::VoiceSample> VoiceInstructionAgent::toSampl
std::vector<VoiceInstructionMessage::VoiceSample> 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<Yard>();
Expand All @@ -270,7 +293,13 @@ std::vector<VoiceInstructionMessage::VoiceSample> 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);
Expand All @@ -296,12 +325,12 @@ std::vector<VoiceInstructionMessage::VoiceSample> 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;
Expand All @@ -316,6 +345,7 @@ std::list<NavigationMessageRef> VoiceInstructionAgent::Process(const NavigationM
// reset state
lastMessage.type=MessageType::NoMessage;
lastMessagePosition=Distance::Zero();
vehicle=routeUpdateMessage->vehicle;
return result;
}

Expand Down

0 comments on commit 7bed716

Please sign in to comment.