diff --git a/OsmAnd/src/net/osmand/plus/routing/data/AnnounceTimeDistances.java b/OsmAnd/src/net/osmand/plus/routing/data/AnnounceTimeDistances.java index 682a7d8430..bc00ae7833 100644 --- a/OsmAnd/src/net/osmand/plus/routing/data/AnnounceTimeDistances.java +++ b/OsmAnd/src/net/osmand/plus/routing/data/AnnounceTimeDistances.java @@ -21,8 +21,7 @@ public class AnnounceTimeDistances { public final static int STATE_SHORT_PNT_APPROACH = 6; public final static int STATE_LONG_PNT_APPROACH = 7; - - // Default speed to have comfortable announcements (Speed in m/s) + // Default speed to have comfortable announcements (m/s) // initial value is updated from default speed settings anyway private float DEFAULT_SPEED = 10; private double voicePromptDelayTimeSec = 0; @@ -45,32 +44,31 @@ public class AnnounceTimeDistances { public AnnounceTimeDistances(ApplicationMode appMode, OsmandSettings settings) { if (appMode.isDerivedRoutingFrom(ApplicationMode.CAR)) { - // keep it as minimum 30 kmh for voice announcement + // keep it as minimum 30 km/h for voice announcement DEFAULT_SPEED = (float) Math.max(8, appMode.getDefaultSpeed()); } else { // minimal is 1 meter for turn now DEFAULT_SPEED = (float) Math.max(0.3, appMode.getDefaultSpeed()); } - // Calculate minimal distance / time to announce turns, so time to turn is always >= ETALON_TIME - // Distance < ETALON_DIST or TIME_WITH_CURRENT_SPEED < ETALON_TIME_DEFAULT_SPEED - // 300 sec: 4 200 - 3 500 m - car [ 115 - 95 sec @ 120 km/h] + // 300 s: car 3750 m (113 s @ 120 km/h) PREPARE_LONG_DISTANCE = (int) (DEFAULT_SPEED * 300); - PREPARE_LONG_DISTANCE_END = (int) (DEFAULT_SPEED * 250) ; + // 250 s: car 3125 m (94 s @ 120 km/h) + PREPARE_LONG_DISTANCE_END = (int) (DEFAULT_SPEED * 250); if (DEFAULT_SPEED < 30) { // Play only for high speed vehicle with speed > 110 km/h // [issue 1411] - used only for goAhead prompt PREPARE_LONG_DISTANCE_END = PREPARE_LONG_DISTANCE * 2; } - // 115 sec: 1 500 m - car [45 sec @ 120 km/h], 320 m - bicycle [45 sec @ 25 km/h], 230 m - pedestrian + // 115 s: car 1438 m (45 s @ 120 km/h), bicycle 319 m (46 s @ 25 km/h), pedestrian 128 m PREPARE_DISTANCE = (int) (DEFAULT_SPEED * 115); - // 90 sec: 1 200 m - car, 250 m - bicycle [36 sec @ 25 km/h], + // 90 s: car 1136 m, bicycle 250 m (36 s @ 25 km/h) PREPARE_DISTANCE_END = (int) (DEFAULT_SPEED * 90); - // 22 sec: 310 m - car, 60 m - bicycle, 50m - pedestrian + // 22 s: car 275 m, bicycle 61 m, pedestrian 24 m TURN_IN_DISTANCE = (int) (DEFAULT_SPEED * 22); - // 15 sec: 210 m - car, 40 m - bicycle, 30 m - pedestrian + // 15 s: car 189 m, bicycle 42 m, pedestrian 17 m TURN_IN_DISTANCE_END = (int) (DEFAULT_SPEED * 15); // Do not play prepare: for pedestrian and slow transport @@ -80,30 +78,29 @@ public class AnnounceTimeDistances { PREPARE_DISTANCE_END = PREPARE_DISTANCE * 2; } - // Turn now: 3.5 sec normal speed, 7 second for halfspeed (default) - // float TURN_NOW_TIME = 7; - - // ** #8749 to keep 1m / 1 sec precision (POSITIONING_TOLERANCE = 12 m) - // 1 kmh - 1 sec, 4 kmh - 2 sec (pedestrian), 10 kmh - 3 sec (*bicycle), 50 kmh - 7 sec (car) - float TURN_NOW_TIME = (float) Math.min(Math.sqrt(DEFAULT_SPEED * 3.6), 8); - float ARRIVAL_DISTANCE_FACTOR = Math.max(settings.ARRIVAL_DISTANCE_FACTOR.getModeValue(appMode), 0.1f); - // TURN_NOW_DISTANCE = (int) (DEFAULT_SPEED * 3.6); // 3.6 sec - // 50 kmh - 48 m (car), 10 kmh - 20 m, 4 kmh - 15 m, 1 kmh - 12 m - // 3.6 sec: 43 m (car), 18 m (bicycle), 12 m (walking, capped by POSITIONING_TOLERANCE) + // Turn now: 3.5 s normal speed, 7 s for half speed (default) + // float TURN_NOW_TIME = 7; + // ** #8749 to keep 1m / 1 sec precision (POSITIONING_TOLERANCE = 12 m) + // car 50 km/h - 7 s, bicycle 10 km/h - 3 s, pedestrian 4 km/h - 2 s, 1 km/h - 1 s + float TURN_NOW_TIME = (float) Math.min(Math.sqrt(DEFAULT_SPEED * 3.6), 8); + + // 3.6 s: car 45 m, bicycle 10 m -> 12 m, pedestrian 4 m -> 12 m (capped by POSITIONING_TOLERANCE) TURN_NOW_DISTANCE = (int) (Math.max(POSITIONING_TOLERANCE, DEFAULT_SPEED * 3.6) * ARRIVAL_DISTANCE_FACTOR); TURN_NOW_SPEED = TURN_NOW_DISTANCE / TURN_NOW_TIME; - // 5 sec: 60 m (car), 25 m (bicycle), 12 m (walking) + // 5 s: car 63 m, bicycle 14 m, pedestrian 6 m -> 12 m (capped by POSITIONING_TOLERANCE) ARRIVAL_DISTANCE = (int) (Math.max(POSITIONING_TOLERANCE, DEFAULT_SPEED * 5.) * ARRIVAL_DISTANCE_FACTOR); - // 50 kmh - 280 m, 10 kmh - 55 m, 4 kmh - 22 m + + // 20 s: car 250 m, bicycle 56 m, pedestrian 22 m OFF_ROUTE_DISTANCE = DEFAULT_SPEED * 20 * ARRIVAL_DISTANCE_FACTOR; // 20 seconds + // assume for backward compatibility speed - 10 m/s - LONG_PNT_ANNOUNCE_RADIUS = (int) (60 * DEFAULT_SPEED * ARRIVAL_DISTANCE_FACTOR); // 700m - SHORT_PNT_ANNOUNCE_RADIUS = (int) (15 * DEFAULT_SPEED * ARRIVAL_DISTANCE_FACTOR); // 150m - LONG_ALARM_ANNOUNCE_RADIUS = (int) (12 * DEFAULT_SPEED * ARRIVAL_DISTANCE_FACTOR); // 150m - SHORT_ALARM_ANNOUNCE_RADIUS = (int) (7 * DEFAULT_SPEED * ARRIVAL_DISTANCE_FACTOR); // 100m + SHORT_ALARM_ANNOUNCE_RADIUS = (int) (7 * DEFAULT_SPEED * ARRIVAL_DISTANCE_FACTOR); // 70 m + LONG_ALARM_ANNOUNCE_RADIUS = (int) (12 * DEFAULT_SPEED * ARRIVAL_DISTANCE_FACTOR); // 120 m + SHORT_PNT_ANNOUNCE_RADIUS = (int) (15 * DEFAULT_SPEED * ARRIVAL_DISTANCE_FACTOR); // 150 m + LONG_PNT_ANNOUNCE_RADIUS = (int) (60 * DEFAULT_SPEED * ARRIVAL_DISTANCE_FACTOR); // 600 m // Trigger close prompts earlier to allow BT SCO link being established, or when VOICE_PROMPT_DELAY is set >0 for the other stream types int ams = settings.AUDIO_MANAGER_STREAM.getModeValue(appMode); @@ -128,22 +125,22 @@ public class AnnounceTimeDistances { public boolean isTurnStateActive(float currentSpeed, double dist, int turnType) { switch (turnType) { + case STATE_TURN_NOW: + return isDistanceLess(currentSpeed, dist, TURN_NOW_DISTANCE, TURN_NOW_SPEED); case STATE_TURN_IN: return isDistanceLess(currentSpeed, dist, TURN_IN_DISTANCE); case STATE_PREPARE_TURN: return isDistanceLess(currentSpeed, dist, PREPARE_DISTANCE); case STATE_LONG_PREPARE_TURN: return isDistanceLess(currentSpeed, dist, PREPARE_LONG_DISTANCE); - case STATE_TURN_NOW: - return isDistanceLess(currentSpeed, dist, TURN_NOW_DISTANCE, TURN_NOW_SPEED); - case STATE_LONG_PNT_APPROACH: - return isDistanceLess(currentSpeed, dist, LONG_PNT_ANNOUNCE_RADIUS); - case STATE_SHORT_PNT_APPROACH: - return isDistanceLess(currentSpeed, dist, SHORT_PNT_ANNOUNCE_RADIUS); - case STATE_LONG_ALARM_ANNOUNCE: - return isDistanceLess(currentSpeed, dist, LONG_ALARM_ANNOUNCE_RADIUS); case STATE_SHORT_ALARM_ANNOUNCE: return isDistanceLess(currentSpeed, dist, SHORT_ALARM_ANNOUNCE_RADIUS); + case STATE_LONG_ALARM_ANNOUNCE: + return isDistanceLess(currentSpeed, dist, LONG_ALARM_ANNOUNCE_RADIUS); + case STATE_SHORT_PNT_APPROACH: + return isDistanceLess(currentSpeed, dist, SHORT_PNT_ANNOUNCE_RADIUS); + case STATE_LONG_PNT_APPROACH: + return isDistanceLess(currentSpeed, dist, LONG_PNT_ANNOUNCE_RADIUS); } return false; } @@ -169,9 +166,12 @@ public class AnnounceTimeDistances { } private boolean isDistanceLess(float currentSpeed, double dist, double etalon, float defSpeed) { + // Check triggers: + // (1) distance < etalon? if (dist - voicePromptDelayTimeSec * currentSpeed <= etalon) { return true; } + // (2) time_with_current_speed < etalon_time_with_default_speed? // check only if speed > 0 if (currentSpeed > 0 && (dist / currentSpeed - voicePromptDelayTimeSec) <= etalon / defSpeed) { return true; @@ -223,14 +223,14 @@ public class AnnounceTimeDistances { if (PREPARE_LONG_DISTANCE_END <= PREPARE_LONG_DISTANCE) { appendTurnDesc(turnDescriptions, "Turn (early prepare)", PREPARE_LONG_DISTANCE); } - appendTurnDesc(turnDescriptions, "Finish", (int) getArrivalDistance()); + appendTurnDesc(turnDescriptions, "Arrival", (int) getArrivalDistance()); if (getOffRouteDistance() > 0) { appendTurnDesc(turnDescriptions, "Off-route", (int) getOffRouteDistance()); } - appendTurnDesc(turnDescriptions, "Alarm (now)", SHORT_ALARM_ANNOUNCE_RADIUS); - appendTurnDesc(turnDescriptions, "Alarm (prepare)", LONG_ALARM_ANNOUNCE_RADIUS); - appendTurnDesc(turnDescriptions, "POI/Waypoint (now)", SHORT_PNT_ANNOUNCE_RADIUS); - appendTurnDesc(turnDescriptions, "POI/Waypoint (prepare)", LONG_PNT_ANNOUNCE_RADIUS); + appendTurnDesc(turnDescriptions, "Alarm (close)", SHORT_ALARM_ANNOUNCE_RADIUS); + appendTurnDesc(turnDescriptions, "Alarm (standard)", LONG_ALARM_ANNOUNCE_RADIUS); + appendTurnDesc(turnDescriptions, "Waypoint / fav / POI (passing)", SHORT_PNT_ANNOUNCE_RADIUS); + appendTurnDesc(turnDescriptions, "Waypoint / fav / POI (approaching)", LONG_PNT_ANNOUNCE_RADIUS); return turnDescriptions.toString(); } }