Mercurial > ublox > ublox8 > experimental
view gnss-galileo.h @ 64:8e85919405df
gnss-galileo: add a valid bit to each ephemeris
This is easier than trying to guess whether the ephemeris contains any
meaningful values.
Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author | Josef 'Jeff' Sipek <jeffpc@josefsipek.net> |
---|---|
date | Wed, 22 Jan 2020 10:10:26 -0500 |
parents | c8c848632471 |
children | 123cac19d9bd |
line wrap: on
line source
/* * Copyright (c) 2020 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #ifndef __GNSS_GALILEO_H #define __GNSS_GALILEO_H #include <jeffpc/types.h> #include "gnss.h" /* The highest sv number that we should ever see */ #define GALILEO_MAX_SV_ID 36 struct galileo_inav_page { bool page_nominal; union { struct { uint32_t sar; /* 22 bits */ uint8_t type; /* 6 bits */ struct { uint16_t iod; /* 10 bits */ uint16_t t0e; /* 14 bits */ int32_t m0; /* 32 bits */ uint32_t e; /* 32 bits */ uint32_t sqrt_a; /* 32 bits */ } w1; struct { uint16_t iod; /* 10 bits */ int32_t omega0; /* 32 bits */ int32_t i0; /* 32 bits */ int32_t omega; /* 32 bits */ int16_t idot; /* 14 bits */ } w2; struct { uint16_t iod; /* 10 bits */ int32_t omegadot; /* 24 bits */ int16_t delta_n; /* 16 bits */ int16_t cuc; /* 16 bits */ int16_t cus; /* 16 bits */ int16_t crc; /* 16 bits */ int16_t crs; /* 16 bits */ uint8_t sisa; /* 8 bits */ } w3; struct { uint16_t iod; /* 10 bits */ uint8_t svid; /* 6 bits */ int16_t cic; /* 16 bits */ int16_t cis; /* 16 bits */ uint16_t t0c; /* 14 bits */ uint32_t af0; /* 31 bits */ uint32_t af1; /* 21 bits */ uint8_t af2; /* 6 bits */ } w4; struct { uint16_t ai0; /* 11 bits */ uint16_t ai1; /* 11 bits */ uint16_t ai2; /* 14 bits */ bool reg1; bool reg2; bool reg3; bool reg4; bool reg5; uint16_t bgda; /* 10 bits */ uint16_t bgdb; /* 10 bits */ uint8_t e5bhs; /* 2 bits */ uint8_t e1bhs; /* 2 bits */ bool e5bdvs; bool e1bdvs; uint16_t wn; /* 12 bits */ uint32_t tow; /* 20 bits */ } w5; struct { uint32_t a0; /* 32 bits */ uint32_t a1; /* 24 bits */ uint8_t delta_tls; /* 8 bits */ uint8_t tot; /* 8 bits */ uint8_t wn0t; /* 8 bits */ uint8_t wnlsf; /* 8 bits */ uint8_t dn; /* 3 bits */ uint8_t delta_tlsf; /* 8 bits */ uint32_t tow; /* 20 bits */ } w6; struct { uint8_t iod; /* 4 bits */ uint8_t wn; /* 2 bits */ uint16_t t0a; /* 10 bits */ uint8_t svid1; /* 6 bits */ int16_t sv1_delta_sqrt_a; /* 13 bits */ uint16_t sv1_e; /* 11 bits */ int16_t sv1_omega; /* 16 bits */ int16_t sv1_delta; /* 11 bits */ int16_t sv1_omega0; /* 16 bits */ int16_t sv1_omegadot; /* 11 bits */ int16_t sv1_m0; /* 16 bits */ } w7; struct { uint8_t iod; /* 4 bits */ int16_t sv1_af0; /* 16 bits */ int16_t sv1_af1; /* 13 bits */ uint8_t sv1_e5bhs; /* 2 bits */ uint8_t sv1_e1bhs; /* 2 bits */ uint8_t svid2; /* 6 bits */ int16_t sv2_delta_sqrt_a; /* 13 bits */ uint16_t sv2_e; /* 11 bits */ int16_t sv2_omega; /* 16 bits */ int16_t sv2_delta; /* 11 bits */ int16_t sv2_omega0; /* 16 bits */ int16_t sv2_omegadot; /* 11 bits */ } w8; struct { uint8_t iod; /* 4 bits */ uint8_t wn; /* 2 bits */ uint16_t t0a; /* 10 bits */ int16_t sv2_m0; /* 16 bits */ int16_t sv2_af0; /* 16 bits */ int16_t sv2_af1; /* 13 bits */ uint8_t sv2_e5bhs; /* 2 bits */ uint8_t sv2_e1bhs; /* 2 bits */ uint8_t svid3; /* 6 bits */ int16_t sv3_delta_sqrt_a; /* 13 bits */ uint16_t sv3_e; /* 11 bits */ int16_t sv3_omega; /* 16 bits */ int16_t sv3_delta; /* 11 bits */ } w9; struct { uint8_t iod; /* 4 bits */ int16_t sv3_omega0; /* 16 bits */ int16_t sv3_omegadot; /* 11 bits */ int16_t sv3_m0; /* 16 bits */ int16_t sv3_af0; /* 16 bits */ int16_t sv3_af1; /* 13 bits */ uint8_t sv3_e5bhs; /* 2 */ uint8_t sv3_e1bhs; /* 2 */ uint16_t a0g; /* 16 bits */ uint16_t a1g; /* 12 bits */ uint8_t t0g; /* 8 bits */ uint8_t wn; /* 6 bits */ } w10; struct { uint16_t wn; /* 12 bits */ uint32_t tow; /* 20 bits */ } w0; } nominal; struct { /* TODO */ } alert; }; }; struct galileo_ephemeris { unsigned int sv; uint16_t iod; bool valid:1; /* All in radians, except as noted */ double m0; double delta_n; /* rad/s */ double e; double sqrt_a; /* sqrt(m) */ double omega0; double i0; double omega; double omegadot; /* rad/s */ double idot; /* rad/s */ double cuc; double cus; double crc; /* m */ double crs; /* m */ double cic; double cis; struct { uint32_t raw; /* s */ uint32_t gst; } t0; }; struct galileo_state; struct galileo_state_time { uint32_t gst; /* calculated from wn & tow */ uint16_t wn; uint32_t tow; bool valid:1; }; struct galileo_state_ops { /* * We got an updated ephemeris from a satellite. If @prev is NULL, * this is the first update for this satellite. */ void (*eph_update)(struct galileo_state *state, const struct galileo_ephemeris *prev, const struct galileo_ephemeris *new); void (*time)(struct galileo_state *state, const unsigned int tx_sv, const struct galileo_state_time *now, const struct galileo_state_time *prev_sv_time); }; struct galileo_state { const struct galileo_state_ops *ops; /* global system time */ struct galileo_state_time time; /* * Note: SV numbers are currently 1..GALILEO_MAX_SV_ID. To make it * simpler, we use them as-is to index into the various structures. * This means, that we need to make all of them have +1 entries, and * the first entry is wasted. */ /* each SV's data */ struct { struct galileo_ephemeris eph; struct galileo_state_time last_time; bool valid_eph:1; } sv[GALILEO_MAX_SV_ID + 1]; /* partially assembled data */ struct { struct { /* The ephemeris is split across 4 pages */ struct galileo_ephemeris eph; uint32_t gst[4]; /* global time when recv'd */ uint16_t iod[4]; } nav; } wip[GALILEO_MAX_SV_ID + 1]; }; extern void galileo_print_eph(const struct galileo_ephemeris *eph); extern void galileo_eph_ecef(const struct galileo_ephemeris *eph, const uint32_t gst, struct ecef *ecef); extern bool galileo_parse_inav_page(struct galileo_inav_page *pg, const uint32_t *words, size_t nwords); extern void galileo_state_init(struct galileo_state *state, const struct galileo_state_ops *ops); extern bool galileo_state_apply_page(struct galileo_state *state, const unsigned int sv, const struct galileo_inav_page *pg); #endif