示例#1
0
        internal override void CheckAndEnableSensors()
        {
            base.CheckAndEnableSensors();

            if (Accelerometer.ShouldBeEnabled)
            {
                motionManager.StartAccelerometerUpdates();
            }

            if ((Compass.ShouldBeEnabled || Orientation.ShouldBeEnabled) && !locationManagerActivated)
            {
                locationManagerActivated = true;
                locationManager.StartUpdatingHeading();
            }

            if (Gyroscope.ShouldBeEnabled)
            {
                motionManager.StartGyroUpdates();
            }

            if ((UserAcceleration.ShouldBeEnabled || Gravity.ShouldBeEnabled || Orientation.ShouldBeEnabled) && !motionManager.DeviceMotionActive)
            {
                motionManager.StartDeviceMotionUpdates();
            }
        }
示例#2
0
		public void Start ()
		{
			mman = new CMMotionManager {
				ShowsDeviceMovementDisplay = true,
			};

			mman.StartDeviceMotionUpdates (
			//	CMAttitudeReferenceFrame.XArbitraryZVertical,
			//	CMAttitudeReferenceFrame.XArbitraryCorrectedZVertical,
//				CMAttitudeReferenceFrame.XMagneticNorthZVertical,
				CMAttitudeReferenceFrame.XTrueNorthZVertical,
				new NSOperationQueue (), 
				(motion, error) => {
					if (error == null) {
						Orientation = ToMatrix4d (motion.Attitude.RotationMatrix);

						var roll = motion.Attitude.Roll;
						var p = motion.Attitude.Pitch;
						if (roll > 0) {
							p = (3 * Math.PI) / 2 + p;
						}
						else {
							p = Math.PI / 2 - p;
						}
						Pitch = p;

						OrientationReceived (this, EventArgs.Empty);
					}
				});
		}
 public void Start()
 {
     motionManager.StartDeviceMotionUpdates();
     isRunning = true;
     isData    = false;
     PerformSelector(new ObjCRuntime.Selector("Update"), null, UpdateInterval);
 }
示例#4
0
        public void Start()
        {
            mman = new CMMotionManager {
                ShowsDeviceMovementDisplay = true,
            };

            mman.StartDeviceMotionUpdates(
                //	CMAttitudeReferenceFrame.XArbitraryZVertical,
                //	CMAttitudeReferenceFrame.XArbitraryCorrectedZVertical,
//				CMAttitudeReferenceFrame.XMagneticNorthZVertical,
                CMAttitudeReferenceFrame.XTrueNorthZVertical,
                new NSOperationQueue(),
                (motion, error) => {
                if (error == null)
                {
                    Orientation = ToMatrix4d(motion.Attitude.RotationMatrix);

                    var roll = motion.Attitude.Roll;
                    var p    = motion.Attitude.Pitch;
                    if (roll > 0)
                    {
                        p = (3 * Math.PI) / 2 + p;
                    }
                    else
                    {
                        p = Math.PI / 2 - p;
                    }
                    Pitch = p;

                    OrientationReceived(this, EventArgs.Empty);
                }
            });
        }
示例#5
0
        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here
            motionManager = new CMMotionManager();
            motionManager.DeviceMotionUpdateInterval = 1 / 60;
            motionManager.StartDeviceMotionUpdates();

            base.Initialize();
        }
示例#6
0
        public override void ViewDidAppear(bool animated)
        {
            base.ViewDidAppear(animated);
            var csize  = panningScrollView.ContentSize;
            var bounds = panningScrollView.Bounds;

            panningScrollView.ContentOffset = new PointF((csize.Width / 2f - bounds.Width) / 2, (csize.Height / 2f - bounds.Height) / 2);
            motionManager.StartDeviceMotionUpdates(NSOperationQueue.MainQueue, (motion, error) => CalculateRotationBasedOn(motion));
        }
示例#7
0
 private void BeginMotionSession()
 {
     if (motionManager.GyroAvailable)
     {
         motionManager.StartDeviceMotionUpdates(CMAttitudeReferenceFrame.XMagneticNorthZVertical);
     }
     else
     {
         System.Console.WriteLine("Gyroscope not available");
     }
 }
示例#8
0
        protected override async Task StartListeningAsync()
        {
            await base.StartListeningAsync();

            _motionManager?.StartDeviceMotionUpdates(new NSOperationQueue(), async(data, error) =>
            {
                if (data != null && error == null)
                {
                    await StoreDatumAsync(new AttitudeDatum(DateTimeOffset.UtcNow, data.Attitude.Quaternion.x, data.Attitude.Quaternion.y, data.Attitude.Quaternion.z, data.Attitude.Quaternion.w));
                }
            });
        }
示例#9
0
        protected override async Task StartListeningAsync()
        {
            await base.StartListeningAsync();

            _motionManager?.StartDeviceMotionUpdates(new NSOperationQueue(), async(data, error) =>
            {
                if (data != null && error == null)
                {
                    await StoreDatumAsync(new LinearAccelerationDatum(DateTimeOffset.UtcNow, data.UserAcceleration.X, data.UserAcceleration.Y, data.UserAcceleration.Z));
                }
            });
        }
示例#10
0
 public override void Start()
 {
     if (started == false)
     {
         // For true north use CMAttitudeReferenceFrame.XTrueNorthZVertical, but be aware that it requires location service
         motionManager.StartDeviceMotionUpdates(CMAttitudeReferenceFrame.XMagneticNorthZVertical, NSOperationQueue.CurrentQueue, MagnetometerHandler);
         started = true;
         state   = SensorState.Ready;
     }
     else
     {
         throw new SensorFailedException("Failed to start compass data acquisition. Data acquisition already started.");
     }
 }
        public override void ViewWillAppear(bool animated)
        {
            base.ViewWillAppear(animated);

            if (isDeviceMotionAvailable == true)
            {
                motionManager.DeviceMotionUpdateInterval = .01;
                motionManager.StartDeviceMotionUpdates();
            }
            else
            {
                Console.WriteLine("Device motion is not available on device");
            }
        }
        public async override void ViewDidAppear(bool animated)
        {
            base.ViewDidAppear(animated);


            adapter = Adapter.Current;

            BigTed.BTProgressHUD.Show("Connecting...");
            RunControlAsync();
            man.StartDeviceMotionUpdates(new NSOperationQueue()
            {
                Name = "robots"
            }, GyroChanged);
            BigTed.BTProgressHUD.Dismiss();
        }
示例#13
0
        /// <summary>
        /// Start the specified sensor type reading.
        /// </summary>
        /// <param name="sensorType">Sensor type</param>
        public override void Start(SensorType sensorType)
        {
            switch (sensorType)
            {
            case SensorType.Accelerometer:
                AccelerometerActive = true;
                motionManager.AccelerometerUpdateInterval = 0.05;
                motionManager.StartAccelerometerUpdates(NSOperationQueue.MainQueue, (data, error) =>
                {
                    EmitAccelerometer(new MotionVector(data.Acceleration.X, data.Acceleration.Y, data.Acceleration.Z));
                });
                break;

            case SensorType.Gyroscope:
                GyroActive = true;
                motionManager.GyroUpdateInterval = 0.05;
                motionManager.StartGyroUpdates(NSOperationQueue.MainQueue, (data, error) =>
                {
                    EmitGyroscope(new MotionVector(data.RotationRate.x, data.RotationRate.y, data.RotationRate.z));
                });
                break;

            case SensorType.DeviceMotion:
                DeviceMotionActive = true;
                motionManager.DeviceMotionUpdateInterval = 0.05d;
                motionManager.StartDeviceMotionUpdates(NSOperationQueue.MainQueue, (motion, error) =>
                {
                    EmitDeviceMotion(new MotionVector(motion.Attitude.Roll, motion.Attitude.Pitch, motion.Attitude.Yaw));
                });
                break;

            case SensorType.Compass:
                CompassActive = true;
                locationManager.UpdatedHeading += (sender, eventArgs) =>
                {
                    // TODO: Fix.
                    EmitCompass(eventArgs.NewHeading.TrueHeading);
                };
                locationManager.StartUpdatingHeading();
                break;

            case SensorType.LightLevel:
                LightLevelActive = false;
                break;
            }
        }
示例#14
0
 private void GetOrientation()
 {
     _motionManager = new CMMotionManager();
     if (_motionManager.DeviceMotionAvailable)             // DeviceMotion is not available on all devices. iOS4+
     {
         this.Log().ErrorIfEnabled(() => "DeviceMotion is available");
         _motionManager.DeviceMotionUpdateInterval = _updateInterval;
         _motionManager.StartDeviceMotionUpdates(NSOperationQueue.CurrentQueue, (motion, error) =>
         {
             OnMotionChanged(motion);
         });
     }
     else             // For iOS devices that don't support CoreMotion
     {
         this.Log().ErrorIfEnabled(() => "SimpleOrientationSensor failed to initialize because CoreMotion is not available");
     }
 }
示例#15
0
 void StartDeviceMotion()
 {
     motionManager = new CMMotionManager
     {
         ShowsDeviceMovementDisplay = true,
         DeviceMotionUpdateInterval = 1.0 / 60.0
     };
     motionManager.StartDeviceMotionUpdates(CMAttitudeReferenceFrame.XTrueNorthZVertical, NSOperationQueue.CurrentQueue, (motion, error) =>
     {
         if (motion != null)
         {
             cameraTransform = new float[16];
             TransformFromCMRotationMatrix(ref cameraTransform, motion.Attitude.RotationMatrix);
             SetNeedsDisplay();
         }
     });
 }
 partial void Initialize()
 {
     _motionManager = new CMMotionManager();
     if (_motionManager.DeviceMotionAvailable)             // DeviceMotion is not available on all devices. iOS4+
     {
         var operationQueue = (NSOperationQueue.CurrentQueue == null || NSOperationQueue.CurrentQueue == NSOperationQueue.MainQueue) ? new NSOperationQueue() : NSOperationQueue.CurrentQueue;
         this.Log().Error("DeviceMotion is available");
         _motionManager.DeviceMotionUpdateInterval = _updateInterval;
         _motionManager.StartDeviceMotionUpdates(operationQueue, (motion, error) =>
         {
             OnMotionChanged(motion);
         });
     }
     else             // For iOS devices that don't support CoreMotion
     {
         this.Log().Error("SimpleOrientationSensor failed to initialize because CoreMotion is not available");
     }
 }
示例#17
0
 public void Start()
 {
     _motionManager = new CMMotionManager();
     _motionManager.StartDeviceMotionUpdates(NSOperationQueue.CurrentQueue, (data, error) =>
     {
         var xMotion = new XMotion
         {
             Pitch = data.Attitude.Pitch,
             Roll = data.Attitude.Roll,
             Yaw = data.Attitude.Yaw
         };
         
         CurrentMotion = xMotion;
         
         if (MotionUpdated != null)
         {
             MotionUpdated(this, EventArgs.Empty);
         }
     });
 }
示例#18
0
        public void Start()
        {
            _motionManager = new CMMotionManager();
            _motionManager.StartDeviceMotionUpdates(NSOperationQueue.CurrentQueue, (data, error) =>
            {
                var xMotion = new XMotion
                {
                    Pitch = data.Attitude.Pitch,
                    Roll  = data.Attitude.Roll,
                    Yaw   = data.Attitude.Yaw
                };

                CurrentMotion = xMotion;

                if (MotionUpdated != null)
                {
                    MotionUpdated(this, EventArgs.Empty);
                }
            });
        }
示例#19
0
        public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
        {
            Xamarin.Forms.Forms.Init();

            // Pitch is speed pi/2 -> 0
            // Roll turning speed -p1/2 -> p1/2
            man.StartDeviceMotionUpdates(new NSOperationQueue(), (m, e) => {
                Roll  = m.Attitude.Roll;
                Pitch = m.Attitude.Pitch;
                Yaw   = m.Attitude.Yaw;
                GyroUpdated(this, EventArgs.Empty);
            });

            app = new App(Adapter.Current, this);

            window = new UIWindow(UIScreen.MainScreen.Bounds);
            window.RootViewController = app.GetMainPage().CreateViewController();
            window.MakeKeyAndVisible();

            return(true);
        }
        public void StartSensorUpdates()
        {
            // Raw accelerometer
            if (_motionManager.AccelerometerAvailable)
            {
                _motionManager.StartAccelerometerUpdates(_queue, HandleCMAccelerometerHandler);
            }

            if (_motionManager.GyroAvailable)
            {
                _motionManager.StartGyroUpdates(_queue, HandleCMGyroHandler);
            }

            if (_motionManager.MagnetometerAvailable)
            {
                _motionManager.StartMagnetometerUpdates(_queue, HandleCMMagnetometerHandler);
            }

            if (_motionManager.DeviceMotionAvailable)
            {
                _motionManager.StartDeviceMotionUpdates(_queue, HandleCMDeviceMotionHandler);
                _pedometer.StartPedometerUpdates(NSDate.Now, HandleCMPedometer);
            }

            //start updating headings
            _locationManager.StartUpdatingHeading();

            //// service for measurements once per minute
            UIDevice.CurrentDevice.BatteryMonitoringEnabled = true;

            Timer timer = new Timer(60000);

            timer.AutoReset = true;
            timer.Elapsed  += SensorMeasurementSessionTimerElapsed;
            timer.Start();


            IsListening = true;
        }
示例#21
0
        private void SaveDeviceMotion()
        {
            NSOperationQueue queue = new NSOperationQueue();

            cmManager.StartDeviceMotionUpdates(queue, async(CMDeviceMotion motion, NSError error) =>
            {
                //Repository<AccelerometerData> accRepo = new Repository<AccelerometerData>(SQLiteHelper.Instance.Connection);

                Debug.WriteLine("DeviceMotionUpdate" + motion.Timestamp);

                // motion.Timestamp, set to accelerometerdata. Time since boot. Convert to time? How?

                DateTimeOffset timestamp = Utils.TimeSinceBootToDateTimeOffset(motion.Timestamp);
                Debug.WriteLine("Compare timestamps vs now: {0} vs {1}", DateTimeOffset.Now, timestamp);

                AccelerometerData userAcc = new AccelerometerData()
                {
                    Type      = AccelerometerType.User,
                    Timestamp = timestamp,
                    X         = motion.UserAcceleration.X,
                    Y         = motion.UserAcceleration.Y,
                    Z         = motion.UserAcceleration.Z
                };

                AccelerometerData gravAcc = new AccelerometerData()
                {
                    Type      = AccelerometerType.Gravity,
                    Timestamp = timestamp,
                    X         = motion.Gravity.X,
                    Y         = motion.Gravity.Y,
                    Z         = motion.Gravity.Z
                };
                Debug.WriteLine("Useracc " + userAcc);
                Debug.WriteLine("gravacc " + gravAcc);

                //await accRepo.Insert(userAcc);
                //await accRepo.Insert(gravAcc);
            });
        }
示例#22
0
        public async override void ViewDidLoad()
        {
            base.ViewDidLoad();
            // Perform any additional setup after loading the view, typically from a nib.
            Button.AccessibilityIdentifier = "myButton";
            Button.TouchUpInside          += delegate {
                var title = string.Format("{0} clicks!", count++);
                Button.SetTitle(title, UIControlState.Normal);
            };


            locator = CrossGeolocator.Current;
            locator.DesiredAccuracy = 50;

            var position = await locator.GetPositionAsync(10000);

            locator.PositionChanged += Locator_PositionChanged;
            await locator.StartListeningAsync(0, 0, false);

            Console.WriteLine("Position Status: {0}", position.Timestamp);
            Console.WriteLine("Position Latitude: {0}", position.Latitude);
            Console.WriteLine("Position Longitude: {0}", position.Longitude);
            Button.SetTitle($"{position.Latitude} {position.Longitude}", UIControlState.Normal);


            ViewModel = new MainViewModel(WorldConfiguration.iOS);


            ViewModel.UpdateWorld(View.Bounds.Width, View.Bounds.Height);

            //RootLayout = this.FindViewById<RelativeLayout>(Resource.Id.myMainLayout);


            motion = new CMMotionManager();
            motion.StartDeviceMotionUpdates(NSOperationQueue.CurrentQueue, MotionHandler);

            PopulateWorld();
        }
        public override void ViewDidLoad()
        {
            Console.WriteLine(finalSpeedArray.Length.ToString());
            base.ViewDidLoad();

            //Check and make sure GPS is enabled
            if (CLLocationManager.Status == CLAuthorizationStatus.Authorized)
            {
                rawGPS.createCoordinatesWhenHeadingChangesToAddToList();


                double currentSpeed = 0;

                avgaccel           = 0;
                currentMaxAvgAccel = 0;

                //Start updating accelerometer data at device motion update interval specified pulling rate
                _motionManager = new CMMotionManager();
                _motionManager.DeviceMotionUpdateInterval = .5;
                _motionManager.StartDeviceMotionUpdates(NSOperationQueue.CurrentQueue, (data, error) =>

                {
                    //Convert motion data into nondirectional vector data (Total G's)
                    avgaccel = Math.Sqrt((data.UserAcceleration.X * data.UserAcceleration.X) +
                                         (data.UserAcceleration.Y * data.UserAcceleration.Y) +
                                         (data.UserAcceleration.Z * data.UserAcceleration.Z));

                    //Calculate current speed in Km/Hr
                    currentSpeed = rawGPS.convertToKilometersPerHour(rawGPS.getSpeedInMetersPerSecondUnits());
                    Console.WriteLine(currentSpeed.ToString());
                    this.currentSpeedLabel.Text = currentSpeed.ToString();

                    //Test if accelerometer event occurs
                    if ((avgaccel > threshold) && (avgaccel < maxThresh))
                    {
                        Console.WriteLine("Event is in progress.");

                        if (!eventInProgress)
                        {
                            isCountingInitialSpeed = true;
                            eventInProgress        = true;
                        }
                    }

                    //Test if accelerometer event has ended
                    else if ((avgaccel < threshold) && eventInProgress)
                    {
                        Console.WriteLine("Event has ended.");
                        eventcount++;
                        eventInProgress        = false;
                        isCountingFinalSpeed   = true;
                        this.eventCounter.Text = eventcount.ToString();
                    }

                    //If event has started, start counting/filling initialSpeedArray
                    if (isCountingInitialSpeed == true && initialSpeedArrayCounter < initialSpeedArray.Length - 1)
                    {
                        initialSpeedArray [initialSpeedArrayCounter] = currentSpeed;
                        Console.WriteLine("Writing 1: " + currentSpeed);
                        initialSpeedArrayCounter++;
                        Console.WriteLine("count1: " + initialSpeedArrayCounter);
                    }

                    //If event has stopped, start counting/filling finalSpeedArray
                    if (isCountingFinalSpeed == true && finalSpeedArrayCounter < finalSpeedArray.Length - 1)
                    {
                        finalSpeedArray [finalSpeedArrayCounter] = currentSpeed;
                        Console.WriteLine("Writing 2: " + currentSpeed);
                        finalSpeedArrayCounter++;
                        Console.WriteLine("count2: " + finalSpeedArrayCounter);
                    }

                    //If both speed arrays are full, test event criteria
                    if ((initialSpeedArrayCounter == initialSpeedArray.Length - 1) && (finalSpeedArrayCounter == finalSpeedArray.Length - 1))
                    {
                        Console.WriteLine("initial" + initialSpeedArray [initialSpeedArray.Length - 1]);
                        Console.WriteLine("final  " + finalSpeedArray [finalSpeedArray.Length - 1]);
                        this.determineHardStoOrHardStart(initialSpeedArray, finalSpeedArray);

                        //####################################################################################
                        //CLEAR METHOD
                        //####################################################################################
                        for (int i = 0; i < initialSpeedArray.Length; i++)
                        {
                            initialSpeedArray [i] = 0;
                        }
                        for (int i = 0; i < finalSpeedArray.Length; i++)
                        {
                            finalSpeedArray [i] = 0;
                        }

                        //Reset for new event
                        isCountingFinalSpeed     = false;
                        isCountingInitialSpeed   = false;
                        initialSpeedArrayCounter = 0;
                        finalSpeedArrayCounter   = 0;
                    }

                    this.avgAcc.Text = avgaccel.ToString("0.0000");

                    if (avgaccel > currentMaxAvgAccel)
                    {
                        currentMaxAvgAccel = avgaccel;
                    }

                    this.maxAvgAcc.Text = currentMaxAvgAccel.ToString("0.0000");
                });
            }

            else
            {
                new UIAlertView("Location Services must be enabled to use application!", "We noticed you have disabled location services for this application. Please enable location services.", null, "Ok", null).Show();
                //FIX LATER###########################################################################
                //DismissModalViewControllerAnimated (animated);
                //####################################################################################
            }

            // Perform any additional setup after loading the view, typically from a nib.
        }
        public void StartUpdatesWithMotionDataType(MotionDataType type, int sliderValue)
        {
            double updateInterval = 0.00;
            double delta          = 0.005;

            switch (graphDataSource)
            {
            case MotionDataType.AccelerometerData:
                updateInterval = GraphViewController.accelerometrMin + delta * sliderValue;
                if (mManager.AccelerometerAvailable)
                {
                    mManager.AccelerometerUpdateInterval = updateInterval;
                    mManager.StartAccelerometerUpdates(NSOperationQueue.CurrentQueue, (data, error) => {
                        if (primaryGraph == null)
                        {
                            return;
                        }

                        primaryGraph.AddX(data.Acceleration.X, data.Acceleration.Y, data.Acceleration.Z);
                        SetLabelValueX(data.Acceleration.X, data.Acceleration.Y, data.Acceleration.Z);
                    });
                }
                primaryGraphLabel.Text = "AccelerometerData.Acceleration";
                break;

            case MotionDataType.GyroData:
                updateInterval = gyroMin + delta * sliderValue;
                if (mManager.GyroAvailable)
                {
                    mManager.GyroUpdateInterval = updateInterval;
                    mManager.StartGyroUpdates(NSOperationQueue.CurrentQueue, (gyroData, error) => {
                        if (primaryGraph == null)
                        {
                            return;
                        }

                        primaryGraph.AddX(gyroData.RotationRate.x, gyroData.RotationRate.y, gyroData.RotationRate.z);
                        SetLabelValueX(gyroData.RotationRate.x, gyroData.RotationRate.y, gyroData.RotationRate.z);
                    });
                }
                primaryGraphLabel.Text = "GyroData.RotationRate";
                break;

            case MotionDataType.DeviceMotion:
                updateInterval = deviceMotionMin + delta * sliderValue;
                if (mManager.DeviceMotionAvailable)
                {
                    mManager.DeviceMotionUpdateInterval = updateInterval;
                    mManager.StartDeviceMotionUpdates(NSOperationQueue.CurrentQueue, (motion, error) => {
                        graphs [(int)DeviceMotionGraphType.Attitude].AddX(motion.Attitude.Roll, motion.Attitude.Pitch, motion.Attitude.Yaw);
                        graphs [(int)DeviceMotionGraphType.RotationRate].AddX(motion.RotationRate.x, motion.RotationRate.y, motion.RotationRate.z);
                        graphs [(int)DeviceMotionGraphType.Gravity].AddX(motion.Gravity.X, motion.Gravity.Y, motion.Gravity.Z);
                        graphs [(int)DeviceMotionGraphType.UserAcceleration].AddX(motion.UserAcceleration.X, motion.UserAcceleration.Y, motion.UserAcceleration.Z);

                        switch ((DeviceMotionGraphType)SegmentedControl.SelectedSegment)
                        {
                        case DeviceMotionGraphType.Attitude:
                            SetLabelValueRoll(motion.Attitude.Roll, motion.Attitude.Pitch, motion.Attitude.Yaw);
                            break;

                        case DeviceMotionGraphType.RotationRate:
                            SetLabelValueX(motion.RotationRate.x, motion.RotationRate.y, motion.RotationRate.z);
                            break;

                        case DeviceMotionGraphType.Gravity:
                            SetLabelValueX(motion.Gravity.X, motion.Gravity.Y, motion.Gravity.Z);
                            break;

                        case DeviceMotionGraphType.UserAcceleration:
                            SetLabelValueX(motion.UserAcceleration.X, motion.UserAcceleration.Y, motion.UserAcceleration.Z);
                            break;
                        }
                    });
                }
                primaryGraphLabel.Text = graphTitles [SegmentedControl.SelectedSegment];
                break;
            }
            UpdateIntervalLabel.Text = updateInterval.ToString();
        }
示例#25
0
        public override void Update()
        {
            base.Update();

            // Enable/disable supported sensors and update enabled sensors
            if (accelerometerSensor != null)
            {
                bool enable = accelerometerSensor.IsEnabled;
                if (enable != motionManager.AccelerometerActive)
                {
                    if (accelerometerSensor.IsEnabled)
                    {
                        motionManager.StartAccelerometerUpdates();
                    }
                    else
                    {
                        motionManager.StopAccelerometerUpdates();
                    }
                }

                if (enable)
                {
                    var accelerometerData = motionManager.AccelerometerData;
                    accelerometerSensor.Acceleration = accelerometerData != null?CmAccelerationToVector3(accelerometerData.Acceleration) : Vector3.Zero;
                }
            }
            if (compassSensor != null)
            {
                bool enable = compassSensor.IsEnabled;
                if (enable != locationManagerActivated)
                {
                    if (compassSensor.IsEnabled)
                    {
                        locationManager.StartUpdatingHeading();
                    }
                    else
                    {
                        locationManager.StopUpdatingHeading();
                    }

                    locationManagerActivated = compassSensor.IsEnabled;
                }

                if (enable)
                {
                    compassSensor.Heading = GetNorthInRadian(locationManager);
                }
            }
            if (gyroscopeSensor != null)
            {
                bool enable = gyroscopeSensor.IsEnabled;
                if (enable != motionManager.GyroActive)
                {
                    if (gyroscopeSensor.IsEnabled)
                    {
                        motionManager.StartGyroUpdates();
                    }
                    else
                    {
                        motionManager.StopGyroUpdates();
                    }
                }

                if (enable)
                {
                    var gyroData = motionManager.GyroData;
                    gyroscopeSensor.RotationRate = gyroData != null?CmRotationRateToVector3(gyroData.RotationRate) : Vector3.Zero;
                }
            }
            if (userAccelerationSensor != null)
            {
                bool enable = userAccelerationSensor.IsEnabled || gravitySensor.IsEnabled || orientationSensor.IsEnabled;
                if (enable != motionManager.DeviceMotionActive)
                {
                    if (enable)
                    {
                        motionManager.StartDeviceMotionUpdates();
                    }
                    else
                    {
                        motionManager.StopDeviceMotionUpdates();
                    }
                }

                if (enable)
                {
                    var motion = motionManager.DeviceMotion;
                    // Update orientation sensor
                    if (motion != null && motion.Attitude != null)
                    {
                        var q          = motionManager.DeviceMotion.Attitude.Quaternion;
                        var quaternion = new Quaternion((float)q.x, (float)q.z, -(float)q.y, (float)q.w);

                        if (compassSensor != null)
                        {
                            // re-adjust the orientation to align with the north (common behavior on other platforms) TODO current implementation only takes in account the first value.
                            if (firstNorthValue <= 0)
                            {
                                firstNorthValue = GetNorthInRadian(locationManager);
                            }

                            quaternion = Quaternion.RotationY(-firstNorthValue) * quaternion;
                        }

                        orientationSensor.FromQuaternion(quaternion);
                    }
                    else
                    {
                        orientationSensor.Reset();
                    }

                    // Update gravity sensor
                    gravitySensor.Vector = motion != null?CmAccelerationToVector3(motion.Gravity) : Vector3.Zero;

                    // Update user acceleration
                    userAccelerationSensor.Acceleration = motion != null?CmAccelerationToVector3(motion.Gravity) : Vector3.Zero;
                }
            }
        }