Search Unity

Illogical accelerometer readings on Z-Axis

Discussion in 'Scripting' started by vipasane, Mar 6, 2015.

  1. vipasane

    vipasane

    Joined:
    Feb 11, 2015
    Posts:
    14
    Hi Im trying to rotate my object on Z-axis depending the readings from accelerometer sensors and selected Axis from the settings..

    Im calibrating the starting position (Accelerometer reading) by getting an average and act accordingly later,
    For some reason especially with Z-axis when I start the game by calibrating the device upside down (camera down) I get crazy behaviour. The object only rotates one way no matter what I do.
    Its like Unity would be changing the axis reading from positive to negative and vice versa.

    This is so hard to test, while cant have readings while debugging.
    Any tips or suggestions you might have, it would be greatly appreciated.
    Im testing with Lumia 1020, but my friend has same issues with iPhone 6. So i believe that the issue relies in between the chair and the kayboard.



    Code (CSharp):
    1.    
    2. void Update()
    3.     {
    4.         if (!gameEnded)
    5.         {
    6.             if(calibrating)
    7.             {
    8. // calibration time remaining
    9.                 timeRemaining -= Time.deltaTime;
    10.  
    11.                 //Trying to get starting position, calibration for current axis
    12.                 //Will take every 10th reading for calibration
    13.                 if(calibrationCounter%10 == 0)
    14.                 {
    15.                     calibrationReadings.Add(GetCurrentAccelerometerReading());
    16.                 }
    17.  
    18.                 if(timeRemaining <= 0)
    19.                 {
    20.                     startGame();
    21.                 }
    22.             }
    23.             else
    24.             {
    25.                 //transform.Rotate (0, 0, 1);
    26.                 //real rotation is something like this
    27.                 Vector3 vec = new Vector3(0, 0 , getNormalizedAccReading());
    28.                 //transform.Rotate(0, 0 , getNormalizedAccReading());
    29.                 transform.Rotate(vec);
    30. .......
    31.  
    32.  
    33.     private float getNormalizedAccReading()
    34.     {
    35.         float ret = 0.0f;
    36.         //reawding range [-1,1]
    37.         float reading = GetCurrentAccelerometerReading ();
    38.  
    39.         //float minDistance = reading - avgCalibration;
    40.  
    41.         // AvgCalibration range [-1,1]
    42.         //reading = avgCalibration + reading;
    43.         // Max Calibration range [-2,2]
    44.         // -1 ja -1 = 0
    45.         // +1 ja +1 = 0
    46.         // 0 ja 0 = 0
    47.  
    48.         float distA;
    49.         float distB;
    50.         if (avgCalibration <= reading)
    51.         {
    52.             distA = reading - avgCalibration;
    53.         }
    54.         else
    55.         {
    56.             distA = reading - avgCalibration;
    57.         }
    58.  
    59.         // Get the shortest distance, eighter direct or from other way around  (the sum ABS values is 2 and other is positive and the other is always negative
    60.         if (distA < 0)
    61.         {
    62.             distB = Mathf.Abs((2.0f - Mathf.Abs (distA)));
    63.         }
    64.         else
    65.         {
    66.             distB = (2.0f - Mathf.Abs(distA));
    67.             if(distB < 0)
    68.             {
    69.                 distB = distB*-1.0F;
    70.             }
    71.         }
    72.  
    73.         // Chosing the nearest point
    74.         if (Mathf.Abs (distA) <= Mathf.Abs (distB))
    75.         {
    76.             ret = distA;
    77.         }
    78.         else
    79.         {
    80.             ret = distB;
    81.         }
    82.  
    83.         return Sensitivity * (getQueuedValueAvg(ret) * getAxisScale ());
    84.  
    85.     }
    86.     // this is for not to make to sudden changes, a small delay
    87.     private float getQueuedValueAvg(float reading)
    88.     {
    89.         if (readingsQueue == null)
    90.         {
    91.             readingsQueue = new Queue<float> (readingsMaxCount);
    92.         }
    93.         if (readingsQueue.Count >= readingsMaxCount)
    94.         {
    95.             readingsQueue.Dequeue();
    96.         }
    97.         readingsQueue.Enqueue (reading);
    98.        
    99.         float avgreading = 0.0f;
    100.         foreach(float f in readingsQueue)
    101.         {
    102.             avgreading = avgreading + f;
    103.         }
    104.         return (avgreading / readingsQueue.Count);
    105.     }
    106.  
    107.  
    108. //Properties and variables
    109.     public float XScale = 1.0f;
    110.     public float YScale  = 1.0f;
    111.     public float ZScale = 1.0f;
    112.  
    113.     public float Sensitivity
    114.     {
    115.         get
    116.         {
    117.             return Settings.Sensitivity;
    118.         }
    119.     }
    120.  
    121.     private int calibrationCounter = 0;
    122.     private List<float> calibrationReadings = new List<float> ();
    123.  
    124.     private int readingsMaxCount = 5;
    125.     private Queue<float> readingsQueue;
    126.  
    127.     public Axis AccelerometerAxis
    128.     {
    129.         get
    130.         {
    131.             return Settings.Axis;
    132.         }
    133.     }
    134.  
    135.  
    136. //Other needed helper functions for reference:
    137.     private float getAxisScale()
    138.     {
    139.         float ret = 0;
    140.         if(AccelerometerAxis == Axis.X)
    141.         {
    142.             ret = XScale;
    143.         }
    144.         else if(AccelerometerAxis == Axis.Y)
    145.         {
    146.             ret = YScale;
    147.         }
    148.         else if(AccelerometerAxis == Axis.Z)
    149.         {
    150.             ret = ZScale;
    151.         }
    152.         return ret;
    153.     }
    154.  
    155.     private float GetCurrentAccelerometerReading()
    156.     {
    157.         float ret = 0;
    158.         if(AccelerometerAxis == Axis.X)
    159.         {
    160.             ret = Input.acceleration.x;
    161.         }
    162.         else if(AccelerometerAxis == Axis.Y)
    163.         {
    164.             ret = Input.acceleration.y;
    165.         }
    166.         else if(AccelerometerAxis == Axis.Z)
    167.         {
    168.             ret = Input.acceleration.z;
    169.         }
    170.         return ret;
    171.     }
    172.  
    173.     private void startGame()
    174.     {
    175.         avgCalibration = 0f;
    176.         if (calibrationReadings.Count > 0)
    177.         {
    178.             float sum = 0f;
    179.             foreach(float f in calibrationReadings)
    180.             {
    181.                 sum = sum + f;
    182.             }
    183.             avgCalibration = sum/calibrationReadings.Count;
    184.         }
    185.         calibrating = false;
    186.     }
    187.  
    188.     public enum Axis
    189.     {
    190.         X,
    191.         Y,
    192.         Z
    193.     };
    194.  
    195.  
     
  2. vipasane

    vipasane

    Joined:
    Feb 11, 2015
    Posts:
    14
    Separated almost everything else in a single cs File. Which is now attached
     

    Attached Files:

  3. vipasane

    vipasane

    Joined:
    Feb 11, 2015
    Posts:
    14
    I am getting similar readings from Z near the both far ends meaning 1 and -1.
    Tiliting few degrees gives the other way 0.98 and 0.98 on the other way. I expected it to come back from -1 side
     
  4. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    First thing to do is check the values directly from the accelerometer on the device, without any of your settings or calibrations, something like this
    Code (CSharp):
    1. void OnGUI () {
    2.   GUILayout.Label(Input.acceleration);
    3. }
    That'll let you see what values unity is getting when you move the device around. Will also help you identify which axis is what (z may not be forward like in-game)
     
  5. vipasane

    vipasane

    Joined:
    Feb 11, 2015
    Posts:
    14
    Hi hpjohn, and thank you for the tip.

    If you look at the script I attached that was exactly what I did, but with component by component. And this is how I got those readings. As I said I apparently have misunderstanding what kind of readings youll get from accelerometer
     
  6. vipasane

    vipasane

    Joined:
    Feb 11, 2015
    Posts:
    14
    Got this working like in 90% of the time when i set target framerate to 60 (I have no idea why it made a diffrence)
    but sometimes I still got some lagging on these readings and getting some funny behavior.