06 Lesson. Calibration of the magnetometer
Getting raw data for magnetometer calibration
By default, the magnetometer is not calibrated, i.e. it gives inaccurate values. Refined values can be obtained from raw data by calibration, which consists in finding the transformation matrix and the displacement vector.
To learn more about the operation of the magnetometer, follow the link: 02 Lesson. Getting to know the sensors.
The raw data from the magnetometer can be obtained by executing the code in C or Python, presented below.
С code:
#include <stdio.h>
#include <stdint.h>
#include "libschsat.h"
int count = 400;
float arrX[400];
float arrY[400];
int dt = 100;
float speed = 600;
void control(void){
float mag_x = 0, mag_y = 0, mag_z = 0;
uint16_t mag_num = 0;
mSleep(1000);
magnetometer_gyro_set_telemetry_period(mag_num, dt);
magnetometer_set_offset(mag_num, 0, 0, 0);
motor_set_speed(1, speed);
for (int i = 0; i < count; i++){
mSleep(dt);
magnetometer_request_raw(mag_num, &mag_x, &mag_y, &mag_z);
arrX[i] = mag_x;
arrY[i] = mag_y;
if (i == count / 2){
motor_set_speed(1, -speed);
}
}
float min, max;
min=max=arrX[0];
for(int j = 0; j < count; j++)
{
if(min>arrX[j])
min=arrX[j];
if(max<arrX[j])
max=arrX[j];
}
float xOffset = (max + min) / 2;
min=max=arrY[0];
for(int k = 0; k < count; k++)
{
if(min>arrY[k])
min=arrY[k];
if(max<arrY[k])
max=arrY[k];
}
float yOffset = (max + min) / 2;
xOffset = xOffset / 14;
yOffset = yOffset / 14;
magnetometer_set_offset(mag_num, xOffset, yOffset, 0);
printf("x: %f y: %f ", xOffset, yOffset);
motor_set_speed(1, 0);
uint8_t data[0];
//saving
send_unican_message(25, 2656, data, 0);
}
Python code
from libschsat import Libschsat
import time
lib=Libschsat()
count = 400
arrX=[]
arrY=[]
dt=0.1
speed=600
time.sleep(1)
lib.magGyroSetTelemetryPeriod (100, 2)
lib.magSetOffset (0, 0, 0)
lib.motorSetSpeed('0xB', speed)
for i in range (count):
time.sleep(dt)
mag_x, mag_y, mag_z = lib.magRequestRaw (2)
arrX.append(mag_x)
arrY.append(mag_y)
if i == count /2:
lib.motorSetSpeed('0xB', -speed)
min=max=arrX[0]
for j in range (count):
if min>arrX[j]:
min=arrX[j]
if max<arrX[j]:
max=arrX[j]
xOffset=(max+min)/2
min=max=arrY[0]
for k in range (count):
if min>arrY[k]:
min=arrY[k]
if max<arrY[k]:
max=arrY[k]
yOffset=(max+min)/2
xOffset=xOffset/14
yOffset=yOffset/14
lib.magSetOffset(int(xOffset), int(yOffset), 0)
print('x: ' + str(xOffset) + '; y:' + str(yOffset))
lib.motorSetSpeed('0xB',0)
lib.sendMsgAndWaitAnswer('0xB60','0xF','0x19',0,[],'0x118')
Hang OrbiCraft 3D in a current frame. When executing the program, the flywheel will rotate the satellite constructor independently. After calibration, the data will be sent to the Houston Application software.
Analysis of the program in C
The program uses the following functions for working with a magnetometer.
cpp
magnetometer_gyro_set_telemetry_period(mag_num, dt)
- setting the telemetry period of the magnetometer and AVSa with the magnetometer number mag_num and the period dt
magnetometer_set_offset(mag_num, mag_x, mag_y, mag_z)
- the function sets the zero offset for the magnetometer with the number mag_num in the x,y,z planes.
motor_set_speed(0, speed);
``
* the function sets the rotation speed of the flywheel with the number **0** and speed **speed**
:::tip
In uniaxial OrbiCraft 3D, the flywheel number corresponds to 0, in triaxial - from 0 to 2 depending on the axis (X-axis - 0, Y-axis - 1, Z-axis - 2)
:::
```cpp
magnetometer_request_raw(mag_num, &mag_x, &mag_y, &mag_z)
- A function that returns raw data measured by a magnetometer with the number mag_num, which is a list of 4 numeric values. We put the read data into the variables mag_x, mag_y and mag_z.
The program uses the loop operator:
for (int i = 0; i < count; i++)
``
which will be executed n times, respectively, n values from the sensor will be collected.
### Analysis of the Python program
``cpp
magGyroSetTelemetryPeriod (100, 2)
``
* setting the telemetry period of the magnetometer and AVSa with the magnetometer number with a telemetry period of 100 ms
```cpp
magSetOffset (0, 0, 0)
``
* The function sets the zero offset for the magnetometer in the x,y,z planes.
``cpp
motorSetSpeed('0xA', speed)
``
* the function sets the rotation speed of the flywheel **0X** and the speed **speed**
``cpp
mag_x, mag_y, mag_z = lib.magRequestRaw (2)
arrX.append(mag_x)
arrY.append(mag_y)
``
* The function requests regular carrier telemetry and returns a list of magnetometer values (x, y, z). Since the satellite rotates around the Z axis in the uniaxial configuration of the constructor, data on the x and y axes are recorded in mag_x and mag_y.