Gyro sensor as a rotation sensor

I have some augmented reality game ideas and one of them requires that I have the ability to track the rotation of a cannon (you know a cannon ) I thought that a triple axis gyro sensor might do the trick so I setup a little experiment:

For this experiment I mounted a triple axis gyro sensor from sparkfun to a tripod. Wired it to an arduino uno and had it spit the sensor readings over to a c# xna app over usb. The idea was to just have the application recreate the orientation of the sensor on screen

So on to the gory details:

First up I needed to wire the sensor to the Arduino, which as it happens is incredibly simple thanks to the quick start guide provided by spark fun.

Next, I needed to have the Arduino take the sensor readings and communicate them to my c# app. Again, this was remarkably simple thanks to the quick start guide. I ended up just using their code as is. All it does is get the readings from sensor and write them our on the serial line for the c# app to read.

Now over to the c# xna app. I decided to package the sensor reading stuff in to a nice little class called GyroSensor. This class is responsible for talking to the sensor and keeping track of its orientation. To get the readings from the gyro you need to use a SerialPort from the System.IO.Ports namespace. These things are great. Nice and easy to use.  To get the communication going all you have to do is new one up, subscribe to the DataReceived event and call .Open()

serialPort = new SerialPort("COM4", 115200);
serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceived);
serialPort.Open();

When you new it up you need to know the Port and BaudRate. For me, the Arduino shows up on COM4, but it may be different on your system. The BaudRate is just how quickly data is sent on the line. Bigger is better, but its important that both sides agree on the rate.

Every time the Arduino writes some data on the serial line the DataReceived event is fired. You can read the sent data like this:

void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    var line = serialPort.ReadLine();
    ...
}

So with this, I now have the sensor readings in my C# app, but the question is what to do those sensor readings even represent? If you were hoping for some numbers that represent how many degrees the board is rotated around each axis I am afraid you will be disappointed. The gyro sensor actually reads angular velocity, or in other words, how quickly you are rotating at any given moment. In fact, it gives you readings in Degrees per Second. So the idea is that if you know where you start and how much you have rotated then you can figure out what your orientation is. Let’s say you lay the sensor on the table and then rotate it at a rate of 45 degrees per second. Each second we are going to read the sensor and see how fast we are rotating and add that value to current rotation. When we start we are at an angle of zero. After a second we read the sensor and see that we are rotating at 45 degree per second, so we add 45 degrees to 0 and get 45 degrees. We are now rotated 45 degrees. After another second passes we read the sensor again. Again, it says that we are rotating at 45 degree per second so we add that to our current rotation of 45 degrees giving us 90 degrees. We are now rotated 90 degrees. After another second we will be at 135, then 180 and so on.  That is the basic idea.  It is almost that simple to keep track of rotation….

However, there is this annoying little problem of drift. If you were to set the gyro down on a table a not have it move at all you would expect the sensor to read 0, 0, 0. That is no rotation on any axis. However because of drift this isn’t the case. On my sensor the reading was something like 10, -9, 48 when not moving. This drift throws off all the readings. But no worries, all you have to do is figure out what the drift is and then subtract it out of your readings. The way I establish drift is to just take the first reading from the gyro and store that in a drift variable (This means that the sensor has to be motionless when you fire up the app).

Ok now we have all that established here is the DataReceived event code that puts it all together

        void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            var line = serialPort.ReadLine();
            stopwatch.Stop();
            float elapsedSeconds = (float)stopwatch.ElapsedMilliseconds / 1000;
            stopwatch.Reset();
            stopwatch.Start();

            var tokens = line.Split('\t');

            if (tokens.Length == 3)
            {
                Vector3 value;
                if (!float.TryParse(tokens[0], out value.X)) return;
                if (!float.TryParse(tokens[2], out value.Y)) return;
                if (!float.TryParse(tokens[1], out value.Z)) return;

                if (!driftEstablished)
                {
                    drift = value;
                    driftEstablished = true;
                }
                else
                {
                    value -= drift;
                    value *= -1;
                    Rotation += value * elapsedSeconds / sensorScalar * piOver180;
                }
            }
        }

Now that you have rotation you can just apply that to a model and you get this:

So how well does it work?  Initially, it looks pretty good, but sadly, it doesn’t take long before the little accuracy errors start to add up and cause your derived rotation value to no longer be correct.  It is a cool little sensor, but trying to track absolute rotation with it for anything more than a minute or so is out of the question.

Source code: http://project-greengiant.googlecode.com/svn/trunk/Blog/MissleCommand

Advertisements

5 thoughts on “Gyro sensor as a rotation sensor

  1. Richard Zhao says:

    so glad to see we are working on the same thing. Our progress : http://v.youku.com/v_show/id_XNDA3OTEzNDI4.html

  2. Helen says:

    Hello there! Quick question that’s totally off topic. Do you know how to make your site mobile friendly? My blog looks weird when browsing from my iphone. I’m trying to find a template or plugin that might
    be able to resolve this problem. If you have any recommendations, please share.
    Cheers!

  3. […] Gyor sensor as a rotation sensor – guide how to use the triple axes ITG-3200 gyro sensor to measure the rotation; […]

  4. very good guide how to use gyro and accelerometer sensors. I add this tutorial on my article where a long list with sensors and tutorials about how to interface and programming accelerometer, gyro and IMU sensors http://www.intorobotics.com/accelerometer-gyroscope-and-imu-sensors-tutorials/

  5. Can anyone please share the link for the code? Thanks

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: