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.

This commit is contained in:
Denis 2014-07-17 12:48:59 +04:00
parent a7775d221f
commit e2e4d234aa
9 changed files with 99 additions and 46 deletions

View file

@ -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();
}

View file

@ -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<LatLon> 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<Location> 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;
}
/**

View file

@ -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
*/

View file

@ -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) {

View file

@ -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(' ');

View file

@ -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) {

View file

@ -21,4 +21,6 @@ public interface CommandPlayer {
public String getLanguage();
public boolean supportsStructuredStreetNames();
public void stop();
}

View file

@ -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) {

View file

@ -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<String, Object> data = new HashMap<String, Object>();