Updated and Validated
[betaflight.git] / src / test / unit / sensor_gyro_unittest.cc
blobab8e25ec8c7ae5e8eb04c150e84f667ab2c736e6
1 /*
2 * This file is part of Cleanflight.
4 * Cleanflight is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * Cleanflight is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
18 #include <stdint.h>
19 #include <stdbool.h>
21 #include <limits.h>
22 #include <algorithm>
24 extern "C" {
25 #include <platform.h>
27 #include "build/build_config.h"
28 #include "build/debug.h"
29 #include "common/axis.h"
30 #include "common/maths.h"
31 #include "common/utils.h"
32 #include "drivers/accgyro/accgyro_fake.h"
33 #include "drivers/accgyro/accgyro_mpu.h"
34 #include "drivers/sensor.h"
35 #include "io/beeper.h"
36 #include "pg/pg.h"
37 #include "pg/pg_ids.h"
38 #include "scheduler/scheduler.h"
39 #include "sensors/gyro.h"
40 #include "sensors/gyro_init.h"
41 #include "sensors/acceleration.h"
42 #include "sensors/sensors.h"
44 STATIC_UNIT_TESTED gyroHardware_e gyroDetect(gyroDev_t *dev);
45 struct gyroSensor_s;
46 STATIC_UNIT_TESTED void performGyroCalibration(struct gyroSensor_s *gyroSensor, uint8_t gyroMovementCalibrationThreshold);
47 STATIC_UNIT_TESTED bool fakeGyroRead(gyroDev_t *gyro);
49 uint8_t debugMode;
50 int16_t debug[DEBUG16_VALUE_COUNT];
53 #include "unittest_macros.h"
54 #include "gtest/gtest.h"
55 extern gyroSensor_s * const gyroSensorPtr;
56 extern gyroDev_t * const gyroDevPtr;
59 TEST(SensorGyro, Detect)
61 const gyroHardware_e detected = gyroDetect(gyroDevPtr);
62 EXPECT_EQ(GYRO_FAKE, detected);
65 TEST(SensorGyro, Init)
67 pgResetAll();
68 const bool initialised = gyroInit();
69 EXPECT_TRUE(initialised);
70 EXPECT_EQ(GYRO_FAKE, detectedSensors[SENSOR_INDEX_GYRO]);
73 TEST(SensorGyro, Read)
75 pgResetAll();
76 gyroInit();
77 fakeGyroSet(gyroDevPtr, 5, 6, 7);
78 const bool read = gyroDevPtr->readFn(gyroDevPtr);
79 EXPECT_TRUE(read);
80 EXPECT_EQ(5, gyroDevPtr->gyroADCRaw[X]);
81 EXPECT_EQ(6, gyroDevPtr->gyroADCRaw[Y]);
82 EXPECT_EQ(7, gyroDevPtr->gyroADCRaw[Z]);
85 TEST(SensorGyro, Calibrate)
87 pgResetAll();
88 gyroInit();
89 gyroSetTargetLooptime(1);
90 fakeGyroSet(gyroDevPtr, 5, 6, 7);
91 const bool read = gyroDevPtr->readFn(gyroDevPtr);
92 EXPECT_TRUE(read);
93 EXPECT_EQ(5, gyroDevPtr->gyroADCRaw[X]);
94 EXPECT_EQ(6, gyroDevPtr->gyroADCRaw[Y]);
95 EXPECT_EQ(7, gyroDevPtr->gyroADCRaw[Z]);
96 static const int gyroMovementCalibrationThreshold = 32;
97 gyroDevPtr->gyroZero[X] = 8;
98 gyroDevPtr->gyroZero[Y] = 9;
99 gyroDevPtr->gyroZero[Z] = 10;
100 performGyroCalibration(gyroSensorPtr, gyroMovementCalibrationThreshold);
101 EXPECT_EQ(8, gyroDevPtr->gyroZero[X]);
102 EXPECT_EQ(9, gyroDevPtr->gyroZero[Y]);
103 EXPECT_EQ(10, gyroDevPtr->gyroZero[Z]);
104 gyroStartCalibration(false);
105 EXPECT_FALSE(gyroIsCalibrationComplete());
106 while (!gyroIsCalibrationComplete()) {
107 gyroDevPtr->readFn(gyroDevPtr);
108 performGyroCalibration(gyroSensorPtr, gyroMovementCalibrationThreshold);
110 EXPECT_EQ(5, gyroDevPtr->gyroZero[X]);
111 EXPECT_EQ(6, gyroDevPtr->gyroZero[Y]);
112 EXPECT_EQ(7, gyroDevPtr->gyroZero[Z]);
115 TEST(SensorGyro, Update)
117 pgResetAll();
118 // turn off filters
119 gyroConfigMutable()->gyro_lpf1_static_hz = 0;
120 gyroConfigMutable()->gyro_lpf2_static_hz = 0;
121 gyroConfigMutable()->gyro_soft_notch_hz_1 = 0;
122 gyroConfigMutable()->gyro_soft_notch_hz_2 = 0;
123 gyroInit();
124 gyroSetTargetLooptime(1);
125 gyroDevPtr->readFn = fakeGyroRead;
126 gyroStartCalibration(false);
127 EXPECT_FALSE(gyroIsCalibrationComplete());
129 fakeGyroSet(gyroDevPtr, 5, 6, 7);
130 gyroUpdate();
131 while (!gyroIsCalibrationComplete()) {
132 fakeGyroSet(gyroDevPtr, 5, 6, 7);
133 gyroUpdate();
135 EXPECT_TRUE(gyroIsCalibrationComplete());
136 EXPECT_EQ(5, gyroDevPtr->gyroZero[X]);
137 EXPECT_EQ(6, gyroDevPtr->gyroZero[Y]);
138 EXPECT_EQ(7, gyroDevPtr->gyroZero[Z]);
139 EXPECT_FLOAT_EQ(0, gyro.gyroADCf[X]);
140 EXPECT_FLOAT_EQ(0, gyro.gyroADCf[Y]);
141 EXPECT_FLOAT_EQ(0, gyro.gyroADCf[Z]);
142 gyroUpdate();
143 // expect zero values since gyro is calibrated
144 EXPECT_FLOAT_EQ(0, gyro.gyroADCf[X]);
145 EXPECT_FLOAT_EQ(0, gyro.gyroADCf[Y]);
146 EXPECT_FLOAT_EQ(0, gyro.gyroADCf[Z]);
147 fakeGyroSet(gyroDevPtr, 15, 26, 97);
148 gyroUpdate();
149 EXPECT_NEAR(10 * gyroDevPtr->scale, gyro.gyroADC[X], 1e-3); // gyro.gyroADC values are scaled
150 EXPECT_NEAR(20 * gyroDevPtr->scale, gyro.gyroADC[Y], 1e-3);
151 EXPECT_NEAR(90 * gyroDevPtr->scale, gyro.gyroADC[Z], 1e-3);
154 // STUBS
156 extern "C" {
158 uint32_t micros(void) {return 0;}
159 void beeper(beeperMode_e) {}
160 uint8_t detectedSensors[] = { GYRO_NONE, ACC_NONE };
161 timeDelta_t getGyroUpdateRate(void) {return gyro.targetLooptime;}
162 void sensorsSet(uint32_t) {}
163 void schedulerResetTaskStatistics(taskId_e) {}
164 int getArmingDisableFlags(void) {return 0;}
165 void writeEEPROM(void) {}