start method
void
start()
Starts gyroscope tracking. Calls calibrate automatically.
Implementation
void start() {
if (kIsWeb) return;
stop();
calibrate();
_lastTimestamp = null;
_prevPitchFused = null;
_prevRollFused = null;
_pitchFused = 0.0;
_rollFused = 0.0;
_accelSubscription =
(accelerometerStreamOverride ?? accelerometerEventStream()).listen((
event,
) {
_accelX = event.x;
_accelY = event.y;
_accelZ = event.z;
});
_subscription = (gyroscopeStreamOverride ?? gyroscopeEventStream()).listen((
event,
) {
if (_calibrating) {
_calibrationSumX += event.x;
_calibrationSumY += event.y;
_calibrationSamples++;
return;
}
final adjustedX = event.x - _offsetX;
final adjustedY = event.y - _offsetY;
final now = DateTime.now();
if (_lastTimestamp == null) {
_lastTimestamp = now;
final accelPitch = atan2(_accelY, _accelZ);
final accelRoll = atan2(
-_accelX,
sqrt(_accelY * _accelY + _accelZ * _accelZ),
);
_pitchFused = accelPitch;
_rollFused = accelRoll;
_prevPitchFused = accelPitch;
_prevRollFused = accelRoll;
return;
}
final dt = now.difference(_lastTimestamp!).inMicroseconds / 1000000.0;
_lastTimestamp = now;
// 1. Calculate absolute pitch/roll from accelerometer gravity vector
final accelPitch = atan2(_accelY, _accelZ);
final accelRoll = atan2(
-_accelX,
sqrt(_accelY * _accelY + _accelZ * _accelZ),
);
// 2. Blend accelerometer and integrated gyroscope values using Complementary Filter
_pitchFused =
_alpha * (_pitchFused + adjustedX * dt) + (1 - _alpha) * accelPitch;
_rollFused =
_alpha * (_rollFused + adjustedY * dt) + (1 - _alpha) * accelRoll;
// 3. Compute delta movements
final dPitchFused = _pitchFused - (_prevPitchFused ?? _pitchFused);
final dRollFused = _rollFused - (_prevRollFused ?? _rollFused);
_prevPitchFused = _pitchFused;
_prevRollFused = _rollFused;
// 4. Forward as landscape rotations (Yaw, Pitch)
target.rotate(-dPitchFused * sensitivity, dRollFused * sensitivity * 1.8);
});
}