예제 #1
0
        private void OnMotionChanged(CMDeviceMotion motion)
        {
            var orientation = ToSimpleOrientation(motion.Gravity.X, motion.Gravity.Y, motion.Gravity.Z, _threshold, _previousOrientation);

            _previousOrientation = orientation;
            SetCurrentOrientation(orientation);
        }
예제 #2
0
        public void GyroChanged(CMDeviceMotion m, NSError e)
        {
            var now = DateTime.Now;

            if (e != null || m == null || m.Attitude == null || now - lastGyroUpdateTime <= GyroUpdateInterval)
            {
                return;
            }
            lastGyroUpdateTime = now;
            var speed = Math.Cos(Math.Max(0, Math.Min(Math.PI / 2, m.Attitude.Pitch)));
            var turn  = Math.Sin(Math.Max(-Math.PI / 2, Math.Min(Math.PI / 2, m.Attitude.Roll)));



            InvokeOnMainThread(() =>
            {
                var speedVariable = client.Variables.FirstOrDefault(x => x.Name == "Speed");
                if (speedVariable != null)
                {
                    speedVariable.Value = speed;
                }

                var turnVariable = client.Variables.FirstOrDefault(x => x.Name == "Turn");
                if (turnVariable != null)
                {
                    turnVariable.Value = turn;
                }

                ViewLeft.Alpha    = (nfloat)(1.0f * (turn > 0 ? 0 : turn * -1));
                ViewRight.Alpha   = (nfloat)(1.0f * (turn < 0 ? 0 : turn));
                ViewForward.Alpha = (nfloat)(1.0f * (speed < 0 ? 0 : speed));

                TextTilt.Text = string.Format("Speed: {0:N2}\nTurn: {1:N2}", Math.Round(speed, 2), Math.Round(turn, 2));
            });
        }
예제 #3
0
        void OnGyroscopeDataUpdate(CMDeviceMotion gyroData, NSError error)
        {
            if (error == null)
            {
                _attitude  = gyroData.Attitude;
                data.Angle = _attitude.Yaw;

                OnCompassDataChanged(this, data);
            }
        }
예제 #4
0
 private void MotionHandler(CMDeviceMotion data, NSError error)
 {
     if (Interlocked.CompareExchange(ref Updating, 1, 0) == 1)
     {
         return;
     }
     InvokeOnMainThread(() =>
     {
         UpdateElementsOnScreen((float)data.Attitude.Roll, (float)data.Attitude.Pitch, (float)data.Attitude.Yaw);
         Interlocked.Exchange(ref Updating, 0);
     });
 }
예제 #5
0
        void UpdateDisplay()
        {
            CMDeviceMotion motion = motionManager.DeviceMotion;

            if (motion != null)
            {
                cameraTransform = new float[16];
                MathHelpers.TransformFromCMRotationMatrix(ref cameraTransform, motion.Attitude.RotationMatrix);

                SetNeedsDisplay();
            }
        }
예제 #6
0
        static void DataUpdated(CMDeviceMotion data, NSError error)
        {
            if (data == null)
            {
                return;
            }

            var field        = data.Attitude.Quaternion;
            var rotationData = new OrientationSensorData(field.x, field.y, field.z, field.w);

            OnChanged(rotationData);
        }
예제 #7
0
        void HandleCMDeviceMotionHandler(CMDeviceMotion data, NSError error)
        {
            //Linear acceleration (acceleration - gravity)
            DateTimeOffset timestamp = DateTimeOffset.Now;

            _accelerometerRepository.Add(new Accelerometer()
            {
                Timestamp = timestamp,
                X         = Convert.ToSingle(data.UserAcceleration.X),
                Y         = Convert.ToSingle(data.UserAcceleration.Y),
                Z         = Convert.ToSingle(data.UserAcceleration.Z)
            });
            //Console.WriteLine("inserted linear acceleratin data");

            //calibrated magnetic field
            _magnetometerRepository.Add(new Magnetometer()
            {
                Timestamp = timestamp,
                X         = Convert.ToSingle(data.MagneticField.Field.X),
                Y         = Convert.ToSingle(data.MagneticField.Field.Y),
                Z         = Convert.ToSingle(data.MagneticField.Field.Z)
            });
            //Console.WriteLine("inserted callibrated magnetometerdata");

            _orientationRepository.Add(new Orientation()
            {
                Timestamp = timestamp,
                X         = Convert.ToSingle(data.Attitude.Roll),
                Y         = Convert.ToSingle(data.Attitude.Pitch),
                Z         = Convert.ToSingle(data.Attitude.Yaw)
            });
            //Console.WriteLine("inserted attitude");

            _quaternionRepository.Add(new Quaternion()
            {
                Timestamp = timestamp,
                X         = Convert.ToSingle(data.Attitude.Quaternion.x),
                Y         = Convert.ToSingle(data.Attitude.Quaternion.y),
                Z         = Convert.ToSingle(data.Attitude.Quaternion.z),
                W         = Convert.ToSingle(data.Attitude.Quaternion.w)
            });

            _gravityRepository.Add(new Gravity()
            {
                Timestamp = timestamp,
                X         = Convert.ToSingle(data.Gravity.X),
                Y         = Convert.ToSingle(data.Gravity.Y),
                Z         = Convert.ToSingle(data.Gravity.Z)
            });
        }
예제 #8
0
        private void ReadingChangedHandler(CMDeviceMotion data, NSError error)
        {
            CompassReading reading = new CompassReading();

            this.IsDataValid = error == null;
            if (this.IsDataValid)
            {
                reading.MagnetometerReading = new Vector3((float)data.MagneticField.Field.Y, (float)-data.MagneticField.Field.X, (float)data.MagneticField.Field.Z);
                reading.TrueHeading         = Math.Atan2(reading.MagnetometerReading.Y, reading.MagnetometerReading.X) / Math.PI * 180;
                reading.MagneticHeading     = reading.TrueHeading;
                switch (data.MagneticField.Accuracy)
                {
                case CMMagneticFieldCalibrationAccuracy.High:
                    reading.HeadingAccuracy = 5d;
                    break;

                case CMMagneticFieldCalibrationAccuracy.Medium:
                    reading.HeadingAccuracy = 30d;
                    break;

                case CMMagneticFieldCalibrationAccuracy.Low:
                    reading.HeadingAccuracy = 45d;
                    break;
                }

                // Send calibrate event if needed
                if (data.MagneticField.Accuracy == CMMagneticFieldCalibrationAccuracy.Uncalibrated)
                {
                    if (this.calibrate == false)
                    {
                        this.Calibrate(this, new CalibrationEventArgs());
                    }
                    this.calibrate = true;
                }
                else if (this.calibrate == true)
                {
                    this.calibrate = false;
                }

                reading.Timestamp = DateTime.Now;
                this.CurrentValue = reading;
            }
            FireOnCurrentValueChanged(this, new SensorReadingEventArgs <CompassReading>(reading));
        }
예제 #9
0
        void Update()
        {
            if (motionManager.DeviceMotionActive)
            {
                CMDeviceMotion deviceMotion = motionManager.DeviceMotion;
                if (deviceMotion != null)
                {
                    CMAcceleration acceleration = deviceMotion.Gravity;
                    xValue = acceleration.X;
                    yValue = acceleration.Y;
                    zValue = acceleration.Z;
                    isData = true;
                }
            }

            if (isRunning)
            {
                PerformSelector(new ObjCRuntime.Selector("Update"), null, UpdateInterval);
            }
        }
예제 #10
0
        static void DataUpdated(CMDeviceMotion data, NSError error)
        {
            if (data == null)
            {
                return;
            }

            var field = data.Attitude.Quaternion;

            // the quaternion returned by the MotionManager refers to a frame where the X axis points north
            var q = new Quaternion((float)field.x, (float)field.y, (float)field.z, (float)field.w);

            // we rotate it by 90 degrees around the Z axis, so that the Y axis points north and the X axis points east
            var qz90 = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, (float)(Math.PI / 2.0));

            q = Quaternion.Multiply(q, qz90);
            var rotationData = new OrientationSensorData(q.X, q.Y, q.Z, q.W);

            OnChanged(rotationData);
        }
예제 #11
0
        void CalculateRotationBasedOn(CMDeviceMotion motion)
        {
            if (!MotionBasedPanEnabled)
            {
                return;
            }
            var rrate = motion.RotationRate;

            if (Math.Abs(rrate.y) <= Math.Abs(rrate.x) + Math.Abs(rrate.z))
            {
                return;
            }
            var   invertedYRotationRate = rrate.y * -1;
            float zoomScale             = MaximumZoomScaleForImage(panningImageView.Image);
            var   interpretedXOffset    = panningScrollView.ContentOffset.X + invertedYRotationRate * zoomScale * RotationMultiplier;
            var   contentOffset         = ClampedContentOffsetForHorizontalOffset((float)interpretedXOffset);

            UIView.Animate(MovementSmoothing,
                           delay: 0,
                           options: UIViewAnimationOptions.BeginFromCurrentState | UIViewAnimationOptions.AllowUserInteraction | UIViewAnimationOptions.CurveEaseOut,
                           animation: () => panningScrollView.SetContentOffset(contentOffset, animated: false), completion: null);
        }
예제 #12
0
        static void DataUpdated(CMDeviceMotion data, NSError error)
        {
            if (data == null)
            {
                return;
            }

            var field = data.Attitude.Quaternion;

            // the quaternion returned by the MotionManager refers to a frame where the X axis points north ("iOS frame")
            var q = new Quaternion((float)field.x, (float)field.y, (float)field.z, (float)field.w);

            // in Xamarin, the reference frame is defined such that Y points north and Z is vertical,
            // so we first rotate by 90 degrees around the Z axis, in order to get from the Xamarin frame to the iOS frame
            var qz90 = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, (float)(Math.PI / 2.0));

            // on top of this rotation, we apply the actual quaternion obtained from the MotionManager,
            // so that the final quaternion will take us from the earth frame in Xamarin convention to the phone frame
            q = Quaternion.Multiply(qz90, q);
            var rotationData = new OrientationSensorData(q.X, q.Y, q.Z, q.W);

            OnChanged(rotationData);
        }
예제 #13
0
        void DataUpdated(CMDeviceMotion data, NSError error)
        {
            if (data == null)
            {
                return;
            }

#pragma warning disable CA1416 // https://github.com/xamarin/xamarin-macios/issues/14619
            var field = data.Attitude.Quaternion;
#pragma warning restore CA1416

            // the quaternion returned by the MotionManager refers to a frame where the X axis points north ("iOS frame")
            var q = new Quaternion((float)field.x, (float)field.y, (float)field.z, (float)field.w);

            // In .NET MAUI, the reference frame is defined such that Y points north and Z is vertical,
            // so we first rotate by 90 degrees around the Z axis, in order to get from the .NET MAUI frame to the iOS frame
            var qz90 = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, (float)(Math.PI / 2.0));

            // on top of this rotation, we apply the actual quaternion obtained from the MotionManager,
            // so that the final quaternion will take us from the earth frame in .NET MAUI convention to the phone frame
            q = Quaternion.Multiply(qz90, q);
            var rotationData = new OrientationSensorData(q.X, q.Y, q.Z, q.W);
            RaiseReadingChanged(rotationData);
        }
예제 #14
0
 private void MagnetometerHandler(CMDeviceMotion magnetometerData, NSError error)
 {
     readingChanged(magnetometerData, error);
 }
예제 #15
0
        void CalculateRotationBasedOn(CMDeviceMotion motion)
        {
            if (!MotionBasedPanEnabled)
                return;
            var rrate = motion.RotationRate;
            if (Math.Abs (rrate.y) <= Math.Abs (rrate.x) + Math.Abs (rrate.z))
                return;
            var invertedYRotationRate = rrate.y * -1;
            float zoomScale = MaximumZoomScaleForImage (panningImageView.Image);
            var interpretedXOffset = panningScrollView.ContentOffset.X + invertedYRotationRate * zoomScale * RotationMultiplier;
            var contentOffset = ClampedContentOffsetForHorizontalOffset ((float)interpretedXOffset);

            UIView.Animate (MovementSmoothing,
                delay: 0,
                options: UIViewAnimationOptions.BeginFromCurrentState|UIViewAnimationOptions.AllowUserInteraction|UIViewAnimationOptions.CurveEaseOut,
                animation: () => panningScrollView.SetContentOffset (contentOffset, animated: false), completion: null);
        }
        /// <summary>
        /// Raises the accelerometer changed event.
        /// </summary>
        /// <param name="data">Data.</param>
        /// <param name="error">Error.</param>
        private void OnDeviceMotionChanged(CMDeviceMotion data, NSError error)
        {
            if (SensorValueChanged == null)
                return;

            SensorValueChanged(this, new SensorValueChangedEventArgs { ValueType = MotionSensorValueType.Attitude, SensorType = MotionSensorType.DeviceMotion, Value = new MotionAttitude() { Pitch = data.Attitude.Pitch, Yaw = data.Attitude.Yaw, Roll = data.Attitude.Roll } });
        }