Search Unity

Need help with accelerometer low pass filter

Discussion in 'iOS and tvOS' started by Ohyouknow, Aug 15, 2018.

  1. Ohyouknow

    Ohyouknow

    Joined:
    Oct 23, 2013
    Posts:
    121
    Hi all,

    Bit of a noob here. Would love your help. My game is incredibly shaky/jerky when on tilt mode. Have tried everything I've found online and still nothing has worked. Wondering if someone can take a look at the code I'm currently using for tilt mode and add a way for a low pass filter to work so that tilt mode is enjoyable, and not cause seizures lol. Thanks for your time!

    if (playerObject)
    {
    if (Application.isMobilePlatform )
    {
    if (playerObject.useTiltControls == true)
    {
    playerObject.turnDirection = Vector3.Lerp(playerObject.turnDirection, new Vector3(Input.acceleration.x, Input.acceleration.z + 0.2f), Time.deltaTime * playerObject.turnSpeed);
    }
    else if (playerObject.useMouseControls == true)
    {
    if (Input.GetButton("Fire1")) playerObject.turnDirection = Vector3.Lerp(playerObject.turnDirection, new Vector3((Input.mousePosition.x - Screen.width * 0.5f) / Screen.width * 2, (Input.mousePosition.y - Screen.height * 0.3f) / Screen.height * 1.4f), Time.deltaTime * playerObject.turnSpeed * 0.25f);

    playerObject.turnDirection = Vector3.ClampMagnitude(playerObject.turnDirection, 1);

    //gameCanvas.Find("Text").GetComponent<Text>().text = new Vector3(playerObject.turnDirection.x, playerObject.turnDirection.y).ToString();
    }

    // Limit the position of the camera
    if (playerObject.transform.position.y > playerObject.heightLimit)
    {
    playerObject.turnDirection = Vector3.Lerp(playerObject.turnDirection, new Vector3(playerObject.turnDirection.x, 0), Time.deltaTime * playerObject.turnSpeed * 0.2f);
    }
    }
    else
    {
    // Using the mouse for movement
    if (usingMouse == true)
    {
    playerObject.turnDirection = Vector3.Lerp(playerObject.turnDirection, new Vector3((Input.mousePosition.x - Screen.width * 0.5f) / Screen.width * 2, (Input.mousePosition.y - Screen.height * 0.5f) / Screen.height * 2), Time.deltaTime * playerObject.turnSpeed);
    }
    else
    {
    playerObject.turnDirection = Vector3.Lerp(playerObject.turnDirection, new Vector3(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical")), Time.deltaTime * playerObject.turnSpeed * 0.1f);
    }
    }
    }
    }
    }
    }
     
  2. MrMatthias

    MrMatthias

    Joined:
    Sep 18, 2012
    Posts:
    191
    A simple lowpass filter would be a moving average. you save x past acceleration vectors and average them. You could also try giving them different weights, so the more recent ones have a greater influence
     
  3. Ohyouknow

    Ohyouknow

    Joined:
    Oct 23, 2013
    Posts:
    121
    @mrmathis

    I'm not quite sure how to do that. I watched a video on youtube which showed adding weights and so on, but I'm not getting different results.

    What could I add to: playerObject.turnDirection = Vector2.Lerp(playerObject.turnDirection, new Vector2(Input.acceleration.x, Input.acceleration.z + 0.2f), Time.deltaTime * playerObject.turnSpeed);

    to stabilize this?
     
  4. Ohyouknow

    Ohyouknow

    Joined:
    Oct 23, 2013
    Posts:
    121
    never mind, got it working.
     
  5. MrMatthias

    MrMatthias

    Joined:
    Sep 18, 2012
    Posts:
    191
    Here is an example:
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class SmoothAccelerometer : MonoBehaviour
    4. {
    5.     [SerializeField] private int _numSamples;
    6.     [SerializeField] private AnimationCurve _weightCurve;
    7.  
    8.     private Vector3[] _samples;
    9.     private float[] _weights;
    10.     private float _weightSum;
    11.     private int _currentSample;
    12.     private Vector3 _acceleration;
    13.  
    14.     public Vector3 acceleration
    15.     {
    16.         get { return _acceleration; }
    17.     }
    18.  
    19.     private void Awake()
    20.     {
    21.         _samples = new Vector3[_numSamples];
    22.         _weights = new float[_numSamples];
    23.         _weightSum = 0;
    24.         for (int i = 0; i < _numSamples; i++)
    25.         {
    26.             _samples[i] = Vector3.zero;
    27.             _weights[i] = _weightCurve.Evaluate(1f - 1f / _numSamples * i);
    28.             _weightSum += _weights[i];
    29.         }
    30.     }
    31.  
    32.     void Update ()
    33.     {
    34.         _samples[_currentSample] = Input.acceleration;
    35.        
    36.         _acceleration = Vector3.zero;
    37.         int index;
    38.         for (int i = 0; i < _numSamples; i++)
    39.         {
    40.             index = _currentSample - i;
    41.             if (index < 0)
    42.                 index = _numSamples - (i - _currentSample);
    43.             _acceleration += _samples[index] * _weights[index];
    44.         }
    45.         _acceleration /= _weightSum;
    46.         _currentSample = ++_currentSample % _numSamples;
    47.     }
    48. }
    Screen Shot 2018-08-19 at 00.46.59.png
    Top 3 are unsmoothed:
    IMG_0019.PNG