plus_plugins
plus_plugins copied to clipboard
[Question]: sensors_plus reports different magnetic values in Android and iOS platforms
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
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
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 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
- With the old implementation
- Values for comparison with the Swift application
- 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
@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
- With the old implementation
- Values for comparison with the Swift application
- 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.
Hi Zabadam, if you want to resubmit those changes in a PR, I can give some assistance reviewing and merging the fixes.
@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
- With the old implementation
- Values for comparison with the Swift application
- 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 withstartDeviceMotionUpdates()
manually coded in place ofstartMagnetometerUpdates()
, 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'smagneticField
, 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
@Zabadam Haven't you updated yet?
Is there an update regarding this? Thanks!
Hello, all, sorry for delay. A PR with this fix should be made shortly.
@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 yes it works correctly, the same line needs to be changed there, I dropped a couple above
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