Skip to content
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

Brief voice instructions #1435

Merged
merged 2 commits into from
May 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading