/// <summary>
 /// The accelerometer sensor value changed handler.
 /// </summary>
 /// <param name="sender">The event sender.</param>
 /// <param name="e">The accelerometer reading event args.</param>
 private static void accelerometerCurrentValueChanged(object sender, AccelerometerHelperReadingEventArgs e)
 {
     currentRawAccelerometerReading              = e.RawAcceleration;
     currentAverageAccelerometerReading          = e.AverageAcceleration;
     currentLowPassFilteredAccelerometerReading  = e.LowPassFilteredAcceleration;
     currentOptimalyFilteredAccelerometerReading = e.OptimalyFilteredAcceleration;
 }
Esempio n. 2
0
 private void OnAccelerometerHelperReadingChanged(object sender, AccelerometerHelperReadingEventArgs e)
 {
     lock (this.accelerometerLock)
     {
         this.accelerometerY = e.AverageAcceleration.Y;
     }
 }
Esempio n. 3
0
 /// <summary>
 /// Aggiorna la posizione del cursore ridefinendone i margini
 /// </summary>
 void UpdateImagePos(AccelerometerHelperReadingEventArgs e)
 {
     //MessageBox.Show("cambio posizione immagine");
     /* Vado a fare data smoothing dei dati presi dall'accelerometro */
     timerX = Math.Round(e.LowPassFilteredAcceleration.X, 3) - x_calib;
     timerY = Math.Round(e.LowPassFilteredAcceleration.Y, 3) - y_calib;
     // Cursore.Margin = new Thickness(getX(), getY(), (width - (getX() + Cursore.Width)), (height - (getY() + Cursore.Height)));
     MargineCursore = new Thickness(getX(), getY(), (width - (getX() + Cursore.Width)), (height - (getY() + Cursore.Height)));
     //MessageBox.Show("cambio posizione immagine" + new Thickness(getX(), getY(), (width - (getX() + Cursore.Width)), (height - (getY() + Cursore.Height))).ToString());
 }
Esempio n. 4
0
 /// <summary>
 /// Update the UI - sensor visuals and check for device orientation
 /// </summary>
 private void UpdateUI(AccelerometerHelperReadingEventArgs e)
 {
     if (SurfaceShown)
     {
         UpdateSurfaceBubble(e);
     }
     else
     {
         UpdateTubeBubble(e);
     }
 }
Esempio n. 5
0
        private void OnAccelerometerHelperReadingChanged(object sender, AccelerometerHelperReadingEventArgs e)
        {
            var x = e.AverageAcceleration.X * -64.0;
            var y = e.AverageAcceleration.Y * 64.0;

            Dispatcher.BeginInvoke(() =>
            {
                BackgroundTransform.X = Math.Max(-24, Math.Min(24, x));
                BackgroundTransform.Y = Math.Max(-24, Math.Min(24, y));
            });
        }
 private void OnAccelerometerHelperReadingChanged(object sender, AccelerometerHelperReadingEventArgs e)
 {
     if (e.OptimalyFilteredAcceleration.X >= 0.6 && e.OptimalyFilteredAcceleration.X <= 1)
     {
         if (saberState == SaberState.On)
         {
             LightSaberSwing();
         }
         else if (saberState == SaberState.Off)
         {
             saberState = SaberState.Starting;
             LightSaberSwitch();
         }
     }
 }
        /// <summary>
        /// Called when the accelerometer provides a new value
        /// </summary>
        private void OnAccelerometerHelperReadingChanged(object sender, AccelerometerHelperReadingEventArgs e)
        {
            // work with optimal vector (without noise)
            Simple3DVector currentVector = e.OptimalyFilteredAcceleration;

            // check if this vector is considered a shake vector
            bool isShakeMagnitude = (Math.Abs(_lastStillVector.Magnitude - currentVector.Magnitude) > ShakeMagnitudeWithoutGravitationThreshold);

            // following is a state machine for detection of shake signal start and end

            // if still --> shake
            if ((!_isInShakeState) && (isShakeMagnitude))
            {
                // set shake state flag
                _isInShakeState = true;

                // clear old shake signal
                ClearShakeSignal();

                // process still signal
                ProcessStillSignal();

                // add vector to shake signal
                AddVectorToShakeSignal(currentVector);
            }
            // if still --> still
            else if ((!_isInShakeState) && (!isShakeMagnitude))
            {
                // add vector to still signal
                AddVectorToStillSignal(currentVector);
            }
            // if shake --> shake
            else if ((_isInShakeState) && (isShakeMagnitude))
            {
                // add vector to shake signal
                AddVectorToShakeSignal(currentVector);

                // reset still counter
                _stillCounter = 0;

                // try to process shake signal
                if (ProcessShakeSignal())
                {
                    // shake signal generated, clear used data
                    ClearShakeSignal();
                }
            }
            // if shake --> still
            else if ((_isInShakeState) && (!isShakeMagnitude))
            {
                // add vector to shake signal
                AddVectorToShakeSignal(currentVector);

                // count still vectors
                _stillCounter++;

                // if too much still samples
                if (_stillCounter > StillCounterThreshold)
                {
                    // clear old still signal
                    _stillSignal.Clear();

                    // add still vectors from shake signal to still signal
                    for (int i = 0; i < StillCounterThreshold; ++i)
                    {
                        // calculate current index element
                        int currentSampleIndex = _shakeSignal.Count - StillCounterThreshold + i;

                        // add vector to still signal
                        AddVectorToStillSignal(currentVector);
                    }

                    // remove last samples from shake signal
                    _shakeSignal.RemoveRange(_shakeSignal.Count - StillCounterThreshold, StillCounterThreshold);

                    // reset shake state flag
                    _isInShakeState = false;
                    _stillCounter   = 0;

                    // try to process shake signal
                    if (ProcessShakeSignal())
                    {
                        ClearShakeSignal();
                    }
                }
            }
        }
Esempio n. 8
0
        /// <summary>
        /// Update the tube level visuals
        /// </summary>
        private void UpdateTubeBubble(AccelerometerHelperReadingEventArgs e)
        {
            // ANGLE TEXT
            // ----------

            // Use filtered accelemeter data (st5ady)
            double x = e.OptimallyFilteredAcceleration.X;
            double y = e.OptimallyFilteredAcceleration.Y;
            double horizontalAcceleration;
            double verticalAcceleration;

            // Choose appropriate axis based on orientation of level
            horizontalAcceleration = _bubbleDirection * (DeviceOrientationHelper.IsPortrait(_levelOrientation) ? x : y);
            verticalAcceleration   = _bubbleDirection * (DeviceOrientationHelper.IsPortrait(_levelOrientation) ? y : -x); // rotate XY plan by -90

            // Convert acceleration vector coordinates to Angles and Magnitude
            // Update reading on screen of instant inclination assuming steady device (gravity = measured acceleration)
            double magnitudeXYZ = e.OptimallyFilteredAcceleration.Magnitude;
            double angle        = 0.0;

            if (magnitudeXYZ != 0.0)
            {
                angle = Math.Asin(horizontalAcceleration / magnitudeXYZ) * 180.0 / Math.PI;
            }
            _angle = angle;
            // Display angles as if they were buoyancy force instead of gravity (opposite) since it is
            // more natural to match targeted bubble location
            _angleText = String.Format("{0:0.0}°", _angle);

            // BUBBLE POSITION
            // ---------------

            // ----------------------------------------------------------
            // For simplicity we are approximating that the bubble experiences a lateral attraction force
            // proportional to the distance to its target location (top of the glass based on inclination).
            // We will neglect the vertical speed of the bubble since the radius of the glass curve is much greater
            // than the radius of radius of usable glass surface

            // Assume tube curve has a 1m radius
            // Destination position is x and y
            // Current position is _bubblePosition.X (use only one dimension)

            // Update Buoyancy
            double lateralAcceleration = (horizontalAcceleration - _bubblePosition.X) * BuoyancyCoef * StandardGravityInMetric;

            // Update drag:
            double drag = _bubbleSpeed.X * (-ViscosityCoef);

            // Update speed:
            lateralAcceleration += drag;
            lateralAcceleration /= AccelerometerRefreshRate; // impulse
            _bubbleSpeed        += new Simple3DVector(lateralAcceleration, 0, 0);

            // Update position
            _bubblePosition += (_bubbleSpeed / AccelerometerRefreshRate);

            double edgeRadius = Math.Sin(EdgeGlassAngle);

            // Get resulting direction and magnitude of bubble position given X
            double magnitudeFlat = Math.Abs(_bubblePosition.X);
            double direction     = Math.Sign(_bubblePosition.X);

            bool atEdge = false;

            if (magnitudeFlat > edgeRadius)
            { // Bubble reaches the edge
                magnitudeFlat = edgeRadius;
                // lossy bouncing when reaching edges
                // change direction
                _bubbleSpeed *= -EdgeBouncingLossCoef;
                // limit bubble position to edge
                _bubblePosition = new Simple3DVector(magnitudeFlat * direction, 0, 0);
                atEdge          = true;
            }

            // Calculate position of bubble
            MoveBubble.X = (_bubblePosition.X / edgeRadius) * ((UsableLateralAmplitude / 2) - (BubbleCanvas.Width / 4));

            // Change bubble shape
            double stretchRatio;

            if (atEdge)
            {
                TubeBubbleSkew.AngleX  = 0;
                stretchRatio           = 1.0 + (Math.Abs(Math.Sin(angle / 180.0 * Math.PI)) - Math.Sin(EdgeGlassAngle)) * AngleBasedTubeBubbleStrechingAtEdgeCoef;
                TubeBubbleScale.ScaleX = 1.0 / stretchRatio;
                TubeBubbleScale.ScaleY = SideWayBubbleAtEdgeBoostOnYAxis * stretchRatio;
            }
            else
            {
                double horizontalSpeed     = Math.Abs(_bubbleSpeed.X);
                double horizontalDirection = Math.Sign(_bubbleSpeed.X);
                // Stretch is proportional to horizontal speed
                stretchRatio = Math.Min(horizontalSpeed * SpeedBubbleStrechingCoef, MaximumBubbleXYStretchRatio - 1.0) + 1.0;
                if (stretchRatio < MinimumStretchRatio)
                {
                    stretchRatio = MinimumStretchRatio;
                }
                TubeBubbleSkew.AngleX = MaximumTubeBubbleSkew * (stretchRatio - 1.0) / (MaximumBubbleXYStretchRatio - 1.0) * horizontalDirection;
                // Stretch is also proportional to buoyancy
                stretchRatio -= TubeBubbleStretchBuoyancyCoef * ((verticalAcceleration / magnitudeXYZ) - MedianVerticalAcceleration);
                if (stretchRatio < MinimumStretchRatio)
                {
                    stretchRatio = MinimumStretchRatio;
                }
                TubeBubbleScale.ScaleX = 1.0 / stretchRatio;
                TubeBubbleScale.ScaleY = MaximumBubbleXYStretchRatio * stretchRatio;
            }
        }
Esempio n. 9
0
        /// <summary>
        /// Update the surface level visuals
        /// </summary>
        private void UpdateSurfaceBubble(AccelerometerHelperReadingEventArgs e)
        {
            // ANGLE TEXT
            // ----------

            // Use filtered accelemeter data (steady)
            double x = -e.OptimallyFilteredAcceleration.X; // Orientation compensation
            double y = e.OptimallyFilteredAcceleration.Y;

            // Convert acceleration vector coordinates to Angles and Magnitude
            // Update reading on screen of instant inclination assuming steady device (gravity = measured acceleration)
            double magnitudeXYZ = e.OptimallyFilteredAcceleration.Magnitude;
            double xAngle       = 0.0;
            double yAngle       = 0.0;

            if (magnitudeXYZ != 0.0)
            {
                xAngle = Math.Asin(x / magnitudeXYZ) * 180.0 / Math.PI;
                yAngle = Math.Asin(y / magnitudeXYZ) * 180.0 / Math.PI;
            }

            _angle = Math.Abs(xAngle) + Math.Abs(yAngle);
            // Display angles as if they were buoyancy force instead of gravity (opposite) since it is
            // more natural to match targeted bubble location
            // Also orientation of Y-axis is opposite of screen for natural upward orientation
            _angleText = String.Format("{0:0.0}°  {1:0.0}°", xAngle, -yAngle);

            // BUBBLE POSITION
            // ---------------

            // ----------------------------------------------------------
            // For simplicity we are approximating that the bubble experiences a lateral attraction force
            // proportional to the distance to its target location (top of the glass based on inclination).
            // We will neglect the vertical speed of the bubble since the radius of the glass curve is much greater
            // than the radius of radius of usable glass surface

            // Assume sphere has a 1m radius
            // Destination position is x and y
            // Current position is _bubblePosition

            // Update Buoyancy
            Simple3DVector lateralAcceleration = (new Simple3DVector(x, y, 0) - _bubblePosition) * BuoyancyCoef * StandardGravityInMetric;

            // Update drag:
            Simple3DVector drag = _bubbleSpeed * (-ViscosityCoef);

            // Update speed:
            lateralAcceleration += drag;
            lateralAcceleration /= AccelerometerRefreshRate; // impulse
            _bubbleSpeed        += lateralAcceleration;

            // Update position
            _bubblePosition += _bubbleSpeed / AccelerometerRefreshRate;

            double edgeRadius = Math.Sin(EdgeGlassAngle);

            x = _bubblePosition.X;
            y = _bubblePosition.Y;

            // Get resulting angle and magnitude of bubble position given X and Y
            double angleFlat     = Math.Atan2(y, x);
            double magnitudeFlat = Math.Sqrt(x * x + y * y);

            bool atEdge = false;

            if (magnitudeFlat > edgeRadius)
            { // Bubble reaches the edge
                magnitudeFlat = edgeRadius;
                // lossy bouncing when reaching edges
                _bubbleSpeed *= EdgeBouncingLossCoef;
                // Mirror movement along center to edge line
                _bubbleSpeed = new Simple3DVector(_bubbleSpeed.X * Math.Cos(2 * angleFlat) + _bubbleSpeed.Y * Math.Sin(2 * angleFlat),
                                                  _bubbleSpeed.X * Math.Sin(2 * angleFlat) - _bubbleSpeed.Y * Math.Cos(2 * angleFlat),
                                                  0);
                // change direction on x and y
                _bubbleSpeed *= new Simple3DVector(-1, -1, 1);
                // limit bubble position to edge
                _bubblePosition = new Simple3DVector(magnitudeFlat * Math.Cos(angleFlat), magnitudeFlat * Math.Sin(angleFlat), 0);
                atEdge          = true;
            }

            // Set x and y location of the surface level bubble based on angle and magnitude
            double xPixelLocation = Math.Cos(angleFlat) * (magnitudeFlat / edgeRadius) * (UsableLateralAmplitude - SurfaceBubble.Width) / 2;
            double yPixelLocation = Math.Sin(angleFlat) * (magnitudeFlat / edgeRadius) * (UsableLateralAmplitude - SurfaceBubble.Width) / 2;

            SurfaceBubble.SetValue(Canvas.LeftProperty, xPixelLocation + (SurfaceLevelOuter.Width - SurfaceBubble.Width) / 2);
            SurfaceBubble.SetValue(Canvas.TopProperty, yPixelLocation + (SurfaceLevelOuter.Height - SurfaceBubble.Width) / 2);

            // Change bubble shape
            double stretchRatio;
            double horizontalDirection;

            if (atEdge)
            {
                stretchRatio        = MaximumBubbleXYStretchRatio;
                horizontalDirection = angleFlat - Math.PI / 2;
            }
            else
            {
                x = _bubbleSpeed.X;
                y = _bubbleSpeed.Y;
                double horizontalSpeed = Math.Sqrt(x * x + y * y);
                horizontalDirection = Math.Atan2(y, x) - Math.PI / 2;
                stretchRatio        = Math.Min(horizontalSpeed * SpeedBubbleStrechingCoef, MaximumBubbleXYStretchRatio - 1.0) + 1.0;
            }
            SurfaceBubbleDirection.Angle = horizontalDirection * 180.0 / Math.PI;
            SurfaceBubbleScale.ScaleX    = stretchRatio;
            SurfaceBubbleScale.ScaleY    = 1.0 / stretchRatio;
        }
Esempio n. 10
0
 /// <summary>
 /// On Reading change / new sample from accelerometer
 /// </summary>
 /// <param name="sender">Event sender</param>
 /// <param name="e">Event arguments</param>
 private void accelerometerHelper_ReadingChanged(object sender, AccelerometerHelperReadingEventArgs e)
 {
     Dispatcher.BeginInvoke(() => UpdateUI(e));
 }
Esempio n. 11
0
 /// <summary>
 /// Ogni 50 volte al secondo (frequenza di campionamento dell'accelerometro)
 /// vado a chiamare il metodo UpdateImagePos
 /// </summary>
 private void OnAccelerometerHelperReadingChanged(object sender, AccelerometerHelperReadingEventArgs e)
 {
     Deployment.Current.Dispatcher.BeginInvoke(() => UpdateImagePos(e));
 }
Esempio n. 12
0
        void _accelerometer_ReadingChanged(object sender, AccelerometerHelperReadingEventArgs e)
        {
            if (_last == null)
            {
                _last = e.RawAcceleration;
            }
            else
            {
                Simple3DVector _current = e.RawAcceleration;

                double _cosa = (_current.X * _last.X + _current.Y * _last.Y + _current.Z * _last.Z) /
                               (Math.Sqrt(_current.X * _current.X + _current.Y * _current.Y + _current.Z * _current.Z) *
                                Math.Sqrt(_last.X * _last.X + _last.Y * _last.Y + _last.Z * _last.Z));

                if (_samplesCount < 10)
                {
                    _dsamples[_samplesCount] += _cosa;
                    _samplesCount            += 1;
                }
                else
                {
                    Array.Copy(_dsamples, 1, _dsamples, 0, _dsamples.Length - 1);
                    _dsamples[9] = _cosa;

                    if (_skip >= 10)
                    {
                        _skip       = 0;
                        _isSkipping = false;
                    }
                    else
                    {
                        if (_isSkipping)
                        {
                            _skip += 1;
                        }
                    }

                    if (!_isSkipping)
                    {
                        //double _weightedAverage = (double)Enumerable.Range(0, 9).Select(x => (x + 2) * _dsamples[x]).Sum() / 55;
                        ////don't know why +2 works but as long as it does...or not

                        //non-LINQ alternative
                        double _weightedAverage = 0;
                        for (int i = 0; i < 10; i++)
                        {
                            _weightedAverage += (i + 1) * _dsamples[i];
                        }
                        _weightedAverage = _weightedAverage / 55;

                        if (_weightedAverage > _lastAverage && _weightedAverage < 0.95) //hardcoded threshold
                        {
                            OnStepDetected();
                            _isSkipping = true;
                            _skip       = 0;
                        }
                        _lastAverage = _weightedAverage;
                    }
                }

                _last = _current;
            }
        }