C Attitude Math Library
Quaternion, Euler, and DCM math utilities for attitude control.
Loading...
Searching...
No Matches
validation.c
Go to the documentation of this file.
2
3#include <math.h>
4
5#include "attitude/dcm.h"
6#include "attitude/euler.h"
8
9static double matrix_error(const double left[3][3], const double right[3][3]) {
10 double sum = 0.0;
11 for (int row = 0; row < 3; ++row) {
12 for (int column = 0; column < 3; ++column) {
13 const double difference = left[row][column] - right[row][column];
14 sum += difference * difference;
15 }
16 }
17 return sqrt(sum);
18}
19
20static uint32_t check_round_trip(const EulerAngles *input) {
21 const double tolerance = 1e-12;
22 double expected[3][3];
23 double quaternion[4];
24 double reconstructed[3][3];
25 double roll;
26 double pitch;
27 double yaw;
28 uint32_t failures = 0;
29
30 if (!euler_to_dcm_checked(input, expected)) {
32 }
33 if (!dcm_is_orthonormal((const double (*)[3])expected, tolerance)) {
35 }
36
37 if (!euler_to_quaternion_checked(input, quaternion)) {
39 } else {
40 quaternion_to_dcm(quaternion, reconstructed);
41 if (matrix_error((const double (*)[3])expected,
42 (const double (*)[3])reconstructed) >= tolerance) {
44 }
45 }
46
47 if (!dcm_to_quaternion_checked((const double (*)[3])expected, quaternion)) {
49 } else {
50 quaternion_to_dcm(quaternion, reconstructed);
51 if (matrix_error((const double (*)[3])expected,
52 (const double (*)[3])reconstructed) >= tolerance) {
54 }
55 }
56
57 if (!dcm_to_euler_checked((const double (*)[3])expected, &roll, &pitch, &yaw)) {
59 } else {
60 const EulerAngles recovered = {roll, pitch, yaw, EULER_ZYX};
61 if (!euler_to_dcm_checked(&recovered, reconstructed) ||
62 matrix_error((const double (*)[3])expected,
63 (const double (*)[3])reconstructed) >= tolerance) {
65 }
66 }
67
68 return failures;
69}
70
71static uint32_t check_rejections(void) {
72 const EulerAngles unsupported = {0.1, 0.2, 0.3, EULER_XYZ};
73 const EulerAngles non_finite = {NAN, 0.2, 0.3, EULER_ZYX};
74 const double reflection[3][3] = {
75 {1.0, 0.0, 0.0},
76 {0.0, 1.0, 0.0},
77 {0.0, 0.0, -1.0}
78 };
79 double dcm[3][3];
80 double quaternion[4];
81 double roll;
82 double pitch;
83 double yaw;
84
85 if (euler_to_dcm_checked(&unsupported, dcm) ||
86 euler_to_quaternion_checked(&unsupported, quaternion) ||
87 euler_to_dcm_checked(&non_finite, dcm) ||
88 dcm_is_orthonormal(reflection, 1e-12) ||
89 dcm_to_quaternion_checked(reflection, quaternion) ||
90 dcm_to_euler_checked(reflection, &roll, &pitch, &yaw)) {
92 }
93 return 0;
94}
95
97 const double pi = 3.14159265358979323846;
98 const EulerAngles cases[] = {
99 {0.0, 0.0, 0.0, EULER_ZYX},
100 {0.3, -0.4, 1.2, EULER_ZYX},
101 {pi, 0.0, 0.0, EULER_ZYX},
102 {0.0, pi, 0.0, EULER_ZYX},
103 {0.0, 0.0, pi, EULER_ZYX},
104 {0.7, pi / 2.0, -0.2, EULER_ZYX},
105 {-0.8, -pi / 2.0, 1.1, EULER_ZYX}
106 };
107 uint32_t failures = 0;
108
109 for (unsigned int index = 0; index < sizeof(cases) / sizeof(cases[0]); ++index) {
110 failures |= check_round_trip(&cases[index]);
111 }
112 failures |= check_rejections();
113 return failures;
114}
int dcm_to_euler_checked(const double dcm[3][3], double *roll, double *pitch, double *yaw)
Checked DCM-to-Euler conversion.
Definition dcm.c:44
int dcm_to_quaternion_checked(const double dcm[3][3], double q[4])
Checked DCM-to-quaternion conversion.
Definition dcm.c:73
int dcm_is_orthonormal(const double dcm[3][3], double tol)
Check whether a DCM is orthonormal within a tolerance.
Definition dcm.c:5
int euler_to_quaternion_checked(const EulerAngles *e, double q[4])
Checked Euler-to-quaternion conversion.
Definition euler.c:47
@ EULER_ZYX
Standard aerospace yaw → pitch → roll sequence.
Definition euler.h:15
@ EULER_XYZ
Roll → pitch → yaw intrinsic sequence.
Definition euler.h:17
int euler_to_dcm_checked(const EulerAngles *e, double dcm[3][3])
Checked Euler-to-DCM conversion.
Definition euler.c:16
void quaternion_to_dcm(const double q[4], double dcm[3][3])
Convert a quaternion to a direction cosine matrix (DCM).
Definition quaternion.c:8
Storage for Euler angles with an associated rotation order.
Definition euler.h:26
uint32_t attitude_validation_run(void)
Run deterministic attitude conversion fixtures.
Definition validation.c:96
@ ATTITUDE_VALIDATION_EULER_TO_QUATERNION
Definition validation.h:13
@ ATTITUDE_VALIDATION_DCM_TO_EULER
Definition validation.h:16
@ ATTITUDE_VALIDATION_INVALID_INPUT
Definition validation.h:17
@ ATTITUDE_VALIDATION_EULER_TO_DCM
Definition validation.h:11
@ ATTITUDE_VALIDATION_QUATERNION_DCM
Definition validation.h:14
@ ATTITUDE_VALIDATION_DCM_TO_QUATERNION
Definition validation.h:15
@ ATTITUDE_VALIDATION_ORTHONORMAL
Definition validation.h:12