From e2e4d234aa197bd6991e441100ab826abc4e5562 Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 17 Jul 2014 12:48:59 +0400 Subject: [PATCH] Removed UTurn message. Added functionality to cancel voice commands if user is off the route. Added off the route indicator with lenght to return to path. --- .../src/net/osmand/router/TurnType.java | 5 +- .../osmand/plus/routing/RoutingHelper.java | 49 +++++++++++-------- .../net/osmand/plus/routing/VoiceRouter.java | 19 +++---- .../net/osmand/plus/views/TurnPathHelper.java | 24 ++++++++- .../views/mapwidgets/NextTurnInfoWidget.java | 16 ++++-- .../mapwidgets/RouteInfoWidgetsFactory.java | 11 +++-- .../net/osmand/plus/voice/CommandPlayer.java | 2 + .../plus/voice/MediaCommandPlayerImpl.java | 12 ++++- .../plus/voice/TTSCommandPlayerImpl.java | 7 +++ 9 files changed, 99 insertions(+), 46 deletions(-) diff --git a/OsmAnd-java/src/net/osmand/router/TurnType.java b/OsmAnd-java/src/net/osmand/router/TurnType.java index 5d5b9b927e..488286a835 100644 --- a/OsmAnd-java/src/net/osmand/router/TurnType.java +++ b/OsmAnd-java/src/net/osmand/router/TurnType.java @@ -12,7 +12,8 @@ public class TurnType { public static final String KR = "KR"; // keep right//$NON-NLS-1$ public static final String TU = "TU"; // U-turn //$NON-NLS-1$ public static final String TRU = "TRU"; // Right U-turn //$NON-NLS-1$ - public static String[] predefinedTypes = new String[] { C, KL, KR, TL, TSLL, TSHL, TR, TSLR, TSHR, TU, TRU }; + public static final String OFFR = "OFFR"; // Off route //$NON-NLS-1$ + public static String[] predefinedTypes = new String[] { C, KL, KR, TL, TSLL, TSHL, TR, TSLR, TSHR, TU, TRU, OFFR }; public static TurnType sraight() { return valueOf(C, false); @@ -138,6 +139,8 @@ public class TurnType { return "Keep left"; } else if(value.equals(KR)) { return "Keep right"; + } else if(value.equals(OFFR)) { + return "Off route"; } return super.toString(); } diff --git a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java index 9b5a1b3a24..7ef6107912 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java @@ -71,8 +71,8 @@ public class RoutingHelper { private RouteProvider provider = new RouteProvider(); private VoiceRouter voiceRouter; - private boolean makeUturnWhenPossible = false; - private long makeUTwpDetected = 0; + private boolean isDeviatedFromRoute = false; + private long deviateFromRouteDetected = 0; //private long wrongMovementDetected = 0; private RouteCalculationProgressCallback progressRoute; @@ -80,11 +80,10 @@ public class RoutingHelper { // private ProgressBar progress; // private Handler progressHandler; - public boolean makeUturnWhenPossible() { - return makeUturnWhenPossible; + public boolean isDeviatedFromRoute() { + return isDeviatedFromRoute; } - public RoutingHelper(OsmandApplication context, CommandPlayer player){ this.app = context; settings = context.getSettings(); @@ -125,7 +124,7 @@ public class RoutingHelper { public synchronized void clearCurrentRoute(LatLon newFinalLocation, List newIntermediatePoints) { route = new RouteCalculationResult(""); - makeUturnWhenPossible = false; + isDeviatedFromRoute = false; evalWaitInterval = 3000; app.runInUIThread(new Runnable() { @Override @@ -210,11 +209,21 @@ public class RoutingHelper { public Location setCurrentLocation(Location currentLocation, boolean returnUpdatedLocation) { return setCurrentLocation(currentLocation, returnUpdatedLocation, route); } + + public double getRouteDeviation(){ + if (route == null || + route.getImmutableAllDirections().size() < 2 || + route.currentRoute == 0){ + return 0; + } + List routeNodes = route.getImmutableAllLocations(); + return getOrthogonalDistance(lastFixedLocation, routeNodes.get(route.currentRoute -1), routeNodes.get(route.currentRoute)); + } private Location setCurrentLocation(Location currentLocation, boolean returnUpdatedLocation, RouteCalculationResult previousRoute) { Location locationProjection = currentLocation; if (finalLocation == null || currentLocation == null) { - makeUturnWhenPossible = false; + isDeviatedFromRoute = false; return locationProjection; } float posTolerance = POSITION_TOLERANCE; @@ -261,10 +270,10 @@ public class RoutingHelper { // don't update in route planing mode announceGpxWaypoints(currentLocation); boolean inRecalc = calculateRoute || isRouteBeingCalculated(); - if (!inRecalc && !uTurnIsNeeded && !wrongMovementDirection) { + if (!inRecalc && !wrongMovementDirection) { voiceRouter.updateStatus(currentLocation, false); - } else if (uTurnIsNeeded) { - voiceRouter.makeUTStatus(); + } else if(isDeviatedFromRoute){ + voiceRouter.interruptRouteCommands(); } } @@ -463,10 +472,10 @@ public class RoutingHelper { public boolean identifyUTurnIsNeeded(Location currentLocation, float posTolerance) { if (finalLocation == null || currentLocation == null || !route.isCalculated()) { - this.makeUturnWhenPossible = false; - return makeUturnWhenPossible; + this.isDeviatedFromRoute = false; + return isDeviatedFromRoute; } - boolean makeUturnWhenPossible = false; + boolean isOffRoute = false; if (currentLocation.hasBearing()) { float bearingMotion = currentLocation.getBearing() ; Location nextRoutePosition = route.getNextRouteLocation(); @@ -479,19 +488,19 @@ public class RoutingHelper { // 60m tolerance to allow for GPS inaccuracy if (d > posTolerance) { // require x sec continuous since first detection - if (makeUTwpDetected == 0) { - makeUTwpDetected = System.currentTimeMillis(); - } else if ((System.currentTimeMillis() - makeUTwpDetected > 10000)) { - makeUturnWhenPossible = true; + if (deviateFromRouteDetected == 0) { + deviateFromRouteDetected = System.currentTimeMillis(); + } else if ((System.currentTimeMillis() - deviateFromRouteDetected > 10000)) { + isOffRoute = true; //log.info("bearingMotion is opposite to bearingRoute"); //$NON-NLS-1$ } } } else { - makeUTwpDetected = 0; + deviateFromRouteDetected = 0; } } - this.makeUturnWhenPossible = makeUturnWhenPossible; - return makeUturnWhenPossible; + this.isDeviatedFromRoute = isOffRoute; + return isOffRoute; } /** diff --git a/OsmAnd/src/net/osmand/plus/routing/VoiceRouter.java b/OsmAnd/src/net/osmand/plus/routing/VoiceRouter.java index 8f15c8a010..8e285bc654 100644 --- a/OsmAnd/src/net/osmand/plus/routing/VoiceRouter.java +++ b/OsmAnd/src/net/osmand/plus/routing/VoiceRouter.java @@ -201,17 +201,6 @@ public class VoiceRouter { return currentStatus <= statusToCheck; } - protected void makeUTStatus() { - // Mechanism via STATUS_UTWP_TOLD: Until turn in the right direction, or route is re-calculated in forward direction - if (currentStatus != STATUS_UTWP_TOLD) { - if (playMakeUTwp()) { - currentStatus = STATUS_UTWP_TOLD; - playGoAheadDist = 0; - } - } - - } - public void announceOffRoute(double dist) { long ms = System.currentTimeMillis(); if(waitAnnouncedOffRoute == 0 || ms - lastAnnouncedOffRoute > waitAnnouncedOffRoute) { @@ -682,7 +671,13 @@ public class VoiceRouter { player.clear(); } } - + + public void interruptRouteCommands() { + if (player != null){ + player.stop(); + } + } + /** * Command to wait until voice player is initialized */ diff --git a/OsmAnd/src/net/osmand/plus/views/TurnPathHelper.java b/OsmAnd/src/net/osmand/plus/views/TurnPathHelper.java index c12441d470..a64db6d620 100644 --- a/OsmAnd/src/net/osmand/plus/views/TurnPathHelper.java +++ b/OsmAnd/src/net/osmand/plus/views/TurnPathHelper.java @@ -140,16 +140,36 @@ public class TurnPathHelper { pathForTurn.rQuadTo(0, -(quadShiftY+th), -b * (quadShiftX+th), -(quadShiftY+th)); pathForTurn.rQuadTo(-b * (quadShiftX+th), 0, -b * (quadShiftX+th), (quadShiftY+th)); pathForTurn.rLineTo(0, sm); - + pathForTurn.rLineTo(-b * hpartArrowL, 0); pathForTurn.rLineTo(b * harrowL/2, harrowL/2); // center pathForTurn.rLineTo(b * harrowL/2, -harrowL/2); pathForTurn.rLineTo(-b *hpartArrowL, 0); - + pathForTurn.rLineTo(0, -sm); pathForTurn.rQuadTo(0, -quadShiftX, b *quadShiftX, -quadShiftY); pathForTurn.rQuadTo(b * quadShiftX, 0, b * quadShiftX, quadShiftY); pathForTurn.rLineTo(0, h); + } else if (TurnType.OFFR.equals(turnType.getValue())){ + int h = (int) (ha - hpartArrowL - 16); + pathForTurn.rMoveTo(th, 0); //12 0 + //first square + pathForTurn.rLineTo(0, -h / 4); //0 -7 + pathForTurn.rLineTo(-th, 0); //-12 0 + pathForTurn.rLineTo(0, h / 4); //0 7 + pathForTurn.rLineTo(th, 0); //12 0 + pathForTurn.rMoveTo(0, -h / 2); //12 0 + //second square + pathForTurn.rLineTo(0, -h / 4); //0 -7 + pathForTurn.rLineTo(-th, 0); //-12 0 + pathForTurn.rLineTo(0, h / 4); //0 7 + pathForTurn.rLineTo(th, 0); //12 0 + pathForTurn.rMoveTo(0, -h / 2 + 1); //31 0 + //arrow + pathForTurn.rLineTo(hpartArrowL, 0); //9 0 + pathForTurn.rLineTo(-harrowL / 2, -harrowL / 2); // center -15 -15 + pathForTurn.rLineTo(-harrowL / 2, harrowL / 2); // -15 15 + pathForTurn.rLineTo(hpartArrowL + th, 0); //9 0 } else if (turnType != null && turnType.isRoundAbout()) { float t = turnType.getTurnAngle(); if (t >= 170 && t < 220) { diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/NextTurnInfoWidget.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/NextTurnInfoWidget.java index 67b7a2b5ea..4141390e5e 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/NextTurnInfoWidget.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/NextTurnInfoWidget.java @@ -1,6 +1,7 @@ package net.osmand.plus.views.mapwidgets; import net.osmand.plus.OsmAndFormatter; +import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.views.MapInfoLayer; import net.osmand.plus.views.OsmandMapLayer.DrawSettings; @@ -22,6 +23,8 @@ public class NextTurnInfoWidget extends BaseMapWidget { private float height ; private static final float miniCoeff = 2.5f; + protected double deviatedPath = 0; + protected Path pathForTurn = new Path(); protected TurnType turnType = null; @@ -34,7 +37,7 @@ public class NextTurnInfoWidget extends BaseMapWidget { private Paint paintBlack; private Paint paintRouteDirection; - protected boolean makeUturnWhenPossible; + protected boolean deviatedFromRoute; protected int turnImminent; protected boolean horisontalMini; @@ -94,7 +97,10 @@ public class NextTurnInfoWidget extends BaseMapWidget { protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (pathForTurn != null) { - if (turnImminent > 0) { + //if user deviates from route that we should draw grey arrow + if (deviatedFromRoute){ + paintRouteDirection.setColor(getResources().getColor(R.color.nav_arrow_distant)); + } else if (turnImminent > 0) { paintRouteDirection.setColor(getResources().getColor(R.color.nav_arrow)); } else if (turnImminent == 0) { paintRouteDirection.setColor(getResources().getColor(R.color.nav_arrow_imminent)); @@ -105,15 +111,15 @@ public class NextTurnInfoWidget extends BaseMapWidget { canvas.translate(0, 3 * scaleCoefficient); canvas.drawPath(pathForTurn, paintRouteDirection); canvas.drawPath(pathForTurn, paintBlack); - if (exitOut != null && !horisontalMini && !makeUturnWhenPossible) { + if (exitOut != null && !horisontalMini && !deviatedFromRoute) { drawShadowText(canvas, exitOut, width / 2 - 7 * scaleCoefficient, height / 2 + textPaint.getTextSize() / 2 - 3 * scaleCoefficient, textPaint); } String text = OsmAndFormatter.getFormattedDistance(nextTurnDirection, getClientContext()); String subtext = null; - if (makeUturnWhenPossible) { - text = getResources().getString(R.string.asap); + if (deviatedFromRoute) { + text = OsmAndFormatter.getFormattedDistance((float) deviatedPath, (OsmandApplication)getContext().getApplicationContext()); } int ls = text.lastIndexOf(' '); diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/RouteInfoWidgetsFactory.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/RouteInfoWidgetsFactory.java index 5cf8d9fb5e..0d442e124f 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/RouteInfoWidgetsFactory.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/RouteInfoWidgetsFactory.java @@ -60,12 +60,13 @@ public class RouteInfoWidgetsFactory { boolean visible = false; boolean followingMode = routingHelper.isFollowingMode() || ctx.getLocationProvider().getLocationSimulation().isRouteAnimating(); if (routingHelper != null && routingHelper.isRouteCalculated() && followingMode) { - makeUturnWhenPossible = routingHelper.makeUturnWhenPossible() ; - if (makeUturnWhenPossible) { + deviatedFromRoute = routingHelper.isDeviatedFromRoute() ; + if (deviatedFromRoute) { visible = true; turnImminent = 0; - turnType = TurnType.valueOf(TurnType.TU, settings.DRIVING_REGION.get().leftHandDriving); + turnType = TurnType.valueOf(TurnType.OFFR, settings.DRIVING_REGION.get().leftHandDriving); TurnPathHelper.calcTurnPath(pathForTurn, turnType, pathTransform); + deviatedPath = routingHelper.getRouteDeviation(); invalidate(); } else { boolean showStraight = false; @@ -147,9 +148,9 @@ public class RouteInfoWidgetsFactory { boolean visible = false; boolean followingMode = routingHelper.isFollowingMode() || ctx.getLocationProvider().getLocationSimulation().isRouteAnimating(); if (routingHelper != null && routingHelper.isRouteCalculated() && followingMode) { - boolean uturnWhenPossible = routingHelper.makeUturnWhenPossible() ; + boolean devitedFromRoute = routingHelper.isDeviatedFromRoute() ; NextDirectionInfo r = routingHelper.getNextRouteDirectionInfo(calc1, true); - if (!uturnWhenPossible) { + if (!devitedFromRoute) { if (r != null) { // next turn is very close (show next next with false to speak) // if (r.imminent >= 0 && r.imminent < 2) { diff --git a/OsmAnd/src/net/osmand/plus/voice/CommandPlayer.java b/OsmAnd/src/net/osmand/plus/voice/CommandPlayer.java index 158a306ba6..814b317074 100644 --- a/OsmAnd/src/net/osmand/plus/voice/CommandPlayer.java +++ b/OsmAnd/src/net/osmand/plus/voice/CommandPlayer.java @@ -21,4 +21,6 @@ public interface CommandPlayer { public String getLanguage(); public boolean supportsStructuredStreetNames(); + + public void stop(); } diff --git a/OsmAnd/src/net/osmand/plus/voice/MediaCommandPlayerImpl.java b/OsmAnd/src/net/osmand/plus/voice/MediaCommandPlayerImpl.java index 089457c0c5..1b6ba08157 100644 --- a/OsmAnd/src/net/osmand/plus/voice/MediaCommandPlayerImpl.java +++ b/OsmAnd/src/net/osmand/plus/voice/MediaCommandPlayerImpl.java @@ -43,7 +43,17 @@ public class MediaCommandPlayerImpl extends AbstractPrologCommandPlayer implemen super.clear(); mediaPlayer = null; } - + + @Override + public void stop(){ + if (filesToPlay != null){ + filesToPlay.clear(); + } + if (mediaPlayer != null){ + mediaPlayer.stop(); + } + } + // Called from the calculating route thread. @Override public synchronized void playCommands(CommandBuilder builder) { diff --git a/OsmAnd/src/net/osmand/plus/voice/TTSCommandPlayerImpl.java b/OsmAnd/src/net/osmand/plus/voice/TTSCommandPlayerImpl.java index 06487b7fbe..98b5fd2d50 100644 --- a/OsmAnd/src/net/osmand/plus/voice/TTSCommandPlayerImpl.java +++ b/OsmAnd/src/net/osmand/plus/voice/TTSCommandPlayerImpl.java @@ -111,6 +111,13 @@ public class TTSCommandPlayerImpl extends AbstractPrologCommandPlayer { } } + @Override + public void stop(){ + if (mTts != null){ + mTts.stop(); + } + } + public void sendAlertToPebble(String message) { final Intent i = new Intent("com.getpebble.action.SEND_NOTIFICATION"); final Map data = new HashMap();