Lab 2

Task 1: Setup

To begin the lab, I installed the nessesary libraries for the IMU and plugged it directly into the Artemis. The ADR jumper was open on the breakout board so ADO-0 was set to 1. I then ran the Example1-Basics tutorial to test my IMU. The results shown below illustrate the IMU’s ability to measure acceleration, angular rate, and magnatometer data.

In addition, to make the IMU easier to work with, I added code that makes the IMU blink 4 times after being initialized by adding the following code at the end of the setup loop.

image

Task 2: Accelerometer

The accelerometer outputs acceleration in the x,y, and z axis. To convert these accelerations to pitch (theta_a) and roll (phi_a), we can use the formulas below.

Or in Arduino code:

image

Note that there is a 1.03 factor in front of both equations. This is because after preforming a two point calibration, I found I needed a correction factor of 1.03 on both pitch and roll. Data after the two point calibration for a (0 -> 90) deg and (0 -> -90) degree rotations are shown for both pitch and roll.

Pitch Roll
pitch_neg_90 roll_90_neg
pitch_90 roll_90_pos

As shown above, the data from the IMU has a fair amount of high frequency noise. To remove this noise, I collected roll and pitch data as I periodically rotated the IMU as shown below.

Pitch data:

Pitch

Roll data:

Roll

To analyze the noise in this data, I preformed an FFT of the data. As can be seen by the FFT of the pitch data, most of the signal is contained between 0 and 6hz. Therefore, I can build a low pass filter to eliminate frequencies higher than that as they are likely noise.

Pitch_FFT

Using the following recursive formulas, we can construct a low pass filter:

For pitch (very similar for roll):

To determine alpha we can use the formulas below. The data above was collected at a sampling period T = 10ms. Setting f_c to 5hz, we get an alpha of 0.266.

In Arduino:

image

The result of the LPF is shown below. As can be seen by the plots, the LPF cuts down a considerable amount of the high frequencty noise.

Pitch_lp

Roll_lp

Task 3: Gyroscope

To compute orientation from gyroscope data, we need to integrate the angular rates over time using the formulas below.

In Arduino:

image

We can then overlay the gyroscope data with raw and filtered accelerometer data. From these plots, we can see that the gyroscope has much less noise even when compared to the filtered accelerometer data. However, it tends to drift over time away from the accelerometer measurements.

gyro_drift_pitch

gyro_drift_roll

To prevent drift, we can implement a complementary filter which fuses the gyroscope and filtered accelerometer data together.

After some experimentation, I found that 0.8 for gamma produced the best results.

Arduino code:

image

As can be seen below, the complimentary filter prevents drift over time in the fused signal. After some experimentation, I determined that its working range contained both positive and negative rotations from about -90 to 90 degrees in both pitch and roll. Beyond that, the data seemed to be a little less reliable.

fused_roll

roll_fused

It also does a good job of rejecting random vibrations.

image

Task 4: Sampling Data Fast

To sample data as quickly as possible, I implemented get_imu_data() which encapsulates all of the previous functionality into a function. I then called this function in the main loop whenever data is ready and a data collection flag rec_data was set to true.

Arduino code:

image

To start and stop/transmit recorded data, I implemented two more commands that can be called over Bluetooth by my computer.

image

image

After removing all of the delays, I was able to collect data for over 5s at a sampling rate of 367hz.

image

image

image

image

To store data, I used 3 float arrays for pitch, roll, and yaw. I selected floats over ints and doubles as they provide more accuracy compared to integers but take up less memory when compared to doubles. Therefore, I think that it is the perfect balance between the two. In all, the Artemis has 384kb of memory or or 33,000 float values. Since I am sampling at 367hz, this equates to about 1.5 min of data. This is not to bad for the Artemis. However, there will likely be other things that need to be stored other than just array data so this value will likely be lower.

Robot Video

Below is a video of my robot driving around a study lounge. As shown, the robot’s motors are very powerful and able to easily flip the car. I cannot wait to turn it into a cool robot.