import 'dart:async'; import 'package:get/get.dart'; import 'package:trackoffical_app/logger.dart'; import 'package:trackoffical_app/service/app.dart'; import 'package:trackoffical_app/utils.dart'; import 'package:sensor/sensor.dart'; import 'package:sensors_plus/sensors_plus.dart'; import '../compass_updater.dart'; import '../plug.dart'; import 'game_instance_std.dart'; class _Accelerometer{ double sum=0; DateTime ts = DateTime.now(); } class PlugOrientation extends Plug{ PlugOrientation(this.instance); GameInstanceStd? instance; final _app = App.to; final _angleFusedUpdater = CompassUpdater(); final _angleSrcUpdater = CompassUpdater(); final _accelerometerList= <_Accelerometer>[]; @override Future init() async{ listenStream(Sensor.orientationStream, (event) { final ins = instance; if(ins!= null){ ins.orientation.value = event; var direction = event.z; if (App.to.userProfile.gameSettingsRealNorth.value) { direction += ins.model.compassRealNorthOffset; } final src = _angleSrcUpdater.updateRadians(direction); if(src!=null){ ins.compassRadiansSrc.value = -src; } // GPS 方向 final gpsD = gpsDirection(ins); if (gpsD != null && ins.isPersonMoving) { direction = gpsD; } final fused = _angleFusedUpdater.updateRadians(direction); if(fused!=null){ ins.compassRadiansFused.value = -fused; } } }); listenStream(userAccelerometerEvents, (event) { final ins = instance; if(ins!= null){ _accelerometerList.add(_Accelerometer() ..sum=(event.x).abs() + (event.y).abs() // + (event.z).abs() ); if(_accelerometerList.length> 10){ _accelerometerList.removeAt(0); } if(_accelerometerList.length>1){ var sum = 0.0; for(var i=1; i< _accelerometerList.length;i++){ final p0 = _accelerometerList[i-1]; final p1 = _accelerometerList[i]; final seconds = p1.ts.difference(p0.ts).inMilliseconds.toDouble() / 1000; sum += p1.sum * seconds*seconds; } ins.sensorSpeedPerSecond = (sum / (_accelerometerList.last.ts.difference(_accelerometerList.first.ts).inMilliseconds / 1000)).meter; } // final now = DateTime.now(); // if(now.difference(_lastAccelerometerTime) >= 1.seconds){ // var sum = (event.x - _lastAccelerometer.x).abs() + // (event.y - _lastAccelerometer.y).abs() + // (event.z - _lastAccelerometer.z).abs(); // // // final d = now.difference(_lastAccelerometerTime); // ins.sensorSpeedPerSecond =( sum / (d.inMilliseconds.toDouble() / 1000)).meter; // // _lastAccelerometerTime = now; // _lastAccelerometer = event; // } } }); } /// GPS 方向 double? gpsDirection(GameInstanceStd ins) { final locations = []; var distance = 0.0.meter; final t = 4.seconds; final bt = App.to.now.add(-t); for (var i = ins.model.myPositionHistory.length - 1; i >= 0; i--) { final one = ins.model.myPositionHistory[i]; if (one.timestamp.isBefore(bt)) { break; } locations.add(one); } if (locations.length > 1) { for (var i = 0; i < locations.length; i++) { if (i > 0) { final p1 = locations[i]; final p2 = locations[i - 1]; distance += p1.distance(p2); } } final d = locations.last.timestamp.difference(locations[0].timestamp); final speedPerS = distance / (d.inMilliseconds.toDouble().abs() / 1000); ins.model.speedPreSecond.value = speedPerS; if (speedPerS > 1.1.meter) { // ---- 均值 ----- // var dSum = 0.0; // var count = 0; // for(var i=locations.length-1; i >=0 && i >= locations.length-3; i--){ // final l1 = locations[i]; // final l2 = locations[i-1]; // dSum += l1.directionTo(l2); // count++; // } // // return dSum/count; // --------------- final l1 = locations[locations.length-1]; var i = locations.length-4; if(i< 0){ i=0; } final l2 = locations[i]; return l1.directionTo(l2); } } return null; } @override Future onClose() async{ _app.locationStop(); instance=null; } }