#ifndef gimbalDef_h
#define gimbalDef_h

//	----------------------------------------------------------------------------
//  Byte align for Messaging
//	----------------------------------------------------------------------------

#if _MSC_VER
__pragma(pack(push, 1))
#else
#pragma pack(1)
#endif

//	----------------------------------------------------------------------------
//  GimbalDefs
//	----------------------------------------------------------------------------

const int HEADER = 0x1957;

#define UTIL_BAUD 8*115200
#define NSAMP 256
#define NiAXES 3
#define NoAXES 2
#define NoAXES3 3
#define NiAXES3 3
#define NLENS 4
#define NiFILT 5
#define NiPID 3
#define kFreq 1918
#define kLensFreq 400
#define IMU_BUF_BITS 11
#define IMU_BUF_COUNT 2048

//	------------------
//  message types
//	------------------

#define MSG_FIRST 0x10
enum {
	MSG_GYRO = MSG_FIRST,		// 16
	MSG_GYRO2,					// 17
	MSG_TUNINGS,				// 18
	MSG_PID_PAR,				// 19
	MSG_FILTER_PAR,				// 20
	MSG_CONTROLS,				// 21
	MSG_COMMAND,				// 22
	MSG_STATE,					// 23
	MSG_BW_PAR,					// 24
	MSG_BW_RES,					// 25
	MSG_OUTER_PAR,				// 26
	MSG_DB_CMD,					// 27
	MSG_UTIL,					// 28
	MSG_CONS_INPUT,				// 29
	MSG_LENS_CMD,				// 30
	MSG_LENS_FB,				// 31
	MSG_STEERING,				// 32
	MSG_OUTER_CMD,				// 33
	MSG_OUTER_FB,				// 34
	MSG_GIM_TO_NAV,				// 35
	MSG_NAV_TO_GIM,				// 36
	MSG_LOG,					// 37
	MSG_unused,					// 38
	MSG_NAV_to_GIM_CS,			// 39
	MSG_GPS_SIM,				// 40
	MSG_NAV_to_GIM_CS_V2,		// 41
	MSG_ODIN_TO_NAV_CFG,		// 42
	MSG_NAV_TO_GIM_AUX,			// 43
	MSG_LAST
};

//	--------------------
//  message type strings
//	--------------------

#define MSG_STRINGS			\
	"MSG_GYRO",				\
	"MSG_GYRO2",			\
	"MSG_TUNINGS",			\
	"MSG_PID_PAR",			\
	"MSG_FILTER_PAR",		\
	"MSG_CONTROLS",			\
	"MSG_COMMAND",			\
	"MSG_STATE",			\
	"MSG_BW_PAR",			\
	"MSG_BW_RES",			\
	"MSG_OUTER_PAR",		\
	"MSG_DB_CMD",			\
	"MSG_UTIL",				\
	"MSG_CONS_INPUT",		\
	"MSG_LENS_CMD",			\
	"MSG_LENS_FB",			\
	"MSG_STEERING",			\
	"MSG_OUTER_CMD",		\
	"MSG_OUTER_FB",			\
	"MSG_GIM_TO_NAV",		\
	"MSG_NAV_TO_GIM",		\
	"MSG_LOG",				\
	"MSG_unused",			\
	"MSG_NAV_to_GIM_CS",	\
	"MSG_GPS_SIM"

//	---------------------
//  msgHeader_t
//	---------------------

typedef struct {
	uint16_t header;
	uint16_t id;
	uint16_t cmd;
	uint16_t count;
	uint32_t len;
} msgHeader_t;

//	---------------------
//  msgTail_t
//	---------------------

typedef struct {
	int16_t checksum;
} msgTail_t;

//  ------------------
//  filter types
//  ------------------

#define FILT_STRINGS " None"," LagLead"," Notch"," Lowpass"
#define FILT_STRINGSx "None", "LagLead", "Notch", "Lowpass"

enum {
	FILTER_NONE,
	FILTER_LAGLEAD,
	FILTER_NOTCH,
	FILTER_LOWPASS,
	NUM_FILTER_TYPES
};

//  ------------------
//  backdrive types
//  ------------------

#define BD_STRINGS "Off","Step","Sine","Drive","VSine"

enum {
	BD_NONE = 0,
	BD_STEP,
	BD_SINE,
	BD_DRIVE,
	BD_VSINE,
	NUM_BD_TYPES
};

//  ------------------
//  plot types
//  ------------------

#define PLOT_STRINGS " Gyro"," Command"," Angle"," Sine"," Drive"," Pwm"," Tach"," PwmOuter"," NavAtt"," Pos"," Set1"," Set2"," Set3"," Set4"
#define PLOT_STRINGSx "Gyro", "Command", "Angle", "Sine", "Drive", "Pwm", "Tach", "PwmOuter", "NavAtt", "Pos", "Set1", "Set2", "Set3", "Set4"

enum {
	PLOT_Gyro = 0,
	PLOT_Command,
	PLOT_Angle,
	PLOT_Sine,
	PLOT_Drive,
	PLOT_Pwm,
	PLOT_Tach,
	PLOT_PwmOuter,
	PLOT_NavAtt,
	PLOT_Pos,
	PLOT_Set1,
	PLOT_Set2,
	PLOT_Set3,
	PLOT_Set4,
	NUM_PLOT_TYPES
};

//	---------------------
//  axisControls_t
//	---------------------

typedef struct {
	int32_t enable;
	int32_t remote;
	int32_t backdrive;
	int32_t jsNull;
	int32_t gyroNull;
	float desiredRate;
	float sinAmp;
	float sinFreq;
	float desiredPos;
} axisControls_t;

//  ------------------
//  steering modes
//  ------------------

#define MODE_STRINGS "Rate","Slave","Geo","Outer","Stow"

enum {
	MODE_RATE = 0,
	MODE_SLAVE,
	MODE_GEO,
	MODE_OUTER,
	MODE_STOW,
	NUM_MODES
};

//  ------------------
//  PID types
//  ------------------

enum {
	PID_RATE = 0,
	PID_GEO,
	PID_POSN,
	NUM_PIDS
};

//	---------------------
//  controls_t
//	---------------------

typedef struct {
	int32_t connect;
	int32_t standby;
	int32_t autonull;
	int32_t mode;
	int32_t plotType;
	int32_t plotAxis;
	int32_t plotRaw;
	axisControls_t axis[NiAXES];
} controls_t;

//	---------------------
//  lensCommand
//	---------------------

typedef struct {
	float command;
} lensCommand_t;

//	---------------------
//  lensCommands
//	---------------------

typedef struct {
	lensCommand_t lensCommand[NLENS];
} lensCommands_t;

//	---------------------
//  lensState
//	---------------------

typedef struct {
	float pos;
	float err;
	float drive;
	int32_t pwm;
} lensState_t;

//	---------------------
//  lensStates
//	---------------------

typedef struct {
	lensState_t lensState[NLENS];
} lensStates_t;

//	---------------------
//  lensPar_t
//	---------------------

typedef struct {
	int32_t enable;
	float kP;
	float kI;
	float kD;
	float kFF;
	float kTach;
	float kPwm;
	float kPwmLim;
	float kPmin;
	float kPmax;
	float kSpan0;
	float kSpan1;
} lensPar_t;

//	---------------------
//  lens_t
//	---------------------

typedef struct {
	float command;
	int32_t ecount;
	int32_t aip;
	float span0;
	float span1;
	float kpos;
	float pos;
	float err;
	float drive;
	float rate;
	int32_t pwm;
} lens_t;

//	---------------------
//  MSG_CONTROLS
//	---------------------

typedef struct {
	msgHeader_t	head;
	controls_t controls;
	msgTail_t tail;
} msgControls_t;

//	---------------------
//  steering_t
//	---------------------

typedef struct {
	float desired[3];
	float focus;
	float iris;
	float zoom;
	double latitude;
	double longitude;
	float altitude;
	double latitude2;
	double longitude2;
	float altitude2;
	int16_t gpsCount;
	int16_t gpsMode;
	int32_t bits;
} steering_t;

//	---------------------
//  MSG_CONTROLS
//	---------------------

typedef struct {
	msgHeader_t	head;
	steering_t steering;
	msgTail_t tail;
} msgSteering_t;

//	---------------------
//  analog_t
//	---------------------

typedef struct {
	float raw;
	float ofs;
	float val;
} analog_t;

//	---------------------
//  encoder_t
//	---------------------

typedef struct {
	int32_t count;
	int32_t indexed;
	float ofs;
	float val;
} encoder_t;

//	---------------------
//  axisState_t
//	---------------------

typedef struct {
	analog_t gyro;
	analog_t angle;
	analog_t tach;
	encoder_t enc;
	float rateCommand;
	float r;
	float rE;
	float rEr;
	float err;
	float erI;
	float drive;
	float current;
	float jitter;
	int32_t pwm;
	int32_t pwmOuter;
	float pos;
	float outerDemandedRate;
	float outerDrive;
	int8_t outerInDeadband;
	int8_t profile;
	int8_t settled;
	int8_t logic1;
	float geoInt;
} axisState_t;

//	---------------------
//  gyroState_t
//	---------------------

typedef struct {
	int32_t gyroFrame;
	int32_t gyroFreq;
	int32_t consFrame;
	int32_t mainFrame;
	int32_t misc0;
	int32_t misc1;
	int32_t misc2;
	int32_t misc3;
} gyroState_t;

//	---------------------
//  commState_t
//	---------------------

typedef struct {
	int32_t gyro;
	int32_t vn200;
	int32_t main422;
	int32_t outer;
	int32_t navbox;
	int32_t navCs;
	int32_t odin;
	int32_t sim;
	int32_t console;
	int32_t util;
	int32_t lens;
	int32_t steering;
} commState_t;

//	---------------------
//  navState_t
//	---------------------

typedef struct {
	uint64_t TimeStartup;
	uint64_t TimeGps;
	uint64_t TimeSyncIn;
	float Ypr[3];
	float AngularRate[3];
	double PosLla[3];
	float VelNed[3];
	uint16_t InsStatus;
	uint16_t ImuStatus;
	float Temperature;
	float YprU[3];
	float PosU;
	float VelU;
} navState_t;

//	---------------------
//  gpsState_t
//	---------------------

typedef struct {
	uint64_t timeGps;
	float ypr[3];
	float angularRate[3];
	double position[3];
	float velocity[3];
	uint16_t insStatus;
	uint16_t unused;
} gpsState_t;

//	---------------------
//  gimToNav_t
//	---------------------

enum GimToNavCommands {
	GimToNavCommand_None = 0,
	GimToNavCommand_SendNavToGim,
	GimToNavCommand_SendCfgStatusToGim,
	GimToNavCommand_SendAuxAttAdjToGim,
	GimToNavCommand_SendCfgStatusV2ToGim,
};

typedef struct {
	uint16_t command;
	uint16_t par;
	float posOuterYprDeg[3];
	float posInnerYprDeg[3];
	float velOuterYprDegPerSec[3];
	float velInnerYprDegPerSec[3];
} gimToNav_t;

//	---------------------
//  geo_t
//	---------------------

typedef struct {
	double cameraL[3];			// camera location geodetic NEU [deg,deg,m]
	double targetL[3];			// target location geodetic NEU [deg,deg,m]
	double passiveL[3];			// passive location geodetic NEU [deg,deg,m]
	float losError[3];			// camera to target los error [deg]
	float losErrorRate[3];		// camera to target los error rate [deg/s]
	float range;				// camera to target distance [m]
	float ypr[3];				// camera attitude [deg]
	float targetAngle[3];		// angle to target [deg]
	float targetRate[3];		// anglular rate to target [deg/s]
	float losError2[3];			// los error alternate calc [deg]
	float losErrorRate2[3];		// camera to target los error rate [deg/s]
	float vprofile[3];			// profile velocity [deg/s]
	float rangeRate;			// camera to target velocity [m/s]
} geo_t;

//	---------------------
//  geoMisc_t
//	---------------------

typedef struct {
	double cameraE[3];			// camera location ECEF [m]
	double targetE[3];			// target location ECEF [m]
	double vectorE[3];			// camera to target vector ECEF [m]
	double vectorT[3];			// camera to target vector tangent NED [m]
	double vectorC[3];			// camera to target vector camera frame [m]
	float cameraV[3];			// camera velocity tangent NED [m/s]
	double Re2t[3][3];			// dcm ECEF to tangent NED
	double c[3][3];				// dcm NED to camera
} geoMisc_t;

//	---------------------
//  geoMisc2_t
//	---------------------

typedef struct {
	double cameraE[3];			// camera location ECEF [m]
	double targetE[3];			// target location ECEF [m]
	double vectorE[3];			// camera to target vector ECEF [m]
	float vectorT[3];			// camera to target vector tangent NED [m]
	float vectorC[3];			// camera to target vector camera frame [m]
	float vectorM[3];			// camera to target vector mount frame [m]
	float vectorI[3];			// camera to target vector imu frame [m]
	float velC[3];				// velocity of target in camer/los frame 
	float cameraV[3];			// camera velocity tangent NED [m/s]
	double Re2t[3][3];			// dcm ECEF to tangent NED
	float c[3][3];				// dcm NED to camera
	float dcmOuter2Inner[3][3];	// dcm Outer to Inner
	float dcmELL2Mount[3][3];	// dcm ELL to Mount
	float dmcMount2Outer[3][3];	// dcm Mount to Outer
	float dcmELL2Outer[3][3];	// dcm ELL to Outer
	float dcmInner2LOS[3][3];	// dcm Inner to los frame
	float dcmELL2LOS[3][3];		// dcm ELL to los frame
} geoMisc2_t;

//	---------------------
//  log_t
//	---------------------

const int logstringlen = 20*sizeof(int32_t);

typedef struct {
	int64_t time;
	int32_t type;
	char s[logstringlen];
} log_t;

//	-------------------------------------------------------------------
//	log string values
//	-------------------------------------------------------------------

#define LOG_STRINGS			\
	""					,	\
	"OSEQ_None"			,	\
	"OSEQ_StareTransit"	,	\
	"OSEQ_Stare"		,	\
	"OSEQ_FireTransit"	,	\
	"OSEQ_WaitCamera"	,	\
	"OSEQ_Imaging"		,	\
	"OSEQ_ClusterDone"	,	\
	"OSEQ_Unknown"		,	\
	"GEO_LOG_SENDING"	,	\
	"GEO_LOG_LOGGING"	,	\
	"fireCamera"		,	\
	"imageComplete"		,	\
	"imageTimeout"		,	\
	"settle timeout"	,	\
	"enter standby"		,	\
	"exit standby"		,	\
	"HSLOG on"			,	\
	"HSLOG off"			,	\
	"SEND_GIM_LOGS = T"	,	\
	"SEND_GIM_LOGS = F"	,	\
	"TRIGGER_CAMERA = T",	\
	"TRIGGER_CAMERA = F",	\
	"Camera Ready"		,	\
	"Camera Timeout"	,	\
	"newSequence"		,	\
	"endStare"			,	\
	"seq ignored"		,	\
	"sendVNSIH"			,	\
	"asyncFireCamera: Camera not Ready, command ignored"			,	\
	"asyncFireCamera: Target Imaging in progress, command ignored"	,	\
	"CanonLens:"		,	\
	"Rate Mode"			,	\
	"Slave Mode"		,	\
	"Geo Mode"			,	\
	"Outer Mode"		,	\
	"Stow Mode"			,	\
	"Unknown Mode"		,	\
	"Odin Mode Custom"	,	\
	"Odin Mode Rate"	,	\
	"Odin Mode Pos"		,	\
	"Odin Mode Geo"		,	\
	"Odin Mode Stow"	,	\
	"Odin Mode Outer"	,	\
	"Odin Mode Unknown"	,	\
	"CanonLens Local"	,	\
	"last"					\

//	-------------------------------------------------------------------
//	log types
//	-------------------------------------------------------------------

enum{
	LOG_GENERIC,
	LOG_OSEQ_NONE,
	LOG_OSEQ_STARE_TRANSIT,
	LOG_OSEQ_STARE,
	LOG_OSEQ_FIRE_TRANSIT,
	LOG_OSEQ_WAIT_CAMERA,
	LOG_OSEQ_FIRE_IMAGING,
	LOG_OSEQ_CLUSTER_DONE,
	LOG_OSEQ_UNKNOWN,
	LOG_GEO_LOG_SENDING,
	LOG_GEO_LOG_LOGGING,
	LOG_fireCamera,
	LOG_imageComplete,
	LOG_imageTimeout,
	LOG_settle_timeout,
	LOG_enter_standby,
	LOG_exit_standby,
	LOG_HSLOG_on,
	LOG_HSLOG_off,
	LOG_GIM_FLAG_SEND_GIMBAL_LOGS_T,
	LOG_GIM_FLAG_SEND_GIMBAL_LOGS_F,
	LOG_GIM_FLAG_TRIGGER_CAMERA_T,
	LOG_GIM_FLAG_TRIGGER_CAMERA_F,
	LOG_Camera_Ready,
	LOG_Camera_Timeout,
	LOG_newSequence,
	LOG_endStare,
	LOG_seq_ignored,
	LOG_sendVNSIH,
	LOG_asyncFire_ErrNotReady,
	LOG_asyncFire_ErrInProg,
	LOG_CanonLens,
	LOG_MODE_RATE,
	LOG_MODE_SLAVE,
	LOG_MODE_GEO,
	LOG_MODE_OUTER,
	LOG_MODE_STOW,
	LOG_MODE_Unknown,
	LOG_ODIN_MODE_CUSTOM,
	LOG_ODIN_MODE_RATE,
	LOG_ODIN_MODE_POS,
	LOG_ODIN_MODE_GEO,
	LOG_ODIN_MODE_STOW,
	LOG_ODIN_MODE_OUTER,
	LOG_ODIN_MODE_Unknown,
	LOG_CanonLens_Local,
	LOG_LAST,
	NUM_LOG_TYPES
};

//	-------------------------------------------------------------------
//	odin.targetSeqIndex values
//	-------------------------------------------------------------------

#define OSEQ_STRINGS "None","StareTransit","Stare","FireTransit","WaitCamera","Imaging","ClusterDone"

//	-------------------------------------------------------------------
//	odin.targetSeqIndex values
//	-------------------------------------------------------------------

enum{
	OSEQ_NONE = 0,
	OSEQ_STARE_TRANSIT,
	OSEQ_STARE,
	OSEQ_FIRE_TRANSIT,
	OSEQ_WAIT_CAMERA,
	OSEQ_FIRE_IMAGING,
	OSEQ_CLUSTER_DONE,
	NUM_OSEQ
};

//	-------------------------------------------------------------------
//	odinState_t
//	-------------------------------------------------------------------

typedef struct {
	uint32_t u32RXBytes;
	uint32_t u32RXPackets;
	uint32_t u32RXExtra;
	uint32_t u32RXErrors;
	uint32_t u32RXBadHeaderChk;
	uint32_t u32RXBadPayloadCRC;
	uint32_t u32RXSeqErrors;
	uint32_t u32TXPackets;
	uint32_t rxGIMBAL_CTRL;
	uint32_t rxGIMBAL_CONFIG;
	uint32_t rxGPS_STATUS;
	uint32_t rxGEO_POINT;
	uint32_t rxLENS_CTRL;
	uint32_t rxLENS_CAL;
	uint32_t txGIMBAL_CONFIG;
	uint32_t txMASTER_STATUS;
	uint32_t txLENS_STATUS;

	float fYawHdgT;
	float fMinRng;
	float fMaxRng;
	float fMinAz;
	float fMaxAz;
	double dLatitude;
	double dLongitude;
	float fAltELL;

	float losJitter;

	uint32_t targets;
	uint32_t frameCount;
	uint32_t fireCount;
	uint32_t clusterID;
	uint32_t targetID;
	uint32_t geoEvent;
	uint32_t gimbalMode;
	uint32_t geoStatus;
	uint32_t gimStatus;
	uint32_t camReady;
	uint32_t camTimeout;
	uint32_t camPulse;
	uint32_t targetSeqIndex;
	uint32_t targetResult;

} 	odinState_t;

//	---------------------
//  navBoxCS_t
//	---------------------

typedef struct {
	float LeverArmGimToImu[3];		// gimbal center to IMU center
	float LeverArmGimToPrimAnt[3];	// gimbal center to primary antenna
	float LeverArmGimToSecAnt[3];	// gimbal center to secondary antenna
	int32_t NovatelCrcCount;		// Novatel CRC error count
	int32_t VectorNavCrcCount;		// VectorNav CRC error count
	char NavBoxVerGitSha[8];		// Version control commit SHA hash, null terminated
	char NavBoxVerHuman[8];			// NavBox human readable version, like v1.2.2, null terminated
	char GimbalVerHuman[8];			// Gimbal human-readable version, null terminated
	uint16_t NovatelHz;				// Novatel incoming packets per second, and VectorNav VNGPE outgoing updates
	uint16_t VectorNavHz;			// VectorNav incoming packets per second
	uint16_t GimbalAnglesInHz;		// Gimbal angles incoming packets per second
	uint16_t MasterStatusOutHz;		// Gimbal MasterStatusDEF outgoing packets per second (as requested by gimbal)
	uint16_t ConfigStatusOutHz;     // NavBoxConfigStatus_t outgoing packets per second (as requested by gimbal)
	uint16_t PlaceholderToAlignTo4Byte;     //
} navBoxCS_t;

//	---------------------
//	Node Types
//	---------------------

#define TYPE_STRINGS "16D","Outer","Lens","WeeCam","Aethon3","SCS16"

//	---------------------
//	Node Types
//	---------------------

enum{
	TYPE_16D = 0,
	TYPE_OUTER,
	TYPE_LENS,
	TYPE_WEECAM,
	TYPE_AETHON3,
	TYPE_S16C,
	NUM_TYPE
};

//	---------------------
//  sysId_t
//	---------------------

typedef struct {
	char name[16];
	uint16_t serno;
	uint16_t type;
} sysId_t;

//	---------------------
//  outerCmd_t
//	---------------------

enum{
	CANON_LENS_UPDATE = 1
};

//	---------------------
//  outerCmd_t
//	---------------------

typedef struct {
	float drive[3];
	uint16_t focus;
	uint16_t iris;
	uint16_t lensbits;
	uint16_t bits;
} outerCmd_t;

//	---------------------
//  outerFb_t
//	---------------------

typedef struct {
	float tach[3];
	int32_t encoder[2];
	char logchar[3];
	uint8_t logindex;
	uint8_t indexed[3];
	int8_t lasterr;
	int16_t focus;
	int16_t iris;
	int16_t lensbits;
	int16_t bits;
} outerFb_t;

//	---------------------
//  state_t
//	---------------------
typedef struct {
	sysId_t id;
	gyroState_t gyro;
	navState_t nav;
	geo_t geo;
	lensStates_t lens;
	axisState_t axis[NiAXES];
	outerCmd_t outerCmd;
	outerFb_t outerFb;
	odinState_t odin;
	navBoxCS_t navbox;
	commState_t comm[3];
} state_t;

//	---------------------
//  msgDbcmd_t
//	---------------------

typedef struct {
	msgHeader_t	head;
	char data[4];
} msgDbcmd_t;

//	---------------------
//  MSG_STATE
//	---------------------

typedef struct {
	msgHeader_t	head;
	int64_t time;
	state_t state;
	msgTail_t tail;
} msgState_t;

//	---------------------
//  MSG_COMMAND
//	---------------------

enum {
	CMD_CONNECT = 10,
	CMD_SET_HEADING,
	CMD_CONNECT_HSLOG,
	CMD_ENABLE_INDEX,
};

//	---------------------
//  command_t
//	---------------------

typedef struct {
	int32_t command;
	int32_t par1;
	int32_t par2;
	float fpar1;
	float fpar2;
} command_t;

//	---------------------
//  MSG_COMMAND
//	---------------------

typedef struct {
	msgHeader_t	head;
	command_t command;
	msgTail_t tail;
} msgCommand_t;

//	---------------------
//  MSG_GYRO
//	---------------------

typedef struct {
	msgHeader_t	head;
	uint64_t timestamp;
	float minval;
	float maxval;
	uint16_t samples[NSAMP];
	msgTail_t tail;
} msgGyroBuf_t;

//	---------------------
//  MSG_TUNINGS
//	--------------------

typedef struct
{
	float kP[NiPID];
	float kI[NiPID];
	float kD[NiPID];
	float kILim[NiPID];
	float kT;
	float kC;
} pidPar_t;

typedef struct
{
	float kP;
	float kFF;
	float kTach;
} outerPar_t;

typedef struct
{
	float kP;
	float kP2;
	float kI;
	float kD;
	float kILim;
	float kMystery2;
} geoPar_t;

typedef struct
{
	float kP;
	float kD;
	float kLim;
} posPar_t;

typedef struct
{
	int32_t ftype;
	float f1;
	float q;
} filterPar_t;

typedef struct
{
	pidPar_t pidP[NiAXES];
	filterPar_t filtP[NiAXES][NiFILT];
	outerPar_t outerP[NoAXES];
	geoPar_t geoP[NiAXES];
	posPar_t posP[NiAXES];
	lensPar_t lensP[NLENS];
} tunings_t;

typedef struct
{
	msgHeader_t	head;
	tunings_t t;
	msgTail_t tail;
} msgTunings_t;

//	---------------------
//  MSG_FILTER_PAR
//	---------------------

typedef struct {
	msgHeader_t	head;
	int32_t axis;
	int32_t ifilt;
	filterPar_t filtPar;
	msgTail_t tail;
} msgFilterPar_t;

//	---------------------
//  MSG_PID_PAR
//	---------------------

typedef struct {
	msgHeader_t	head;
	int32_t axis;
	pidPar_t pidPar;
	msgTail_t tail;
} msgPidPar_t;

//	---------------------
//  MSG_OUTER_PAR
//	---------------------

typedef struct {
	msgHeader_t	head;
	int32_t axis;
	outerPar_t outerPar;
	msgTail_t tail;
} msgOuterPar_t;

//	---------------------
//  msgPwm_t
//	---------------------

typedef struct {
	uint8_t header;
	uint8_t bits;
	uint8_t yaw;
	uint8_t pit;
	uint8_t rol;
	uint8_t dom;
	uint8_t vsw;
	uint8_t sum;
} msgPwm_t;

//	---------------------
//  bwPar_t
//	---------------------

typedef struct {
	uint32_t start;
	uint32_t axis;
	uint32_t openloop;
	uint32_t opendrive;
	uint32_t shake;
	uint32_t numfreqs;
	float amplitude;
	float minfreq;
	float maxfreq;
} bwPar_t;

//	---------------------
//  bwRes_t
//	---------------------

#define NUMBW 60

typedef struct {
	uint32_t index;
	int32_t bwState;
	float drive;
	float output;
	float time;
	float cycles;
	float freq[NUMBW];
	float gain[NUMBW];
	float phase[NUMBW];
} bwRes_t;

//	---------------------
//  MSG_BW_PAR
//	---------------------

typedef struct {
	msgHeader_t	head;
	bwPar_t bwPar;
	msgTail_t tail;
} msgBwPar_t;

//	---------------------
//  MSG_BW_RES
//	---------------------

typedef struct {
	msgHeader_t	head;
	bwRes_t bwRes;
	msgTail_t tail;
} msgBwRes_t;

//	---------------------
//  consInput
//	---------------------

typedef struct {
	int32_t buttons;
	int32_t enc1;
	int32_t enc2;
	int32_t enc3;
	float zoom;
	float focus;
	float iris;
} consInput_t;

//	---------------------
//  MSG_CONS_INPUT
//	---------------------

typedef struct {
	msgHeader_t	head;
	consInput_t consInput;
	msgTail_t tail;
} msgConsInput_t;

//	---------------------
//  MSG_LENS_CMD
//	---------------------

typedef struct {
	msgHeader_t	head;
	float focus;
	float iris;
	float zoom;
	msgTail_t tail;
} msgLensCommand_t;

//	---------------------
//  MSG_LENS_FB
//	---------------------

typedef struct {
	msgHeader_t	head;
	lensStates_t lens;
	msgTail_t tail;
} msgLensFeedback_t;

//	---------------------
//  MSG_OUTER_CMD
//	---------------------

typedef struct {
	msgHeader_t	head;
	outerCmd_t cmd;
	msgTail_t tail;
} msgOuterCmd_t;

//	---------------------
//  MSG_OUTER_FB
//	---------------------

typedef struct {
	msgHeader_t	head;
	outerFb_t outerFb;
	msgTail_t tail;
} msgOuterFb_t;

//	-------------------------------------------------------------------
//	GPSStatusMessage_t
//	-------------------------------------------------------------------

typedef struct {
	uint64_t u64Validity;
	uint64_t u64GPSTime;
	uint16_t u16GPSStatus;
	uint8_t u8SatV;
	uint8_t u8SatT;
	uint8_t u8Align;
	uint8_t u8Qual;
	double dLatitude;
	double dLongitude;
	double dAltELL;
	float fPitch;
	float fRoll;
	float fYawHdgT;
	float fVelN;
	float fVelE;
	float fVelD;
	float AngRate[3];
	float fPFOM;
	float fHFOM;
	float fHDOP;
	float fVDOP;
	float fHPosErr;
	float fVPosErr;
} GPSStatusMessage_t;

//	---------------------
//  msgGpsSim_t
//	---------------------

typedef struct {
	msgHeader_t	head;
	GPSStatusMessage_t	GPSStatusMessage;
	msgTail_t tail;
} msgGpsSim_t;

//	---------------------
//  MESSAGE_LENGTH_CASES
//	---------------------

#define MESSAGE_LENGTH_CASES \
	case MSG_GYRO:				 return sizeof(msgGyroBuf_t);		\
	case MSG_GYRO2:				 return sizeof(msgGyroBuf_t);		\
	case MSG_TUNINGS:			 return sizeof(msgTunings_t);		\
	case MSG_PID_PAR:			 return sizeof(msgPidPar_t);		\
	case MSG_FILTER_PAR:		 return sizeof(msgFilterPar_t);		\
	case MSG_CONTROLS:			 return sizeof(msgControls_t);		\
	case MSG_COMMAND:			 return sizeof(command_t);			\
	case MSG_STATE:				 return sizeof(msgState_t);			\
	case MSG_BW_PAR:			 return sizeof(msgBwPar_t);			\
	case MSG_BW_RES:			 return sizeof(msgBwRes_t);			\
	case MSG_OUTER_PAR:			 return sizeof(msgOuterPar_t);		\
	case MSG_DB_CMD:			 return 0;							\
	case MSG_UTIL:				 return 0;							\
	case MSG_CONS_INPUT:		 return sizeof(msgConsInput_t);		\
	case MSG_LENS_CMD:			 return sizeof(msgLensCommand_t);	\
	case MSG_LENS_FB:			 return sizeof(msgLensFeedback_t);	\
	case MSG_STEERING:			 return sizeof(msgSteering_t);		\
	case MSG_OUTER_CMD:			 return sizeof(msgOuterCmd_t);		\
	case MSG_OUTER_FB:			 return sizeof(msgOuterFb_t);		\
	case MSG_GIM_TO_NAV:		 return sizeof(msgGimToNav_t);		\
	case MSG_NAV_TO_GIM:		 return sizeof(msgNavToGim_t);		\
	case MSG_LOG:				 return sizeof(msgLog_t);			\
	case MSG_unused:			 return 0;							\
	case MSG_NAV_to_GIM_CS:		 return sizeof(msgNavBoxCS_t);		\
	case MSG_GPS_SIM:			 return sizeof(msgGpsSim_t);		\
	case MSG_NAV_to_GIM_CS_V2:	 return 0;							\
	case MSG_ODIN_TO_NAV_CFG:	 return 0;							\
	case MSG_NAV_TO_GIM_AUX:	 return sizeof(msgNavToGimAux_t);

//	---------------------
//  t1Data_t
//	---------------------

typedef struct {
	uint8_t portb;
	uint8_t admux;
	uint8_t adcsra;
	uint8_t adcl;
	uint8_t adch;
	uint8_t nextmux;
} t1Data_t;

//	----------------------------------------------------------------------------
//	NovAtel Rx types
//	----------------------------------------------------------------------------

enum {
	novAtelNone = 0,
	novAtelBestPos = 42,
	novAtelBestVel = 99,
	novAtelBestXyz = 241,
	novAtelDualAntennaHeading = 2042,
	novAtelUnknown = 0xFFFF
};

typedef struct  {
	uint32_t PosSolutionStatus;
	uint32_t PositionType;
	double	PositionXYZ[3];
	float	PositionXYZStdev[3];
	uint32_t VelSolutionStatus;
	uint32_t VelType;
	double	VelocityXYZ[3];
	float	VelocityXYZStdev[3];
	uint8_t StationID[4];

	float DifferentialAgeSec;
	float SolutionAge;
	uint8_t NumberOfSatsTracked;
	uint8_t NumberOfSatsOInSolution;
	uint8_t NumberOfL1E1B1SatsOInSolution;
	uint8_t NumberOfMultiFreqSignalsInSol;
	uint8_t Reserved;
	uint8_t ExtSolStatus;
	uint8_t GalileoBeiDouSignalMask;
	uint8_t GpsGlonassSignalMask;

} bestxyz_raw_t;

//int x1 = sizeof(bestxyz_raw_t);
//int x2 = sizeof(dualantennaheading_raw_t);


//	--------------------------------------------------------
//  dualantennaheading_raw_t, as described in Novatel manual
//	--------------------------------------------------------

typedef struct {
	uint32_t SolutionStatus;
	uint32_t PositionType;
	float BaselineLengthM;
	float HeadingDeg;
	float PitchDeg;
	float Reserved1;
	float HeadingStdevDeg;
	float pitchStdevDeg;
	char StationID[4];
	uint8_t NumberOfSatsTracked;
	uint8_t NumberOfSatsOInSolution;
	uint8_t NumberAboveElev;
	uint8_t NumberAboveElevL2;
	uint8_t SolSource;
	uint8_t ExtSolSource;
	uint8_t GalileoBeiDouSignalMask;
	uint8_t GpsGlonassSignalMask;
} dualantennaheading_raw_t;


typedef struct {
	uint32_t SolutionStatus;
	uint32_t PositionType;
	double LatitudeDeg;
	double LongitudeDeg;
	double HeightMsl;
	float Undulation;
	uint32_t DatumID;
	float LatitudeStdevM;
	float LongitudeStdevM;
	float HeightStdevM;
	char StationID[4];
	float DifferentialAgeSec;
	float SolutionAge;
	uint8_t NumberOfSatsTracked;
	uint8_t NumberOfSatsOInSolution;
	uint8_t NumberOfL1E1B1SatsOInSolution;
	uint8_t NumberOfMultiFreqSignalsInSol;
	uint8_t Reserved;
	uint8_t ExtSolStatus;
	uint8_t GalileoBeiDouSignalMask;
	uint8_t GpsGlonassSignalMask;
} bestpos_raw_t;

typedef struct {
	uint32_t SolutionStatus;
	uint32_t VelocityType;
	float LatencySec;
	float DifferentialAgeSec;
	double HorzGroundSpeedMS;
	double VelocityAzimuthDeg;
	double VertSpeedUpMS;
	float Reserved;
} bestvel_raw_t;

//	---------------------
//  navToGim_t
//	---------------------

typedef struct {

	uint8_t					u8Version;					// MASTER_STATUS_VER_LATEST
	uint8_t					u8GeoEvent;					// Geo Event ID (GEO_EVEN_)
	uint8_t					u8GimbalMode;				// Gimbal Mode (GIM_MODE_) (Alignment)
	uint8_t					u8SensorStatus;				// Sensor Status (SENSOR_STATUS_) (Identifies which Sensor)

	// General (and Things moved for Alignment)
	//
	uint32_t				u32GimSystemTime_us;		// Gimbal microseconds since start (1980)
	uint32_t				u32Frame;					// Number of Frames (Triggers) from Gimbals point of view
	uint16_t				u16ClusterID;				// ID of currently active Cluster
	uint16_t				u16TargetID;				// ID of currently active (pointed at) Target
	uint16_t				u16TotalPower;				// 1/100 W	Consumption of whatever components it's possible to measure
	uint16_t				u16GeoStatus;				// TBD (GEO_STATUS_) (Moved for Alignment)

	// GPS (NovaTel)
	//
	uint64_t				u64GPSTime1980_ms;			// GPS Time, ms since 1980-01-06
	double					dGPSLat;					// Primary antenna Latitude (degrees)
	double					dGPSLng;					// Primary antenna Longitude (degrees)
	double					dGPSAltELL;					// Ellipsoid Altitude (meters)
	float					fGPSLatAccu;				// as-is from NovaTel BESTPOS msg (meters)
	float					fGPSLngAccu;				// as-is from NovaTel BESTPOS msg (meters)
	float					fGPSAltAccu;				// as-is from NovaTel BESTPOS msg (meters)
	float					fGPSVelNED[3];				// NED frame, need to be recalculated from BESTVEL (m/s)
	uint8_t					u8GPSSolutionStatus;		// as-is from BESTPOS msg (NOVA_SOL_)
	uint8_t					u8GPSPositionType;			// as-is from BESTPOS msg (NOVA_POS_)
	uint8_t					u8GPSNumOfSat;				// Tracking
	uint8_t					u8GPSScaledPDOP;			// fPDOP * 10 (Limit to 255 (25.5))
	float					fGPSHeadingT;				// From DUALANTENNAHEADING message (degrees)
	float					fGPSPitch;					// From DUALANTENNAHEADING message (degrees)
	float					fGPSHeadingAccu;			// From DUALANTENNAHEADING message (degrees)

	// INS (VectorNav)
	//
	float					fINSYaw;					// Yaw in NED, from Group 1 or 5 (degrees) (Camera Heading)
	float					fINSPitch;					// Pitch in NED, from Group 1 or 5 (degrees)
	float					fINSRoll;					// Roll in NED, from Group 1 or 5 (degrees)
	float					fINSYawAccu;				// Yaw uncertainty, From Group 5 - YprU (degrees)
	float					fINSPitchAccu;				// Pitch uncertainty, From Group 5 - YprU (degrees)
	float					fINSRollAccu;				// Roll uncertainty, From Group 5 - YprU (degrees)
	double					dINSLat;					// Latitude IMU position, from Group 1 (degrees)
	double					dINSLng;					// Longitude (degrees)
	double					dINSAltELL;					// Altitude (Ellipsoid) (meters)
	float					fINSPosStdev;				// IMU Position uncertainty, from Group 6 (meters)
	float					fINSVelStdev;				// IMU Velocity uncertainty, from Group 6 (meters)
	float					fINSVelNED[3];				// IMU velocity, from group 1 (m/s)
	float					fINSAngRate[3];				// Angular rate, from Group 3 (deg/s)
	uint16_t				u16INSStatus;				// VNAV_INS	From Group 1
	int16_t					s16INSTemperature;			// 1/100 deg C Group 3 (Trying to save space)
	uint64_t				u64INSTimeStartup_ns;		// Time since INS startup, from Group1 (nanosec)
	uint64_t				u64INSTimeGps_ns;			// The absolute GPS time since start of GPS epoch 1980, from Group 1 (nanosec)

	// Resolved
	//
	float					fPlatformHdgT;				// Resolved Aircraft Heading (TRUE)

	// Gimbal
	//
	float					fGIMOuter[3];				// Outer Angles (degrees)
	float					fGIMInner[3];				// Inner Angles (degrees)
	float					fGIMOuterAngRate[3];		// deg/s
	float					fGIMInnerAngRate[3];		// deg/s
	float					fGIMLosJitter;				// Line-of-sight jitter (deg)
	uint16_t				u16GimStatus;				// Gimbal Ok, INS Ok, GPS Ok, INS Ok (GIM_STATUS_)
	int16_t					s16GPSBaselineLength;		// Negative value for invalid or N/A length (mm) (Moved for Alignment)

	// Geo Target
	//
	double					dTargetLat;					// GeoPoint Target Latitude (degrees)
	double					dTargetLng;					// GeoPoint Target Longitude (degrees)
	float					fTargetAltELL;				// GeoPoint Target Altitude (Ellipsoid) (meters)

} navToGim_t;

//	---------------------
//  msgGimToNav_t
//	---------------------

typedef struct {
	msgHeader_t	head;
	gimToNav_t gim;
	msgTail_t tail;
} msgGimToNav_t;

//	---------------------
//  msgNavToGim_t
//	---------------------

typedef struct {
	msgHeader_t	head;
	navToGim_t nav;
	msgTail_t tail;
} msgNavToGim_t;

//	---------------------
//  msgLog_t
//	---------------------

typedef struct {
	msgHeader_t	head;
	log_t entry;
	msgTail_t tail;
} msgLog_t;

//	-------------------------------
//  msgNavBoxCS_t
//	-------------------------------

typedef struct {
	msgHeader_t	head;
	navBoxCS_t navbox;
	msgTail_t tail;
} msgNavBoxCS_t;

//	-------------------------------
//  auxAttitudeAdjustment_t
//	-------------------------------

// Contains angles to be added to payload INS's YPR solution; expected to be zero or close to zero,
// normally not exceeding 5-10 degrees. Will be calculated by comparing payload solution
// reduced to fixed platform reference frame the to dual-antenna GPS heading or fixed INS solution.

//	-------------------------------
//  auxAttitudeAdjustment_t
//	-------------------------------

typedef struct {
	float auxAttitudeAdjYprDeg[3];
} AuxAttitudeAdjustment_t;

//	-------------------------------
//  msgNavToGimAuxAttAdj_t
//	-------------------------------

typedef struct {
	msgHeader_t head;
	AuxAttitudeAdjustment_t auxAttitudeAdjustment;
	msgTail_t tail;
} msgNavToGimAux_t;

//	---------------------
//  comStats_t
//	---------------------

typedef struct {
	int32_t kTimeout;
	int32_t count;
	int32_t count2;
	int32_t countsPerSec;
	int32_t crcCount;
	int32_t crcCount2;
	int32_t crcPerSec;
	int32_t connected;
	int64_t lastRx;
} comStats_t;

//	---------------------
//  NavBoxConfigStatusV2_t
//	---------------------
/*
typedef struct NavBoxConfigStatusV2_t
{
	float LeverArmGimToImu[3];			// gimbal center to IMU center
	float LeverArmGimToPrimAnt[3];		// gimbal center to primary antenna
	float LeverArmGimToSecAnt[3];		// gimbal center to secondary antenna
	float LeverArmGimToFixedImu[3];		// gimbal center to fixed IMU
	int32_t NovatelCrcErrorCount;		// Novatel CRC error count
	int32_t VectorNavCrcErrorCount;		// VectorNav CRC error count
	float fPayloadINSPosStdev;			// Payload INS - position accuracy STDEV
	float fPayloadINSAttStdev;			// Payload INS - worst angle accuracy of YPR
	float fFixedINSPosStdev;			// Fixed INS - position accuracy STDEV
	float fFixedINSAttStdev;			// Fixed INS - worst angle accuracy of YPR
	char NavBoxVerGitSha[8];			// Version control commit SHA hash
	char NavBoxVerHuman[8];				// NavBox human readable version, like v1.2.2
	char GimbalVerHuman[8];				// Gimbal human-readable version
	uint16_t NovatelHz;					// Novatel incoming packets per second, and VectorNav VNGPE outgoing updates
	uint16_t PayloadVectorNavHz;		// Payload VectorNav incoming packets per second
	uint16_t FixedVectorNavHz;			// Fixed VectorNav incoming packets per second
	uint16_t GimbalAnglesInHz;			// Gimbal angles incoming packets per second
	uint16_t MasterStatusOutHz;			// Gimbal MasterStatusDEF outgoing packets per second (as requested by gimbal)
	uint16_t ConfigStatusOutHz;			// NavBoxConfigStatus_t outgoing packets per second (as requested by gimbal)
	uint16_t LeverArmCalcMode;			//  Lever arm calculation mode, see LeverArmMode enum
	uint16_t PlaceholderToAlignTo4Byte;	//
	float AuxAttitudeAdjustment[3];		// Axillary attitude adjustment sent to gimbal; angular values
										// to be added to INS solution to correct for bias (as determined
										// by comparing payload INS attitude to fixed INS or dual antenna yaw)
} NavBoxConfigStatusV2_t;
*/

//	----------------------------------------------------------------------------
//  Normal align
//	----------------------------------------------------------------------------

#pragma pack(1)
#if _MSC_VER
__pragma(pack(pop))
#else
#pragma pack()
#endif


#endif	// gimbalDef_h
