Search code examples
javaembeddedaccelerometerphysics

How do i calculate the orientation/direction and the velocity of a Sun Spot?


I am experimenting with the accelerometer on my sunspot. I am trying to calculate the velocity by measuring the values of the accelerometer from the axis X and Y but they kind of seem random to me.

What's the proper way to get the values and the orientation/direction of the movement and to calculate its velocity?

This is my code:

while (true) {

        try {
             offset=Math.sqrt(accel.getAccelX()*accel.getAccelX()+accel.getAccelY()*accel.getAccelY());
               if(offset<0.1 && offset>-0.1)
                   offset=0;

            v=(offset+ ((offset-anterior))/2)*0.2; //0.2 is 200millisecs
            anterior=offset;
            Utils.sleep(200);//5 reads per secound
          }}...

UPDATE For example, I move the sunspot in a direction and the variable v(velocity) give me values from negative up to 7ms by random order (not sequencial). If the change the direction of the movement it doesn't give me negative values as I expected.

example:(if I move it to my right)

v =0.4771031167950723
v =0.4771031167950723
v =-0.15903437226502407
v =-0.15903437226502407
v =0.33841556285063856
v =0.33841556285063856
v =0.7397145777969039

Thanks in advance.


Solution

  • Like @John Story stated the best way to handle this is by making an average. Sun spots accelarometers are very unstable and aren't suited for precise velocity prevision.

    Anyway this is the best code i could make

    double v=0;
        double anterior=0;
    
        while (true) {
            double time=System.currentTimeMillis()+200;
            double currentTime=System.currentTimeMillis();
            double offset=0;
            int tries=0;
            double maximo=0;
            double minimo=0;
            while(time>currentTime){ //lets run for 0.2seconds :)
    
                try {
                    double temp=-accel.getAccelY(); //front shouln't be negative
                    tries++;
                    if(temp<0.1201 && temp>-0.1201){
                        tries--; //oops threadshould sample
                    }else{
                        if(temp>maximo)
                            maximo=temp;
                        if(temp<minimo)
                            minimo=temp;
                        offset+=temp;
                    }   
                }catch (Exception e) {
                    System.err.println("Caught " + e + " while collecting/sending sensor samples.");
                }
                Utils.sleep(10); //sleep 10milisecs
                currentTime=System.currentTimeMillis();
            }
            if(tries>2)
                offset=(offset-minimo-maximo)/(tries-2); //remove max value and min value from sample and makes average
            else if(tries>0)
                offset/=2; //you wont take max or min from a two value sample
            try {
                dg.reset();         //clears
                v=anterior+offset*0.2; //vf=vi+at
                dg.writeDouble(Math.abs(v*100)); // sends in cm
                anterior=offset;    //vi=vf
                rCon.send(dg);     //sends radiogram
                Utils.sleep(200); //sleep 0.2s
            }catch (Exception e) {
                System.err.println("Caught " + e + " while sending velocity.");
            }
        }
    }