Over a period of four months, hands-on research activities and laboratory projects were conducted at the Kyushu Institute of Technology (Kyutech) in Japan, along with a group of students from Instituto Tecnológico y de Estudios Superiores de Monterrey (ITESM) in México. Kyutech, recognized as one of the most distinguished traditional national universities of Japan and notable for its aerospace research, established the Laboratory of Lean Satellite Enterprises and In-Orbit Experiments (LaSEINE) to promote the utilization of nanosatellites, especially the CubeSat, based on the new concept of Lean Satellite [1].
This repository documents the implementation of a gyroscope verification system for Kyutech's MO-2 satellite.
Gyroscopes are inertial sensors used to measure the angular velocity of the platform to which they are attached [2].
MEMS gyroscopes are widely adopted in CubeSat missions due to their compact size, low power consumption, cost-effectiveness, and precision. However, their accuracy tends to degrade over time as a result of combined errors, including noise, biases, drift, and scale factor instability. If left uncorrected, these deterministic errors accumulate, leading to progressively larger discrepancies in position and orientation estimates, a phenomenon well-documented in previous missions utilizing MEMS sensors for Attitude Determination and Control Systems (ADCS) [3].
Inertial sensor errors are classified into random and deterministic categories. Deterministic errors, such as biases and scale factors, must be corrected through calibration. Furthermore, because these errors in MEMS sensors are highly sensitive to temperature fluctuations, the calibration model must explicitly account for thermal dependencies to prevent significant accuracy degradation over the mission duration [3].
To ensure accurate data, a calibration procedure is performed prior to the mission to estimate deterministic error terms. While a zero-order calibration can simply estimate biases, more comprehensive approaches, such as the six-position method, estimate error terms for all three axes. This latter method typically involves rotating the gyroscope on a rotary table at a known velocity to produce a signal strong enough for accurate calibration. This mechanical assistance is indispensable for low-cost sensors, as they often lack the sensitivity to detect the Earth's turn rate [2].
Consequently, the task assigned to the ITESM student group was to validate the functionality of the MO-2 L3G4200D gyroscope mounted on a Digilent Pmod verification board and to perform the calibration tests.
The scope included conducting controlled laboratory experiments: first, executing the six-position method to generate calibration data, and second, subjecting the gyroscope to thermal chamber testing to evaluate its temperature-dependent behavior across the standard space operational range.
A significant technical challenge in these tests involves data retrieval and cabling. In the proposed setup, a NUCLEO-F446RET6 development board connects to the gyroscope to read data. If the board is placed off the rotary table, long jumper wires are required to reach the spinning sensor, creating a risk of disconnection.
Alternatively, placing the board on the table alongside the sensor requires a USB cable connecting to a PC, which inevitably tangles during rotation. A similar issue arises in the thermal test, which would require a sufficiently long USB cable to exit the chamber.
To resolve these issues, an MT25QL01GBBB8ESF-0SIT TR flash memory module, also with flight heritage, was proposed. This allows data to be saved locally and retrieved after the test, eliminating the need for a continuous physical connection to a PC during dynamic operations.
Furthermore, to facilitate a safe and repeatable testing procedure, a custom Printed Circuit Board (PCB) was designed. This integration combines all necessary components onto a single platform, ensuring stable electrical connections while simplifying the physical mounting of the hardware onto the rotary table and inside the thermal chamber.
An ideal MEMS gyroscope is characterized by the absence of noise or offset and perfect linearity—meaning it produces a strictly proportional and predictable output for any given rotation. However, real-world sensors are subject to several deterministic errors [3]:
Bias (Offset): The deviation of the gyroscope output from the expected theoretical value when the device is stationary. This "zero reading" tends to drift over time due to the integration of inherent device imperfections and internal noise [3].
Scale Factor Error: A metric describing the deviation of the sensor's sensitivity from unity. It quantifies the discrepancy between the sensor's measured output range and the actual input rotation range [3].
Non-orthogonalities (Misalignment): The error resulting from imperfect alignment of the gyroscope's sensing axes relative to an ideal mutually orthogonal coordinate system [3].
The output of a typical MEMS gyroscope can be modeled as a function of the true input angular velocity and the sensor's deterministic error variables. This relationship is expressed as [3]:
Where represents the angular velocity recorded by the gyroscope (measured), and
represents the true input angular velocity.
represents the bias vector.
is the matrix accounting for non-orthogonality and scale factors [3]:
In this matrix, the diagonal elements
represent the scale factors, while the off-diagonal elements
represent non-orthogonality (misalignment) errors [3].
Expanding Equation (1) into matrix form yields [3]:
Since misalignment angles are small in low-cost gyroscopes, only scale factors and bias errors are typically considered. The reduced model is therefore [2]:
In order to solve Equation (4), a combination of static and dynamic tests using a rotary table will be performed [3]. This procedure is explained below.
To determine the bias for each axis, the orthogonal gyroscope triad is positioned on a leveled surface. Each sensitive axis is oriented alternately in the upward and downward directions, resulting in a total of six distinct measurement positions. The bias is then calculated as [3]:
Where is the bias for each axis, and
and
represent the measured angular rates recorded by the gyroscope when pointing upward and downward, respectively [3].
The scale factor errors are determined using a procedure similar to the bias calculation, but this time a rotary table is employed to spin the gyroscope triad both clockwise and counter-clockwise for each sensitive axis (six different measurements) [3]. The scale factor error for a given axis i is calculated as [2]:
Where is the scale factor error for the pertinent axis,
and
represent the angular rates measured by the gyroscope when spinning clockwise and counter-clockwise respectively, and
is the known reference angular velocity of the rotary table or ground truth (GT) [3].
For both bias and scale factor error, the bar notation () indicates that each measurement is sustained for a duration T, allowing the measurements to be averaged to eliminate sensor noise.
To calibrate the sensor and recover the true angular velocity vector , the error model in Equation (1) must be inverted.
Thermal calibration is performed to model the temperature dependencies of the gyroscope's deterministic errors: bias and scale factor. Two primary methods are employed for this characterization [4]:
Thermal Soak Method: The MEMS sensor is placed inside a thermal chamber and allowed to stabilize at a series of discrete temperature setpoints. Data collection is initiated only after the sensor has reached thermal equilibrium at each target temperature. By recording measurements and calculating sensor errors at these stable points, a dataset of error-versus-temperature values is generated. Errors at intermediate temperatures can then be estimated using interpolation techniques [4].
Thermal Ramp Method: In this approach, the sensor is polled continuously while the thermal chamber temperature is linearly increased or decreased across the desired operating range. While this method is inherently faster because it eliminates the time-consuming stabilization periods, it introduces two significant sources of error. First, a thermal gradient often exists between the inertial sensor core and the temperature sensor, leading to measurement discrepancies similar to hysteresis. Second, because the temperature evolves dynamically during the data acquisition window for a single calibration scheme, the resulting error parameters are derived from data collected at varying temperatures rather than a single thermal point [4].
Although time-intensive, the soak method ensures the most reliable error characterization [4]; therefore, it has been selected for this verification.
Detailed documentation regarding the hardware design is maintained in a dedicated repository. For access to the files required to reproduce the custom PCB, please visit the MO-2_GyroscopeShield repository.
For the steps below, it is assumed that all components have been soldered onto the PCB. This should be done following the silkscreen labels provided on the PCB surface. When referring to the "System," this implies the custom PCB mounted on top of the NUCLEO-F446RE board.
There are two distinct options for powering the system: E5V (External 5V) or U5V (USB 5V). These modes cannot coexist; you must choose one.
In this mode, the power subsystem uses an LM2596 step-down switching regulator. This component regulates the input voltage from a main battery pack (two Lithium-Ion cells) to the stable 5V required by the NUCLEO-F446RE board.
- Switch: A switch is required to power the system remotely. Solder a cable to each terminal of the switch and secure the free ends to the J5 terminal on the PCB. If a switch is not used, a jumper wire must be installed in J5 to close the circuit; otherwise, the system will not power on.
- Battery: The Li-Ion batteries must be charged using an appropriate charger and placed in the battery holder. Connect the battery holder cables to the J4 power terminal, strictly following the polarity markings on the PCB silkscreen.
WARNING: Failure to respect the following order of operations may damage the NUCLEO-F446RE board or the PC.
- Connect a jumper between Pin 2 and Pin 3 of header JP5 on the NUCLEO-F446RE board.
- Ensure that jumper JP1 on the NUCLEO-F446RE board is removed.
- Mount the custom PCB onto the NUCLEO-F446RE board.
- Connect the battery holder cables to the J4 terminal on the PCB (observe polarity).
- Verify that the red LD3 LED on the NUCLEO-F446RE board turns on.
- Only after these steps, if code upload is required, connect the PC to the USB connector CN1.
In this mode, the system is powered directly via the ST-LINK USB connector (CN1). You may use a PC or a portable power bank capable of supplying 5V and at least 300 mA.
Note: If using a power bank, the firmware must be uploaded to the board before connecting the power bank. If using a PC, the code can be uploaded while powered.
WARNING: Failure to respect the following order of operations may damage the board.
- Connect a jumper between Pin 1 and Pin 2 of header JP5 on the NUCLEO-F446RE board (this differs from E5V mode).
- Ensure that jumper JP1 on the NUCLEO-F446RE board is removed.
- Mount the custom PCB onto the NUCLEO-F446RE board.
- Connect the PC or Power Bank to the USB connector CN1 on the NUCLEO-F446RE.
Note: During the actual tests, using a battery (E5V) or power bank (U5V) is mandatory. A USB connection to a PC is not feasible due to the cable.
The custom PCB includes a push-button that controls the data logging process. Pressing the button initiates an uninterrupted gyroscope data logging cycle for a specific duration T. Once the cycle finishes, another can be initiated.
Gyroscope Biases - Static Test: Each cycle corresponds to a specific position.
Gyroscope Scale Factor Errors - Dynamic Rotary Test: Each cycle corresponds to a specific rotation.
Gyroscope Biases - Static Thermal Test: Each cycle corresponds to a specific temperature stability point. The button logic is mandatory here, as the time required for the chamber to stabilize varies and cannot be automated with a simple timer.
The code supporting this button functionality is found in the button_logic branch.
If the NUCLEO-F446RE board has not been programmed, follow these instructions:
Clone the Repository: Open your terminal, navigate to your STM32CubeIDE workspace directory, and execute:
git clone https://github.com/fectec/MO-2_GyroscopeVerification.gitImport Project: In STM32CubeIDE, go to File > Open Projects from File System. Browse to the
MO-2_GyroscopeVerificationfolder. Ensure "Search for nested projects" and "Detect and configure project natures" are checked, then click Finish.Flash Firmware: Connect the board to the PC via USB. Open
Core/Src/main.c, then click the Run button (Play icon) to compile and upload.
IMPORTANT: Before starting a new test, you must erase the previous data from the flash memory. Connect the system to the PC, open a Serial Terminal (like PuTTY or the Arduino Serial Monitor) on the correct COM port, and send the character 'e'. This clears the memory. Failure to do this will result in corrupted data when reading the new test.
The NUCLEO-F446RE logs raw gyroscope data to the flash memory. The calculation of the biases is performed by a Python script on the PC.
Prerequisite: Download the script located at MO-2_GyroscopeVerification/PythonScripts/gyro_static_test.py. This script is compatible with Windows.
Execution Steps:
Configure Firmware: In STM32CubeIDE, open
Core/Src/main.cand modify#define LOG_DURATION_MSto set the log duration T (in milliseconds) for each button press.Power Up: Connect the Battery Pack (E5V) or Power Bank (U5V). If using E5V, turn on the switch. Verify the PCB LED is toggling (blinking), indicating Idle mode. Ensure no USB cables are connected.
Perform Data Logging: Perform the logging routine for each of the required positions. CRITICAL: You must perform the tests in the exact order shown (Position 1 → Position 2 → Position 3). For every position listed below:
- Place the system on a leveled surface matching the reference image.
- Press the button to start logging. The PCB LED will turn Solid ON.
- Wait for the PCB LED to return to Blinking (cycle complete) before moving to the next position.
Connect to PC:
- If using E5V: Keep the batteries connected and switch ON. Connect the USB cable to the PC.
- If using U5V: Disconnect the power bank and connect the USB cable to the PC.
Identify Port: Open Windows Device Manager and find the COM port number for STMicroelectronics STLink Virtual COM Port.
Run Analysis: Update the
COM_PORTvariable in the Python script and run it.Results: The script generates a text file containing the logs and a summary of the results, as well as a plot displaying the averaged angular rates (
and
) per axis, along with the calculated biases.
The NUCLEO-F446RE logs raw gyroscope data to the flash memory. The calculation of the scale factor errors is performed by a Python script on the PC.
Prerequisite: Download the script located at MO-2_GyroscopeVerification/PythonScripts/gyro_dynamic_test.py. This script is compatible with Windows.
Execution Steps:
Configure Firmware: In STM32CubeIDE, open
Core/Src/main.cand modify#define LOG_DURATION_MSto set the log duration T (in milliseconds) for each button press.- Configure Script: In the Python script, update the variable
TABLE_GROUND_TRUTH_DPSto match the angular velocity you will set on the rotary table. Power Up: Connect the Battery Pack (E5V) or Power Bank (U5V). If using E5V, turn on the switch. Verify the PCB LED is toggling (blinking), indicating Idle mode. Ensure no USB cables are connected.
Perform Data Logging: Execute the logging sequence for the three positions shown below. CRITICAL: You must perform the tests in the exact order shown (Position 1 (CW → CCW) → Position 2 (CW → CCW) → Position 3 (CW → CCW)).
For each position, repeat the following steps:
- Place the system on the rotary table as shown in the corresponding image.
- Clockwise (CW): Configure the table to spin CW at the defined velocity and start rotation. Press the button to log (LED solid ON). When the LED returns to blinking, stop the table.
- Counter-Clockwise (CCW): Configure the table to spin CCW at the defined velocity and start rotation. Press the button to log (LED solid ON). When the LED returns to blinking, stop the table.
Connect to PC:
- If using E5V: Keep the batteries connected and switch ON. Connect the USB cable to the PC.
- If using U5V: Disconnect the power bank and connect the USB cable to the PC.
Identify Port: Open Windows Device Manager and find the COM port number for STMicroelectronics STLink Virtual COM Port.
Run Analysis: Update the
COM_PORTvariable in the Python script and run it.Results: The script generates a text file containing the logs and a summary of the results, as well as a plot displaying the averaged angular rates (
and
) per axis, along with the calculated scale factor errors.
This procedure applies the calculated biases and scale factor errors to a selected raw data log. The Python script utilizes the inverse error model to recover the calibrated angular velocity () and compares it against the raw measured data (
) for visual inspection.
Prerequisite: Download the script located at MO-2_GyroscopeVerification/PythonScripts/log_gyro_calibration.py.
Execution Steps:
-
Select Log File: Locate the text file containing the raw gyroscope data you wish to calibrate. Ensure this file is accessible to the script.
-
Configure Script: Open the Python script in a text editor or IDE. You must manually update the USER CONFIGURATION section at the top of the file with the specific parameters obtained from previous tests:
Update the
LOG_FILE_NAMEvariable with the exact name of your target log file.Enter the calculated Bias values (
b_x, b_y, b_z) in units of dps.Enter the calculated Scale Factor Error values (
s_x, s_y, s_z).
-
Run Analysis: Run the Python script. This script processes the file locally and does not require the hardware system to be connected.
-
Results: The script will automatically detect the number of data cycles in the log file and generate a separate window for each cycle. Each window contains three subplots (X, Y, Z) displaying:
Uncalibrated (Dark Blue): The raw angular velocity as originally measured by the sensor.
Calibrated (Light Blue): The corrected angular velocity recovered using the manual input parameters.
This visual comparison allows for the immediate verification of the calibration performance across different test positions or rotations.
This procedure determines the dependence of gyroscope bias on temperature by calculating the bias values at five distinct points: -20°C, 0°C, 20°C, 40°C, and 60°C. Since reorienting the system inside the thermal chamber during a test is not feasible, the standard static method is adapted into three separate thermal runs. Each run maintains a single static position while sweeping through the full temperature range.
The process begins with the system in Position 1, executing the thermal sweep, after which the data is retrieved and the flash memory is erased. This sequence is repeated identically for Position 2 and Position 3, ensuring the memory is cleared between runs.
Two scripts manage the data: the first retrieves the raw logs from each run, and the second stitches these three files together. By grouping the data from all three positions corresponding to the same temperature point, the script calculates the final bias for each of the five thermal steps.
Prerequisite: Download the retrieval script (gyro_static_thermal_test_position.py) and the calculation script (gyro_static_thermal_test_biases.py).
Execution Steps:
-
Configure Firmware: In STM32CubeIDE, open
Core/Src/main.cand modify#define LOG_DURATION_MSto set the log duration T (in milliseconds) for each temperature point. Ensure the duration is sufficient to capture stable data. -
Power Up & Cabling: To ensure safety and operational stability across the full temperature range, lithium-ion batteries and portable power banks are strictly prohibited inside the thermal chamber. Instead, the system must be powered using a bench power supply placed inside the chamber alongside the device. Route the power supply's AC power cable and the extended logging control button cable through the chamber's side access port, ensuring that the system can be powered and controlled from the outside. Once the cables are routed, seal the access port to ensure thermal isolation. Connect the power supply to an external outlet, configure the output to 5V, and verify that the PCB LED is toggling to confirm the system is in Idle mode.
-
Perform Thermal Run 1 (Position 1):
-
Verify Orientation: Ensure that the system was placed in Position 1 during the initial setup.
-
Temperature Sweep: For each temperature target (-20°, 0°, 20°, 40°, 60°): Set the chamber temperature and allow the system to stabilize for the designated Soak Time (typically 15 minutes). Once stable, press the external button to log data (LED Solid ON). Wait for the LED to return to blinking before proceeding to the next temperature.
-
Retrieve Data: Once the sweep is complete, turn off the power supply and remove the system from the chamber. Connect it to the PC, run the retrieval script, and save the log file with a unique name corresponding to Position 1.
-
Erase Memory: Send the 'e' command via the Serial Terminal to clear the flash memory. This step is critical to prevent data overlap.
-
-
Perform Thermal Run 2 (Position 2):
-
Reorient & Setup: Place the system back inside the thermal chamber, this time oriented in Position 2. Route the cables, seal the access port, and power up the system as before.
-
Temperature Sweep: Repeat the logging process for all temperature targets, adhering to the 15-minute Soak Time for each step.
-
Retrieve Data: Remove the system, retrieve the data, and save the log file with a unique name corresponding to Position 2.
-
Erase Memory: Clear the flash memory using the 'e' command.
-
-
Perform Thermal Run 3 (Position 3):
-
Reorient & Setup: Place the system back inside the thermal chamber, oriented in Position 3. Route the cables, seal the access port, and power up.
-
Temperature Sweep: Repeat the logging process for all temperature targets, adhering to the 15-minute Soak Time for each step.
-
Retrieve Data: Remove the system, retrieve the data, and save the final log file corresponding to Position 3.
-
-
Run Analysis: Open
gyro_static_thermal_test_biases.py. Update theLOG_FILESlist to include the three text files. Run the script and map the files to their positions when prompted. -
Results: The script generates a summary text file and a plot illustrating the bias drift for the X, Y, and Z axes across the tested range.
Gyroscopes are critical sensors in aerospace applications, such as rockets and satellites. To create accurate simulations, engineers must precisely model the sensors. This requires characterizing stochastic errors (noise) that cannot be removed by simple calibration [5].
Angle Random Walk describes the high-frequency "white noise" in the gyroscope's rate output. The concept is based on a "random walk" mathematical model, analogous to flipping a coin to decide whether to take a step forward or backward. Even with equal probability, after many flips, your position will drift randomly from the starting line. Since gyroscope rate measurements are integrated over time to compute angles, this white noise causes the calculated angle to take random steps, accumulating drift from sample to sample [5].
While a gyroscope has a constant "turn-on bias" (the offset reading when stationary), this bias is not truly static—it wanders gradually over time. Bias Instability quantifies this low-frequency drift. It represents the limit of the sensor's stability; meaning that after a certain duration, averaging the data no longer improves accuracy but instead includes more error due to this drift. This is arguably the most critical parameter for sensor fusion algorithms (like Kalman Filters), which typically assume bias is constant; if instability is high, the filter may fail to track the bias correctly [5].
To quantify these parameters, we use the Allan Variance. Originally derived to measure the noise characteristics and frequency stability of clock oscillators, this method is used to separate random noise processes from systematic errors (such as temperature effects) [5].
The result is the Allan Deviation (), which is simply the square root of the Allan Variance. It is visualized as a plot on a log-log scale. The x-axis represents the averaging time (
) in seconds, and the y-axis represents the deviation in degrees per second. By analyzing the slope and shape of this curve, we can extract the specific values for ARW and Bias Instability [5].
It is possible to determine if the sensor exhibits Gaussian white noise. This is verified by analyzing the slope of the Allan Deviation plot. If the slope on the left side of the plot follows a gradient of -0.5, the sensor noise is confirmed to be Gaussian white noise. Verifying this characteristic is crucial because many sensor fusion algorithms, such as Kalman Filters, rely on the assumption that state observations (measurements) contain Gaussian white noise [5].
1. Angle Random Walk: It is calculated by taking the deviation value at second and converting it to standard units [5]:
2. Bias Instability: On the plot, this corresponds to the local minimum (the "valley" or flat region) of the curve. It is calculated using the minimum deviation value () and the standard constant 0.664 from IEEE Standard 952-1997 [5]:
MO-2_GyroscopeVerification/PythonScripts/gyro_ARW_bias_instability.py.
-
Configure Firmware: In
Core/Src/main.c, set#define LOG_DURATION_MSto 14400000 (4 Hours). Flash the board with this configuration. -
Data Logging: Place the system in a vibration-free environment. Crucially, the system must be oriented in Position 1 (as shown below). Connect the power source and press the button to start the long logging cycle.
-
Retrieve and Analyze: Once the logging period is complete, connect the board to the PC. Run the Python script. It will first retrieve the long data log from the flash memory, and then automatically calculate the Allan Deviation, identifying the ARW and Bias Instability values.
-
Results: The script outputs the calculated noise parameters and generates a plot of the Allan Deviation.
Kyushu Institute of Technology, "Kyutech Brochure 2024," Kitakyushu, Japan, 2024. [Online]. Available: https://www.kyutech.ac.jp//media/014/202404/brochure2024.pdf
Z. Yampolsky and I. Klein, "Data-Driven Gyroscope Calibration," arXiv preprint arXiv:2410.12485, 2024. [Online]. Available: https://arxiv.org/pdf/2410.12485
D. Royo Serrano, "Development of a calibration procedure for gyroscopes in CubeSat missions," Master's thesis, Luleå University of Technology, Luleå, Sweden, 2021. [Online]. Available: https://www.diva-portal.org/smash/get/diva2:1537570/FULLTEXT01.pdf
X. Niu, Y. Li, H. Zhang, Q. Wang, and Y. Ban, "Fast Thermal Calibration of Low-Grade Inertial Sensors and Inertial Measurement Units," Sensors, vol. 13, no. 9, pp. 12192-12217, 2013. [Online]. Available: https://doi.org/10.3390/s130912192
M. Wrona, "Gyro Noise and Allan Deviation + IMU Example," Michael Wrona's Blog, May 9, 2021. [Online]. Available: https://mwrona.com/posts/gyro-noise-analysis/






