21
CASA IMU Report Fugett, Daniel and Kraft, Brian California Polytechnic State University, San Luis Obispo, California, 93405 A project was given by CASA to design and test an Inertial Measurement Unit that can be used for a low-cost UAV. Given to this project were a Sparkfun IMU containing both an accelerometer and a gyroscope, and an Arduino Uno microcontroller. The objectives of this project were to read the IMU sensor values into an Arduino IDE, calibrate the sensors for the gravity bias, low pass filter the measurements to remove noise, and propagate the measured values to find position, velocity, and attitude of the IMU. A software plan was created that would complete those objectives. Upon first implementation of the software, the values returned were too inaccurate, so further work was done to refine the software. Eventually the software was accurate enough to be able to predict the position of the IMU to within 3 degrees of the actual attitude of the Arduino. The future steps to this project would be implementing a Kahlman filter or some other more refined filter. Additionally sensor blending would likely improve the results that were obtained. Overall the data that was obtained was relatively accurate for the instrumentation and the time period provided. Nomenclature ACL_CON = conversion factor to natural units for accelerometer “Convert_Thresho ld” alpha1 = smoothing factor Exponential Smoothing avg_iter = number of samples in the average “Lowpass_Mechani cal” cnt = counting variable “Lowpass_Mechani cal” GYRO_CON = conversion factor to natural units for gyroscope “Convert_Thresho ld” here_x = most recent measured sample (LSB) “Lowpass_Mechani cal” i = counting variable “Measure_from” Measure = structure containing the measured value from previous (LSB) “Convert_Thresho ld” MyValues = structure holding calibrated and converted data (m/sec 2 ) “Convert_Thresho ld” American Institute of Aeronautics and Astronautics 1

465 senior lab final report

Embed Size (px)

Citation preview

Page 1: 465 senior lab final report

CASA IMU Report

Fugett, Daniel and Kraft, BrianCalifornia Polytechnic State University, San Luis Obispo, California, 93405

A project was given by CASA to design and test an Inertial Measurement Unit that can be used for a low-cost UAV. Given to this project were a Sparkfun IMU containing both an accelerometer and a gyroscope, and an Arduino Uno microcontroller. The objectives of this project were to read the IMU sensor values into an Arduino IDE, calibrate the sensors for the gravity bias, low pass filter the measurements to remove noise, and propagate the measured values to find position, velocity, and attitude of the IMU. A software plan was created that would complete those objectives. Upon first implementation of the software, the values returned were too inaccurate, so further work was done to refine the software. Eventually the software was accurate enough to be able to predict the position of the IMU to within 3 degrees of the actual attitude of the Arduino. The future steps to this project would be implementing a Kahlman filter or some other more refined filter. Additionally sensor blending would likely improve the results that were obtained. Overall the data that was obtained was relatively accurate for the instrumentation and the time period provided.

NomenclatureACL_CON = conversion factor to natural units for accelerometer “Convert_Threshold”alpha1 = smoothing factor Exponential Smoothingavg_iter = number of samples in the average “Lowpass_Mechanical”cnt = counting variable “Lowpass_Mechanical”GYRO_CON

= conversion factor to natural units for gyroscope “Convert_Threshold”

here_x = most recent measured sample (LSB) “Lowpass_Mechanical”i = counting variable “Measure_from”Measure = structure containing the measured value from previous (LSB) “Convert_Threshold”MyValues = structure holding calibrated and converted data (m/sec2) “Convert_Threshold”Offset = structure containing the offset value as measured before (LSB) “Convert_Threshold”some_Values = structure containing averaged value (LSB) “Lowpass_Mechanical”t_step = time since previous integration (sec) Kinematic Equationst_Values = structure type, applies to all mentioned structures “IMU.h”values = array holding sensor register data, “Measure_from”xacc = array holding acceleration from current and previous time

(m/sec2)Kinematic Equations

xpos = array holding position from current and previous timestep (m) Kinematic Equationsxvel = array holding velocity from current and previous timestep

(m/sec)Kinematic Equations

I. IntroductionInertial Measurement Units (IMUs) are commonly used to assist in guidance and navigation of aerospace

vehicles. Two of the common sensors used in IMUs are accelerometers and gyroscopes. An accelerometer measures the absolute acceleration of the vehicle with respect to the inertial frame of reference. This can be integrated over time to determine the velocity and position of the vehicle. Gyroscopes measure the vehicle’s angular velocity, which can then be integrated over time to determine the vehicle’s attitude. This project will design and test a simple IMU

American Institute of Aeronautics and Astronautics1

Page 2: 465 senior lab final report

Undergraduate, Aerospace Engineering, 1 Grand Ave., AIAA member. Undergraduate, Aerospace Engineering, 1 Grand Ave., AIAA memberto be used on a new low-cost UAV. The IMU will be capable of three axis measurements; however gravity bias and sensor noise will need to be accounted for in order to make the measurements accurate.

The IMU will need to be controlled by some sort of processor to be useful. In this case, the IMU will be connected to a microcontroller that will feed the IMU commands while receiving data. There are many different families of microcontrollers, but in this project an Arduino Uno will be used. Arduino is part of a family of microcontrollers that has been developed in an open-source environment. The programming platform used for the Arduino will be the Arduino Integrated Development Environment (IDE). This IDE uses a language similar to C, and is capable of communicating to the IMU using a protocol called I2C. Detailed knowledge of this protocol is not necessary for this project, as Arduino features a host of internal libraries that can take of it.

The objectives of this project are to:1) Connect the IMU given to Arduino that has been installed on a computer2) Display on the computer screen simple and unfiltered data from the sensors on the IMU.3) Calibrate the sensors for gravity bias and low pass filter the measurement noise.4) Propagate the velocity, position, and attitude of the IMU over time. 5) Develop a library that communicates with the IMU using singular function calls.6) Become familiar with both the Arduino and the IMU.

At the end of this project, there should be an IMU and Arduino setup that outputs accurate position and attitude measurements, which can be tested by moving the IMU around on the table.

II. Apparatus and Procedure To complete our objectives, a Sparkfun SEN-10121 was used for our IMU. This breakout board includes the

ADXL345 accelerometer and the ITG-3200 gyroscope. This allows the lab setup to feature only one interface between the Arduino and the two IMU sensors. An Arduino Uno microcontroller with a serial cable to connect to a computer was also included. Lastly, 4 small breadboard cables and a breadboard were used to connect the IMU to the Arduino Uno board. These components were all connected in the following way

American Institute of Aeronautics and Astronautics2

Page 3: 465 senior lab final report

Figure 1. Circuit Schematic

In the above schematic, the Arduino Uno is connected to a computer via a USB cable. The 3.3V port on the Arduino is connected to the 3.3V port on the IMU. Similarly, the ground port on the Arduino is connected to the ground port on the IMU. The SDA port on the IMU was connected to the A4 pin, and the SCL port on the IMU was connected to the A5 pin.

Next, the Arduino IDE was downloaded and installed on the working computer. With that setup, the software development was ready to begin. The following steps were taken in the development of the software.

Step 1: Read simple and unfiltered data from the sensors to the computer screen. This was done to ensure that the I2C functions were implemented correctly, and that the accelerometer and the gyroscope were in working condition. To do this, the proper registers for each sensor were referenced from the sensor register maps. To turn on the accelerometer, the command 0 was given to register 0x2D- Power Control. This wakes up the accelerometer and puts it into standby mode. Next the command of 8 was given to the power register, turning the accelerometer into measurement mode. To turn on the gyroscope, the command of 0 was given to register 62- Power Control. Then a command of 24 was given to register 22. This sets the gyroscope to the proper orientation. Next, the measured values were read from registers 0x32 to 0x37 from the accelerometer and from registers 29 to 34 from the gyroscope. These measured values were then printed to the serial monitor from the Arduino.

American Institute of Aeronautics and Astronautics

IMU 3.3V GND SDA SCL INT1 INT0

3

Page 4: 465 senior lab final report

Step 2: Implement a function library that can be used for all further commands. This was done to clean up the code. For example, the commands to turn on both sensors were reduced to a simple function call, taking up only a couple lines of code. To do this, 2 functions were written, one that feeds a given register a command, and one that measures values from the sensors. The functions were created such that they could be used for both the accelerometer and the gyroscope. The functions were written into a .cpp file, and a proper header file was created as well. These files were then implemented into the Arduino libraries using the import libraries tool. The library was called IMU, so a #include “IMU.h” line was written into the script. All future created functions were written into this library as well.

Step 3: Calibrate the accelerometer and the gyroscope for sensor bias. This is done to ensure that the sensors read data that make sense. For example, while the IMU is at rest, the accelerometer and the gyroscope should read 0 in all directions; which the raw data does not show. To do this, the algorithms in reference AN3397 [1] were followed. A new function was created that could take many measurement samples and average them, producing a calibrated value to be used for the offset. The values from this function were called the offset variables. For all future measurements, the offset variables were subtracted from the most recently measured variables to form the used variable.

Step 4: Convert the used variable from voltage output to physical units. When the IMU outputs data, it gives a serial voltage reading based on the sensitivity of the sensor. But for the accelerometer, the preferred acceleration units are m/s2, and for the gyroscope, the preferred measurement unit is deg/sec. To do this, the resolution units of the different sensors were looked up. For the accelerometer, the resolution was 4 mg/LSB [2]. So the measured variables were all multiplied by .004 to convert them to g’s, and multiplied again by 9.81 to convert them into units of m/sec2. For the gyroscope, the resolution is 14.375 LSB/ o/sec [3]. So the measured variables were all divided by 14.375 to convert their values into o/sec. These conversion were implemented inside another function inside the IMU library.

Step 5: Implement a low pass filter. This is needed because the sensor’s data is noisy, so to produce accurate position and attitude values the noise needs to be removed. To implement a low pass filter, reference AN23397 [1] was used again. Both the “Filtering” and the “Mechanical Filtering Window” algorithms were used. This means all measured values had to be an average of a larger amount of samples taken. Because a measurement average was already implemented in a function in Step 3, this filtering just needed a proper calibration to determine how many samples to take per measurement value. For the mechanical filtering window algorithm, the measured values are just compared to a certain threshold value. If the measured values fall beneath the threshold then the values are set to 0 instead. This ensures that a “no movement condition” can be met.

Step 6: Integrate the measured values from the IMU to determine velocity, position, and attitude of the IMU. This is done because those are the measurements that the UAV will use to navigate. To integrate, the kinematic equations are used in conjunction with a designated time step. Further details about these equations are given in the next section. The output of the kinematic equations, velocity, position, and attitude, are propagated with time such that the IMU constantly outputs those values and changes them with respect to the new measurements from the IMU.

III. AnalysisIn order to power on the sensors and prepare them for measurement, a function “Write_to” was developed in the

IMU library. When fed a device address, register, and command, the function will simply write the respective command. This function is called multiple times in the setup function in the Arduino, and by the end of the function the IMU is fully prepared to start outputting values.

After powering on the sensors, the raw data needs to be taken from the sensors (step 1). This is done with a function in the IMU library called “Measure_from.” A sample of the code in this function is shown below.

int i = 0; (1) while(Wire.available()){ (2) values[i] = Wire.read(); (3)

American Institute of Aeronautics and Astronautics4

Page 5: 465 senior lab final report

i++; (4) } (5)

In this code, i represents a counting variable. values is an array which holds the read value. So together, these lines of code pull the 6 bytes of data needed for the three axis measurement from the sensor. In the next step in the function, the 6 byte values in value are conjoined together to form the measured data.

The measured data that is output from the “Measure_from” function takes the form of a structure. This structure contains the data points for the x, y, and z components from the sensor. To create this structure, a new type was defined in the IMU library. This code can be found below:

typedef struct t_Values{ (6) float x; (7) float y; (8) float z; (9)

} t_Values; (10)

So now all further structures used in functions are of type t_Values, meaning that all structures have an x,y, and z component that is a float variable. This will allow the x,y, and z components from a sensor to all be output from a function at once.

Occasionally, a large amount of samples are desired to be taken, and then averaged to produce the measured value. For example, this needs to be done for the calibration offset variable (step 3), talked about more below. In order to achieve this, the function “Lowpass_Mechanical ” was developed in the IMU library. A portion of this code is shown below.

while (cnt <= avg_iter){ (11)here_x = Measure_from(….) (12)

some_Values.x = some_Values.x + here_x; (13)cnt++ (14)

} (15)some_Values.x = some_Values.x / avg_iter; (16)

In these lines, cnt is a count variable, meaning it starts at 0 and increases by one for every iteration. here_x is the most recent measured sample. some_Values is a structure which will contain the average value, and this structure is what will be returned from the function. And avg_iter is an input variable which tells the function how many samples the average should contain.

Next, the sensor data needed to be calibrated for the gravity bias (step 3) and converted into natural units (step 4). To calibrate for the gravity bias, the offset variable that was recorded prior is subtracted from the recently measured value. To convert the value into natural units, a simple multiplication by a conversion factor is needed. These are both accomplished in the following line of code, given in the x direction for the accelerometer only. This code can be found in the “Convert_Threshold” function inside the IMU library.

MyValues.x = (Measure.x - Offset.x)*ACL_CON; (17)

In those lines, MyValues (m/sec2 or deg/sec) is a structure which holds the calibrated and converted sensor value. Measure (LSB) is a structure which holds the most recently measured sensor value. Offset (LSB) is a structure which holds the sensor value for offset, which is measured in the beginning of the code. ACL_CON is the conversion factor from voltage reading to m/s2, and is equal to 9.81/250. Because both sensors need an offset, a very similar line of code can be used for the gyroscope, with a variable for GYRO_CON instead. GYRO_CON is equal to 1/14.375 to convert the measurement into degrees/sec.

After being calibrated and offset, the measured variable needs to be passed through a low pass filter (Step 5). One of the low pass filters implemented is a simple mechanical threshold. In order for the measured value to be

American Institute of Aeronautics and Astronautics5

Page 6: 465 senior lab final report

passed on to integration, it needs to be above a certain threshold value; otherwise the measured value becomes zero. To accomplish this, there are more lines of code in the function “Convert_Threshold”

if ( abs(MyValues.x) <= thresh){ (18)MyValues.x = 0;} (19)

In this code, the variable thresh (m/sec2 or deg/sec) is an input into the function, and represents the threshold value that the user desires. If the threshold is set too high, then valid data points might be lost and the IMU could always think that it is in the “no movement” condition even if it is moving. If the threshold is set too low, then noisy signals from the filter could cause the sensors to read that the IMU is moving, even when it is at rest. The thought process behind setting the threshold value is discussed in the next section.

To implement the second part of the low pass filter (step 5), a rolling average needs to be implemented. A function was needed to take many samples from a sensor, and then output the average of those samples as the measured value. However, this function was already developed in “Lowpass_Mechanical.” Therefore, in order to fulfill that step, the :Lowpass_Mechanical” function needed to be implemented directed after the raw measurements are taken.

In order to integrate the measured acceleration and angular velocity, the kinematic equations were used. This

code was not put into the function library, instead it is just written into the main Arduino script. An example of the code used for the x position and x angle is shown below.

xvel[1] = xvel[0] + xacc[1] * (t_step/1000); (20)xpos[1] = xpos[0] + xvel[1] * (t_step/1000) + ((xacc[1] * (t_step/1000)^2; (21)

xang[1] = xang[0] + xavel[1] * (t_step/1000); (22)

xpos (m) is the array holding the position information for both the current and previous time step. xvel (m/s) is the array holding the velocity in the x direction. xacc (m/s2) is the array holding the acceleration in the x direction, which is measured from the IMU. Similarly for the gyroscope information, xang (deg) is the array which holds the total rotation in the x direction, while xavel (deg/sec) contains the angular velocity in the x direction, which is measured from the IMU. The variable t_step (ms) contains the time since the previous integration has happened. For all arrays the second variable of the array is for the current time step, while the first element of the array is for the previous time step.

Lastly in the IMU library, a function titled “Print_myvalues” was created. This function takes an x, y, and z value, and prints them to the serial monitor in an easily comprehendable way. The values can be acceleration, velocity, position, angular velocity, or attitude.

So in summary, the following steps were taken in orderto take data from the sensors

Table 1. Procedure with Functions

Step # Description of Step Functions in Library Used1 Power on Sensors “Write_to”1 Read raw data from sensors to ensure working condition “Measure_from”3 Create Offset variable “Measure_from”; “Lowpass_Mechanical”3 Read a set of measured data from sensors “Measure_from”5 Implement a low pass filter using averaged values “Lowpass_Mechanical”3 Offset the measured data with the offset variable “Convert_Threshold”3 Convert the measured data into natural units “Convert_Threshold”5 Implement a low pass filter for no movement condition “Convert_Threshold”6 Integrate the measured values over time The Kinematic Equations6 Print the Position and Attitude Values “Print_myvalues”

American Institute of Aeronautics and Astronautics6

Page 7: 465 senior lab final report

This is how the code was first developed and implemented. The following section details what changes the code underwent after this first implementation.

IV. Results and DiscussionPictures please! Show the results. Describe something unexpected or surprising to you. What did you learn?

What went right? What went wrong?

A. Exponential FilteringOne of the problems the code ran into was time lag. Often, a sudden move of the IMU would register in the

few measurements after, but not immediately. The reason for this problem was discovered when the code was imported to Matlab. To import into Matlab, the IMU code would be uploaded to the Arduino. Then the Matlab script would be run that takes in the IMU data for a few seconds, then plots the data against time. Both the immediately measured value and the averaged value from the low-pass filter would be graphed. An example of this filtering is included in the results section for the angular velocity from the gyroscope. Keep in mind that this methodology was used for both the angular velocity and the accelerations.

The value passed into the low pass filter using averages often lags behind the true value. This means that the position and velocity readings will also lag behind the true values, such that they will still be readings movement even after the IMU is put to rest. In order to fix this problem and obtain more accurate and real-time measurements, a new low pass filter needed to be applied. The low pass filter chosen was an exponential smoothing filter. The equation for exponential smoothing was implemented into the code in the following way:

xacc[1] = alpha1*Acc_Real.x + (1-alpha1)*Acc_prev.x; (23)

Where xacc[1] is the value of the most recent measured and filtered accelerometer reading. Acc_Real is a structure holding the most recent sampled raw measurement for x acceleration. Acc_prev is a structure holding the previous iteration’s filtered measurement value. And alpha1 is the smoothing factor. The value for the constant alpha1 was chosen to best eliminate the noise from the signal while still accurately representing the raw data. The smoothing factor value was eventually chosen as 0.1. A smoothing factor closer to zero places a higher weight on incoming values while a value closer to one places higher weight on the previously measured values. Since we want our code to be adaptive to quick changes in acceleration or angular velocity a value closer to zero was chosen. Multiple test runs were conducted and this value proved to be the most effective for our application. The results of this filter and the averaging filter, when passed into Matlab, can be seen in Figure 3 below.

Figure 2. Low Pass Filter with Exponential Smoothing and Averaging: In this picture the green line represents the raw data, the black line represents the exponentially smoothed data and the red line represents the averaging filter.

By comparing these two lines, it can be seen that the exponential smoothing filter accurately follows the raw data without having the lag of the averaging filter. Also the exponential smoothing seems to measure the values more accurately. Overall this type of filtering proved to be easy and extremely beneficial for our data. An additional example of this type of smoothing can be seen in the results section.

American Institute of Aeronautics and Astronautics7

Page 8: 465 senior lab final report

B. Movement End CheckSomething that AN3397 [1] recommended implementing was a movement end check. This is similar to the

threshold check that was implemented beforehand. However, if the accelerometer were rapidly moved to a new location, unless the integration of acceleration while it was positive perfectly matched the integration acceleration while it was negative, then a small velocity would be left over. This is called “sloped positioning” and means that the velocity will never reach zero. This might be desired in some cases, but because this IMU is connected to a static computer, there should be no velocity left over after movement. Therefore the movement end check implemented checks to see if the accelerometer starts to read similar values in the current iteration to the previous iteration, and if it does, the velocity variable is set to zero. This will ensure that short movements of the accelerometer are tracked more accurately, and that short movements don’t cause small velocities to be left over due to measurement errors. And in the case of the UAV in flight, the acceleration of one time step should never be so close to the acceleration of a previous time step, due to internal vibrations and external disturbances, so this condition could only be triggered on the ground. The movement end check was implemented in the following way:

n4 = abs(abs(xacc[1]) - abs(xacc[0])); (24)if (n4 < 5){ (25)

xacc[1] = 0;c1++;

(26)

}if (c1>3){xvel[1]=0;

c1=0;}

(27)(28)(29)

In this case, xacc[1] (m/sec2), like before, means the most recent filtered measurement value. xacc[0] m/sec2 contains the previous iterations filtered measurement value. And xvel[1] (m/sec) contains the velocity for this iteration. Therefore, if the difference between the two values is less than 5 the acceleration will be set to zero (which serves as another mechanical filter) and a counter will increment. If the difference between the two values is less than five for four consecutive passes then the velocity will be set to zero and the counter will start over again. This ensures that only large changes in acceleration appear in the data and that the velocity and acceleration do not continue to increase or decrease after movement has ceased.

C. Gravity Bias with QuaternionsEliminating the gravity bias was a challenging task in this assignment. If the accelerometer remained flat on the

table for the duration of the experiment then it would be quite easy to set an offset and remove the effects of gravity. Unfortunately this methodology breaks down if the accelerometer pitches or rolls during data collection. To prevent this issue a quaternion was used to constantly update the attitude of the accelerometer relative to the inertial frame. The first step in this process is determining the angle between the gravity vector in the inertial frame and the gravity vector in the body frame.

c4 = -zacc[1]/ sqrt(xacc[1]*xacc[1] + yacc[1]*yacc[1] + zacc[1]*zacc[1]); (30)ang = acos(c4)/2; (31)

In this code a dot product is performed and this value is then divided by the norm of both of the gravity vectors. The dot product simplifies to –zacc[1] and the other values for the acceleration (yacc[1] and xacc[1]) are used to calculate c4. C4 simply serves as a place holder and is implemented into an inverse cosine function and then divided by two (since the angle used in quaternion math is always divided by two, this is merely a simplification of the code). In order to obtain this value a cross product was performed and each component of this cross product was divided by the magnitude of the cross product. These values combined with the angle can be used to find all four components of the quaternion. From there, these values could easily be converted to a rotation matrix and the gravity vector could be subtracted from the accelerations measured in the body frame. The code to calculate the quaternion and the rotation is extremely tedious and was difficult to debug in Arduino. Since the Arduino does not understand complex matrix this body of code is quite long and I suggest you view the header titled “// Quaternion Calculation” and “//Rotation matrix calculation” in the appendix.

A check was performed to ensure the gravity vector did not affect the acceleration readings when a roll or a pitch was performed. Figure 3 and Figure 4 show the checks to ensure the gravity bias is constantly removed from the data. The red line depicts the acceleration with the gravity vector removed and the blue line represents the true

American Institute of Aeronautics and Astronautics8

Page 9: 465 senior lab final report

accelerations that are measured. Physically rotating the accelerometer induced some error in the sensor but overall the quaternion was extremely accurate.

Figure 3. Acceleration Calculations for Y-Axis Gravity Vector

Figure 4. Acceleration Calculations for X-Axis Gravity Vector

As the gravity vector becomes more prominent in other axes, the z-value starts to dips until it finally reaches zero. When the Z-value is at zero this means that the gravity vector is present solely in other axes. The red line maintains a constant value of zero therefore proving the functionality of the quaternion in our code.

D. Results

American Institute of Aeronautics and Astronautics9

Page 10: 465 senior lab final report

When all of the function in the Analysis were implemented and run, the code would generate position and attitude measurements successfully. However, they were wildly inaccurate in the beginning. All ideas implemented in the previous section were just to narrow down the accuracy of the measurements.

The basic idea of the code as described in the Analysis section worked and remained throughout the project. The sensors were turned on without a hitch, and their raw values were read to ensure that they were in good working condition. The IMU library was implemented with great success. The library cut down on the amount of code required to be shown in one singular Arduino script, allowing the coding and debugging process to be quicker. The conversion and threshold function worked well, with the only change to it being what the threshold value was set to 0.1 for both the accelerometer and the gyroscope. And the kinematic equations remained unchanged.

As previously mentioned, lag proved to be an issue when determining the position and velocity through integration. A check was performed for each axis to ensure that the accelerometer was outputting data accurately. The displacement that were measured were slightly higher than the actual displacements that were implemented and this is likely due to the amount of iterations required to enact the movement end check. A faster sampling of the data and an alteration of the smoothing value might mitigate this issue. No delays were used in this code therefore speeding up the iterations was not an option and therefore these results were the best that could be produced given the code and the equipment that was used.

The first movement check that was performed was the X-axis movement and is shown below in Figure . Spurious effects were measured in both the Y and the Z axes but this did not significantly contribute to the data that was measured. These perturbations might not have been entirely erroneous considering it is difficult to slide an Arduino across the table in purerly one axis. It is important to note that the Z-axis only changed by a small quantity and might be more representative of the error that was produced by the code.

Figure 5. X-Axis Movement

The Y-axis check is depicted in Figure 6, shown below. The same trends that were discussed for the X-axis movement could be applied to this graph. As previously mentioned, it is likely that the Arduino was also moved some distance in the X-direction. The check for Z-axis movement is also shown below, please refer to Figure 7.

American Institute of Aeronautics and Astronautics10

Page 11: 465 senior lab final report

Figure 6. Y-Axis Movement

Figure 7. Z-Axis Movement

Examining the data it is obvious that the filter did not work as effectively as it once had. By implementing more code for the quaternion and other necessary calculations the number of iterations performed per second slowed down. This produced error which produced a deformed shape for the integration. Although the different levels of integration do look logical for some checks they are not perfect. Given more time this code could likely be rewritten to increase the number of iterations that can be performed for a given time period

A similar check was performed for the angular velocity and angle calculations. The angular velocity data was filtered and some of the subplots that will follow this paragraph feature the relationship between the filtered angular velocity and the raw angular velocity.

American Institute of Aeronautics and Astronautics11

Page 12: 465 senior lab final report

Figure 8 shows the raw and filtered angular velocity used to calculate the angles. Figure 9 shows the angles that were calculated through the data presented in Figure 8. Once more lag was an issue with the filtering of the data. These two figures verify that a single angle can be measured without a large influence on the other two angles. The Arduino was rotated 90 degrees about the X-axis which accurately correlates to the peak of the data at a value of about 1.57 radians.

Figure 8. Raw and Filtered Angular Velocity for X-Axis Check

Figure 9. Angles for X-Axis Check

American Institute of Aeronautics and Astronautics12

Page 13: 465 senior lab final report

Figure 10 and 11 correlate to a similar check for the Y-Axis. Once more the Arduino was rotated by 90 degrees and the peak of the curve accurately corresponds to about 1.57 radians.

Figure 10. Raw and Filtered Angular Velocity for Y-Axis Check

Figure 11. Angles for Y-Axis Check

Figure 12 and 13 correlate to a similar check for the Z-Axis. Once more the Arduino was rotated by 90 degrees and the peak of the curve accurately corresponds to about 1.57 radians.

American Institute of Aeronautics and Astronautics13

Page 14: 465 senior lab final report

Figure 12. Raw and Filtered Data for Z-Axis Check

Figure 13. Angles for Z-Axis Check

V. ConclusionOverall the values that were determined proved to be relatively accurate. The angles that were calculated proved

to be the most accurate of all of the values that were integrated. This is likely due to the fact that these values only underwent one level of integration whereas the position values required two integrations therefore compounding any error that was present. Angles were measured within 3 degrees of their true values while the positions varied more greatly. A quaternion was used to remove the gravity bias and this methodology proved effective throughout the code. Initial offsets were also implemented to ensure they did not induce any transient effects. The exponential

American Institute of Aeronautics and Astronautics14

Page 15: 465 senior lab final report

smoothing filter provided to be effective for frequent iterations but started to break down as more complicated calculations slowed down the code. A different filter or gravity bias algorithm might be more effective to reduce the amount of time that the code takes to iterate. Furthermore a restructuring of the code to measure more values before attempting to filter could also be viable, it is difficult to say without these numbers at hand. Despite all our efforts lag was not completely removed from the code and this induced transient effects on all of the measurements. A more refined code with adaptive filtering based off of the magnitude of previous changes in data could be the best method for filtering this data. As the values increase or decrease rapidly more data points could be used to ensure the data is represented smoothly.

VI. References

[1] Seifert, Kurt, and Oscar Camacho. "AN3397: Implementing Positioning Algorithms Using Accelerometers." 02/2007; <http://cache.freescale.com/files/sensors/doc/app_note/AN3397.pdf>

[2] “ADXL345 2 Axis Digital Accelerometer Reference Sheet”; Sparkfun Electronics, Analog Devices Inc. <https://www.sparkfun.com/datasheets/Sensors/Accelerometer/ADXL345.pdf>

[3] “ITG-3200 Product Specification, Revision 1.4” Sparkfun Electronics, InvenSense Inc. <https://www.sparkfun.com/datasheets/Sensors/Gyro/PS-ITG-3200-00-01.4.pdf>

[4] “Inertial Measurement Unit – Lab Manual 2015-2” Department of Aerospace Engineering, California Polytechnic State University, San Luis Obispo.

American Institute of Aeronautics and Astronautics15