Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/master/libraries/AP_ADSB/sagetech-sdk/sgDecodeSVR.c
Views: 1799
/**1* @copyright Copyright (c) 2021 Sagetech, Inc. All rights reserved.2*3* @file sgDecodeSVR.c4* @author jimb5*6* @date Feb 10, 20217*8* This file receives a raw ADS-B target state vector report message buffer and9* parses the payload into a data struct.10*/1112#include <string.h>13#include <stdbool.h>14#include <string.h>15#include <math.h>1617#include "sg.h"18#include "sgUtil.h"19#include "target.h"2021// airborne surface22// -------- --------23#define SV_PARAM_TOA_EPOS (1 << 3) // x24#define SV_PARAM_TOA_POS (1 << 2) // x x25#define SV_PARAM_TOA_VEL (1 << 1) // x x26#define SV_PARAM_LATLON (1 << 0) // x x2728#define SV_PARAM_GEOALT (1 << 7) // x29#define SV_PARAM_VEL (1 << 6) // x30#define SV_PARAM_SURF_GS (1 << 5) // x31#define SV_PARAM_SURF_HEAD (1 << 4) // x32#define SV_PARAM_BAROALT (1 << 3) // x33#define SV_PARAM_VRATE (1 << 2) // x34#define SV_PARAM_NIC (1 << 1) // x x35#define SV_PARAM_ESTLAT (1 << 0) // x3637#define SV_PARAM_ESTLON (1 << 7) // x38#define SV_PARAM_ESTNVEL (1 << 6)39#define SV_PARAM_ESTEVAL (1 << 5)40#define SV_PARAM_SURV (1 << 4) // x x41#define SV_PARAM_REPORT (1 << 3) // x x4243/// the payload offset.44#define PBASE 44546/*47* Documented in the header file.48*/49bool sgDecodeSVR(uint8_t *buffer, sg_svr_t *svr)50{51// memset(svr, 0, sizeof(sg_svr_t));5253uint8_t fields[3];54memcpy(&fields, &buffer[PBASE + 0], 3);5556svr->type = buffer[PBASE + 0] == 0x1F ? svrAirborne : svrSurface;57svr->flags = buffer[PBASE + 3];58svr->eflags = buffer[PBASE + 4];59svr->addr = toInt32(&buffer[PBASE + 5]) & 0xFFFFFF;60svr->addrType = buffer[PBASE + 8] & 0xFF;6162uint8_t ofs = 9;6364if (fields[0] & SV_PARAM_TOA_EPOS)65{66svr->toaEst = toTOA(&buffer[PBASE + ofs]);67ofs += 2;68}69if (fields[0] & SV_PARAM_TOA_POS)70{71svr->toaPosition = toTOA(&buffer[PBASE + ofs]);72ofs += 2;73}74if (fields[0] & SV_PARAM_TOA_VEL)75{76svr->toaSpeed = toTOA(&buffer[PBASE + ofs]);77ofs += 2;78}7980if (fields[0] & SV_PARAM_LATLON)81{82if (svr->validity.position)83{84svr->lat = toLatLon(&buffer[PBASE + ofs + 0]);85svr->lon = toLatLon(&buffer[PBASE + ofs + 3]);86}87else88{89svr->lat = 0.0;90svr->lon = 0.0;91}9293ofs += 6;94}9596if (svr->type == svrAirborne)97{98if (fields[1] & SV_PARAM_GEOALT)99{100if (svr->validity.geoAlt)101{102svr->airborne.geoAlt = toAlt(&buffer[PBASE + ofs]);103}104else105{106svr->airborne.geoAlt = 0;107}108109ofs += 3;110}111112if (fields[1] & SV_PARAM_VEL)113{114if (svr->validity.airSpeed)115{116int16_t nvel = toVel(&buffer[PBASE + ofs + 0]);117int16_t evel = toVel(&buffer[PBASE + ofs + 2]);118119svr->airborne.heading = toHeading2((double)nvel, (double)evel);120svr->airborne.speed = sqrt(nvel * nvel + evel * evel);121svr->airborne.velEW = evel;122svr->airborne.velNS = nvel;123}124else125{126svr->airborne.heading = 0;127svr->airborne.speed = 0;128svr->airborne.velEW = 0;129svr->airborne.velNS = 0;130}131132ofs += 4;133}134135if (fields[1] & SV_PARAM_BAROALT)136{137if (svr->validity.baroAlt)138{139svr->airborne.baroAlt = toAlt(&buffer[PBASE + ofs]);140}141else142{143svr->airborne.baroAlt = 0;144}145146ofs += 3;147}148149if (fields[1] & SV_PARAM_VRATE)150{151if (svr->validity.baroVRate || svr->validity.geoVRate)152{153svr->airborne.vrate = toInt16(&buffer[PBASE + ofs]);154}155else156{157svr->airborne.vrate = 0;158}159160ofs += 2;161}162}163else164{165if (fields[1] & SV_PARAM_SURF_GS)166{167if (svr->validity.surfSpeed)168{169svr->surface.speed = toGS(&buffer[PBASE + ofs]);170}171else172{173svr->surface.speed = 0;174}175176ofs += 1;177}178179if (fields[1] & SV_PARAM_SURF_HEAD)180{181if (svr->validity.surfHeading)182{183svr->surface.heading = toHeading(&buffer[PBASE + ofs]);184}185else186{187svr->surface.heading = 0;188}189190ofs += 1;191}192}193194if (fields[1] & SV_PARAM_NIC)195{196svr->nic = buffer[PBASE + ofs];197198ofs += 1;199}200201if (fields[1] & SV_PARAM_ESTLAT)202{203if (svr->evalidity.estPosition)204{205svr->airborne.estLat = toLatLon(&buffer[PBASE + ofs]);206}207else208{209svr->airborne.estLat = 0;210}211212ofs += 3;213}214215if (fields[2] & SV_PARAM_ESTLON)216{217if (svr->evalidity.estPosition)218{219svr->airborne.estLon = toLatLon(&buffer[PBASE + ofs]);220}221else222{223svr->airborne.estLon = 0;224}225226ofs += 3;227}228229if (fields[2] & SV_PARAM_SURV)230{231svr->survStatus = buffer[PBASE + ofs];232ofs += 1;233}234235if (fields[2] & SV_PARAM_REPORT)236{237svr->mode = buffer[PBASE + ofs];238}239240return true;241}242243244