Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1702 - 1
/// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
2
//
3
// Unit tests for the AP_Math rotations code
4
//
5
 
6
#include <FastSerial.h>
7
#include <AP_Common.h>
8
#include <AP_Math.h>
9
 
10
FastSerialPort(Serial, 0);
11
 
12
#ifdef DESKTOP_BUILD
13
// all of this is needed to build with SITL
14
#include <DataFlash.h>
15
#include <APM_RC.h>
16
#include <GCS_MAVLink.h>
17
#include <Arduino_Mega_ISR_Registry.h>
18
#include <AP_PeriodicProcess.h>
19
#include <AP_ADC.h>
20
#include <AP_Baro.h>
21
#include <AP_Compass.h>
22
#include <AP_GPS.h>
23
Arduino_Mega_ISR_Registry isr_registry;
24
AP_Baro_BMP085_HIL      barometer;
25
AP_Compass_HIL     compass;
26
#endif
27
 
28
#include <AP_Declination.h> // ArduPilot Mega Declination Helper Library
29
 
30
 
31
// standard rotation matrices (these are the originals from the old code)
32
#define MATRIX_ROTATION_NONE               Matrix3f(1, 0, 0, 0, 1, 0, 0 ,0, 1)
33
#define MATRIX_ROTATION_YAW_45             Matrix3f(0.70710678, -0.70710678, 0, 0.70710678, 0.70710678, 0, 0, 0, 1)
34
#define MATRIX_ROTATION_YAW_90             Matrix3f(0, -1, 0, 1, 0, 0, 0, 0, 1)
35
#define MATRIX_ROTATION_YAW_135            Matrix3f(-0.70710678, -0.70710678, 0, 0.70710678, -0.70710678, 0, 0, 0, 1)
36
#define MATRIX_ROTATION_YAW_180            Matrix3f(-1, 0, 0, 0, -1, 0, 0, 0, 1)
37
#define MATRIX_ROTATION_YAW_225            Matrix3f(-0.70710678, 0.70710678, 0, -0.70710678, -0.70710678, 0, 0, 0, 1)
38
#define MATRIX_ROTATION_YAW_270            Matrix3f(0, 1, 0, -1, 0, 0, 0, 0, 1)
39
#define MATRIX_ROTATION_YAW_315            Matrix3f(0.70710678, 0.70710678, 0, -0.70710678, 0.70710678, 0, 0, 0, 1)
40
#define MATRIX_ROTATION_ROLL_180           Matrix3f(1, 0, 0, 0, -1, 0, 0, 0, -1)
41
#define MATRIX_ROTATION_ROLL_180_YAW_45    Matrix3f(0.70710678, 0.70710678, 0, 0.70710678, -0.70710678, 0, 0, 0, -1)
42
#define MATRIX_ROTATION_ROLL_180_YAW_90    Matrix3f(0, 1, 0, 1, 0, 0, 0, 0, -1)
43
#define MATRIX_ROTATION_ROLL_180_YAW_135   Matrix3f(-0.70710678, 0.70710678, 0, 0.70710678, 0.70710678, 0, 0, 0, -1)
44
#define MATRIX_ROTATION_PITCH_180          Matrix3f(-1, 0, 0, 0, 1, 0, 0, 0, -1)
45
#define MATRIX_ROTATION_ROLL_180_YAW_225   Matrix3f(-0.70710678, -0.70710678, 0, -0.70710678, 0.70710678, 0, 0, 0, -1)
46
#define MATRIX_ROTATION_ROLL_180_YAW_270   Matrix3f(0, -1, 0, -1, 0, 0, 0, 0, -1)
47
#define MATRIX_ROTATION_ROLL_180_YAW_315   Matrix3f(0.70710678, -0.70710678, 0, -0.70710678, -0.70710678, 0, 0, 0, -1)
48
 
49
static void print_matrix(Matrix3f &m)
50
{
51
    Serial.printf("[%.2f %.2f %.2f] [%.2f %.2f %.2f] [%.2f %.2f %.2f]\n",
52
                  m.a.x, m.a.y, m.a.z,
53
                  m.b.x, m.b.y, m.b.z,
54
                  m.c.x, m.c.y, m.c.z);
55
}
56
 
57
// test one matrix
58
static void test_matrix(enum Rotation rotation, Matrix3f m)
59
{
60
	Matrix3f m2, diff;
61
	const float accuracy = 1.0e-6;
62
	m2.rotation(rotation);
63
	diff = (m - m2);
64
	if (diff.a.length() > accuracy ||
65
	    diff.b.length() > accuracy ||
66
	    diff.c.length() > accuracy) {
67
		Serial.printf("rotation matrix %u incorrect\n", (unsigned)rotation);
68
        print_matrix(m);
69
        print_matrix(m2);
70
	}
71
}
72
 
73
// test generation of rotation matrices
74
static void test_matrices(void)
75
{
76
    Serial.println("testing rotation matrices\n");
77
    test_matrix(ROTATION_NONE, MATRIX_ROTATION_NONE);
78
    test_matrix(ROTATION_YAW_45, MATRIX_ROTATION_YAW_45);
79
    test_matrix(ROTATION_YAW_90, MATRIX_ROTATION_YAW_90);
80
    test_matrix(ROTATION_YAW_135, MATRIX_ROTATION_YAW_135);
81
    test_matrix(ROTATION_YAW_180, MATRIX_ROTATION_YAW_180);
82
    test_matrix(ROTATION_YAW_225, MATRIX_ROTATION_YAW_225);
83
    test_matrix(ROTATION_YAW_270, MATRIX_ROTATION_YAW_270);
84
    test_matrix(ROTATION_YAW_315, MATRIX_ROTATION_YAW_315);
85
    test_matrix(ROTATION_ROLL_180, MATRIX_ROTATION_ROLL_180);
86
    test_matrix(ROTATION_ROLL_180_YAW_45, MATRIX_ROTATION_ROLL_180_YAW_45);
87
    test_matrix(ROTATION_ROLL_180_YAW_90, MATRIX_ROTATION_ROLL_180_YAW_90);
88
    test_matrix(ROTATION_ROLL_180_YAW_135, MATRIX_ROTATION_ROLL_180_YAW_135);
89
    test_matrix(ROTATION_PITCH_180, MATRIX_ROTATION_PITCH_180);
90
    test_matrix(ROTATION_ROLL_180_YAW_225, MATRIX_ROTATION_ROLL_180_YAW_225);
91
    test_matrix(ROTATION_ROLL_180_YAW_270, MATRIX_ROTATION_ROLL_180_YAW_270);
92
    test_matrix(ROTATION_ROLL_180_YAW_315, MATRIX_ROTATION_ROLL_180_YAW_315);
93
}
94
 
95
// test rotation of vectors
96
static void test_vector(enum Rotation rotation, Vector3f v1, bool show=true)
97
{
98
	Vector3f v2, diff;
99
	Matrix3f m;
100
	v2 = v1;
101
	m.rotation(rotation);
102
	v1.rotate(rotation);
103
	v2 = m * v2;
104
	diff = v1 - v2;
105
	if (diff.length() > 1.0e-6) {
106
		Serial.printf("rotation vector %u incorrect\n", (unsigned)rotation);
107
		Serial.printf("%u  %f %f %f\n",
108
			      (unsigned)rotation,
109
			      v2.x, v2.y, v2.z);
110
	}
111
    if (show) {
112
        Serial.printf("%u  %f %f %f\n",
113
                      (unsigned)rotation,
114
                      v1.x, v1.y, v1.z);
115
    }
116
}
117
 
118
// generate a random float between -1 and 1
119
static float rand_num(void)
120
{
121
	float ret = ((unsigned)random()) % 2000000;
122
	return (ret - 1.0e6) / 1.0e6;
123
}
124
 
125
// test rotation of vectors
126
static void test_vector(enum Rotation rotation)
127
{
128
    uint8_t i;
129
 
130
	Vector3f v1;
131
	v1.x = 1;
132
	v1.y = 2;
133
	v1.z = 3;
134
    test_vector(rotation, v1);
135
 
136
    for (i=0; i<10; i++) {
137
        v1.x = rand_num();
138
        v1.y = rand_num();
139
        v1.z = rand_num();
140
        test_vector(rotation, v1, false);
141
    }
142
}
143
 
144
// test rotation of vectors
145
static void test_vectors(void)
146
{
147
    Serial.println("testing rotation of vectors\n");
148
    test_vector(ROTATION_NONE);
149
    test_vector(ROTATION_YAW_45);
150
    test_vector(ROTATION_YAW_90);
151
    test_vector(ROTATION_YAW_135);
152
    test_vector(ROTATION_YAW_180);
153
    test_vector(ROTATION_YAW_225);
154
    test_vector(ROTATION_YAW_270);
155
    test_vector(ROTATION_YAW_315);
156
    test_vector(ROTATION_ROLL_180);
157
    test_vector(ROTATION_ROLL_180_YAW_45);
158
    test_vector(ROTATION_ROLL_180_YAW_90);
159
    test_vector(ROTATION_ROLL_180_YAW_135);
160
    test_vector(ROTATION_PITCH_180);
161
    test_vector(ROTATION_ROLL_180_YAW_225);
162
    test_vector(ROTATION_ROLL_180_YAW_270);
163
    test_vector(ROTATION_ROLL_180_YAW_315);
164
}
165
 
166
 
167
// test combinations of rotations
168
static void test_combinations(void)
169
{
170
    enum Rotation r1, r2, r3;
171
    bool found;
172
 
173
	for (r1=ROTATION_NONE; r1<ROTATION_MAX;
174
	     r1 = (enum Rotation)((uint8_t)r1+1)) {
175
        for (r2=ROTATION_NONE; r2<ROTATION_MAX;
176
             r2 = (enum Rotation)((uint8_t)r2+1)) {
177
            r3 = rotation_combination(r1, r2, &found);
178
            if (found) {
179
                Serial.printf("rotation: %u + %u -> %u\n",
180
                              (unsigned)r1, (unsigned)r2, (unsigned)r3);
181
            } else {
182
                Serial.printf("ERROR rotation: no combination for %u + %u\n",
183
                              (unsigned)r1, (unsigned)r2);
184
            }
185
        }
186
    }
187
}
188
 
189
/*
190
  rotation tests
191
 */
192
void setup(void)
193
{
194
    Serial.begin(115200);
195
    Serial.println("rotation unit tests\n");
196
    test_matrices();
197
    test_vectors();
198
    test_combinations();
199
    Serial.println("rotation unit tests done\n");
200
}
201
 
202
void
203
loop(void)
204
{
205
}