plug_orientation.dart 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. import 'dart:async';
  2. import 'package:get/get.dart';
  3. import 'package:trackoffical_app/logger.dart';
  4. import 'package:trackoffical_app/service/app.dart';
  5. import 'package:trackoffical_app/utils.dart';
  6. import 'package:sensor/sensor.dart';
  7. import 'package:sensors_plus/sensors_plus.dart';
  8. import '../compass_updater.dart';
  9. import '../plug.dart';
  10. import 'game_instance_std.dart';
  11. class _Accelerometer{
  12. double sum=0;
  13. DateTime ts = DateTime.now();
  14. }
  15. class PlugOrientation extends Plug{
  16. PlugOrientation(this.instance);
  17. GameInstanceStd? instance;
  18. final _app = App.to;
  19. final _angleFusedUpdater = CompassUpdater();
  20. final _angleSrcUpdater = CompassUpdater();
  21. final _accelerometerList= <_Accelerometer>[];
  22. @override
  23. Future<void> init() async{
  24. listenStream(Sensor.orientationStream, (event) {
  25. final ins = instance;
  26. if(ins!= null){
  27. ins.orientation.value = event;
  28. var direction = event.z;
  29. if (App.to.userProfile.gameSettingsRealNorth.value) {
  30. direction += ins.model.compassRealNorthOffset;
  31. }
  32. final src = _angleSrcUpdater.updateRadians(direction);
  33. if(src!=null){
  34. ins.compassRadiansSrc.value = -src;
  35. }
  36. // GPS 方向
  37. final gpsD = gpsDirection(ins);
  38. if (gpsD != null && ins.isPersonMoving) {
  39. direction = gpsD;
  40. }
  41. final fused = _angleFusedUpdater.updateRadians(direction);
  42. if(fused!=null){
  43. ins.compassRadiansFused.value = -fused;
  44. }
  45. }
  46. });
  47. listenStream(userAccelerometerEvents, (event) {
  48. final ins = instance;
  49. if(ins!= null){
  50. _accelerometerList.add(_Accelerometer()
  51. ..sum=(event.x).abs()
  52. + (event.y).abs()
  53. // + (event.z).abs()
  54. );
  55. if(_accelerometerList.length> 10){
  56. _accelerometerList.removeAt(0);
  57. }
  58. if(_accelerometerList.length>1){
  59. var sum = 0.0;
  60. for(var i=1; i< _accelerometerList.length;i++){
  61. final p0 = _accelerometerList[i-1];
  62. final p1 = _accelerometerList[i];
  63. final seconds = p1.ts.difference(p0.ts).inMilliseconds.toDouble() / 1000;
  64. sum += p1.sum * seconds*seconds;
  65. }
  66. ins.sensorSpeedPerSecond = (sum / (_accelerometerList.last.ts.difference(_accelerometerList.first.ts).inMilliseconds / 1000)).meter;
  67. }
  68. // final now = DateTime.now();
  69. // if(now.difference(_lastAccelerometerTime) >= 1.seconds){
  70. // var sum = (event.x - _lastAccelerometer.x).abs() +
  71. // (event.y - _lastAccelerometer.y).abs() +
  72. // (event.z - _lastAccelerometer.z).abs();
  73. //
  74. //
  75. // final d = now.difference(_lastAccelerometerTime);
  76. // ins.sensorSpeedPerSecond =( sum / (d.inMilliseconds.toDouble() / 1000)).meter;
  77. //
  78. // _lastAccelerometerTime = now;
  79. // _lastAccelerometer = event;
  80. // }
  81. }
  82. });
  83. }
  84. /// GPS 方向
  85. double? gpsDirection(GameInstanceStd ins) {
  86. final locations = <MPosition>[];
  87. var distance = 0.0.meter;
  88. final t = 4.seconds;
  89. final bt = App.to.now.add(-t);
  90. for (var i = ins.model.myPositionHistory.length - 1; i >= 0; i--) {
  91. final one = ins.model.myPositionHistory[i];
  92. if (one.timestamp.isBefore(bt)) {
  93. break;
  94. }
  95. locations.add(one);
  96. }
  97. if (locations.length > 1) {
  98. for (var i = 0; i < locations.length; i++) {
  99. if (i > 0) {
  100. final p1 = locations[i];
  101. final p2 = locations[i - 1];
  102. distance += p1.distance(p2);
  103. }
  104. }
  105. final d = locations.last.timestamp.difference(locations[0].timestamp);
  106. final speedPerS =
  107. distance / (d.inMilliseconds.toDouble().abs() / 1000);
  108. ins.model.speedPreSecond.value = speedPerS;
  109. if (speedPerS > 1.1.meter) {
  110. // ---- 均值 -----
  111. // var dSum = 0.0;
  112. // var count = 0;
  113. // for(var i=locations.length-1; i >=0 && i >= locations.length-3; i--){
  114. // final l1 = locations[i];
  115. // final l2 = locations[i-1];
  116. // dSum += l1.directionTo(l2);
  117. // count++;
  118. // }
  119. //
  120. // return dSum/count;
  121. // ---------------
  122. final l1 = locations[locations.length-1];
  123. var i = locations.length-4;
  124. if(i< 0){
  125. i=0;
  126. }
  127. final l2 = locations[i];
  128. return l1.directionTo(l2);
  129. }
  130. }
  131. return null;
  132. }
  133. @override
  134. Future<void> onClose() async{
  135. _app.locationStop();
  136. instance=null;
  137. }
  138. }