From 68c5662526d578612f0aacfedbf2b151e9ea2db7 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Mon, 12 Jul 2010 22:31:21 +0000 Subject: [PATCH] implement voice navigation git-svn-id: https://osmand.googlecode.com/svn/trunk@321 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8 --- .../activities/ShowRouteInfoActivity.java | 23 +- .../src/com/osmand/voice/CommandPlayer.java | 254 ++++++++++++------ OsmAnd/voice/_config.p | 92 +++++++ 3 files changed, 291 insertions(+), 78 deletions(-) create mode 100644 OsmAnd/voice/_config.p diff --git a/OsmAnd/src/com/osmand/activities/ShowRouteInfoActivity.java b/OsmAnd/src/com/osmand/activities/ShowRouteInfoActivity.java index c69251beaf..a07b6d8fab 100644 --- a/OsmAnd/src/com/osmand/activities/ShowRouteInfoActivity.java +++ b/OsmAnd/src/com/osmand/activities/ShowRouteInfoActivity.java @@ -35,6 +35,7 @@ import com.osmand.activities.RoutingHelper.TurnType; import com.osmand.osm.MapUtils; import com.osmand.views.MapInfoLayer; import com.osmand.voice.CommandPlayer; +import com.osmand.voice.CommandPlayer.CommandBuilder; /** * @@ -65,8 +66,26 @@ public class ShowRouteInfoActivity extends ListActivity { Location loc = inst.getLocationFromRouteDirection(item); CommandPlayer player = CommandPlayer.getInstance(this); if(player != null){ - // TODO temp solution - player.newCommandBuilder().prepareTurnLeft(300).play(); + // TODO temp solution roundabout + CommandBuilder builder = player.newCommandBuilder(); + if(item.turnType.getValue() == TurnType.C){ + builder.goAhead(item.distance); + } else if(item.turnType.getValue() == TurnType.TU){ + builder.makeUT(item.distance); + } else if(item.turnType.getValue() == TurnType.TL){ + builder.turnLeft(item.distance); + } else if(item.turnType.getValue() == TurnType.TSLL) { + builder.turnSLLeft(item.distance); + } else if(item.turnType.getValue() == TurnType.TSHL) { + builder.turnSHLeft(item.distance); + } else if(item.turnType.getValue() == TurnType.TR){ + builder.turnRight(item.distance); + } else if(item.turnType.getValue() == TurnType.TSLR) { + builder.turnSLRight(item.distance); + } else if(item.turnType.getValue() == TurnType.TSHR) { + builder.turnSHRight(item.distance); + } + builder.play(); } if(loc != null){ OsmandSettings.setMapLocationToShow(this, loc.getLatitude(),loc.getLongitude()); diff --git a/OsmAnd/src/com/osmand/voice/CommandPlayer.java b/OsmAnd/src/com/osmand/voice/CommandPlayer.java index 1b63d27bcf..04b74f4c9d 100644 --- a/OsmAnd/src/com/osmand/voice/CommandPlayer.java +++ b/OsmAnd/src/com/osmand/voice/CommandPlayer.java @@ -155,82 +155,6 @@ public class CommandPlayer { return new CommandBuilder(); } - protected static final String P_VERSION = "version"; //$NON-NLS-1$ - protected static final String P_RESOLVE = "resolve"; //$NON-NLS-1$ - - protected static final String С_PREPARE_TURN_LEFT = "prepare_turn_left"; //$NON-NLS-1$ - protected static final String С_PREPARE_TURN_RIGHT = "prepare_turn_right"; //$NON-NLS-1$ - protected static final String С_PREAMBLE = "preamble"; //$NON-NLS-1$ - - protected static final String DELAY_CONST = "delay_"; //$NON-NLS-1$ - - public class CommandBuilder { - - - private boolean alreadyExecuted = false; - private List listStruct = new ArrayList(); - - public CommandBuilder(){ - this(true); - } - - public CommandBuilder(boolean preamble) { - if (preamble) { - addCommand(С_PREAMBLE); - } - } - - private void checkState(){ - if(alreadyExecuted){ - throw new IllegalArgumentException(); - } - } - - private CommandBuilder addCommand(String name, Object... args){ - checkState(); - Term[] list = new Term[args.length]; - for (int i = 0; i < args.length; i++) { - Object o = args[i]; - if(o instanceof java.lang.Number){ - if(o instanceof java.lang.Double){ - list[i] = new alice.tuprolog.Double((Double) o); - } else if(o instanceof java.lang.Float){ - list[i] = new alice.tuprolog.Float((Float) o); - } else if(o instanceof java.lang.Long){ - list[i] = new alice.tuprolog.Long((Long) o); - } else { - list[i] = new alice.tuprolog.Int(((java.lang.Number)o).intValue()); - } - } else if(o instanceof String){ - list[i] = new Struct((String) o); - } - if(list[i]== null){ - throw new NullPointerException(name +" " + o); //$NON-NLS-1$ - } - } - Struct struct = new Struct(name, list); - listStruct.add(struct); - return this; - } - - public CommandBuilder prepareTurnLeft(double dist){ - return addCommand(С_PREPARE_TURN_LEFT, dist); - } - - public CommandBuilder prepareTurnRight(double dist){ - return addCommand(С_PREPARE_TURN_LEFT, dist); - } - - public void play(){ - CommandPlayer.this.playCommands(this); - } - - protected List execute(){ - alreadyExecuted = true; - return CommandPlayer.this.execute(listStruct); - } - - } protected List execute(List listCmd){ Struct list = new Struct(listCmd.toArray(new Term[listCmd.size()])); @@ -306,6 +230,184 @@ public class CommandPlayer { } } + + + protected static final String P_VERSION = "version"; //$NON-NLS-1$ + protected static final String P_RESOLVE = "resolve"; //$NON-NLS-1$ + + protected static final String A_LEFT = "left"; //$NON-NLS-1$ + protected static final String A_LEFT_SH = "left_sh"; //$NON-NLS-1$ + protected static final String A_LEFT_SL = "left_sl"; //$NON-NLS-1$ + protected static final String A_RIGHT = "right"; //$NON-NLS-1$ + protected static final String A_RIGHT_SH = "right_sh"; //$NON-NLS-1$ + protected static final String A_RIGHT_SL = "right_sl"; //$NON-NLS-1$ + + protected static final String С_PREPARE_TURN = "prepare_turn"; //$NON-NLS-1$ + protected static final String С_PREPARE_MAKE_UT = "prepare_make_ut"; //$NON-NLS-1$ + protected static final String С_GO_AHEAD = "go_ahead"; //$NON-NLS-1$ + protected static final String С_TURN = "turn"; //$NON-NLS-1$ + protected static final String С_MAKE_UT = "make_ut"; //$NON-NLS-1$ + protected static final String С_PREAMBLE = "preamble"; //$NON-NLS-1$ + + protected static final String DELAY_CONST = "delay_"; //$NON-NLS-1$ + + public class CommandBuilder { + + + private boolean alreadyExecuted = false; + private List listStruct = new ArrayList(); + + public CommandBuilder(){ + this(true); + } + + public CommandBuilder(boolean preamble) { + if (preamble) { + addCommand(С_PREAMBLE); + } + } + + private void checkState(){ + if(alreadyExecuted){ + throw new IllegalArgumentException(); + } + } + + private CommandBuilder addCommand(String name, Object... args){ + checkState(); + Term[] list = new Term[args.length]; + for (int i = 0; i < args.length; i++) { + Object o = args[i]; + if(o instanceof java.lang.Number){ + if(o instanceof java.lang.Double){ + list[i] = new alice.tuprolog.Double((Double) o); + } else if(o instanceof java.lang.Float){ + list[i] = new alice.tuprolog.Float((Float) o); + } else if(o instanceof java.lang.Long){ + list[i] = new alice.tuprolog.Long((Long) o); + } else { + list[i] = new alice.tuprolog.Int(((java.lang.Number)o).intValue()); + } + } else if(o instanceof String){ + list[i] = new Struct((String) o); + } + if(list[i]== null){ + throw new NullPointerException(name +" " + o); //$NON-NLS-1$ + } + } + Struct struct = new Struct(name, list); + listStruct.add(struct); + return this; + } + + + public CommandBuilder goAhead(){ + return addCommand(С_GO_AHEAD); + } + + public CommandBuilder goAhead(double dist){ + return addCommand(С_GO_AHEAD, dist); + } + + public CommandBuilder makeUT(){ + return addCommand(С_MAKE_UT); + } + + public CommandBuilder makeUT(double dist){ + return addCommand(С_MAKE_UT, dist); + } + + public CommandBuilder prepareMakeUT(double dist){ + return addCommand(С_PREPARE_MAKE_UT, dist); + } + + + public CommandBuilder turnLeft(){ + return addCommand(С_TURN, A_LEFT); + } + + public CommandBuilder turnSLLeft(){ + return addCommand(С_TURN, A_LEFT_SL); + } + + public CommandBuilder turnSHLeft(){ + return addCommand(С_TURN, A_LEFT_SH); + } + + public CommandBuilder turnRight(){ + return addCommand(С_TURN, A_RIGHT); + } + + public CommandBuilder turnSLRight(){ + return addCommand(С_TURN, A_RIGHT_SL); + } + + public CommandBuilder turnSHRight(){ + return addCommand(С_TURN, A_RIGHT_SL); + } + + + public CommandBuilder turnLeft(double dist){ + return addCommand(С_TURN, A_LEFT, dist); + } + + public CommandBuilder turnSLLeft(double dist){ + return addCommand(С_TURN, A_LEFT_SL, dist); + } + + public CommandBuilder turnSHLeft(double dist){ + return addCommand(С_TURN, A_LEFT_SH, dist); + } + + public CommandBuilder turnRight(double dist){ + return addCommand(С_TURN, A_RIGHT, dist); + } + + public CommandBuilder turnSLRight(double dist){ + return addCommand(С_TURN, A_RIGHT_SL, dist); + } + + public CommandBuilder turnSHRight(double dist){ + return addCommand(С_TURN, A_RIGHT_SL, dist); + } + + public CommandBuilder prepareTurnLeft(double dist){ + return addCommand(С_PREPARE_TURN, A_LEFT, dist); + } + + public CommandBuilder prepareTurnSLLeft(double dist){ + return addCommand(С_PREPARE_TURN, A_LEFT_SL, dist); + } + public CommandBuilder prepareTurnSHLeft(double dist){ + return addCommand(С_PREPARE_TURN, A_LEFT_SH, dist); + } + + public CommandBuilder prepareTurnRight(double dist){ + return addCommand(С_PREPARE_TURN, A_RIGHT, dist); + } + + public CommandBuilder prepareTurnSLRight(double dist){ + return addCommand(С_PREPARE_TURN, A_RIGHT_SL, dist); + } + + public CommandBuilder prepareTurnSHRight(double dist){ + return addCommand(С_PREPARE_TURN, A_RIGHT_SH, dist); + } + + + + public void play(){ + CommandPlayer.this.playCommands(this); + } + + protected List execute(){ + alreadyExecuted = true; + return CommandPlayer.this.execute(listStruct); + } + + } + + } diff --git a/OsmAnd/voice/_config.p b/OsmAnd/voice/_config.p new file mode 100644 index 0000000000..00a5049d8a --- /dev/null +++ b/OsmAnd/voice/_config.p @@ -0,0 +1,92 @@ +:- op('==', xfy, 500). +version(0). + + +% before each announcement (beep) +preamble - []. + + +%% TURNS +turn('left', ['turn.ogg', 'left.ogg']). +turn('left_sh', ['turn_sharply.ogg', 'left.ogg']). +turn('left_sl', ['turn_slightly_left.ogg']). +turn('right', ['turn.ogg', 'right.ogg']). +turn('right_sh', ['turn_sharply.ogg', 'right.ogg']). +turn('right_sl', ['turn_slightly_right.ogg']). + +prepare_turn(Turn, Dist) == ['Prepare_to.ogg', 'in.ogg', delay_450, D, delay_450, M] :- + distance(Dist) == D, turn(Turn, M). +turn(Turn, Dist) == ['in.ogg', delay_450, D, delay_450, M] :- + distance(Dist) == D, turn(Turn, M). +turn(Turn) == M :- turn(Turn, M). + + +prepare_make_ut(Dist) == ['Prepare_to.ogg', 'in.ogg', delay_450, D, delay_450, 'Turn_back.ogg'] :- + distance(Dist) == D. + +make_ut(Dist) == ['in.ogg', delay_450, D, delay_450, 'Turn_back.ogg'] :- + distance(Dist) == D. +make_ut == ['Turn_back.ogg']. + + +go_ahead(Dist) == ['continue.ogg', D]:- distance(Dist) == D. +go_ahead == ['continue.ogg']. + + +%%% distance measure +distance(Dist) == [F, 'meters.ogg'] :- Dist < 1000, dist(Dist, F). +dist(D, '10.ogg') :- D < 20, !. +dist(D, '20.ogg') :- D < 30, !. +dist(D, '30.ogg') :- D < 40, !. +dist(D, '40.ogg') :- D < 50, !. +dist(D, '50.ogg') :- D < 60, !. +dist(D, '60.ogg') :- D < 70, !. +dist(D, '70.ogg') :- D < 80, !. +dist(D, '80.ogg') :- D < 90, !. +dist(D, '90.ogg') :- D < 100, !. +dist(D, '100.ogg') :- D < 150, !. +dist(D, '150.ogg') :- D < 200, !. +dist(D, '200.ogg') :- D < 250, !. +dist(D, '250.ogg') :- D < 300, !. +dist(D, '300.ogg') :- D < 350, !. +dist(D, '350.ogg') :- D < 400, !. +dist(D, '400.ogg') :- D < 450, !. +dist(D, '450.ogg') :- D < 500, !. +dist(D, '500.ogg') :- D < 550, !. +dist(D, '550.ogg') :- D < 600, !. +dist(D, '600.ogg') :- D < 650, !. +dist(D, '650.ogg') :- D < 700, !. +dist(D, '700.ogg') :- D < 750, !. +dist(D, '750.ogg') :- D < 800, !. +dist(D, '800.ogg') :- D < 850, !. +dist(D, '850.ogg') :- D < 900, !. +dist(D, '900.ogg') :- D < 950, !. +dist(D, '950.ogg') :- !. + + +distance(Dist) == ['more_than.ogg', '1.ogg', 'kilometr.ogg'] :- Dist < 1500. +distance(Dist) == ['more_than.ogg', '1.5k.ogg', 'kilometra.ogg'] :- Dist < 2000. +distance(Dist) == ['more_than.ogg', '2.ogg', 'kilometra.ogg'] :- Dist < 3000. +distance(Dist) == ['more_than.ogg', '3.ogg', 'kilometra.ogg'] :- Dist < 4000. +distance(Dist) == ['more_than.ogg', '4.ogg', 'kilometra.ogg'] :- Dist < 5000. +distance(Dist) == ['more_than.ogg', '5.ogg', 'kilometrov.ogg'] :- Dist < 6000. +distance(Dist) == ['more_than.ogg', '6.ogg', 'kilometrov.ogg'] :- Dist < 7000. +distance(Dist) == ['more_than.ogg', '7.ogg', 'kilometrov.ogg'] :- Dist < 8000. +distance(Dist) == ['more_than.ogg', '8.ogg', 'kilometrov.ogg'] :- Dist < 9000. +distance(Dist) == ['more_than.ogg', '9.ogg', 'kilometrov.ogg'] :- Dist < 10000. +distance(Dist) == ['more_than.ogg', X, 'kilometrov.ogg'] :- D is Dist/1000, dist(D, X). + + + +%% resolve command main method +%% if you are familar with Prolog you can input specific to the whole mechanism, +%% by adding exception cases. +flatten(X, Y) :- flatten(X, [], Y), !. +flatten([], Acc, Acc). +flatten([X|Y], Acc, Res):- + flatten(Y, Acc, R), flatten(X, R, Res). +flatten(X, Acc, [X|Acc]). + +resolve(X, Y) :- resolve_impl(X,Z), flatten(Z, Y). +resolve_impl([],[]). +resolve_impl([X|Rest], List) :- resolve_impl(Rest, Tail), ((X == L) -> append(L, Tail, List); List = Tail). \ No newline at end of file