## Materials and Methods
### Methodology  
First, we needed to configure the IMU in an Arduino sketch program by applying the Wire library [19], which allowed communication with I2C (Inter-Integrated circuit) devices. This configuration program was uploaded to the Teensy 3.2 microcontroller. It was used to set up the accelerometer and the gyroscope. We set the data format register of the accelerometer to 0 \(\times\) 09, which could set the acceleration range from \(-\)4 g (1 g = 9.8 m/s2) to +4 g. According to the datasheet of ADXL345 [20], it sets the device to a full resolution mode, where the output resolution increases with the g range set by the range bits to maintain a 3.9 mg/LSB scale factor. This setting information is useful for converting the unit of the raw output data to g. We set the power control register to 0 \(\times\) 08 to make the accelerometer in a measurement mode. Should we want to have the minimum power consumption, we could set this register to 0 \(\times\) 00 to make it in a standby mode. Similarly, we configured the ITG3200 gyroscope's settings in this program according to its datasheet [21]. The range of rotation speed was set from -2000 degree/second (dps) to +2000 degree/second, which was a full-scale range. The sensitivity was 14.375 LSB, which was also useful for converting the unit of the raw output data to dps. The low pass filter bandwidth was set to 98 Hz, and its sampling rate was set to 100 Hz. In addition, we implemented the functions for reading and outputting the acceleration values relative to the earth and the angular speed values in the Arduino sketch program.  
The next step was to do some calibration work. We applied the sensitivity values, 256 LSB and 14.375 LSB, to convert the units of the raw output of accelerometer and the raw output of gyroscope to  
Figure 2: **(a)** Teensy 3.2 and Inertial Measurement Unit (IMU) connected on a breadboard; **(b)** Teensy 3.2 and IMU connected on a breadboard with motion capture markers.  
g and dps, respectively. These values can be found in the datasheets of the sensors. We implemented a function of calculating the offsets (chip specific) of the first 200 samples in the Arduino sketch program.  
Finally, we needed to apply an algorithm to predict the orientation. Kalman-based filters have been widely used in orientation estimation [22]. In the beginning, we tried to implement a complementary Kalman-based algorithm. However, the result of the orientation estimation was bad due to a drifting error that kept occurring in calculating the velocities. Figure 3 displays the acceleration data obtained from the IMU sensor and the corresponding velocity data, which was calculated by the complementary Kalman-based filter. Obviously, the velocity data cannot come back to zero at the end of the test, which is known as a drifting error. Then, we started looking for some other ways to get the accurate orientation. [PERSON]'s algorithm [23] is also known as [PERSON]'s MARG (magnetic, angular rate, and gravity) filter or AHRS (attitude and heading reference systems) algorithm. As [PERSON] mentions in his work, Kalman-based filters are difficult to implement because they may require sampling rates far exceeding the subject bandwidth. Our sensor device has a fairly low sampling rate, which is only 50 Hz. This is probably one of the reasons that we experienced the velocity drifting error. As [PERSON] claims in his study, his algorithm can be effective even at lower sampling rates, like 10 Hz. In addition, [PERSON] compares the performance of his algorithm with a Kalman-based filter in his study, and the results indicate his algorithm has a slightly better accuracy. Therefore, we decided to apply [PERSON]'s algorithm. We tried two versions of his filters to predict the orientation in MATLAB R2017a.