1 /* 2 * Copyright (c) 2021 Kevin Townsend 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 /** 8 * @defgroup AHRS Attitude and Heading Reference System 9 * 10 * @brief Functions and structs for dealing with 'Attitude' and AHRS. 11 * 12 * Structs like @ref zsl_attitude are inteded to be used as 'last-mile' 13 * represetnations, to convert Euler angles (in radians) to something more 14 * human-friendly like degrees. Most calculations should make use of Euler 15 * angles, and the richer API around them, with conversion to degrees as the 16 * final step. 17 * 18 * @ingroup ORIENTATION 19 * @{ */ 20 21 /** 22 * @file 23 * @brief API header file for attitude and AHRS in zscilib. 24 * 25 * This file contains the zscilib AHRS APIs. 26 */ 27 28 #ifndef ZEPHYR_INCLUDE_ZSL_AHRS_H_ 29 #define ZEPHYR_INCLUDE_ZSL_AHRS_H_ 30 31 #include <zsl/zsl.h> 32 #include <zsl/vectors.h> 33 #include <zsl/orientation/euler.h> 34 35 #ifdef __cplusplus 36 extern "C" { 37 #endif 38 39 /** 40 * @brief Represents the orientation of a rigid body with respect to 41 * the world frame in terms of roll, pitch and yaw (heading), 42 * expressed in degrees. 43 * 44 * @note This is functionally identical to @ref zsl_euler, but attitude is 45 * usually repesented in degrees, not radians. This struct has been 46 * defined to differentiate between the two representations. 47 */ 48 struct zsl_attitude { 49 union { 50 struct { 51 /** @brief Longitudinal axis in degrees. A positive rolling motion 52 * lifts the left wing and lowers the right wing of an 53 * airplane. */ 54 zsl_real_t roll; 55 /** @brief Transverse axis in degrees. A positive pitching motion 56 * raises the nose of the aircraft and lowers the tail. */ 57 zsl_real_t pitch; 58 /** @brief Vertical axis in degrees. A positive yawing motion moves 59 * the nose of the aircraft to the right. AKA heading. */ 60 zsl_real_t yaw; 61 }; 62 /** @brief Array-based access. */ 63 zsl_real_t idx[3]; 64 }; 65 union { 66 struct { 67 /** @brief If non-zero, indicates that #roll is invalid. */ 68 uint8_t roll_invalid : 1; 69 /** @brief If non-zero, indicates that #pitch is invalid. */ 70 uint8_t pitch_invalid : 1; 71 /** @brief If non-zero, indicates that #yaw is invalid. */ 72 uint8_t yaw_invalid : 1; 73 } status; 74 /** @brief Invalid field indicators. */ 75 uint8_t status_bits; 76 }; 77 }; 78 79 /** 80 * @brief Takes the values in the supplied @ref zsl_attitude, and assigns the 81 * same memory address to a @ref zsl_vec, allowing for vector functions 82 * to be used on the zsl_attitude values. 83 * 84 * @param a Pointer to the zsl_attitude struct to use. 85 * @param v Pointer to the zsl_vec struct to use. 86 * 87 * @return 0 if everything executed correctly, otherwise a negative error code. 88 */ 89 int zsl_att_to_vec(struct zsl_attitude *a, struct zsl_vec *v); 90 91 /** 92 * @brief Converts the input @ref zsl_attitude, expessed in degrees, to it's 93 * equivalent in radians in the output @ref zsl_euler. 94 * 95 * @param a Pointer to the zsl_attitued struct to use. 96 * @param e Pointer to the zsl_euler struct to use. 97 * 98 * @return 0 if everything executed correctly, otherwise a negative error code. 99 */ 100 int zsl_att_to_euler(struct zsl_attitude *a, struct zsl_euler *e); 101 102 /** 103 * @brief Converts the input @ref zsl_euler, expessed in radians, to it's 104 * equivalent in degrees in the output @ref zsl_attitude. 105 * 106 * @param e Pointer to the zsl_euler struct to use. 107 * @param a Pointer to the zsl_attitued struct to use. 108 * 109 * @return 0 if everything executed correctly, otherwise a negative error code. 110 */ 111 int zsl_att_from_euler(struct zsl_euler *e, struct zsl_attitude *a); 112 113 /** 114 * @brief Converts a three-axis accelerometer (in m/s^2) and a three-axis 115 * magnetometer sample (in micro-Tesla) to attitude. 116 * 117 * @param accel Acceleration triplet in m/s^2. 118 * @param mag Magnetometer triplet in micro-Tesla. 119 * @param a Pointer the the output @ref zsl_attitude struct. 120 * 121 * @return 0 if everything executed correctly, otherwise a negative error code. 122 */ 123 int zsl_att_from_accelmag(struct zsl_vec *accel, struct zsl_vec *mag, 124 struct zsl_attitude *a); 125 126 /** 127 * @brief Converts a three-axis accelerometer sample (in m/s^2) to roll and 128 * pitch. 129 * 130 * @param accel Acceleration triplet in m/s^2. 131 * @param a Pointer the the output @ref zsl_attitude struct. 132 * 133 * @return 0 if everything executed correctly, otherwise a negative error code. 134 */ 135 int zsl_att_from_accel(struct zsl_vec *accel, struct zsl_attitude *a); 136 137 /** 138 * @brief Calculates the angle between two accelerometers. 139 * 140 * @param a1 First acceleration triplet in m/s^2. 141 * @param a2 First acceleration triplet in m/s^2. 142 * @param b Angle between the accelerometers, in radians. 143 * 144 * @return 0 if everything executed correctly, otherwise a negative error code 145 * if the accelerometer data is not tridimensional. 146 */ 147 int zsl_att_accel_angle(struct zsl_vec *a1, struct zsl_vec *a2, zsl_real_t *b); 148 149 #ifdef __cplusplus 150 } 151 #endif 152 153 #endif /* ZEPHYR_INCLUDE_ZSL_AHRS_H_ */ 154 155 /** @} */ /* End of ahrs group */ 156