Fix voice router. Consider speed, be more accurate
This commit is contained in:
parent
f07e297cdf
commit
f77b3869af
3 changed files with 206 additions and 131 deletions
|
@ -321,7 +321,7 @@ public class RoutingHelper {
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
voiceRouter.updateStatus();
|
voiceRouter.updateStatus(currentLocation);
|
||||||
|
|
||||||
lastFixedLocation = currentLocation;
|
lastFixedLocation = currentLocation;
|
||||||
if(calculateRoute){
|
if(calculateRoute){
|
||||||
|
|
|
@ -226,10 +226,10 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
|
||||||
}
|
}
|
||||||
registerListPreference(osmandSettings.MAX_LEVEL_TO_DOWNLOAD_TILE, screen, entries, intValues);
|
registerListPreference(osmandSettings.MAX_LEVEL_TO_DOWNLOAD_TILE, screen, entries, intValues);
|
||||||
|
|
||||||
Float[] floatValues = new Float[] {0.3f, 0.5f, 0.7f, 0.8f, 1.0f, 1.2f, 1.3f, 1.5f, 2.0f, 2.5f};
|
Float[] floatValues = new Float[] {0.6f, 0.8f, 1.0f, 1.2f, 1.5f};
|
||||||
entries = new String[floatValues.length];
|
entries = new String[floatValues.length];
|
||||||
for (int i = 0; i < floatValues.length; i++) {
|
for (int i = 0; i < floatValues.length; i++) {
|
||||||
entries[i] = floatValues[i] +"";
|
entries[i] = (int) (floatValues[i] * 100) +" %";
|
||||||
}
|
}
|
||||||
registerListPreference(osmandSettings.MAP_TEXT_SIZE, screen, entries, floatValues);
|
registerListPreference(osmandSettings.MAP_TEXT_SIZE, screen, entries, floatValues);
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import net.osmand.plus.voice.AbstractPrologCommandPlayer;
|
||||||
import net.osmand.plus.voice.CommandBuilder;
|
import net.osmand.plus.voice.CommandBuilder;
|
||||||
import net.osmand.plus.voice.CommandPlayer;
|
import net.osmand.plus.voice.CommandPlayer;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.location.Location;
|
||||||
|
|
||||||
|
|
||||||
public class VoiceRouter {
|
public class VoiceRouter {
|
||||||
|
@ -25,6 +26,19 @@ public class VoiceRouter {
|
||||||
|
|
||||||
private int currentStatus = STATUS_UNKNOWN;
|
private int currentStatus = STATUS_UNKNOWN;
|
||||||
|
|
||||||
|
// default speed to have comfortable announcements (if actual speed is higher than it would be problem)
|
||||||
|
// Speed in m/s
|
||||||
|
protected float DEFAULT_SPEED = 12;
|
||||||
|
|
||||||
|
protected int PREPARE_LONG_DISTANCE_ST = 2500;
|
||||||
|
protected int PREPARE_LONG_DISTANCE_END = 3200;
|
||||||
|
|
||||||
|
protected int PREPARE_DISTANCE = 0;
|
||||||
|
protected int PREPARE_DISTANCE_END = 0;
|
||||||
|
protected int TURN_IN_DISTANCE = 0;
|
||||||
|
protected int TURN_IN_DISTANCE_END = 0;
|
||||||
|
protected int TURN_DISTANCE = 0;
|
||||||
|
|
||||||
|
|
||||||
public VoiceRouter(RoutingHelper router, CommandPlayer player) {
|
public VoiceRouter(RoutingHelper router, CommandPlayer player) {
|
||||||
this.router = router;
|
this.router = router;
|
||||||
|
@ -53,42 +67,89 @@ public class VoiceRouter {
|
||||||
return player.newCommandBuilder();
|
return player.newCommandBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int PREPARE_LONG_DISTANCE_ST = 2500;
|
|
||||||
protected int PREPARE_LONG_DISTANCE_END = 3000;
|
|
||||||
|
|
||||||
protected int PREPARE_DISTANCE = 0;
|
|
||||||
protected int TURN_IN_DISTANCE = 0;
|
|
||||||
protected int TURN_DISTANCE = 0;
|
|
||||||
|
|
||||||
public void updateAppMode(){
|
public void updateAppMode(){
|
||||||
|
// Else consider default time
|
||||||
if(router.getAppMode() == ApplicationMode.PEDESTRIAN){
|
if(router.getAppMode() == ApplicationMode.PEDESTRIAN){
|
||||||
PREPARE_DISTANCE = 400;
|
// prepare distance needed ?
|
||||||
TURN_IN_DISTANCE = 150;
|
PREPARE_DISTANCE = 320; // 160 second
|
||||||
TURN_DISTANCE = 30;
|
PREPARE_DISTANCE_END = 200; // 75 second
|
||||||
|
TURN_IN_DISTANCE = 100; // 50 seconds
|
||||||
|
TURN_IN_DISTANCE_END = 70; // 35 seconds
|
||||||
|
TURN_DISTANCE = 25; // 12 seconds
|
||||||
|
DEFAULT_SPEED = 2f;
|
||||||
} else if(router.getAppMode() == ApplicationMode.BICYCLE){
|
} else if(router.getAppMode() == ApplicationMode.BICYCLE){
|
||||||
PREPARE_DISTANCE = 550;
|
PREPARE_DISTANCE = 530; // 100 seconds
|
||||||
TURN_IN_DISTANCE = 200;
|
PREPARE_DISTANCE_END = 370; // 70 seconds
|
||||||
TURN_DISTANCE = 55;
|
TURN_IN_DISTANCE = 230; // 40 seconds
|
||||||
|
TURN_IN_DISTANCE_END = 90; // 16 seconds
|
||||||
|
TURN_DISTANCE = 55; // 11 seconds
|
||||||
|
DEFAULT_SPEED = 5;
|
||||||
} else {
|
} else {
|
||||||
PREPARE_DISTANCE = 800;
|
PREPARE_DISTANCE = 730; // 60 seconds
|
||||||
TURN_IN_DISTANCE = 300;
|
PREPARE_DISTANCE_END = 530; // 45 seconds
|
||||||
TURN_DISTANCE = 70;
|
TURN_IN_DISTANCE = 330; // 25 seconds
|
||||||
|
TURN_IN_DISTANCE_END = 160; // 14 seconds
|
||||||
|
TURN_DISTANCE = 75; // 6 seconds
|
||||||
|
DEFAULT_SPEED = 12;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private boolean isDistanceLess(float currentSpeed, double dist, double etalon){
|
||||||
|
if(dist < etalon || (dist / currentSpeed < etalon / DEFAULT_SPEED)){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
protected void updateStatus(){
|
|
||||||
|
private void nextStatusAfter(int previousStatus){
|
||||||
|
// if(previousStatus == STATUS_TURN){
|
||||||
|
// this.currentStatus = STATUS_TOLD;
|
||||||
|
// } else if(previousStatus == STATUS_200_TURN){
|
||||||
|
// this.currentStatus = STATUS_TURN;
|
||||||
|
// } else if(previousStatus == STATUS_800_PREPARE){
|
||||||
|
// this.currentStatus = STATUS_200_TURN;
|
||||||
|
// } else if(previousStatus == STATUS_3000_PREPARE){
|
||||||
|
// this.currentStatus = STATUS_800_PREPARE;
|
||||||
|
// } else
|
||||||
|
if(previousStatus != STATUS_TOLD){
|
||||||
|
this.currentStatus = previousStatus ++;
|
||||||
|
} else {
|
||||||
|
this.currentStatus = previousStatus;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean statusNotPassed(int statusToCheck){
|
||||||
|
return currentStatus <= statusToCheck;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates status of voice guidance
|
||||||
|
* @param currentLocation
|
||||||
|
*/
|
||||||
|
protected void updateStatus(Location currentLocation){
|
||||||
// directly after turn (go - ahead dist)
|
// directly after turn (go - ahead dist)
|
||||||
// < 800m prepare
|
// < 800m prepare
|
||||||
// < 200m turn in
|
// < 200m turn in
|
||||||
// < 50m turn
|
// < 50m turn
|
||||||
|
float speed = DEFAULT_SPEED;
|
||||||
|
if(currentLocation != null && currentLocation.hasSpeed()){
|
||||||
|
speed = Math.max(currentLocation.getSpeed(), speed);
|
||||||
|
}
|
||||||
|
RouteDirectionInfo next = router.getNextRouteDirectionInfo();
|
||||||
|
int dist = router.getDistanceToNextRouteDirection();
|
||||||
|
|
||||||
|
// if routing is changed update status to unknown
|
||||||
if(currentDirection != router.currentDirectionInfo){
|
if(currentDirection != router.currentDirectionInfo){
|
||||||
currentDirection = router.currentDirectionInfo;
|
currentDirection = router.currentDirectionInfo;
|
||||||
currentStatus = STATUS_UNKNOWN;
|
currentStatus = STATUS_UNKNOWN;
|
||||||
}
|
}
|
||||||
RouteDirectionInfo next = router.getNextRouteDirectionInfo();
|
|
||||||
int dist = router.getDistanceToNextRouteDirection();
|
|
||||||
|
// the last turn say
|
||||||
if(next == null || next.distance == 0) {
|
if(next == null || next.distance == 0) {
|
||||||
if(currentStatus == STATUS_UNKNOWN && currentDirection > 0){
|
if(currentStatus == STATUS_UNKNOWN && currentDirection > 0){
|
||||||
CommandBuilder play = getNewCommandPlayerToPlay();
|
CommandBuilder play = getNewCommandPlayerToPlay();
|
||||||
|
@ -99,29 +160,111 @@ public class VoiceRouter {
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(dist == 0){
|
if(dist == 0 || currentStatus == STATUS_TOLD){
|
||||||
// nothing said possibly that's wrong case we should say before that
|
// nothing said possibly that's wrong case we should say before that
|
||||||
// however it should be checked manually !?
|
// however it should be checked manually ?
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RouteDirectionInfo nextNext = router.getNextNextRouteDirectionInfo();
|
|
||||||
|
|
||||||
if(currentStatus == STATUS_UNKNOWN){
|
RouteDirectionInfo nextNext = router.getNextNextRouteDirectionInfo();
|
||||||
if(dist > PREPARE_DISTANCE){
|
if(statusNotPassed(STATUS_TURN) && isDistanceLess(speed, dist, TURN_DISTANCE)){
|
||||||
|
if(isDistanceLess(speed, next.distance, TURN_DISTANCE) || next.distance < TURN_IN_DISTANCE_END) {
|
||||||
|
playMakeTurnRightNow(next, nextNext);
|
||||||
|
} else {
|
||||||
|
playMakeTurnRightNow(next, null);
|
||||||
|
}
|
||||||
|
nextStatusAfter(STATUS_TURN);
|
||||||
|
} else if(statusNotPassed(STATUS_200_TURN) && isDistanceLess(speed, dist, TURN_IN_DISTANCE)){
|
||||||
|
if (dist >= TURN_IN_DISTANCE_END) {
|
||||||
|
if(isDistanceLess(speed, next.distance, TURN_DISTANCE) || next.distance < TURN_IN_DISTANCE_END) {
|
||||||
|
playMakeTurnInShortDistance(next, dist, nextNext);
|
||||||
|
} else {
|
||||||
|
playMakeTurnInShortDistance(next, dist, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nextStatusAfter(STATUS_200_TURN);
|
||||||
|
} else if (statusNotPassed(STATUS_800_PREPARE) && isDistanceLess(speed, dist, PREPARE_DISTANCE)) {
|
||||||
|
if (dist >= PREPARE_DISTANCE_END) {
|
||||||
|
playPrepareLongDistanceTurn(next, dist);
|
||||||
|
}
|
||||||
|
nextStatusAfter(STATUS_800_PREPARE);
|
||||||
|
} else if(statusNotPassed(STATUS_UNKNOWN)){
|
||||||
|
if (dist >= PREPARE_DISTANCE * 1.3f) {
|
||||||
|
playGoAhead(dist);
|
||||||
|
}
|
||||||
|
if (dist >= PREPARE_LONG_DISTANCE_END * 1.5f) {
|
||||||
|
nextStatusAfter(STATUS_UNKNOWN);
|
||||||
|
} else {
|
||||||
|
nextStatusAfter(STATUS_3000_PREPARE);
|
||||||
|
}
|
||||||
|
} else if(statusNotPassed(STATUS_3000_PREPARE) && isDistanceLess(speed, dist, PREPARE_LONG_DISTANCE_END)){
|
||||||
|
if (dist >= PREPARE_LONG_DISTANCE_ST) {
|
||||||
|
playPrepareLongDistanceTurn(next, dist);
|
||||||
|
}
|
||||||
|
nextStatusAfter(STATUS_3000_PREPARE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void playGoAhead(int dist) {
|
||||||
CommandBuilder play = getNewCommandPlayerToPlay();
|
CommandBuilder play = getNewCommandPlayerToPlay();
|
||||||
if(play != null){
|
if(play != null){
|
||||||
play.goAhead(dist).play();
|
play.goAhead(dist).play();
|
||||||
}
|
}
|
||||||
currentStatus = STATUS_3000_PREPARE;
|
}
|
||||||
} else if (dist < TURN_IN_DISTANCE){
|
|
||||||
// should already told it
|
private void playPrepareLongDistanceTurn(RouteDirectionInfo next, int dist) {
|
||||||
currentStatus = STATUS_TURN;
|
CommandBuilder play = getNewCommandPlayerToPlay();
|
||||||
|
if(play != null){
|
||||||
|
String tParam = getTurnType(next.turnType);
|
||||||
|
if(tParam != null){
|
||||||
|
play.prepareTurn(tParam, dist).play();
|
||||||
|
} else if(next.turnType.isRoundAbout()){
|
||||||
|
play.prepareRoundAbout(dist).play();
|
||||||
|
} else if(next.turnType.getValue().equals(TurnType.TU)){
|
||||||
|
play.prepareMakeUT(dist).play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void playMakeTurnInShortDistance(RouteDirectionInfo next, int dist, RouteDirectionInfo pronounceNextNext) {
|
||||||
|
CommandBuilder play = getNewCommandPlayerToPlay();
|
||||||
|
if (play != null) {
|
||||||
|
String tParam = getTurnType(next.turnType);
|
||||||
|
boolean isPlay = true;
|
||||||
|
if (tParam != null) {
|
||||||
|
play.turn(tParam, dist);
|
||||||
|
} else if (next.turnType.isRoundAbout()) {
|
||||||
|
play.roundAbout(dist, next.turnType.getTurnAngle(), next.turnType.getExitOut());
|
||||||
|
} else if (next.turnType.getValue().equals(TurnType.TU)) {
|
||||||
|
play.makeUT(dist);
|
||||||
|
} else {
|
||||||
|
isPlay = false;
|
||||||
|
}
|
||||||
|
// small preparation to next after next
|
||||||
|
if (pronounceNextNext != null) {
|
||||||
|
TurnType t = pronounceNextNext.turnType;
|
||||||
|
isPlay = true;
|
||||||
|
if (next.turnType.getValue().equals(TurnType.C) &&
|
||||||
|
!TurnType.C.equals(t.getValue())) {
|
||||||
|
play.goAhead(dist);
|
||||||
|
}
|
||||||
|
if (TurnType.TL.equals(t.getValue()) || TurnType.TSHL.equals(t.getValue()) || TurnType.TSLL.equals(t.getValue())
|
||||||
|
|| TurnType.TU.equals(t.getValue())) {
|
||||||
|
play.then().bearLeft();
|
||||||
|
} else if (TurnType.TR.equals(t.getValue()) || TurnType.TSHR.equals(t.getValue()) || TurnType.TSLR.equals(t.getValue())) {
|
||||||
|
play.then().bearRight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(isPlay){
|
||||||
|
play.play();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(currentStatus <= STATUS_TURN && dist <= TURN_DISTANCE){
|
|
||||||
|
private void playMakeTurnRightNow(RouteDirectionInfo next, RouteDirectionInfo nextNext) {
|
||||||
CommandBuilder play = getNewCommandPlayerToPlay();
|
CommandBuilder play = getNewCommandPlayerToPlay();
|
||||||
if(play != null){
|
if(play != null){
|
||||||
String tParam = getTurnType(next.turnType);
|
String tParam = getTurnType(next.turnType);
|
||||||
|
@ -138,8 +281,8 @@ public class VoiceRouter {
|
||||||
} else {
|
} else {
|
||||||
isplay = false;
|
isplay = false;
|
||||||
}
|
}
|
||||||
|
// add turn after next
|
||||||
if (nextNext != null && next.distance <= TURN_IN_DISTANCE) {
|
if (nextNext != null) {
|
||||||
String t2Param = getTurnType(nextNext.turnType);
|
String t2Param = getTurnType(nextNext.turnType);
|
||||||
if (t2Param != null) {
|
if (t2Param != null) {
|
||||||
if(isplay) { play.then(); }
|
if(isplay) { play.then(); }
|
||||||
|
@ -157,74 +300,6 @@ public class VoiceRouter {
|
||||||
play.play();
|
play.play();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
currentStatus = STATUS_TOLD;
|
|
||||||
} else if(currentStatus <= STATUS_200_TURN && dist <= TURN_IN_DISTANCE){
|
|
||||||
CommandBuilder play = getNewCommandPlayerToPlay();
|
|
||||||
if (play != null) {
|
|
||||||
String tParam = getTurnType(next.turnType);
|
|
||||||
boolean isPlay = true;
|
|
||||||
if (tParam != null) {
|
|
||||||
play.turn(tParam, dist);
|
|
||||||
} else if (next.turnType.isRoundAbout()) {
|
|
||||||
play.roundAbout(dist, next.turnType.getTurnAngle(), next.turnType.getExitOut());
|
|
||||||
} else if (next.turnType.getValue().equals(TurnType.TU)) {
|
|
||||||
play.makeUT(dist);
|
|
||||||
} else {
|
|
||||||
isPlay = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nextNext != null && next.distance <= TURN_DISTANCE) {
|
|
||||||
TurnType t = nextNext.turnType;
|
|
||||||
isPlay = true;
|
|
||||||
if (next.turnType.getValue().equals(TurnType.C) &&
|
|
||||||
!TurnType.C.equals(t.getValue())) {
|
|
||||||
play.goAhead(dist);
|
|
||||||
}
|
|
||||||
if (TurnType.TL.equals(t.getValue()) || TurnType.TSHL.equals(t.getValue()) || TurnType.TSLL.equals(t.getValue())
|
|
||||||
|| TurnType.TU.equals(t.getValue())) {
|
|
||||||
play.then().bearLeft();
|
|
||||||
} else if (TurnType.TR.equals(t.getValue()) || TurnType.TSHR.equals(t.getValue()) || TurnType.TSLR.equals(t.getValue())) {
|
|
||||||
play.then().bearRight();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(isPlay){
|
|
||||||
play.play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
currentStatus = STATUS_TURN;
|
|
||||||
} else if(currentStatus <= STATUS_800_PREPARE && dist <= PREPARE_DISTANCE){
|
|
||||||
CommandBuilder play = getNewCommandPlayerToPlay();
|
|
||||||
if(play != null){
|
|
||||||
String tParam = getTurnType(next.turnType);
|
|
||||||
if(tParam != null){
|
|
||||||
play.prepareTurn(tParam, dist).play();
|
|
||||||
} else if(next.turnType.isRoundAbout()){
|
|
||||||
play.prepareRoundAbout(dist).play();
|
|
||||||
} else if(next.turnType.getValue().equals(TurnType.TU)){
|
|
||||||
play.prepareMakeUT(dist).play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
currentStatus = STATUS_200_TURN;
|
|
||||||
} else if((currentStatus <= STATUS_800_PREPARE && dist <= PREPARE_DISTANCE)
|
|
||||||
|| (currentStatus <= STATUS_3000_PREPARE && dist <= PREPARE_LONG_DISTANCE_END && dist >= PREPARE_LONG_DISTANCE_ST)){
|
|
||||||
CommandBuilder play = getNewCommandPlayerToPlay();
|
|
||||||
if(play != null){
|
|
||||||
String tParam = getTurnType(next.turnType);
|
|
||||||
if(tParam != null){
|
|
||||||
play.prepareTurn(tParam, dist).play();
|
|
||||||
} else if(next.turnType.isRoundAbout()){
|
|
||||||
play.prepareRoundAbout(dist).play();
|
|
||||||
} else if(next.turnType.getValue().equals(TurnType.TU)){
|
|
||||||
play.prepareMakeUT(dist).play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
currentStatus = currentStatus <= STATUS_3000_PREPARE ? STATUS_800_PREPARE : STATUS_200_TURN;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getTurnType(TurnType t){
|
private String getTurnType(TurnType t){
|
||||||
|
|
Loading…
Reference in a new issue