startHeadTracking method

Future<HeadTrackingResponse> startHeadTracking({
  1. VitureImuFrequency imuFrequency = VitureImuFrequency.freq120Hz,
  2. bool setDarwinOpenExclusive = false,
})

Implementation

Future<HeadTrackingResponse> startHeadTracking({
  VitureImuFrequency imuFrequency = VitureImuFrequency.freq120Hz,
  bool setDarwinOpenExclusive = false,
}) async {
  if (_isHeadTrackingActive || _isStarting) {
    return HeadTrackingResponse(
      status: true,
      message: 'Already running',
      code: 0,
    );
  }
  if (_isReleasing) {
    throw StateError('Cannot start while release is in progress');
  }

  _isStarting = true;
  try {
    _sensorController ??= StreamController<VitureSensorData>.broadcast();
    _stateController ??= StreamController<VitureStateEvent>.broadcast();

    final opFuture = _opQueue.then((_) async {
      await connect();
      final device = _device;
      if (device == null) {
        throw StateError('No device connected');
      }

      device.onStateChange(
        ((JSNumber id, JSNumber value) {
          final c = _stateController;
          if (c == null || c.isClosed) return;
          c.add(VitureStateEvent(id.toDartInt, value.toDartInt));
        }).toJS,
      );

      final freq = imuFrequency.value;
      await device
          .onPose(
            ((PoseJS pose) {
              if (!_isHeadTrackingActive) return;
              final c = _sensorController;
              if (c == null || c.isClosed) return;
              c.add(
                VitureSensorData.pose(
                  roll: pose.roll,
                  pitch: pose.pitch,
                  yaw: pose.yaw,
                  quatW: pose.qw,
                  quatX: pose.qx,
                  quatY: pose.qy,
                  quatZ: pose.qz,
                  timestamp: DateTime.now().millisecondsSinceEpoch,
                ),
              );
            }).toJS,
            freq.toJS,
          )
          .toDart;
    });
    _opQueue = opFuture.then((_) {}, onError: (_) {});
    await opFuture;

    _isHeadTrackingActive = true;
    return HeadTrackingResponse(
      status: true,
      message: 'Successfully started head tracking.',
      code: 0,
    );
  } catch (e) {
    await _forceCleanupHeadTracking();
    return HeadTrackingResponse(
      status: false,
      message: 'Unable to find the glasses.',
      code: -1,
    );
  } finally {
    _isStarting = false;
  }
}