MotorSignal-App/lib/services/compass_service.dart

53 lines
1.5 KiB
Dart

import 'dart:async';
import 'dart:math' as math;
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:sensors_plus/sensors_plus.dart';
final compassServiceProvider = Provider<CompassService>((ref) {
return CompassService();
});
final headingStreamProvider = StreamProvider<double>((ref) {
return ref.watch(compassServiceProvider).headingStream;
});
class CompassService {
final _headingController = StreamController<double>.broadcast();
StreamSubscription? _magSub;
Stream<double> get headingStream => _headingController.stream;
CompassService() {
_startSensors();
}
void _startSensors() {
_magSub = magnetometerEventStream(samplingPeriod: const Duration(milliseconds: 200)).listen((MagnetometerEvent event) {
// Calculate heading from magnetometer (X and Y components).
// Note: For a phone mounted vertically on a motorcycle, the axes might need mapping.
// This calculates basic 2D heading assuming phone is flat.
// Full tilt-compensated compass requires accelerometer fusion.
double heading = math.atan2(event.y, event.x) * (180.0 / math.pi);
// Adjust to 0-360 degrees
if (heading < 0) {
heading += 360;
}
_headingController.add(heading);
});
}
static String getHeadingString(double heading) {
const directions = ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW'];
final index = ((heading + 22.5) % 360 / 45).floor();
return directions[index];
}
void dispose() {
_magSub?.cancel();
_headingController.close();
}
}