plus_plugins icon indicating copy to clipboard operation
plus_plugins copied to clipboard

[Question]: sensors_plus reports different magnetic values in Android and iOS platforms

Open Hung-Hsun opened this issue 11 months ago • 11 comments

What is your question?

I listen magnetometerEventStream to get magnetic values of the device in x, y, z directions. However, when I executed in Android and iOS devices which are oriented in almost same attitude, they reported very different values of MagnetometerEvent as shown below.

Android: I/flutter (30017): [MagnetometerEvent (x: 7.65749979019165, y: 17.76624870300293, z: 17.66499900817871)]

iOS: flutter: [MagnetometerEvent (x: 192.7864227294922, y: 8.718887329101562, z: -91.60765075683594)]

My code snippet is:

void listenMagnetometerEvent() { _magnetometerEventStream ??= magnetometerEventStream().listen( (MagnetometerEvent event) { _magnetometerEventNotifier.value = event; print(event); }, onError: (error) { _magnetometerEventStream = null; throw Exception('Listen magnetometer event error: $error'); }, cancelOnError: true, ); }

Checklist before submitting a question

  • [X] I searched issues in this repository and couldn't find such bug/problem
  • [X] I Google'd a solution and I couldn't find it
  • [X] I searched on StackOverflow for a solution and I couldn't find it
  • [X] I read the README.md file of the plugin
  • [X] I am using the latest version of the plugin
  • [X] All dependencies are up to date with flutter pub upgrade
  • [X] I did a flutter clean
  • [X] I tried running the example project

Hung-Hsun avatar Mar 05 '24 08:03 Hung-Hsun

There was already a similar problem, they apparently never fixed it https://github.com/fluttercommunity/plus_plugins/issues/781

you can try using https://pub.dev/packages/motion_sensors or dchs_motion_sensors, they seem to write that it gives the correct values

Silverviql avatar Mar 29 '24 17:03 Silverviql

Without follow-up, I was unsure if the issue was ever resolved until now.

It seems still the discrepancy is caused by the source of the magnetometer data.

motion_sensors uses motionManager.startDeviceMotionUpdates() and sensors_plus calls _motionManager.startMagnetometerUpdates().

I do not have an iOS device to test, but perhaps you could try modifying the local package's code to use startDeviceMotionUpdates() and see if that resolves the issue. I never was able to do this myself, and I've needed someone else to try this.

Zabadam avatar Mar 29 '24 22:03 Zabadam

@Zabadam can you roll out an update so that I don’t have to rewrite the implementation in the project using motion_sensors? ))))

startDeviceMotionUpdates

I don't know Swift took sample code from https://github.com/zesage/motion_sensors/blob/6dafc3639b3e96460fabc639768a60b431b53610/ios/Classes/SwiftMotionSensorsPlugin.swift#L146

It turned out like this and now the data looks correct

`class FPPMagnetometerStreamHandlerPlus: NSObject, MotionStreamHandler {

var samplingPeriod = 200000 {
    didSet {
        _initMotionManager()
        _motionManager.magnetometerUpdateInterval = Double(samplingPeriod) * 0.000001
    }
}

func onListen(
        withArguments arguments: Any?,
        eventSink sink: @escaping FlutterEventSink
) -> FlutterError? {
    _initMotionManager()
    _motionManager.startDeviceMotionUpdates(using: CMAttitudeReferenceFrame.xArbitraryCorrectedZVertical, to: OperationQueue()) { data, error in
        if _isCleanUp {
            return
        }
        if (error != nil) {
            sink(FlutterError(
                    code: "UNAVAILABLE",
                    message: error!.localizedDescription,
                    details: nil
            ))
            return
        }
        if data != nil {
            let magneticField = data!.magneticField.field
            sendTriplet(x: magneticField.x, y: magneticField.y, z: magneticField.z, sink: sink)
        }
    }
    return nil
}

func onCancel(withArguments arguments: Any?) -> FlutterError? {
    _motionManager.stopDeviceMotionUpdates()
    return nil
}

func dealloc() {
    FPPSensorsPlusPlugin._cleanUp()
}

}`

I am attaching a screen recording with the values

  1. With the old implementation
  2. Values ​​for comparison with the Swift application
  3. Already corrected code with correct values ​​and comparing them with values ​​from another application

https://github.com/fluttercommunity/plus_plugins/assets/23103415/f6c2afd9-afa5-4288-bd48-cdcd36aacd8a

Silverviql avatar Mar 30 '24 12:03 Silverviql

@Zabadam can you roll out an update so that I don’t have to rewrite the implementation in the project using motion_sensors? ))))

I don't know Swift

Me neither, ha! It looks like you were able to accomplish just what I was looking for anyway, because...

I am attaching a screen recording with the values

  1. With the old implementation
  2. Values ​​for comparison with the Swift application
  3. Already corrected code with correct values ​​and comparing them with values ​​from another application

in the final portion of the video, you are using our sensors_plus but with startDeviceMotionUpdates() manually coded in place of startMagnetometerUpdates(), correct?

If yes, then a PR could be made where the function call is simply swapped out. Edit: And the field is accessed from the event's magneticField, which you correctly caught your code above.

(Or is the final part of the video a demonstration of your app with the package replaced entirely be motion_sensors?)

Edit: Just now I have realized what happened. In the past, I did indeed make a follow-up PR that swapped out the "magnetometer updates" call for a "device motion updates" call.

For that fix, I never did receive confirmation of corrected behavior, but it was merged anyway (as some other sensor functions were already utilizing device motion and it seemed appropriate to implement).

When this package was updated to Swift, the revised usage of the device motion sensor was somehow reverted back to utilizing the raw magnetometer sensor.

Zabadam avatar Mar 30 '24 14:03 Zabadam

Hi Zabadam, if you want to resubmit those changes in a PR, I can give some assistance reviewing and merging the fixes.

miquelbeltran avatar Mar 30 '24 16:03 miquelbeltran

@Zabadam can you roll out an update so that I don’t have to rewrite the implementation in the project using motion_sensors? )))) I don't know Swift

Me neither, ha! It looks like you were able to accomplish just what I was looking for anyway, because...

I am attaching a screen recording with the values

  1. With the old implementation
  2. Values ​​for comparison with the Swift application
  3. Already corrected code with correct values ​​and comparing them with values ​​from another application

in the final portion of the video, you are using our sensors_plus but with startDeviceMotionUpdates() manually coded in place of startMagnetometerUpdates(), correct?

If yes, then a PR could be made where the function call is simply swapped out. Edit: And the field is accessed from the event's magneticField, which you correctly caught your code above.

(Or is the final part of the video a demonstration of your app with the package replaced entirely be motion_sensors?)

Edit: Just now I have realized what happened. In the past, I did indeed make a follow-up PR that swapped out the "magnetometer updates" call for a "device motion updates" call.

For that fix, I never did receive confirmation of corrected behavior, but it was merged anyway (as some other sensor functions were already utilizing device motion and it seemed appropriate to implement).

When this package was updated to Swift, the revised usage of the device motion sensor was somehow reverted back to utilizing the raw magnetometer sensor.

yes I posted what code I entered manually

I didn’t use motion_sensors, I took a look at how it was implemented and modified it to fit your code

Silverviql avatar Mar 30 '24 17:03 Silverviql

@Zabadam Haven't you updated yet?

Silverviql avatar Apr 03 '24 19:04 Silverviql

Is there an update regarding this? Thanks!

franz-velasco avatar May 20 '24 05:05 franz-velasco

Hello, all, sorry for delay. A PR with this fix should be made shortly.

Zabadam avatar Jun 03 '24 17:06 Zabadam

@franz-velasco @Silverviql @Hung-Hsun

It would be very helpful if someone could confirm proper functionality now that DeviceMotion is in use:

dependencies
  # Testing calibrated magnetometer on iOS (https://github.com/fluttercommunity/plus_plugins/pull/3019)
  sensors_plus:
    git:
      url: https://github.com/Zabadam/plus_plugins.git
      ref: 1e2248d # Branch mag-sensor-ios
      path: packages/sensors_plus/sensors_plus

Zabadam avatar Jun 03 '24 22:06 Zabadam

@Zabadam yes it works correctly, the same line needs to be changed there, I dropped a couple above

Silverviql avatar Jun 05 '24 09:06 Silverviql

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 15 days

github-actions[bot] avatar Sep 04 '24 00:09 github-actions[bot]