CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
Ardupilot

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: Ardupilot/ardupilot
Path: blob/master/libraries/AP_ADSB/sagetech-sdk/sgEncodeOperating.c
Views: 1799
1
/**
2
* @copyright Copyright (c) 2021 Sagetech, Inc. All rights reserved.
3
*
4
* @file sgEncodeOperating.c
5
* @author Jacob.Garrison
6
*
7
* @date Feb 15, 2021
8
*
9
* This file receives a populated operating message struct and
10
* converts it into a operating message buffer.
11
*/
12
13
#include <stdbool.h>
14
#include <stdlib.h>
15
16
#include "sg.h"
17
#include "sgUtil.h"
18
19
#define SG_PAYLOAD_LEN_OPMSG SG_MSG_LEN_OPMSG - 5 /// the payload length.
20
21
#define PBASE 4 /// the payload offset.
22
#define OFFSET_SQUAWK 0 /// the squawk code offset in the payload.
23
#define OFFSET_CONFIG 2 /// the mode/config offset in the payload.
24
#define OFFSET_EMRG_ID 3 /// the emergency flag offset in the payload.
25
#define OFFSET_ALT 4 /// the altitude offset in the payload.
26
#define OFFSET_RATE 6 /// the climb rate offset in the payload.
27
#define OFFSET_HEADING 8 /// the heading offset in the payload.
28
#define OFFSET_AIRSPEED 10 /// the airspeed offset in the payload.
29
30
/*
31
* Documented in the header file.
32
*/
33
bool sgEncodeOperating(uint8_t *buffer, sg_operating_t *op, uint8_t msgId)
34
{
35
// populate header
36
buffer[0] = SG_MSG_START_BYTE;
37
buffer[1] = SG_MSG_TYPE_HOST_OPMSG;
38
buffer[2] = msgId;
39
buffer[3] = SG_PAYLOAD_LEN_OPMSG;
40
41
// populate Squawk code
42
uint162Buf(&buffer[PBASE + OFFSET_SQUAWK], op->squawk);
43
44
// populate Mode/Config
45
buffer[PBASE + OFFSET_CONFIG] = op->milEmergency << 5 |
46
op->enableXBit << 4 |
47
op->enableSqt << 3 |
48
op->savePowerUp << 2 |
49
op->opMode;
50
51
// populate Emergency/Ident
52
buffer[PBASE + OFFSET_EMRG_ID] = op->identOn << 3 |
53
op->emergcType;
54
55
// populate Altitude
56
uint16_t altCode = 0;
57
if (op->altUseIntrnl)
58
{
59
altCode = 0x8000;
60
}
61
else if (op->altHostAvlbl)
62
{
63
// 100 foot encoding conversion
64
altCode = (op->altitude + 1200) / 100;
65
66
if (op->altRes25)
67
{
68
altCode *= 4;
69
}
70
71
// 'Host altitude available' flag
72
altCode += 0x4000;
73
}
74
uint162Buf(&buffer[PBASE + OFFSET_ALT], altCode);
75
76
// populate Altitude Rate
77
int16_t rate = op->climbRate / 64;
78
if (!op->climbValid)
79
{
80
rate = 0x8000;
81
}
82
uint162Buf(&buffer[PBASE + OFFSET_RATE], rate);
83
84
// populate Heading
85
// conversion: heading * ( pow(2, 15) / 360 )
86
uint16_t heading = op->heading * 32768 / 360;
87
if (op->headingValid)
88
{
89
heading += 0x8000;
90
}
91
uint162Buf(&buffer[PBASE + OFFSET_HEADING], heading);
92
93
// populate Airspeed
94
uint16_t airspeed = op->airspd;
95
if (op->airspdValid)
96
{
97
airspeed += 0x8000;
98
}
99
uint162Buf(&buffer[PBASE + OFFSET_AIRSPEED], airspeed);
100
101
// populate checksum
102
appendChecksum(buffer, SG_MSG_LEN_OPMSG);
103
104
return true;
105
}
106
107