plug_orientation.dart 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. import 'dart:async';
  2. import 'dart:math';
  3. import 'package:get/get.dart';
  4. import 'package:trackoffical_app/logger.dart';
  5. import 'package:trackoffical_app/model.dart';
  6. import 'package:trackoffical_app/service/app.dart';
  7. import 'package:trackoffical_app/service/game/compass_updater.dart';
  8. import 'package:trackoffical_app/service/game/map_status.dart';
  9. import 'package:sensors_plus/sensors_plus.dart';
  10. import 'package:vector_math/vector_math.dart';
  11. import 'game_model.dart';
  12. import 'plug.dart';
  13. import 'package:sensor/sensor.dart';
  14. import 'package:simple_kalman/simple_kalman.dart';
  15. class PlugOrientation extends Plug {
  16. PlugOrientation({required this.mapStatus});
  17. StreamSubscription<Orientation>? compassListener;
  18. StreamSubscription<AccelerometerEvent>? accelerometer;
  19. final GameModel _model = Get.find();
  20. final MapStatus mapStatus;
  21. final _angleFusedUpdater = CompassUpdater();
  22. final _angleSrcUpdater = CompassUpdater();
  23. var _lastAccelerometer = AccelerometerEvent(0, 0, 0);
  24. var _lastAccelerometerTime = DateTime.now();
  25. @override
  26. Future<void> init() async {
  27. _model.isMoving =false;
  28. compassListener = Sensor.orientationStream.listen((event) {
  29. _model.orientation.value = event;
  30. var direction = event.z;
  31. if (_model.isUseRealNorth) {
  32. direction += _model.compassRealNorthOffset;
  33. }
  34. final src = _angleSrcUpdater.updateRadians(direction);
  35. if(src!=null){
  36. _model.compassRadiansSrc.value = -src;
  37. }
  38. // GPS 方向
  39. final gpsD = gpsDirection();
  40. _model.isMoving = gpsD != null;
  41. if (gpsD != null) {
  42. direction = gpsD;
  43. }
  44. final fused = _angleFusedUpdater.updateRadians(direction);
  45. if(fused!=null){
  46. _model.compassRadiansFused.value = -fused;
  47. }
  48. });
  49. accelerometer = accelerometerEvents.listen((AccelerometerEvent event) {
  50. final now = DateTime.now();
  51. if(now.difference(_lastAccelerometerTime) >= 1.seconds){
  52. var sum = (event.x - _lastAccelerometer.x).abs() +
  53. (event.y - _lastAccelerometer.y).abs() +
  54. (event.z - _lastAccelerometer.z).abs();
  55. final d = now.difference(_lastAccelerometerTime);
  56. _model.deviceSpeed = sum / (d.inMilliseconds.toDouble() / 1000);
  57. _lastAccelerometerTime = now;
  58. _lastAccelerometer = event;
  59. }
  60. });
  61. }
  62. /// GPS 方向
  63. double? gpsDirection() {
  64. if(_model.deviceSpeed < 1){
  65. return null;
  66. }
  67. final locations = <MPosition>[];
  68. var disKm = 0.0;
  69. final t = 4.seconds;
  70. final bt = App.to.now.add(-t);
  71. for (var i = _model.myPositionHistoryTmp.length - 1; i >= 0; i--) {
  72. final one = _model.myPositionHistoryTmp[i];
  73. if (one.timestamp.isBefore(bt)) {
  74. break;
  75. }
  76. locations.add(one);
  77. }
  78. if (locations.length > 1) {
  79. for (var i = 0; i < locations.length; i++) {
  80. if (i > 0) {
  81. final p1 = locations[i];
  82. final p2 = locations[i - 1];
  83. disKm += p1.distance(p2).km;
  84. }
  85. }
  86. final d = locations.last.timestamp.difference(locations[0].timestamp);
  87. final speedMPerS =
  88. disKm * 1000 / (d.inMilliseconds.toDouble().abs() / 1000);
  89. _model.speedMPreS.value = speedMPerS;
  90. if (speedMPerS > 1.1) {
  91. // ---- 均值 -----
  92. // var dSum = 0.0;
  93. // var count = 0;
  94. // for(var i=locations.length-1; i >=0 && i >= locations.length-3; i--){
  95. // final l1 = locations[i];
  96. // final l2 = locations[i-1];
  97. // dSum += l1.directionTo(l2);
  98. // count++;
  99. // }
  100. //
  101. // return dSum/count;
  102. // ---------------
  103. final l1 = locations[locations.length-1];
  104. var i = locations.length-4;
  105. if(i< 0){
  106. i=0;
  107. }
  108. final l2 = locations[i];
  109. return l1.directionTo(l2);
  110. }
  111. }
  112. return null;
  113. }
  114. @override
  115. Future<void> close() async {
  116. super.close();
  117. compassListener?.cancel();
  118. accelerometer?.cancel();
  119. }
  120. }