4

In Android I can get the device yaw, roll and pitch using a GAME_ROTATION_VECTOR sensor.

I need to do the same thing in Flutter, but I haven't been able to find anything but the sensors package, which only gives access to accelerometer & gyroscope sensors.

What can I do? Do I need to calculate the orientation myself from the accelerometer and gyro?

Hexwell
  • 130
  • 2
  • 11
  • 2
    You could use `plaform_channel` to call android methods and fetch the result from flutter – Rémi Rousselet Aug 08 '18 at 14:34
  • @RémiRousselet Can I do the opposite? Like call Flutter functions from Android? Because that will solve my problem better – Hexwell Aug 08 '18 at 14:40
  • 2
    Yes, see [How to call methods in Dart portion of the app, from the native platform...](https://stackoverflow.com/questions/50187680/flutter-how-to-call-methods-in-dart-portion-of-the-app-from-the-native-platfor) – Richard Heap Aug 09 '18 at 02:29

2 Answers2

4

Don't know if this is still relevant, as the question wasn't closed, but for those seeking the answer... there is now a Flutter Sensors package which does all the magic for you.

You'll have to subscribe to the streams to get the current values of the accelerometers and gyroscopes, of course.

For example:

  @override
  void initState() {
    super.initState();
    _streamSubscriptions
        .add(accelerometerEvents.listen((AccelerometerEvent event) {
      setState(() {
        _accelerometerValues = <double>[event.x, event.y, event.z];
      });
    }));
    _streamSubscriptions.add(gyroscopeEvents.listen((GyroscopeEvent event) {
      setState(() {
        _gyroscopeValues = <double>[event.x, event.y, event.z];
      });
    }));
    _streamSubscriptions
        .add(userAccelerometerEvents.listen((UserAccelerometerEvent event) {
      setState(() {
        _userAccelerometerValues = <double>[event.x, event.y, event.z];
      });
    }));
  }
benPesso
  • 79
  • 3
  • Unfortunately the yaw (Azimut) is not available with this package – Bil5 May 21 '19 at 15:15
  • Umm, Yaw is the Z axis. (Y - Pitch, X - Roll) – benPesso May 23 '19 at 07:28
  • 3
    Sorry I was talking about https://github.com/aeyrium/aeyrium-sensor/ package, concerning the 'sensors' package, it's not very handy as you can only get a delta and not current values at a time, which means that you have to track values from a starting 'basis' position, which is not the case with the aeyrium-sensor package but which unfortunately lacks the yaw value. – Bil5 May 23 '19 at 08:12
  • 1
    From what the documentation says about the Flutter package, these are "current" values of acceleration. Not deltas. For example: "Acceleration force along the x axis (including gravity) measured in m/s^2." See more here: https://github.com/flutter/plugins/blob/master/packages/sensors/lib/sensors.dart – benPesso May 27 '19 at 17:53
1

I would not use the Flutter sensors_plus package to get yaw, roll or pitch. Even if you only wanted yaw (aka. heading or azimuth), as shown in this Github issue: MagnetometerEvent to compass values. It is challenging to convert magnetometer readings (microteslas) into roll, pitch, yaw because of the maths. You only get raw magnetometer readings.

As I wrote in the comment there:

I would highly recommend using https://pub.dev/packages/flutter_compass, https://pub.dev/packages/motion_sensors or writing your own plugin to use the OS APIs to get the data you need directly, instead of using the magnetometer readings (unit: micro Teslas), to allow you to use the operating-system calculated heading, which could use multiple sensors (sensor fusion) to give improved accuracy based on the hardware, as well as compensate for the location (the magnetometer only allows you to calculate magnetic north, not true north).

  • motion_sensors provides an OrientationEvent, which contains roll, pitch and yaw, in radians.

Writing your own plugin

If you need roll or pitch (more than yaw/heading/azimuth), the OS APIs provide it:

                float orientationData[] = new float[3];
                SensorManager.getOrientation(R, orientationData);
                azimuth = orientationData[0];
                pitch = orientationData[1];
                roll = orientationData[2];
CMQuaternion quat = self.motionManager.deviceMotion.attitude.quaternion;
myRoll = radiansToDegrees(atan2(2*(quat.y*quat.w - quat.x*quat.z), 1 - 2*quat.y*quat.y - 2*quat.z*quat.z)) ;
myPitch = radiansToDegrees(atan2(2*(quat.x*quat.w + quat.y*quat.z), 1 - 2*quat.x*quat.x - 2*quat.z*quat.z));
myYaw = radiansToDegrees(asin(2*quat.x*quat.y + 2*quat.w*quat.z));
Ben Butterworth
  • 22,056
  • 10
  • 114
  • 167