Lab 2: IMU
Setup the IMU
First, I connected the IMU chip to my Artemis using the QWIIC cable as seen below.
Then, I downloaded the SparkFun 9DOF IMU Breakout - ICM 20948 - Arduino Library to use a demo to print IMU data. An image of the output is below. The example uses a variable called AD0_VAL, for the last bit of the I2C address. It is by default in the code set to 1. The IMU chip I received came with a connection soldered indicating that this variable should be set to 0 instead.
The accelerometer is measuring the acceleration of the board along each axis (x, y, z). The gyroscope is measuring the angular velocity along the three axes. Below is a screenshot of the accelerometer measurements with the board flat on a table. The z-acceleration reads 1000 mg, because the board is feeling gravity. The gyroscope measurements were all around 0.
Accelerometer
I used the following equations to convert the accelerometer measurements into pitch and roll. I also multiplied each by a factor of 180/$\pi$ to convert the output from radians to degrees.
Pitch is measured as rotation around the X axis, and roll as rotation around the Y axis. The following image displays this and shows how I would rotate the IMU to achieve the necessary angles.
I then rotated the IMU at angles of 90, 0, and -90 degree pitch and roll and printed the outputs.
Pitch 90 Degrees
Pitch -90 Degrees
Roll 90 Degrees
Roll -90 Degrees
Pitch and Roll at 0 Degrees
From the data the accelerometer seems to be fairly accurate. There looks like there is a slight 1-2 degree error in some measurements.
I then did a Fourier analysis of the data. I setup new commands in Arduino to gather and send 1000 data points each of pitch and roll. Below are the graphs of the data.
Here is a plot of the resulting fft analysis of both pitch and roll data.
There is a little noise at low frequencies. Therefore a good cutoff frequency for a low pass filter could be 0.1-0.2 Hz. Also, one reason that there is little noise from the data is that the datasheet for the IMU states that the accelerometer has optional low-pass filters.
Here is the low pass filter equation I used on all the pitch and roll data as I collected it. I set the value of alpha for a cutoff frequency of 0.1 Hz. I then collected new data and plotted the signals.
Here is the plot of the pitch and roll data after filtering each.
Both of these plots have a lot less noise. Now, the pitch values cover a range of 0.2 degrees while the unfiltered data covered 3 degrees. The same trend is true with the filtered roll data.
Gyroscope
I was able to use the gyroscope to measure the pitch, roll and yaw of the Artemis. I used the following equations to use its data to get the necessary angles. The variable currDt represents the change in time between each measurement.
Here is the pitch, roll, and yaw output while I was holding the IMU flat. The measurements accumulate error over time. This was the main difference I saw compared to the accelerometer measurements. THe gyroscope measurements do seem to have less noise though.
Here is a video rotating the IMU and changing its orientation. The pitch, roll, and yaw values are plotted along with being printed to the serial monitor.
Another observation I made was that decreasing the sampling frequency made my measurements less accurate.
To eliminate noise and drift, I used a complimentary filter to measure pitch and roll. The equations I used are below, in the equations the variables pitch and roll are the pitch and roll calculated from the accelerometer alone. I chose a value of 0.1 for alpha in the filter.
Here are the results of the complimentary filter from different IMU orientations. The measurements are much more accurate. There is no drift at all, and there is also a lot less noise.
Sample Data
To speed up the data sampling, I removed all delays and print statements in my main loop. Each sample took around 3-4ms to collect. At this rate the IMU is producing values faster than the loop is running.
I added a new command to collect 5 seconds worth of IMU data and then send it over bluetooth to my computer. I collected x,y, and z values for both the accelerometer and gyroscope. I chose to use one array of floats for each so that all data is easily accessible and organized. I used floats as the data type for each array since it uses less space than doubles but also retains precision. I found that an array of length 1500 allowed for a full 5 seconds of data to be recorded without running out of array entries. Below is an image of the code I wrote and Jupyter output. I sent one data point from each together in one string with a timestamp.
Record a stunt
I charged the RC car’s 850 mAh battery and used the controller to do stunts with the car. The video is included below. One observation I had was that the RC car can turn in place extremely quickly. The car accelerates quickly and flips over when changing directions from forwards or backwards.