/**
 * @file adcs_bsk.h
 *
 * @brief # This file contains abstraction functions, structures, enum for
 *          ADCS simulation.
 *
 * @copyright Copyright 2023 Antaris, Inc.
 */

#ifndef ADCS_BSK_H_
#define ADCS_BSK_H_

#include "stdint.h"

#ifdef __cplusplus
extern "C" {
#endif

/// Adcs sensors
typedef enum 
{
    ADCS_MAG = 0,            ///< Magnetometer
    ADCS_RED_MAG = 1,        ///< Redundant Magnetometer
    ADCS_MEMS_RATE,          ///< MEMS Rate sensor
    ADCS_COARSE_SUN,         ///< Coarse momentum sensor
    ADCS_FINE_SUN,           ///< Fine momentum sensor
    ADCS_NADIR_SENS,         ///< Nadir pointing sensor
    ADCS_GPS,                ///< GPS sensor
    ADCS_STAR_SENS           ///< Star tracking sensor
}e_adcs_sensor_type;

/// Adcs actuators
typedef enum 
{
    ADCS_MAG_TORQUER = 0,   ///< Magnetorquer
    ADCS_WHEEL = 1,         ///< Reaction wheel
    ADCS_THRUSTER           ///< Thruster
}e_adcs_actuator_type;

/// Rest Cause enumeration
typedef enum
{
    ADCS_RESET_CAUSE_POR = 0,       ///< Power on reset
    ADCS_RESET_CAUSE_BOR = 1,       ///< Brownout reset
    ADCS_RESET_CAUSE_WDG = 2        ///< Watchdog reset
}e_adcs_reset_cause;

/// Boot cause enumeration
typedef enum
{
    ADCS_BOOTCAUSE_UNEXPECTED = 0,  ///< Unexpected
    ADCS_BOOTCAUSE_NORMAL = 1,      ///< Normal
    ADCS_BOOTCAUSE_ERROR = 2        ///< Error
}e_adcs_boot_cause;

/// Magnetometer mode value enumeration
typedef enum
{
    ADCS_MAGMTR_MODE_1 = 0,         ///< Magnetometer mode 1
    ADCS_MAGMTR_MODE_2 = 1,         ///< Magnetometer mode 2
    ADCS_MAGMTR_MODE_3 = 2          ///< Magnetometer mode 3
}e_adcs_magmtr_mode_val;

/// GPS type enumeration
typedef enum
{
    ADCS_GPS_SELECT_NONE = 0        ///< GPS type none
}e_adcs_gps_type;

/// Star Tracker mode enumeration
typedef enum 
{
    ADCS_STAR_MODE_TRACKING = 0,    ///< Tracking Mode
    ADCS_STAR_MODE_LOST = 1         ///< Lost
}e_adcs_star_mode;

/// Capture result enumeration
typedef enum
{
    ADCS_CAPTURE_STARTUP = 0,       ///< Capture Startup
    ADCS_CAPTURE_PENDING = 1,       ///< Capture Pending
    ADCS_CAPTURE_SUCCESS = 2,       ///< Capture Success
    ADCS_CAPTURE_SUCCESS_HIFT = 3,  ///< Capture Success HIFT
    ADCS_CAPTURE_TIMEOUT = 4,       ///< Capture Time out
    ADCS_CAPTURE_SRAM_ERR = 5       ///< Capture SRAM error
}e_adcs_capture_result;

/// Detect result enumeration
typedef enum
{
    ADCS_DETECT_STRATUP = 0,        ///< Detect Startup
    ADCS_DETECT_NO_DETECT = 1,      ///< No Detect
    ADCS_DETECT_PENDING = 2,        ///< Detect Pending
    ADCS_DETECT_TOO_MANY_EDGES = 3, ///< Detect too many edges
    ADCS_DETECT_TOO_FEW_EDGES = 4,  ///< Detect too few edges
    ADCS_DETECT_BAD_FIT = 5,        ///< Detect bad fit
    ADCS_DETECT_SUN_NOT_FOUND = 6,  ///< Detect sun not found
    ADCS_DETECT_SUCCESS = 7         ///< Detect success
}e_adcs_detect_result;

/// GPS solution status enumeration
typedef enum
{
    ADCS_GPS_SOL_COMPUTED = 0,          ///< GPS solution computed
    ADCS_GPS_SOL_INSUFFICIENT_OBS = 1,  ///< GPS solution insufficient
    ADCS_GPS_SOL_NO_CONVERGENCE = 2,    ///< GPS solution no convergence
    ADCS_GPS_SOL_SINGULARITY = 3,       ///< GPS solution singularity
    ADCS_GPS_SOL_COVTRACE = 4,          ///< GPS solution covtrace
    ADCS_GPS_SOL_COLD_START = 5,        ///< GPS solution cold start
    ADCS_GPS_SOL_VH_LIMIT = 6,          ///< GPS solution VH limit
    ADCS_GPS_SOL_VARIANCE = 7,          ///< GPS solution variance
    ADCS_GPS_SOL_INTEGRITY_WARNING = 8, ///< GPS solution integrity warning
    ADCS_GPS_SOL_PENDING = 9,           ///< GPS solution pending
    ADCS_GPS_SOL_INVALID_FIX = 10,      ///< GPS solution invalid fix
    ADCS_GPS_SOL_UNAUTHORIZED = 11      ///< GPS solution unauthorized
}e_adcs_gps_sol_sts;

/// AxisSelect enumeration
typedef enum
{
    ADCS_AXIS_SELECT_POSX = 0,          ///< Positive X
    ADCS_AXIS_SELECT_NEGX = 1,          ///< Negative X
    ADCS_AXIS_SELECT_POSY = 2,          ///< Positive Y
    ADCS_AXIS_SELECT_NEGY = 3,          ///< Negative Y
    ADCS_AXIS_SELECT_POSZ = 4,          ///< Positive Z
    ADCS_AXIS_SELECT_NEGZ = 5,          ///< Negative Z
    ADCS_AXIS_SELECT_NOTUSED = 6,       ///< Not Used
    ADCS_AXIS_SELECT_POSXPOSY45DEG = 7  ///< Positive X/Y 45 degree
}e_adcs_axis_select;

/// Estimation mode enumeration
typedef enum
{
    ADCS_EST_NONE = 0,                  ///< Estimation mode none
    ADCS_EST_MEMS_RATE = 1,             ///< Estimation mode MEMS rate
    ADCS_EST_GYRO_EKF = 2               ///< Estimation mode Gyro EKF
}e_adcs_est_mode;

/// ADCS States
typedef enum
{
    ADCS_STATE_NONE = 0                 ///< ADCS none state
}e_adcs_state;

/// Attitude control mode enumeration
typedef enum 
{
    ADCS_CTRL_MODE_NONE = 0,                    ///< No control mode
    ADCS_CTRL_MODE_DETUMBLING = 1,              ///< Detumbling control mode
    ADCS_CTRL_MODE_Y_SPIN_STABILIZATION = 2,    ///< Y Spin Stabilization
    ADCS_CTRL_MODE_Z_SPIN_STABILIZATION = 3,    ///< Z Spin Stabilization
    ADCS_CTRL_MODE_THREE_AXIS = 4,              ///< 3axis stabilization
    ADCS_CTRL_MODE_SUN_POINTING = 5,            ///< Sun pointing
    ADCS_CTRL_MODE_NADIR_POINTING = 6,          ///< Nadir pointing
    ADCS_CTRL_MODE_TARGET_TRACKING = 7,         ///< Target tracking
    ADCS_CTRL_MODE_CUSTOM = 8                   ///< Custom control mode
}e_adcs_att_ctrl_mode;

/// TC TM ID
typedef enum
{
    API_REQ_RESET = 1,          ///< Reset command
    API_REQ_UTC,                ///< UTC Set command
    API_REQ_CLEAR_ERROR,        ///< Clear Error
    API_REQ_SAVE_ORBIT,         ///< Save orbit parameters
    API_REQ_TLE,                ///< TLE Set command
    API_REQ_MOI,                ///< Set moment of intertia
    API_REQ_PWR,                ///< Set Power configuration
    API_REQ_MAGMTR_MODE_OPER,   ///< Set magnetometer operation mode
    API_REQ_GYRO_CFG,           ///< Set gyro configuration
    API_REQ_CSS_CFG,            ///< Set coarse sun sensor configuration
    API_REQ_STAR_TRAC_CFG,      ///< Set star tracker configuration
    API_REQ_MAGMTR_CFG,         ///< Set Magnetometer configuration
    API_REQ_REDUN_MAGMTR_CFG,   ///< Set Redudent magnetometer
                                ///< configuration
    API_REQ_MAG_BOOM,           ///< Set Magnetometer boom
    API_REQ_MGNTRQR_OUT,        ///< Set Magnetorquer output
    API_REQ_RW_SPEED,           ///< Set Reaction wheel speed
    API_REQ_MGNTRQR_CFG,        ///< Set Magnetorquer configuration
    API_REQ_RW_CFG,             ///< Set Reaction wheel configuration
    API_REQ_CTRL_MODE,          ///< Set Control mode configuration
    API_REQ_DETUMBLE_CTRL,      ///< Set Detumble control parameters
    API_REQ_Y_RW_CTRL,          ///< Set Y axis Reaction wheel control
                                ///< parameter
    API_REQ_Z_RW_CTRL,          ///< Set Z axis Reaction wheel control
                                ///< parameter
    API_REQ_RW_CTRL,            ///< Set Reaction wheel control
    API_REQ_TRCK_CTRL_GAIN,     ///< Set tracking control gain
    API_REQ_ATTITUDE_ANGL,      ///< Set attitude angle parameters
    API_REQ_TRCK_TARGET,        ///< Set target tracking parameters
    API_REQ_INRTL_REF,          ///< Set inertial reference
    API_REQ_EST_MODE,           ///< Set estimation mode
    API_REQ_EST_PARAM,          ///< Set estimation parameters
    API_REQ_SENSORS_CFG,        ///< Set Sensor configuration
    API_REQ_ACTUATORS_CFG,      ///< Set Acruator configuration
    API_REQ_FSS_CFG,            ///< Set Fine sun sensor configuration
    API_REQ_NADIR_CFG,          ///< Set Nadir configuration
    API_RESP_ID = 128,          ///< Get Identification
    API_RESP_STATE,             ///< Get ADCS state
    API_RESP_TLE,               ///< Get TLE
    API_RESP_MOI,               ///< Get moment of inetria
    API_RESP_PWR,               ///< Get power configuration
    API_RESP_MAG_FIELD_VEC,     ///< Get magnetic field vector
    API_RESP_CSS_VEC,           ///< Get CSS vector
    API_RESP_FSS_VEC,           ///< Get FSS vector
    API_RESP_NADIR_VEC,         ///< Get nadir vector
    API_RESP_SENSOR_RATE,       ///< Get sensor rate
    API_RESP_STAR_TRKR_BVEC,    ///< Get star tracker body vector
    API_RESP_STAR_TRKR_OVEC,    ///< Get star trackere orbit vector
    API_RESP_RAW_NADIR_SEN,     ///< Get raw nadir sensor meaurement
    API_RESP_RAW_FSS_SEN,       ///< Get raw fine sun sensor measurement
    API_RESP_RAW_MAGMTR,        ///< Get raw magnetometer measurement
    API_RESP_RAW_GPS_STS,       ///< Get raw GPS staus
    API_RESP_RAW_GPS_TIME,      ///< Get raw GPS time
    API_RESP_RAW_GPS_X,         ///< Get raw GPS X axis
    API_RESP_RAW_GPS_Y,         ///< Get raw GPS Y axis
    API_RESP_RAW_GPS_Z,         ///< Get raw GPS Z axis
    API_RESP_STAR_MAG,          ///< Get star magnitude
    API_RESP_STAR_PERFORM,      ///< Get star performance
    API_RESP_STAR_TIMING,       ///< Get star timing
    API_RESP_RAW_SENS,          ///< Get raw sensor measurement
    API_RESP_RAW_GPS,           ///< Get raw GPS measurement
    API_RESP_RAW_STAR_TRAC,     ///< Get raw star tracker measurement
    API_RESP_STAR_RDATA,        ///< Get raw star tracker data
    API_RESP_RAW_SEC_MAGMTR,    ///< Get raw secondary magnetometer
                                ///< measurement
    API_RESP_RAW_SENS_RATE,     ///< Get raw sensor rates
    API_RESP_STAR_EST_RATE,     ///< Get star tracker estimation rate
    API_RESP_SENS_CUR,          ///< Get sensor current
    API_RESP_CON_CUR,           ///< Get adcs consumed current measurement
    API_RESP_RW_CUR,            ///< Get reaction wheel current
    API_RESP_TEMP,              ///< Get adcs temperature
    API_RESP_SENS_RATE_TEMP,    ///< Get rate sensor temperature
    API_RESP_POW_TEMP,          ///< Get power and temperature measurement
    API_RESP_GYRO_CFG,          ///< Get gyro configuration
    API_RESP_STAR_TRAC_CFG,     ///< Get star tracker configuration
    API_RESP_MAGMTR_CFG,        ///< Get magnetometer configuration
    API_RESP_CSS_CFG,           ///< Get CSS configuration
    API_RESP_FSS_CFG,           ///< Get FSS configuration
    API_RESP_NADIR_CFG,         ///< Get Nadir configuration
    API_RESP_RED_MAGMTR_CFG,    ///< Get Redudant magnetometer
                                ///< configuration
    API_RESP_MGNTRQR_CFG,       ///< Get magnetorquer configuration
    API_RESP_RW_CFG,            ///< Get reaction wheel configuration
    API_RESP_DETUMBLE_CTRL,     ///< Get detumble parameters
    API_RESP_Y_RW_CTRL,         ///< Get Y reaction wheel control
    API_RESP_RW_CTRL,           ///< Get reaction wheel control
    API_RESP_TRCK_CTRL_GAIN,    ///< Get tracking control gain
    API_RESP_ATTITUDE_ANGL,     ///< Get attitude angle
    API_RESP_TRCK_TARGET,       ///< Get target tracking parameters
    API_RESP_INRTL_REF,         ///< Get inertial reference
    API_RESP_EST_PARAM,         ///< Get estimation paremeters
    API_RESP_POS_ECI,           ///< Get sattelite position ECI
    API_RESP_VEL,               ///< Get sattelite velocity
    API_RESP_POS_LLH,           ///< Get sattelte position LLH
    API_RESP_EST_RATE,          ///< Get estimation rates
    API_RESP_EST_QUTRN,         ///< Get estimated quaternion
    API_RESP_ECEF_POS,          ///< Get ECEF sattelite position
    API_RESP_MODL_MAG,          ///< Get moduled magnetic field vector
    API_RESP_MODL_SUN,          ///< Get moduled sun vector
    API_RESP_EST_GYRO,          ///< Get estimated gyro measurement
    API_RESP_EST_INNOVN,        ///< Get estimation innovation
    API_RESP_QUTR_ERROR,        ///< Get quaternion error vector
    API_RESP_QUTR_COVR,         ///< Get quaternion covariance
    API_RESP_ANGL_COVR,         ///< Get angular rate covariance
    API_RESP_CTRL_MODE,         ///< Get Control mode
    API_RESP_RW_SPEED,          ///< Get Reaction wheel commanded speed
    API_RESP_RW_SPEED_MEASURE   ///< Get Reaction wheel measurement
}e_api_req_id;

/// API Response Id
typedef enum
{
    API_RESP_OK=1,                    ///< Responce ID OK
    API_RESP_ERROR                    ///< Responce Error
}e_api_resp_id;


/// API Error
typedef enum
{
    API_ERR_INVALID_REQ=1,            ///< Invalid Request Id received
    API_ERR_FRAME_ERR,                ///< Frame Error (SOF/EOF)
    API_ERR_CRC_ERR,                  ///< Checksum Error
    API_ERR_DATA_INVALID              ///< Invalid Data Error
}e_api_error;


/**
 * @brief This structure repersent the ADCS context 
 * will be updated in future
 */
typedef struct
{
    uint32_t magic;  /*!< Always equals to 0XAE */
}__attribute__ ((__packed__))s_adcs_ctx;

/**
 * @brief Power command structure power sorce can either be sensor or actuator.
 *        Supports upto 32 Power Sources. Each source will be internally mapped
 *        inside the Basilisk Tool
 */
typedef struct
{
    uint32_t pwr_source;            /*!< 1 - Power On/ 0 - Power Off Each Bit 
                                        can be mapped to each source*/
}__attribute__ ((__packed__))s_adcs_pwr_cmd;

/**
 * @brief Reset command structure
 */
typedef struct
{
    uint8_t magic;           /*!< Identification byte which always 
                                equals to 0x5A */
}__attribute__ ((__packed__))s_adcs_reset;

/**
 * @brief Identification command
 */
typedef struct
{
    uint32_t id;             /*!< Identification element */
}__attribute__ ((__packed__))s_adcs_id;

/**
 * @brief ADCS current state
 */
typedef struct
{
    uint8_t state; /*!< ADCS State */
}__attribute__ ((__packed__))s_adcs_state;

/**
 * @brief TLE configuration structure
 */
typedef struct
{
    double inclination;        /*!< Inclination */
    double eccentricity;       /*!< Eccenticity */
    double raan;               /*!< Right-ascension of the Ascending Node */
    double arg_perigee;        /*!< Argument of Perigee */
    double b_star;             /*!< B-Star drag term */
    double mean_motion;        /*!< Mean Motion */
    double mean_anomaly;       /*!< Mean Anomaly */
    double epoch;              /*!< Epoch Time */
}__attribute__ ((__packed__))s_adcs_tle;

/**
 * @brief Moment of inertia matrix
 */
typedef struct
{
    float mom_iner_xx;        /*!< Moment Of Inertia - Ixx. (Unit [kg.m^2]) */
    float mom_iner_yy;        /*!< Moment Of Inertia - Iyy. (Unit [kg.m^2]) */
    float mom_iner_zz;        /*!< Moment Of Inertia - Izz. (Unit [kg.m^2]) */
    float prod_iner_xy;       /*!< Product Of Inertia - Ixy. (Unit [kg.m^2]) */
    float prod_iner_xz;       /*!< Product Of Inertia - Ixz. (Unit [kg.m^2]) */
    float prod_iner_yz;       /*!< Product Of Inertia - Iyz. (Unit [kg.m^2]) */
}__attribute__ ((__packed__))s_adcs_moi;

/**
 * @brief Current Unix Time
 */
typedef struct
{
    uint32_t utc_time;           /*!< Time in s since 01/01/1970,00:00.
                                    (Unit [s]) */
    uint16_t milli_sec;          /*!< Current millisecond count. (Unit [ms]) */
}__attribute__ ((__packed__))s_adcs_time;

/**
 * @brief Magnetometer configuration
 */
typedef struct
{
    double angle_1;            /*!< Magnetometer Mounting Transform Alpha Angle
                                (Uint [deg])*/
    double angle_2;            /*!< Magnetometer Mounting Transform Beta Angle
                                (Uint [deg])*/
    double angle_3;            /*!< Magnetometer Mounting Transform Gamma Angle
                                (Uint [deg])*/
    double offset_1;           /*!< Magnetometer Channel 1 Offset */
    double offset_2;           /*!< Magnetometer Channel 2 Offset */
    double offset_3;           /*!< Magnetometer Channel 3 Offset */
    double sens_11;            /*!< Magnetometer Sensitivity Matrix S11 */
    double sens_12;            /*!< Magnetometer Sensitivity Matrix S12 */
    double sens_13;            /*!< Magnetometer Sensitivity Matrix S13 */
    double sens_21;            /*!< Magnetometer Sensitivity Matrix S21 */
    double sens_22;            /*!< Magnetometer Sensitivity Matrix S22 */
    double sens_23;            /*!< Magnetometer Sensitivity Matrix S23 */
    double sens_31;            /*!< Magnetometer Sensitivity Matrix S31 */
    double sens_32;            /*!< Magnetometer Sensitivity Matrix S32 */
    double sens_33;            /*!< Magnetometer Sensitivity Matrix S33 */
}__attribute__ ((__packed__))s_adcs_mgmtr_cfg;

/**
 * @brief Raw Magnetometer
 */
typedef struct
{
    int16_t mag_raw_x;          /*!< Raw magnetometer X measuremen */
    int16_t mag_raw_y;          /*!< Raw magnetometer Y measurement */
    int16_t mag_raw_z;          /*!< Raw magnetometer Z measurement */
}__attribute__ ((__packed__))s_adcs_raw_mgmtr;

/**
 * @brief Deploy magnetometer boom
 */
typedef struct
{
    uint8_t time_out;   /*!< Deployment actuation timeout value.(Unit [s]) */
}__attribute__ ((__packed__))s_adcs_mgmtr_boom;

/**
 * @brief CSS pointing direction and scale factor
 */
typedef struct
{
    uint8_t css_conf;                   /*!< CSS Axis configuration */
    double css_scale;                   /*!< CSS Relative Scaling Factor */
    uint8_t css_min;                    /*!< CSS Minimum Threshold */
}__attribute__ ((__packed__))s_adcs_css_cfg;

/**
 * @brief FSS pointing direction and scale factor
 */
typedef struct
{
    uint8_t fss_conf;                   /*!< FSS Axis configuration */
    double fss_scale;                   /*!< FSS Relative Scaling Factor */
    uint8_t fss_min;                    /*!< FSS Minimum Threshold */
}__attribute__ ((__packed__))s_adcs_fss_cfg;

/**
 * @brief Nadir sensor configuration
 */
typedef struct
{
    uint8_t max_deviation_pct;          /*!< Nadir Max Deviation Percentage */
    uint8_t max_bad_edges;              /*!< Nadir Max Bad Edges */
    uint8_t max_radius;                 /*!< Maximum Radius. (Unit [°]) */
    uint8_t min_radius;                 /*!< Minimum Radius. (Unit [°]) */
}__attribute__ ((__packed__))s_adcs_nadir_cfg;

/**
 * @brief Nadir sensor measurement
 */
typedef struct
{
    int16_t nadir_raw_x;                /*!< Nadir sensor raw X angle */
    int16_t nadir_raw_y;                /*!< Nadir sensor raw Y angle */
    uint8_t nadir_busy;                 /*!< Nadir sensor capture status */
    uint8_t nadir_result;               /*!< Nadir sensor detection result */
}__attribute__ ((__packed__))s_adcs_nadir_sens;

/**
 * @brief FSS measurement
 */
typedef struct
{
    int16_t fss_raw_x;                  /*!< FSS raw X angle */
    int16_t fss_raw_y;                  /*!< FSS raw Y angle */
    uint8_t fss_busy;                   /*!< FSS capture status */
    uint8_t fss_result;                 /*!< FSS detection result */
}__attribute__ ((__packed__))s_adcs_fss_sens;

/**
 * @brief Gyro configuration
 */
typedef struct
{
    uint8_t gyro_conf;                  /*!< Gyro axis configuration */
    double x_rate_offset;               /*!< X-Rate Sensor Offset */
    double y_rate_offset;               /*!< Y-Rate Sensor Offse */
    double z_rate_offset;               /*!< Z-Rate Sensor Offse */
    uint8_t rate_sensor_mult;           /*!< Multiplier of rate sensor 
                                            measurement */
}__attribute__ ((__packed__))s_adcs_gyro_cfg;

/**
 * @brief Star Tracker configuration
 */
typedef struct
{
    double angle_1;                     /*!< StarTracker Mounting Transform 
                                        Alpha Angle */
    double angle_2;                     /*!< StarTracker Mounting Transform 
                                        Beta Angle */
    double angle_3;                     /*!< StarTracker Mounting Transform 
                                        Gamma Angle */
    uint16_t exposure;                  /*!< StarTracker exposure time */
    uint16_t gain;                      /*!< StarTracker analog gain */
    uint8_t detection_threshold;        /*!< StarTracker detection threshold */
    uint8_t threshold;                  /*!< StarTracker star threshold */
    uint8_t max_star_matched;           /*!< Maximum Star Matched */
    uint16_t timeout_time;              /*!< Detection Timeout duration */
    uint8_t max_star_pixel;             /*!< Maximum Star Pixel */
    uint8_t min_star_pixel;             /*!< Minimum Star Pixel */
    double error_margin;                /*!< Star Tracker Error Margin */
    uint16_t delay_time;                /*!< Star Tracker Delay Time */
    float cent_x;                       /*!< Star Tracker Centroid X */
    float cent_y;                       /*!< Star Tracker Centroid Y */
    float focal;                        /*!< Star Tracker Focal Length */
    float lens_k1;                      /*!< K1 radial distortion coefficient */
    float lens_k2;                      /*!< K2 radial distortion coefficient */
    float lens_p1;                      /*!< P1 tangential distortion 
                                            coefficient */
    float lens_p2;                      /*!< P2 tangential distortion 
                                            coefficient */
    uint8_t window_width;               /*!< Star tracking window width */
    double tracking_margin;             /*!< Star Tracking Margin */
    double validation_margin;           /*!< Star Validation Margin */
    uint8_t module_enable;              /*!< Star Tracking Module Enable */
    uint8_t location_prediction_enable; /*!< Star Tracking Location Prediction 
                                        Enable */
    double search_width;                /*!< Star Tracking Search Width */
}__attribute__ ((__packed__))s_adcs_star_trkr_cfg;

/**
 * @brief Star Tracker magnitude of identified
 */
typedef struct
{
    uint16_t mag_star_1;             /*!< Instrument magnitude of star 1 */
    uint16_t mag_star_2;             /*!< Instrument magnitude of star 2 */
    uint16_t mag_star_3;             /*!< Instrument magnitude of star 3 */
}__attribute__ ((__packed__))s_adcs_star_trkr_mag;

/**
 * @brief Star Tracker performance
 */
typedef struct
{
    uint8_t num_stars_detected;          /*!< Number of stars detected */
    uint8_t star_image_noise;            /*!< Star image noise */
    uint8_t invalid_stars;               /*!< Invalid Star */
    uint8_t num_stars_id;                /*!< Number of star identified */
    uint8_t id_mode;                     /*!< Identification mode */
    uint8_t image_dark_value;            /*!< Image dark value  The average 
                                            value of center line in image */
}__attribute__ ((__packed__))s_adcs_star_trkr_perform;

/**
 * @brief Timing information of star measurement
 */
typedef struct
{
    uint16_t capture;            /*!< Capture */
    uint16_t detection;          /*!< Detection */
    uint16_t id;                 /*!< Identification */
}__attribute__ ((__packed__))s_adcs_star_trkr_timing;

/**
 * @brief Star Tracker raw measurement
 */
typedef struct
{
    uint8_t num_stars_detected;         /*!< Number of stars detected */
    uint8_t star_image_noise;           /*!< Star image noise */
    uint8_t invalid_stars;              /*!< Invalid Star */
    uint8_t num_stars_id;               /*!< Number of star identified */
    uint8_t id_mode;                    /*!< Identification mode */
    uint8_t image_dark_value;           /*!< Image dark value  The average 
                                           value of center line in image */
    uint8_t image_capture_success;      /*!< Image Capture Success */
    uint8_t detection_success;          /*!< Detection Success */
    uint8_t id_success;                 /*!< Identification Success*/
    uint8_t attitude_success;           /*!< Attitude Success */
    uint8_t processing_time_error;      /*!< Processing Time Error */
    uint8_t tracking_module_enabled;    /*!< Tracking module enabled */
    uint8_t prediction_enabled;         /*!< Prediction enabled */
    uint8_t comms_error;                /*!< Comms error */
    uint8_t s1_conf;                    /*!< Star 1 confidence.
                                            (Unit[percentage]) */
    uint8_t s2_conf;                    /*!< Star 2 confidence.
                                            (Unit[percentage]) */
    uint8_t s3_conf;                    /*!< Star 3 confidence.
                                            (Unit[percentage]) */
    uint16_t mag_star_1;                /*!< Instrument magnitude of star 1 */
    uint16_t mag_star_2;                /*!< Instrument magnitude of star 2 */
    uint16_t mag_star_3;                /*!< Instrument magnitude of star 3 */
    uint16_t capture;                   /*!< Capture */
    uint16_t detection;                 /*!< Detection */
    uint16_t id;                        /*!< Identification */
    double rate_x;                      /*!< Estimated Rate X-axis */
    double rate_y;                      /*!< Estimated Rate Y-axis */
    double rate_z;                      /*!< Estimated Rate Z-axis */
    double est_attitude_q1;             /*!< Estimated attitude Q1 */
    double est_attitude_q2;             /*!< Estimated attitude Q2 */
    double est_attitude_q3;             /*!< Estimated attitude Q3 */
}__attribute__ ((__packed__))s_adcs_raw_star_trkr;

/**
 * @brief Star Tracker body vector for xyz axis
 */
typedef struct
{
    int16_t star_b_x;               /*!< Star body X-vector */
    int16_t star_b_y;               /*!< Star body Y-vector */
    int16_t star_b_z;               /*!< Star body Z-vector */
}__attribute__ ((__packed__))s_adcs_star_trkr_body;

/**
 * @brief Star Tracker Orbit vector for xyz axis
 */
typedef struct
{
    int16_t star_o_x;               /*!< Star orbit X-vector */
    int16_t star_o_y;               /*!< Star orbit Y-vector */
    int16_t star_o_z;               /*!< Star orbit Z-vector */
}__attribute__ ((__packed__))s_adcs_star_trkr_orbit;

/**
 *@brief generic sensor configration union.
 */
typedef union
{
    s_adcs_mgmtr_cfg magetometer_config;        /*!< Magnetometer config  */
    s_adcs_mgmtr_cfg red_magetometer_config;    /*!< Retudent Magnetometer 
                                                    config */
    s_adcs_css_cfg corase_config;               /*!< Coarse configuration */
    s_adcs_fss_cfg fss_config;                  /*!< Fss configuration */
    s_adcs_nadir_cfg nadir_config;              /*!< Nadir configuration */
    s_adcs_star_trkr_cfg star_trkr_config;      /*!< Star tracker 
                                                    configuration */
}u_adcs_sensor_config;

/**
 *@brief generic sensor configration parameter.
 */
typedef struct
{
    uint8_t sensor_type;                        /*!< Sesnor type */
    uint8_t sensor_id;                          /*!< Sensor Id */
    u_adcs_sensor_config sensor_cfg;            /*!< Sensor Configuration 
                                                    parameters */
}__attribute__ ((__packed__))s_adcs_sensor_cfg;

/**
 * @brief Tracking Controller Gain Parameters
 */
typedef struct
{
    float prop_gain;                        /*!< Tracking Proportional Gain */
    float derv_gain;                        /*!< Tracking Derivative Gain */
    float integ_gain;                       /*!< Tracking Integral Gain */
    uint8_t target_Track_Facet;             /*!< Target-tracking Facet */
}__attribute__ ((__packed__))s_adcs_trck_ctrl_gain;

/**
 * @brief Magnetorquer configuration
 */
typedef struct
{
    uint8_t mgntrqr_axis;           /*!< Magnetorquer axis configuration */
}__attribute__ ((__packed__))s_adcs_mgntrqr_cfg;

/*
 * @brief Magnetorquer output
 */
typedef struct
{
    int16_t torquer_cmd_x;          /*!< Commanded X Magnetorquer duty cycle */
    int16_t torquer_cmd_y;          /*!< Commanded y Magnetorquer duty cycle */
    int16_t torquer_cmd_z;          /*!< Commanded Z Magnetorquer duty cycle */
}__attribute__ ((__packed__))s_adcs_mgntrqr_out;

/**
 * @brief Reaction Wheel configuration
 */
typedef struct
{
    uint8_t rw_conf;       /*!< Reaction wheel axis configuration */
}__attribute__ ((__packed__))s_adcs_rw_cfg;

/**
 * @brief Reaction Wheel Speed
 */
typedef struct
{
    int16_t rw_speed;       /*!< Command wheel speed */
}__attribute__ ((__packed__))s_adcs_rw_speed;

/**
 *@brief generic Actuator configration Union.
 */
typedef union
{
    s_adcs_rw_cfg rwheel_config;           /*!< Reactionwheel config */
    s_adcs_mgntrqr_cfg magnotorque_config; /*!< Magnetorquer config  */
}u_adcs_acutator_config;

/**
 *@brief generic Actuator configration parameter.
 */
typedef struct
{
    uint8_t actuator_type;                  /*!< Actuator type */
    uint8_t actuator_id;                    /*!< Actuator Id */
    u_adcs_acutator_config actuator_cfg;    /*!< Actuator configurtion 
                                                parameters */
}__attribute__ ((__packed__))s_adcs_actuators_cfg;

/**
 * @brief Y-Wheel Control Parameters
 */
typedef struct
{
    float ctrl_gain;              /*!< Y-Momentum Control Gain */
    float nutation_damp_gain;     /*!< Y-momentum Nutation Damping Gain */
    float prop_gain;              /*!< Y-momentum Proportional Gain */
    float derv_gain;              /*!< Y-momentum Derivative Gain */
    float ref_rw_mom;             /*!< Reference Wheel Momentum */
}__attribute__ ((__packed__))s_adcs_y_rw_ctrl;

/**
 * @brief Z-Wheel Control Parameters
 */
typedef struct
{
    float ctrl_gain;              /*!< Z-Momentum Control Gain */
    float nutation_damp_gain;     /*!< Z-momentum Nutation Damping Gain */
    float prop_gain;              /*!< Z-momentum Proportional Gain */
    float derv_gain;              /*!< Z-momentum Derivative Gain */
    float ref_rw_mom;             /*!< Reference Wheel Momentum */
}__attribute__ ((__packed__))s_adcs_z_rw_ctrl;

/**
 * @brief Reaction wheel Control Parameters
 */
typedef struct
{
    float rw_prop_gain;                   /*!< RWheel Proportional Gain */
    float rw_derv_gain;                   /*!< RWheel Derivative Gain */
    float y_rw_bias;                      /*!< Y-Wheel Bias Momentum */
    uint8_t sun_point_facet;              /*!< Sun-pointing Facet */
    uint8_t rw_error_handling;            /*!< Automatic Control Transition 
                                            due to Wheel Errors */
}__attribute__ ((__packed__))s_adcs_rw_ctrl;

/**
 * @brief Reaction wheel Current parameter
 */
typedef struct
{
    double rw_current;        /*!< Reaction wheel current */
}__attribute__ ((__packed__))s_adcs_rw_cur;

/**
 * @brief Raw sensor measurement
 */
typedef struct
{
    int16_t nadir_raw_x;                /*!< Nadir sensor raw X angle */
    int16_t nadir_raw_y;                /*!< Nadir sensor raw Y angle */
    uint8_t nadir_busy;                 /*!< Nadir sensor capture status */
    uint8_t nadir_result;               /*!< Nadir sensor detection result */
    int16_t fss_raw_x;                  /*!< FSS raw X angle */
    int16_t fss_raw_y;                  /*!< FSS raw Y angle */
    uint8_t fss_busy;                   /*!< FSS capture status */
    uint8_t fss_result;                 /*!< FSS detection result */
    uint8_t css_raw;                    /*!< CSS Raw measurement */
    int16_t mag_raw_x;                  /*!< Raw magnetometer X measurement */
    int16_t mag_raw_y;                  /*!< Raw magnetometer Y measurement */
    int16_t mag_raw_z;                  /*!< Raw magnetometer Z measurement */
    int16_t raw_rate_x;                 /*!< Raw Angular rate X axis */
    int16_t raw_rate_y;                 /*!< Raw Angular rate Y axis */
    int16_t raw_rate_z;                 /*!< Raw Angular rate Z axis */
}__attribute__ ((__packed__))s_adcs_raw_sensor;

/**
 * @brief Control mode configuration
 */
typedef struct
{
    uint8_t ctrl_mode;                  /*!< Control mode */
    uint16_t time_out;                  /*!< Timeout value for assigned 
                                            control mode */
}__attribute__ ((__packed__))s_adcs_ctrl_mode;

/**
 * @brief Control mode configuration
 */
typedef struct
{
    float spin_gain;            /*!< Detumbling spin gain */
    float damping_gain;         /*!< Detumbling Damping Gain */
    double rw_ref_spin_rate;    /*!< Reference spin rate */
    float f_bdot_gain;          /*!< Fast BDot Detumbling Gain */
}__attribute__ ((__packed__))s_adcs_detumble_ctrl;

/**
 * @brief Rate sensor xyz axis measurement
 */
typedef struct
{
    double rate_x;         /*!< X axis rate sensor measurement value */
    double rate_y;         /*!< Y axis rate sensor measurement value */
    double rate_z;         /*!< Z axis rate sensor measurement value */
}__attribute__ ((__packed__))s_adcs_rate_sens;

/**
 * @brief Rate sensor raw measurement
 */
typedef struct
{
    int16_t raw_rate_x;     /*!< X axis raw rate sensor measurement */
    int16_t raw_rate_y;     /*!< Y axis raw rate sensor measurement */
    int16_t raw_rate_z;     /*!< Z axis raw rate sensor measurement */
}__attribute__ ((__packed__))s_adcs_raw_rate_sens;

/**
 * @brief Attitude Angle
 */
typedef struct
{
    double roll;           /*!< Command Roll Angle */
    double pitch;          /*!< Command Pitch Angle */
    double yaw;            /*!< Command Yaw Angle */
}__attribute__ ((__packed__))s_adcs_attitude_angl;

/**
 * @brief Target tarcking parameter
 */
typedef struct
{
    float long_ref;       /*!< Geocentric longitude of target */
    float lat_ref;        /*!< Geocentric latitude of target */
    float alt_ref;        /*!< Geocentric altitude of target */
}__attribute__ ((__packed__))s_adcs_trck_target;

/**
 * @brief Inertial Pointing Reference Vector
 */
typedef struct
{
    int16_t iner_ref_x;     /*!< Inertial Reference X */
    int16_t iner_ref_y;     /*!< Inertial Reference Y */
    int16_t iner_ref_z;     /*!< Inertial Reference Z */
}__attribute__ ((__packed__))s_adcs_inrt_ref;

/**
 * @brief generic control mode configuration parameter.
 */
typedef union
{
    s_adcs_attitude_angl attitude_ctrl;     /*!< Attitude control parameters */
    s_adcs_trck_target target_track_ctrl;   /*!< Traget tracking parameters */
    uint32_t nadir_point_mode;              /*!< Nadir pointing mode */
}__attribute__ ((__packed__))u_control_mode_param;

/**
 * @brief Estimated star tracker rates
 */
typedef struct
{
    int16_t x_axis_rate;    /*!< Estimated X axis rate measurement */
    int16_t y_axis_rate;    /*!< Estimated Y axis rate measurement */
    int16_t z_axis_rate;    /*!< Estimated Z axis rate measurement */
}__attribute__ ((__packed__))s_adcs_star_est_rate;

/**
 * @brief GPS and Sattelite tracker structure
 */
typedef struct
{
    uint8_t gps_sol_sts;            /*!< Gps Solution Status */
    uint8_t gps_num_sats_tracked;   /*!< Number of tracked GPS satellites */
    uint8_t gps_num_sats_sol;       /*!< Number of GPS satellites used 
                                        in solution */
    uint8_t gps_xyz_log_ctr;        /*!< Counter for XYZ Lof from GPS */
    uint8_t gps_range_log_ctr;      /*!< Counter for RANGE log from GPS */
    uint8_t gps_response;           /*!< Response Message for GPS log setup */
}__attribute__ ((__packed__))s_adcs_gps_s;

/**
 * @brief GPS time format
 */
typedef struct
{
    uint16_t gps_week;               /*!< GPS Reference Week */
    uint32_t gps_time_ms;            /*!< GPS Time Milliseconds */
}__attribute__ ((__packed__))s_adcs_gps_time;

/**
 * @brief Position and velocity in ECEF format for X axis
 */
typedef struct
{
    int32_t ecef_pos_x;             /*!< ECEF Position X */
    int16_t ecef_vel_x;             /*!< ECEF Velocity X */
}__attribute__ ((__packed__))s_adcs_gps_x;

/**
 * @brief Position and velocity in ECEF format for Y axis
 */
typedef struct
{
    int32_t ecef_pos_y;             /*!< ECEF Position Y */
    int16_t ecef_vel_y;             /*!< ECEF Velocity Y */
}__attribute__ ((__packed__))s_adcs_gps_y;

/**
 * @brief Position and velocity in ECEF format for Z axis
 */
typedef struct
{
    int32_t ecef_pos_z;             /*!< ECEF Position Z */
    int16_t ecef_vel_z;             /*!< ECEF Velocity Z */
}__attribute__ ((__packed__))s_adcs_gps_z;

/**
 * @brief Raw GPS measurement
 */
typedef struct
{
    uint8_t gps_sol_sts;            /*!< Gps Solution Status */
    uint8_t gps_num_sats_tracked;   /*!< Number of tracked GPS satellites */
    uint8_t gps_num_sats_sol;       /*!< Number of GPS satellites used 
                                        in solution */
    uint8_t gps_xyz_log_ctr;        /*!< Counter for XYZ Lof from GPS */
    uint8_t gps_range_log_ctr;      /*!< Counter for RANGE log from GPS */
    uint8_t gps_response;           /*!< Response Message for GPS log setup */
    uint16_t gps_week;              /*!< GPS Reference Week */
    uint32_t gps_time_ms;           /*!< GPS Time Milliseconds */
    int32_t ecef_pos_x;             /*!< ECEF Position X */
    int16_t ecef_vel_x;             /*!< ECEF Velocity X */
    int32_t ecef_pos_y;             /*!< ECEF Position Y */
    int16_t ecef_vel_y;             /*!< ECEF Velocity Y */
    int32_t ecef_pos_z;             /*!< ECEF Position Z */
    int16_t ecef_vel_z;             /*!< ECEF Velocity Z */
    double std_dev_pos_x;           /*!< X-pos Standard Deviation */
    double std_dev_pos_y;           /*!< Y-pos Standard Deviation */
    double std_dev_pos_z;           /*!< Z-pos Standard Deviation */
    uint8_t std_dev_vel_x;          /*!< X-vel Standard Deviation */
    uint8_t std_dev_vel_y;          /*!< Y-vel Standard Deviation */
    uint8_t std_dev_vel_z;          /*!< Z-vel Standard Deviation */
}__attribute__ ((__packed__))s_adcs_raw_gps;

/**
 * @brief Estimation mode configuration
 */
typedef struct
{
    uint8_t est_mode;               /*!< Estimation mode */
}__attribute__ ((__packed__))s_adcs_est_mode;

/**
 * @brief Estimation parameter
 */
typedef struct
{
    float mag_rate_noise;               /*!< Magnetometer Rate Filter System 
                                            Noise */
    float ekf_sys_noise;                /*!< EKF System Noise */
    float css_noise;                    /*!< CSS Measurement Noise */
    float sun_noise;                    /*!< Sun Sensor Measurement Noise */
    float nadir_noise;                  /*!< Nadir Sensor Measurement Noise */
    float mag_noise;                    /*!< Magnetometer Measurement Noise */
    float star_noise;                   /*!< Star Tracker Measurement Noise */
    uint8_t use_sun_est;                /*!< Use Sun Sensor in EKF */
    uint8_t use_nadir_est;              /*!< Use Nadir Sensor in EKF */
    uint8_t use_css_est;                /*!< Use CSS measurement in EKF */
    uint8_t use_star_est;               /*!< Use Star Tracker measurement in 
                                            EKF */
    uint8_t nadir_terminator_check;     /*!< Nadir sensor terminator test */
    uint8_t mag_mode;                   /*!< Magnetometer Mode */
}__attribute__ ((__packed__))s_adcs_est_param;

/**
 * @brief ECI position of the sattlite
 */
typedef struct
{
    int16_t position_x;         /*!< ECI referenced X coordinate */
    int16_t position_y;         /*!< ECI referenced Y coordinate */
    int16_t position_z;         /*!< ECI referenced Z coordinate */
}__attribute__ ((__packed__))s_adcs_eci_position;

/**
 * @brief ECI velocity of the Sattelite
 */
typedef struct
{
    int16_t velocity_x;             /*!< ECI referenced X velocity */
    int16_t velocity_y;             /*!< ECI referenced Y velocity */
    int16_t velocity_z;             /*!< ECI referenced Z velocity */
}__attribute__ ((__packed__))s_adcs_eci_velocity;

/**
 * @brief Estimated angular rates
 */
typedef struct
{
    int16_t est_x_angular_rate;     /*!< Estimated X Angular Rate */
    int16_t est_y_angular_rate;     /*!< Estimated Y Angular Rate */
    int16_t est_z_angular_rate;     /*!< Estimated Z Angular Rate */
}__attribute__ ((__packed__))s_adcs_est_rate;

/**
 * @brief Estimated quaternion
 */
typedef struct
{
    int16_t est_qutrn_1;            /*!< Star tracker estimated attitude Q1 */
    int16_t est_qutrn_2;            /*!< Star tracker estimated attitude Q2 */
    int16_t est_qutrn_3;            /*!< Star tracker estimated attitude Q3 */
}__attribute__ ((__packed__))s_adcs_est_qutrn;

/**
 * @brief Estimation innovation vector
 */
typedef struct
{
    int16_t innovn_vec_x;       /*!< Innovation Vector X */
    int16_t innovn_vec_y;       /*!< Innovation Vector Y */
    int16_t innovn_vec_z;       /*!< Innovation Vector Z */
}__attribute__ ((__packed__))s_adcs_est_innovn;

/**
 * @brief Estimation gyro measurement
 */
typedef struct
{
    int16_t est_gyro_x;         /*!< Estimated X-gyro Bias */
    int16_t est_gyro_y;         /*!< Estimated Y-gyro Bias */
    int16_t est_gyro_z;         /*!< Estimated Z-gyro Bias */
}__attribute__ ((__packed__))s_adcs_est_gyro;

/**
 * @brief Quaternion error vector
 */
typedef struct
{
    int16_t qutr_error_q1;      /*!< Quaternion Error -Q1 */
    int16_t qutr_error_q2;      /*!< Quaternion Error -Q2 */
    int16_t qutr_error_q3;      /*!< Quaternion Error -Q3 */
}__attribute__ ((__packed__))s_adcs_qutr_error;

/**
 * @brief Quaternion covariance
 */
typedef struct
{
    int16_t qutr_covr_q1;      /*!< Quaternion Covariance - Q1 RMS */
    int16_t qutr_covr_q2;      /*!< Quaternion Covariance - Q2 RMS */
    int16_t qutr_covr_q3;      /*!< Quaternion Covariance - Q3 RMS */
}__attribute__ ((__packed__))s_adcs_qutr_covr;

/**
 * @brief Angular rate covariance
 */
typedef struct
{
    int16_t covr_ang_rate_x;    /*!< X Angular Rate Covariance */
    int16_t covr_ang_rate_y;    /*!< Y Angular Rate Covariance */
    int16_t covr_ang_rate_z;    /*!< Z Angular Rate Covariance */
}__attribute__ ((__packed__))s_adcs_angl_rate_covr;

/**
 * @brief Magnetic filed vector measurement
 */
typedef struct
{
    int16_t mag_filed_x;        /*!< X axis magnetic field vector */
    int16_t mag_filed_y;        /*!< Y axis magnetic field vector */
    int16_t mag_filed_z;        /*!< Z axis magnetic field vector */
}__attribute__ ((__packed__))s_adcs_mag_vector;

/**
 * @brief Sun Vector measurement
 */
typedef struct
{
    int16_t sun_x;              /*!< X axis Sun vector */
    int16_t sun_y;              /*!< Y axis Sun vector */
    int16_t sun_z;              /*!< Z axis Sun vector */
}__attribute__ ((__packed__))s_adcs_sun_vector;

/**
 * @brief Nadir Vector measurement
 */
typedef struct
{
    int16_t nadir_x;              /*!< X axis Nadir vector */
    int16_t nadir_y;              /*!< Y axis Nadir vector */
    int16_t nadir_z;              /*!< Z axis Nadir vector */
}__attribute__ ((__packed__))s_adcs_nadir_vector;

/**
 * @brief Current measurement
 */
typedef struct
{
    uint16_t current_3v3;        /*!< Current value measured in 3.3V */
    uint16_t current_5v;         /*!< Current value measured in 5V */
}__attribute__ ((__packed__))s_adcs_current;

/**
 * @brief Current measurement
 */
typedef struct
{
    int16_t mcu_temperature;            /*!< MCU temperature value */
    int16_t mgmtr_temperature;          /*!< Magnetometer temperature value */
    int16_t rate_sensor_temperature;    /*!< Rate sensor temperature value */
}__attribute__ ((__packed__))s_adcs_temperature;

/**
 * @brief Rate sensor temeprature measurement
 */
typedef struct
{
    int16_t x_rate_temp;        /*!< X axis Rate sensor temeprature value */
    int16_t y_rate_temp;        /*!< Y axis Rate sensor temeprature value */
    int16_t z_rate_temp;        /*!< Z axis Rate sensor temeprature value */
}__attribute__ ((__packed__))s_adcs_rate_temperature;

/**
 * @brief Sensors Current measurement
 */
typedef struct
{
    double nadir_current;       /*!< Nadir Sensor current measurement */
    double fss_current;         /*!< Fine Sun Sensor current measurement */
    double css_current;         /*!< Coarse Sun Sensor current measurement */
}__attribute__ ((__packed__))s_adcs_sens_cur;

/**
 * @brief ADCS Current and Temperature
 */
typedef struct
{
    s_adcs_temperature adcs_temp;   /*!< ADCS Temperature */
    s_adcs_current adcs_current;    /*!< ADCS Curreent */
}__attribute__ ((__packed__))s_adcs_cur_temp;

/**
 * @brief Health Metrics Structure - Measured Fine Sun Sensor Vector
 */
typedef struct
{
    uint8_t status;             /*!< Operation Status */
    uint64_t time;              /*!< Epoch Time */
    int16_t sun_x;              /*!< X-Axis Sun Vector */
    int16_t sun_y;              /*!< Y-Axis Sun Vector */
    int16_t sun_z;              /*!< Z-Axis Sun Vector */
}__attribute__ ((__packed__))s_adcs_hm_fss_vec;

/**
 * @brief Health Metrics Structure - Estimated Angular Rates
 */
typedef struct
{
    uint8_t status;             /*!< Operation Status */
    uint64_t time;              /*!< Epoch Time */
    int16_t est_rate_x;         /*!< Estimated X Angular Rate */
    int16_t est_rate_y;         /*!< Estimated Y Angular Rate */
    int16_t est_rate_z;         /*!< Estimated Z Angular Rate */
}__attribute__ ((__packed__))s_adcs_hm_est_rates_sns;

/**
 * @brief Health Metrics Structure - ADCS Misc Current Measurement
 */
typedef struct
{
    uint8_t status;           /*!< Operation Status */
    uint64_t time;            /*!< Epoch Time */
    double cubestar_cur;      /*!< CubeStar Current Measurement */
    double mgntqr_cur;        /*!< Magnetorquer Current Measurement */
    double cubestar_mcu_temp; /*!< CubeStar MCU Temperature */
}__attribute__ ((__packed__))s_adcs_hm_misc_cur;

/**
 * @brief Health Metrics Structure - ADCS Temperature
 */
typedef struct
{
    uint8_t status;         /*!< Operation Status */
    uint64_t time;          /*!< Epoch Time */
    int16_t mcu_temp;       /*!< MCU Temperature */
    double mgntr_temp;      /*!< Magnetometer Temperature */
    double re_mgntr_temp;   /*!< Redundant Magnetometer Temperature */
}__attribute__ ((__packed__))s_adcs_hm_temp;

/**
 * @brief Health Metrics Structure - Estimated Rate Sensor Temperature
 */
typedef struct
{
    uint8_t status;         /*!< Operation Status */
    uint64_t time;          /*!< Epoch Time */
    int16_t x_rate_sns;     /*!< X Rate Sensor Temperature */
    int16_t y_rate_sns;     /*!< Y Rate Sensor Temperature */
    int16_t z_rate_sns;     /*!< Z Rate Sensor Temperature */
}__attribute__ ((__packed__))s_adcs_hm_est_rate_sns_temp;


/**
 * @brief Health Metrics Structure - Current ADCS State
 */
typedef struct
{
    uint8_t status;                 /*!< Operation Status */
    uint64_t time;                  /*!< Epoch Time */
    uint8_t att_est_mode;           /*!< Attitude Estimation Mode */
    uint8_t ctrl_mode;              /*!< Control Mode */
    uint8_t run_mode : 2;           /*!< ADCS Run mode */
    uint8_t asgp4_mode : 2;         /*!< ASGP4 Mode */
    uint8_t ctrl_sig_en :1;         /*!< Cube Control Signal Enabled */
    uint8_t ctrl_motor_en : 1;      /*!< Cube Control Motor Enabled */
    uint8_t cubesense1_en : 1;      /*!< Cubesense1 Enabled */
    uint8_t cubesense2_en : 1;      /*!< Cubesense2 Enabled */
    uint8_t rw1_en : 1;             /*!< Cube Wheel 1 Enabled */
    uint8_t rw2_en : 1;             /*!< Cube Wheel 2 Enabled */
    uint8_t rw3_en : 1;             /*!< Cube Wheel 3 Enabled */
    uint8_t star_en : 1;            /*!< Cube Star Enabled */
    uint8_t gps_recv_en : 1;        /*!< GPS Receiver Enabled */
    uint8_t gps_lna_pwr_en : 1;     /*!< GPS LNA Power Enabled */
    uint8_t motor_driver_en : 1;    /*!< Motor Driver Enabled */
    uint8_t sun_above_horizon : 1;  /*!< Sun is Above Local Horizon */
    uint8_t cubesens1_comm_err : 1; /*!< Cubesense1 Communications Error */
    uint8_t cubesens2_comm_err : 1; /*!< Cubesense2 Communications Error */
    uint8_t ctrl_sig_comm_err : 1;  /*!< CubeControl Signal Communications
                                       Error */
    uint8_t ctrl_motor_comm_err : 1; /*!< CubeControl Motor Communications
                                       Error */
    uint8_t rw1_comm_err : 1;        /*!< Cube Wheel1 Communications Error */
    uint8_t rw2_comm_err : 1;         /*!< Cube Wheel2 Communications Error */
    uint8_t rw3_comm_err : 1;        /*!< Cube Wheel3 Communications Error */
    uint8_t star_comm_err : 1;       /*!< Cube Star Communications Error */
    uint8_t mgntr_range_err : 1;     /*!< Magnetometer Range Error */
    uint8_t cam1_sram_ocur : 1;      /*!< Cam1 SRAM Overcurrent Detected */
    uint8_t cam1_3v3_ocur : 1;        /*!< Cam1 3v3 Overcurrent Detected */
    uint8_t cam1_sns_busy_err : 1;   /*!< Cam1 Sensor Busy Error */
    uint8_t cam1_sns_err : 1;        /*!< Cam1 Sensor Detection Error */
    uint8_t sun_sns_range_err : 1;   /*!< Sun Sensor Range Error */
    uint8_t cam2_sram_ocur : 1;      /*!< Cam2 SRAM Overcurrent Detected */
    uint8_t cam2_3v3_ocur : 1;       /*!< Cam2 3v3 Overcurrent Detected */
    uint8_t cam2_sns_busy_err : 1;   /*!< Cam2 Sensor Busy Error */
    uint8_t cam2_sns_err : 1;        /*!< Cam2 Sensor Detection Error */
    uint8_t nadir_sns_range_err : 1; /*!< Nadir Sensor Range Error */
    uint8_t rate_sns_range_err : 1;  /*!< Rate Sensor Range Error */
    uint8_t rw_spd_range_err : 1;    /*!< Wheel Speed Range Error */
    uint8_t css_err : 1;             /*!< Coarse Sun Sensor Error */
    uint8_t star_trckr_match_err : 1;/*!< Star Tracker Match Error */
    uint8_t star_trckr_ocur : 1;     /*!< Star Tracker Overcurrent Detected*/
    uint8_t orbit_param_invalid : 1;   /*!< Orbit Parameters are Invalid */
    uint8_t cfg_invalid : 1;           /*!< Configuration is Invalid */
    uint8_t ctrl_mode_chg_not_alwd : 1;/*!< Control Mode Change is not
                                            allowed */
    uint8_t est_chg_not_alwd : 1;      /*!< Estimator Change is not allowed */
    uint8_t cur_mgntr_mode : 2;        /*!<Current Magnetometer Sampling Mode*/
    uint8_t magfield_model_err : 1;    /*!< Modelled and measured magnetic
                                          field differs in size */
    uint8_t node_reco_err : 1;         /*!< Node Recovery Error */
    uint8_t cubesense1_runt_err : 1;   /*!< CubeSense1 Runtime Error */
    uint8_t cubesense2_runt_err : 1;   /*!< CubeSense2 Runtime Error */
    uint8_t cubectrl_sig_runt_err : 1; /*!< CubeControl Signal Runtime Error */
    uint8_t cubectrl_m_runt_err : 1;   /*!< CubeControl Motor Runtime Error */
    uint8_t rw1_runt_err : 1;          /*!< CubeWheel1 Runtime Error */
    uint8_t rw2_runt_err : 1;          /*!< CubeWheel2 Runtime Error */
    uint8_t rw3_runt_err : 1;          /*!< CubeWheel3 Runtime Error */
    uint8_t star_runt_err : 1;         /*!< CubeStar Runtime Error */
    uint8_t mgntr_err : 1;             /*!< Magnetometer Error */
    uint8_t rate_sns_fail : 1;         /*!< Rate Sensor Failure */

}__attribute__ ((__packed__))s_adcs_hm_crnt_state;

// Health Metrics Id Enumeration
typedef enum
{
    ADCS_HM_SESNOR_CURRENT,         ///< Sensor Current Consumption
    ADCS_HM_CONS_CURRENT,           ///< Controller Current Consumption
    ADCS_HM_RW_CURRENT,             ///< Reaction Wheel Current Measure
    ADCS_HM_CSS_VECTOR,             ///< Coarse Sun Sensor Vector
    ADCS_HM_EST_ATTITUDE_ANGLE,     ///< Estimated Attitude Angle
    ADCS_HM_RAW_MAG_MEASURE,        ///< Raw Magnetometer Measurement
    ADCS_HM_RAW_RATE_SENSOR_MEASURE,///< Raw Rate Sensor Sensor Measurement
    ADCS_HM_RATE_SENSOR_MEASURE,    ///< Rate Sensor Measurement
    ADCS_HM_FSS_VECTOR,             ///< Fine Sun Sensor Vector
    ADCS_HM_EST_RATES,              ///< Estimated Angular rates
    ADCS_HM_MISC_CURRENT,           ///< ADCS Misc Current Measurement
    ADCS_HM_TEMPERATURE,            ///< ADCS Temperature
    ADCS_HM_RATE_SENSOR_TEMPERATURE,///< Rate Sensor Temperature
    ADCS_HM_CURRENT_STATE,          ///< Current ADCS State
    ADCS_HM_MAX                     ///< Health metrics Maximum
}e_adcs_health_metrics_id;

/**
 * @brief Health Metrics Structure - Sensors Current measurement
 */
typedef struct
{
    uint8_t status;             /*!< Operation Status */
    uint64_t time;              /*!< Epoch Time */
    double nadir_3v3_current;   /*!< Nadir Sensor 3V3 current measurement */
    double fss_3v3_current;     /*!< FSS 3V3 current measurement */
    double nadir_sram_current;  /*!< Nadir Sensor SRAM current measurement */
    double fss_sram_current;    /*!< FSS SRAM current measurement */
}__attribute__ ((__packed__))s_adcs_hm_sen_cur;

/**
 * @brief Health Metrics Structure - Consumed Current measurement
 */
typedef struct
{
    uint8_t status;             /*!< Operation Status */
    uint64_t time;              /*!< Epoch Time */
    double current_3v3;         /*!< Current value measured in 3.3V */
    double current_5v;          /*!< Current value measured in 5V */
    double current_vbat;        /*!< Vbat current value */
}__attribute__ ((__packed__))s_adcs_hm_cons_cur;

/**
 * @brief Health Metrics Structure - Reaction wheel Current measurement
 */
typedef struct
{
    uint8_t status;             /*!< Operation Status */
    uint64_t time;              /*!< Epoch Time */
    double rw1_current;         /*!< Reaction wheel current 1 */
    double rw2_current;         /*!< Reaction wheel current 2 */
    double rw3_current;         /*!< Reaction wheel current 3 */
}__attribute__ ((__packed__))s_adcs_hm_rw_cur;

/**
 * @brief Health Metrics Structure - CSS Vector
 */
typedef struct
{
    uint8_t status;             /*!< Operation Status */
    uint64_t time;              /*!< Epoch Time */
    int16_t sun_x;              /*!< X axis Sun vector */
    int16_t sun_y;              /*!< Y axis Sun vector */
    int16_t sun_z;              /*!< Z axis Sun vector */
}__attribute__ ((__packed__))s_adcs_hm_css_vector;

/**
 * @brief Health Metrics Structure - Estimated Attitude Angles
 */
typedef struct
{
    uint8_t status;             /*!< Operation Status */
    uint64_t time;              /*!< Epoch Time */
    double roll;                /*!< Estimated Roll Angle */
    double pitch;               /*!< Estimated Pitch Angle */
    double yaw;                 /*!< Estimated Yaw Angle */
}__attribute__ ((__packed__))s_adcs_hm_est_att_angl;

/**
 * @brief Health Metrics Structure - Raw Magnetometer Measurement
 */
typedef struct
{
    uint8_t status;             /*!< Operation Status */
    uint64_t time;              /*!< Epoch Time */
    int16_t mag_raw_x;          /*!< Raw magnetometer X measurement */
    int16_t mag_raw_y;          /*!< Raw magnetometer Y measurement */
    int16_t mag_raw_z;          /*!< Raw magnetometer Z measurement */
}__attribute__ ((__packed__))s_adcs_hm_raw_mag_measure;

/**
 * @brief Health Metrics Structure - Raw Rate Sensor Measurement
 */
typedef struct
{
    uint8_t status;             /*!< Operation Status */
    uint64_t time;              /*!< Epoch Time */
    int16_t raw_rate_x;         /*!< X axis raw rate sensor measurement */
    int16_t raw_rate_y;         /*!< Y axis raw rate sensor measurement */
    int16_t raw_rate_z;         /*!< Z axis raw rate sensor measurement */
}__attribute__ ((__packed__))s_adcs_hm_raw_rates;

/**
 * @brief Health Metrics Structure - Measured Angular Rates
 */
typedef struct
{
    uint8_t status;             /*!< Operation Status */
    uint64_t time;              /*!< Epoch Time */
    double rate_x;              /*!< Measured X axis Rates */
    double rate_y;              /*!< Measured Y axis Rates */
    double rate_z;              /*!< Measured Z axis Rates */
}__attribute__ ((__packed__))s_adcs_hm_meas_rates;

/**
 * @brief This function extract the telemetry data based on telemetry id.
 */
void unfied_tlm_data_extract(uint8_t *data,uint16_t pld_len,uint8_t id);

#ifdef __cplusplus
}
#endif
#endif /* ADCS_BSK_H_ */
