Skip to content

Commit 0c29ce8

Browse files
implementation of the Compass page
Made suggested changes
1 parent 8fbccb5 commit 0c29ce8

File tree

7 files changed

+396
-3
lines changed

7 files changed

+396
-3
lines changed

android/app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
<meta-data
3737
android:name="flutterEmbedding"
3838
android:value="2" />
39+
3940
</application>
4041
<!-- Required to query activities that can process text, see:
4142
https://developer.android.com/training/package-visibility and

assets/icons/compass_icon.png

247 KB
Loading

lib/main.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import 'package:pslab/view/oscilloscope_screen.dart';
99
import 'package:pslab/view/settings_screen.dart';
1010
import 'package:pslab/view/about_us_screen.dart';
1111
import 'package:pslab/view/software_licenses_screen.dart';
12-
12+
import 'package:pslab/view/compass_screen.dart';
1313
import 'constants.dart';
1414

1515
void main() {
@@ -44,6 +44,7 @@ class MyApp extends StatelessWidget {
4444
routes: {
4545
'/': (context) => const InstrumentsScreen(),
4646
'/oscilloscope': (context) => const OscilloscopeScreen(),
47+
'/compass': (context) => const CompassScreen(),
4748
'/connectDevice': (context) => const ConnectDeviceScreen(),
4849
'/faq': (context) => const FAQScreen(),
4950
'/settings': (context) => const SettingsScreen(),
@@ -60,4 +61,4 @@ void _preCacheImages(BuildContext context) {
6061
}
6162
precacheImage(
6263
const AssetImage('assets/icons/ic_nav_header_logo.png'), context);
63-
}
64+
}

lib/providers/compass_provider.dart

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
import 'dart:async';
2+
import 'dart:math';
3+
import 'package:flutter/material.dart';
4+
import 'package:sensors_plus/sensors_plus.dart';
5+
import 'package:flutter/foundation.dart';
6+
7+
class CompassProvider extends ChangeNotifier {
8+
MagnetometerEvent _magnetometerEvent =
9+
MagnetometerEvent(0, 0, 0, DateTime.now());
10+
AccelerometerEvent _accelerometerEvent =
11+
AccelerometerEvent(0, 0, 0, DateTime.now());
12+
StreamSubscription? _magnetometerSubscription;
13+
StreamSubscription? _accelerometerSubscription;
14+
String _selectedAxis = 'X';
15+
double _currentDegree = 0.0;
16+
int _direction = 0;
17+
double _smoothedHeading = 0.0;
18+
19+
MagnetometerEvent get magnetometerEvent => _magnetometerEvent;
20+
AccelerometerEvent get accelerometerEvent => _accelerometerEvent;
21+
String get selectedAxis => _selectedAxis;
22+
double get currentDegree => _currentDegree;
23+
int get direction => _direction;
24+
double get smoothedHeading => _smoothedHeading;
25+
26+
void initializeSensors() {
27+
_magnetometerSubscription = magnetometerEventStream().listen(
28+
(event) {
29+
_magnetometerEvent = event;
30+
_updateCompassDirection();
31+
notifyListeners();
32+
},
33+
onError: (error) {
34+
debugPrint("Magnetometer error: $error");
35+
},
36+
cancelOnError: true,
37+
);
38+
39+
_accelerometerSubscription = accelerometerEventStream().listen(
40+
(event) {
41+
_accelerometerEvent = event;
42+
_updateCompassDirection();
43+
notifyListeners();
44+
},
45+
onError: (error) {
46+
debugPrint("Accelerometer error: $error");
47+
},
48+
cancelOnError: true,
49+
);
50+
}
51+
52+
void disposeSensors() {
53+
_magnetometerSubscription?.cancel();
54+
_accelerometerSubscription?.cancel();
55+
}
56+
57+
@override
58+
void dispose() {
59+
disposeSensors();
60+
super.dispose();
61+
}
62+
63+
void _updateCompassDirection() {
64+
double radians = _getRadiansForAxis(_selectedAxis);
65+
double degrees = radians * (180 / pi);
66+
if (degrees < 0) {
67+
degrees += 360;
68+
}
69+
70+
degrees = (degrees - 90) % 360;
71+
if (degrees < 0) {
72+
degrees += 360;
73+
}
74+
75+
const double alpha = 0.45;
76+
double angleDiff = degrees - _smoothedHeading;
77+
if (angleDiff > 180) {
78+
angleDiff -= 360;
79+
} else if (angleDiff < -180) {
80+
angleDiff += 360;
81+
}
82+
_smoothedHeading = _smoothedHeading + alpha * angleDiff;
83+
if (_smoothedHeading >= 360) {
84+
_smoothedHeading -= 360;
85+
} else if (_smoothedHeading < 0) {
86+
_smoothedHeading += 360;
87+
}
88+
switch (_selectedAxis) {
89+
case 'X':
90+
_currentDegree = -(_smoothedHeading * pi / 180);
91+
break;
92+
case 'Y':
93+
_currentDegree = ((_smoothedHeading - 10) * pi / 180);
94+
break;
95+
case 'Z':
96+
_currentDegree = -((_smoothedHeading + 90) * pi / 180);
97+
break;
98+
}
99+
}
100+
101+
double _getRadiansForAxis(String axis) {
102+
double ax = _accelerometerEvent.x;
103+
double ay = _accelerometerEvent.y;
104+
double az = _accelerometerEvent.z;
105+
double mx = _magnetometerEvent.x;
106+
double my = _magnetometerEvent.y;
107+
double mz = _magnetometerEvent.z;
108+
109+
double pitch = atan2(ay, sqrt(ax * ax + az * az));
110+
double roll = atan2(-ax, az);
111+
112+
double xH = mx * cos(pitch) + mz * sin(pitch);
113+
double yH = mx * sin(roll) * sin(pitch) +
114+
my * cos(roll) -
115+
mz * sin(roll) * cos(pitch);
116+
double zH = -mx * cos(roll) * sin(pitch) +
117+
my * sin(roll) +
118+
mz * cos(roll) * cos(pitch);
119+
120+
switch (axis) {
121+
case 'X':
122+
return atan2(yH, xH);
123+
case 'Y':
124+
return atan2(-xH, zH);
125+
case 'Z':
126+
return atan2(yH, -zH);
127+
default:
128+
return atan2(yH, xH);
129+
}
130+
}
131+
132+
double getDegreeForAxis(String axis) {
133+
double radians = _getRadiansForAxis(axis);
134+
double degree = radians * (180 / pi);
135+
136+
switch (axis) {
137+
case 'X':
138+
degree = (degree - 90) % 360;
139+
break;
140+
case 'Y':
141+
degree = (-degree + 100) % 360;
142+
break;
143+
case 'Z':
144+
degree = (degree + 90) % 360;
145+
break;
146+
}
147+
148+
return degree < 0 ? degree + 360 : degree;
149+
}
150+
151+
void onAxisSelected(String axis) {
152+
_selectedAxis = axis;
153+
switch (axis) {
154+
case 'X':
155+
_direction = 0;
156+
break;
157+
case 'Y':
158+
_direction = 1;
159+
break;
160+
case 'Z':
161+
_direction = 2;
162+
break;
163+
}
164+
notifyListeners();
165+
}
166+
}

0 commit comments

Comments
 (0)