@@ -731,13 +731,15 @@ class ATP {
731
731
// It takes 3.9 s for train in H0 at 40 km/h to pass 50 cm (sensor-signal distance)
732
732
// -> 3 s should be safe for stopping before the signal
733
733
static final int OVERSPEED_DELAY_EB_MS = 3000 ;
734
+ static final int DIR_MISMATCH_DELAY_EB_MS = 3000 ;
734
735
public enum Mode {
735
736
TRAIN ,
736
737
SHUNT ,
737
738
}
738
739
739
740
public Mode mode = Mode .TRAIN ;
740
741
private boolean overspeed ;
742
+ private boolean dirMismatch ;
741
743
private MediaPlayer soundPlayer ;
742
744
743
745
Handler t_overSpeedEB = new Handler (); // EB = emergency braking
@@ -746,6 +748,12 @@ public enum Mode {
746
748
public void run () { overSpeedEB (); }
747
749
};
748
750
751
+ Handler t_dirMismatchEB = new Handler (); // EB = emergency braking
752
+ Runnable t_dirMismatchEBRunnable = new Runnable () {
753
+ @ Override
754
+ public void run () { dirMismatchEB (); }
755
+ };
756
+
749
757
public ATP () {
750
758
try {
751
759
this .soundPlayer = new MediaPlayer ();
@@ -763,10 +771,13 @@ public ATP() {
763
771
public void onDestroy () {
764
772
if (this .overspeed )
765
773
this .overSpeedEnd ();
774
+ if (this .dirMismatch )
775
+ this .dirMismatchEnd ();
766
776
}
767
777
768
778
public void update () {
769
779
this .overSpeedUpdate ();
780
+ this .directionUpdate ();
770
781
}
771
782
772
783
private void soundStart () {
@@ -779,13 +790,18 @@ private void soundStart() {
779
790
}
780
791
}
781
792
782
- private void soundStop () {
783
- if ((this .soundPlayer != null ) && (this .soundPlayer .isPlaying ())) {
793
+ private void soundCheckStop () {
794
+ if ((! this . overspeed ) && (! this . dirMismatch ) && ( this .soundPlayer != null ) && (this .soundPlayer .isPlaying ())) {
784
795
this .soundPlayer .stop ();
785
796
this .soundPlayer .prepareAsync ();
786
797
}
787
798
}
788
799
800
+ private void removeAllEBCallbacks () {
801
+ this .t_overSpeedEB .removeCallbacks (t_overSpeedEBRunnable );
802
+ this .t_dirMismatchEB .removeCallbacks (t_dirMismatchEBRunnable );
803
+ }
804
+
789
805
private void overSpeedUpdate () {
790
806
final Engine thisEngine = EngineController .this .engine ;
791
807
@@ -830,22 +846,82 @@ private void overSpeedEnd() {
830
846
this .t_overSpeedEB .removeCallbacks (t_overSpeedEBRunnable );
831
847
EngineController .this .tv_kmhSpeed .clearAnimation ();
832
848
EngineController .this .tv_expSpeed .clearAnimation ();
833
- this .soundStop ();
849
+ this .soundCheckStop ();
834
850
}
835
851
836
852
private void overSpeedEB () {
837
853
final SharedPreferences sharedPreferences = PreferenceManager .getDefaultSharedPreferences (EngineController .this );
854
+ this .removeAllEBCallbacks ();
838
855
839
856
if ((EngineController .this .engine .isMyControl ()) && (!sharedPreferences .getBoolean ("ATPEBDisable" , false ))) {
840
857
EngineController .this .emergencyStop ();
841
858
842
859
new AlertDialog .Builder (EngineController .this )
843
860
.setMessage (getString (R .string .ta_atp_overspeed_eb_msg ))
861
+ .setCancelable (false )
844
862
.setPositiveButton (getString (R .string .dialog_ok ), (dialog , which ) -> {})
845
863
.show ();
846
864
}
847
865
}
848
866
867
+ private void directionUpdate () {
868
+ final Engine thisEngine = EngineController .this .engine ;
869
+
870
+ boolean dirMismatch = false ;
871
+ if ((thisEngine .isMyControl ()) && (this .mode != Mode .SHUNT ) && (thisEngine .stepsSpeed > 0 )) {
872
+ dirMismatch = (thisEngine .expDirection != Engine .ExpDirection .UNKNOWN ) ? (!thisEngine .expDirectionMatch (thisEngine .direction )) : false ;
873
+ }
874
+ this .dirMismatchSet (dirMismatch );
875
+ }
876
+
877
+ private void dirMismatchSet (boolean mismatch ) {
878
+ if (mismatch == this .dirMismatch )
879
+ return ;
880
+ this .dirMismatch = mismatch ;
881
+
882
+ if (mismatch )
883
+ this .dirMismatchBegin ();
884
+ else
885
+ this .dirMismatchEnd ();
886
+ }
887
+
888
+ private void dirMismatchBegin () {
889
+ this .t_dirMismatchEB .postDelayed (t_dirMismatchEBRunnable , DIR_MISMATCH_DELAY_EB_MS );
890
+
891
+ { // Animation
892
+ Animation blink = new AlphaAnimation (0.0f , 1.0f );
893
+ blink .setDuration (100 );
894
+ blink .setRepeatMode (Animation .REVERSE );
895
+ blink .setRepeatCount (Animation .INFINITE );
896
+ EngineController .this .s_direction .startAnimation (blink );
897
+ EngineController .this .tv_expDirection .startAnimation (blink );
898
+ }
899
+
900
+ this .soundStart ();
901
+ }
902
+
903
+ private void dirMismatchEnd () {
904
+ this .t_dirMismatchEB .removeCallbacks (t_dirMismatchEBRunnable );
905
+ EngineController .this .s_direction .clearAnimation ();
906
+ EngineController .this .tv_expDirection .clearAnimation ();
907
+ this .soundCheckStop ();
908
+ }
909
+
910
+ private void dirMismatchEB () {
911
+ final SharedPreferences sharedPreferences = PreferenceManager .getDefaultSharedPreferences (EngineController .this );
912
+ this .removeAllEBCallbacks ();
913
+
914
+ if ((EngineController .this .engine .isMyControl ()) && (!sharedPreferences .getBoolean ("ATPEBDisable" , false ))) {
915
+ EngineController .this .emergencyStop ();
916
+
917
+ new AlertDialog .Builder (EngineController .this )
918
+ .setMessage (getString (R .string .ta_atp_direction_eb_msg ))
919
+ .setCancelable (false )
920
+ .setPositiveButton (getString (R .string .dialog_ok ), (dialog , which ) -> {})
921
+ .show ();
922
+ }
923
+ }
924
+
849
925
public boolean isMovementStartAllowed () {
850
926
final Engine thisEngine = EngineController .this .engine ;
851
927
if (this .mode == Mode .SHUNT )
0 commit comments