Compare commits

..
47 changed files with 441 additions and 10713 deletions

View file

@ -6,7 +6,7 @@ jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v2
with: with:
submodules: "recursive" submodules: "recursive"
- name: deps - name: deps

View file

@ -9,15 +9,15 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v6 uses: actions/checkout@v2
- name: Checkout submodules - name: Checkout submodules
run: git submodule update --init --recursive run: git submodule update --init --recursive
- name: Set up docker qemu
id: qemu
uses: docker/setup-qemu-action@v4
- name: Set up docker buildx - name: Set up docker buildx
id: buildx id: buildx
uses: docker/setup-buildx-action@v4 uses: crazy-max/ghaction-docker-buildx@v3
with:
buildx-version: latest
qemu-version: latest
- name: Login to docker registry - name: Login to docker registry
run: | run: |
docker login --username ${{ secrets.DOCKER_USERNAME }} --password ${{ secrets.DOCKER_TOKEN }} docker login --username ${{ secrets.DOCKER_USERNAME }} --password ${{ secrets.DOCKER_TOKEN }}

View file

@ -3,18 +3,18 @@
# #
FROM debian:10-slim AS builder FROM debian:10-slim AS builder
ENV DEBIAN_FRONTEND=noninteractive ENV DEBIAN_FRONTEND noninteractive
ENV LC_ALL=C.UTF-8 ENV LC_ALL C.UTF-8
# This allows you to use a local Debian mirror # This allows you to use a local Debian mirror
ARG APT_URL=http://archive.debian.org/debian ARG APT_URL=http://deb.debian.org/debian/
ARG MAKE_FLAGS=-j2 ARG MAKE_FLAGS=-j2
RUN sed -i "s%http://deb.debian.org/debian%${APT_URL}%" /etc/apt/sources.list RUN sed -i "s%http://deb.debian.org/debian/%${APT_URL}%" /etc/apt/sources.list \
RUN apt-get update && apt-get -y upgrade \ && apt-get update && apt-get -y upgrade \
&& apt-get install -y protobuf-compiler libh2o-dev libcurl4-openssl-dev \ && apt-get install -y protobuf-compiler libh2o-dev libcurl4-openssl-dev \
libssl-dev libprotobuf-dev libh2o-evloop-dev libwslay-dev \ libssl-dev libprotobuf-dev libh2o-evloop-dev libwslay-dev \
libeigen3-dev libzstd-dev libfmt-dev libncurses-dev libfmt-dev \ libeigen3-dev libzstd-dev libfmt-dev libncurses-dev \
make gcc g++ git build-essential curl autoconf automake help2man make gcc g++ git build-essential curl autoconf automake help2man
# Build # Build
@ -27,9 +27,6 @@ RUN cd /galmon-src/ \
# Second stage - contains just the binaries # Second stage - contains just the binaries
# #
FROM debian:10-slim FROM debian:10-slim
COPY --from=builder /etc/apt/sources.list /etc/apt/sources.list
RUN apt-get update && apt-get -y upgrade \ RUN apt-get update && apt-get -y upgrade \
&& apt-get install -y libcurl4 libssl1.1 libprotobuf17 libh2o-evloop0.13 \ && apt-get install -y libcurl4 libssl1.1 libprotobuf17 libh2o-evloop0.13 \
libncurses6 \ libncurses6 \
@ -37,5 +34,5 @@ RUN apt-get update && apt-get -y upgrade \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
COPY --from=builder /galmon/ /galmon/ COPY --from=builder /galmon/ /galmon/
ENV PATH=/galmon/bin:${PATH} ENV PATH=/galmon/bin:${PATH}
ENV LC_ALL=C.UTF-8 ENV LC_ALL C.UTF-8
WORKDIR /galmon/bin WORKDIR /galmon/bin

View file

@ -39,11 +39,12 @@ navmon.pb.cc: navmon.proto
protoc --cpp_out=./ navmon.proto protoc --cpp_out=./ navmon.proto
H2OPP=ext/powerblog/h2o-pp.o
SIMPLESOCKETS=ext/powerblog/ext/simplesocket/swrappers.o ext/powerblog/ext/simplesocket/sclasses.o ext/powerblog/ext/simplesocket/comboaddress.o SIMPLESOCKETS=ext/powerblog/ext/simplesocket/swrappers.o ext/powerblog/ext/simplesocket/sclasses.o ext/powerblog/ext/simplesocket/comboaddress.o
clean: clean:
rm -f *~ *.o *.d ext/*/*.o ext/*/*.d $(PROGRAMS) navmon.pb.h navmon.pb.cc $(patsubst %.cc,%.o,$(wildcard ext/sgp4/libsgp4/*.cc)) $(SIMPLESOCKETS) rm -f *~ *.o *.d ext/*/*.o ext/*/*.d $(PROGRAMS) navmon.pb.h navmon.pb.cc $(patsubst %.cc,%.o,$(wildcard ext/sgp4/libsgp4/*.cc)) $(H2OPP) $(SIMPLESOCKETS)
rm -f ext/sgp4/libsgp4/*.d ext/powerblog/ext/simplesocket/*.d rm -f ext/sgp4/libsgp4/*.d ext/powerblog/ext/simplesocket/*.d
help2man: help2man:
@ -62,11 +63,21 @@ install: $(PROGRAMS) help2man
mkdir -p $(DESTDIR)$(prefix)$(htdocs)/galmon mkdir -p $(DESTDIR)$(prefix)$(htdocs)/galmon
cp -a html $(DESTDIR)$(prefix)$(htdocs)/galmon/ cp -a html $(DESTDIR)$(prefix)$(htdocs)/galmon/
download-debian-package:
apt-key adv --fetch-keys https://ota.bike/public-package-signing-keys/86E7F51C04FBAAB0.asc
echo "deb https://ota.bike/debian/ buster main" > /etc/apt/sources.list.d/galmon.list
apt-get update && apt-get install -y galmon
download-raspbian-package:
apt-key adv --fetch-keys https://ota.bike/public-package-signing-keys/86E7F51C04FBAAB0.asc
echo "deb https://ota.bike/raspbian/ buster main" > /etc/apt/sources.list.d/galmon.list
apt-get update && apt-get install -y galmon
decrypt: decrypt.o bits.o decrypt: decrypt.o bits.o
$(CXX) -std=gnu++17 $^ -o $@ -lfmt $(CXX) -std=gnu++17 $^ -o $@ -lfmt
navparse: navparse.o $(SIMPLESOCKETS) minicurl.o ubx.o bits.o navmon.pb.o gps.o ephemeris.o beidou.o glonass.o $(patsubst %.cc,%.o,$(wildcard ext/sgp4/libsgp4/*.cc)) tle.o navmon.o coverage.o osen.o trkmeas.o influxpush.o ${EXTRADEP} githash.o sbas.o rtcm.o galileo.o navparse: navparse.o $(H2OPP) $(SIMPLESOCKETS) minicurl.o ubx.o bits.o navmon.pb.o gps.o ephemeris.o beidou.o glonass.o $(patsubst %.cc,%.o,$(wildcard ext/sgp4/libsgp4/*.cc)) tle.o navmon.o coverage.o osen.o trkmeas.o influxpush.o ${EXTRADEP} githash.o sbas.o rtcm.o galileo.o
$(CXX) -std=gnu++17 $^ -o $@ -pthread -L/usr/local/lib -L/usr/local/opt/openssl/lib/ -lz -lcurl -lprotobuf -lfmt $(CXX) -std=gnu++17 $^ -o $@ -pthread -L/usr/local/lib -L/usr/local/opt/openssl/lib/ -lh2o-evloop -lssl -lcrypto -lz -lcurl -lprotobuf $(WSLAY) -lfmt
reporter: reporter.o $(SIMPLESOCKETS) minicurl.o ubx.o bits.o navmon.pb.o gps.o ephemeris.o beidou.o glonass.o $(patsubst %.cc,%.o,$(wildcard ext/sgp4/libsgp4/*.cc)) tle.o navmon.o coverage.o osen.o githash.o influxpush.o reporter: reporter.o $(SIMPLESOCKETS) minicurl.o ubx.o bits.o navmon.pb.o gps.o ephemeris.o beidou.o glonass.o $(patsubst %.cc,%.o,$(wildcard ext/sgp4/libsgp4/*.cc)) tle.o navmon.o coverage.o osen.o githash.o influxpush.o
$(CXX) -std=gnu++17 $^ -o $@ -pthread -L/usr/local/lib -lprotobuf -lcurl -lfmt $(CXX) -std=gnu++17 $^ -o $@ -pthread -L/usr/local/lib -lprotobuf -lcurl -lfmt

View file

@ -82,20 +82,27 @@ receiver-only tools.
To build everything, including the webserver, try: To build everything, including the webserver, try:
``` ```
apt-get install protobuf-compiler libcurl4-openssl-dev libssl-dev libprotobuf-dev \ apt-get install protobuf-compiler libh2o-dev libcurl4-openssl-dev libssl-dev libprotobuf-dev \
libncurses5-dev libeigen3-dev libzstd-dev g++ libfmt-dev libh2o-evloop-dev libwslay-dev libncurses5-dev libeigen3-dev libzstd-dev g++ libfmt-dev
git clone https://github.com/berthubert/galmon.git --recursive git clone https://github.com/berthubert/galmon.git --recursive
cd galmon cd galmon
make make
``` ```
If this doesn't succeed with an error about h2o, make sure you have this
library installed. If you get an error about 'wslay', do the following, and run make again:
```
echo WSLAY=-lwslay > Makefile.local
```
Building on OSX Building on OSX
--------------- ---------------
With thanks to a contributor from Prague. First make sure you've installed With thanks to a contributor from Prague. First make sure you've installed
brew, which you can get [here](https://brew.sh/). Then do: brew, which you can get [here](https://brew.sh/). Then do:
``` ```
brew install protobuf lzlib zstd eigen brew install protobuf lzlib zstd h2o eigen
``` ```
And then: And then:
@ -321,7 +328,7 @@ Documents
* [GLONASS CDMA](http://russianspacesystems.ru/wp-content/uploads/2016/08/ICD-GLONASS-CDMA-General.-Edition-1.0-2016.pdf) * [GLONASS CDMA](http://russianspacesystems.ru/wp-content/uploads/2016/08/ICD-GLONASS-CDMA-General.-Edition-1.0-2016.pdf)
not actually relevant for the CDMA aspects, but has appendices on more not actually relevant for the CDMA aspects, but has appendices on more
precise orbit determinations. precise orbit determinations.
* [GPS](https://www.navcen.uscg.gov/sites/default/files/pdf/gps/IS-GPS-200N.pdf) * [GPS](https://www.gps.gov/technical/icwg/IS-GPS-200K.pdf)
* [U-blox 8 interface specification](https://www.u-blox.com/sites/default/files/products/documents/u-blox8-M8_ReceiverDescrProtSpec_%28UBX-13003221%29_Public.pdf) * [U-blox 8 interface specification](https://www.u-blox.com/sites/default/files/products/documents/u-blox8-M8_ReceiverDescrProtSpec_%28UBX-13003221%29_Public.pdf)
* [U-blox 9 interface specification](https://www.u-blox.com/sites/default/files/u-blox_ZED-F9P_InterfaceDescription_%28UBX-18010854%29.pdf) * [U-blox 9 interface specification](https://www.u-blox.com/sites/default/files/u-blox_ZED-F9P_InterfaceDescription_%28UBX-18010854%29.pdf)
* [U-blox 10 interface specification](https://content.u-blox.com/sites/default/files/documents/u-blox-F10-SPG-6.00_InterfaceDescription_UBX-23002975.pdf) * [U-blox 10 interface specification](https://content.u-blox.com/sites/default/files/documents/u-blox-F10-SPG-6.00_InterfaceDescription_UBX-23002975.pdf)

View file

@ -1,8 +1,6 @@
#include "beidou.hh" #include "beidou.hh"
#include "bits.hh" #include "bits.hh"
#include <iostream> #include <iostream>
#include <vector>
#include "navmon.hh"
using namespace std; using namespace std;
@ -31,7 +29,7 @@ static int checkbds(int bits)
return 1; return 1;
} }
std::vector<uint8_t> getCondensedBeidouMessage(const std::vector<uint8_t>& payload) std::basic_string<uint8_t> getCondensedBeidouMessage(std::basic_string_view<uint8_t> payload)
{ {
// payload consists of 32 bit words where we have to ignore the first 2 bits of every word // payload consists of 32 bit words where we have to ignore the first 2 bits of every word
@ -58,7 +56,7 @@ std::vector<uint8_t> getCondensedBeidouMessage(const std::vector<uint8_t>& paylo
setbitu(buffer, 26+22*(w-1), 22, getbitu(&payload[0], 2 + w*32, 22)); setbitu(buffer, 26+22*(w-1), 22, getbitu(&payload[0], 2 + w*32, 22));
} }
return makeVec(buffer, 28); return std::basic_string<uint8_t>(buffer, 28);
} }

View file

@ -4,10 +4,9 @@
#include "bits.hh" #include "bits.hh"
#include <math.h> #include <math.h>
#include <stdexcept> #include <stdexcept>
#include <vector>
#include "ephemeris.hh" #include "ephemeris.hh"
std::vector<uint8_t> getCondensedBeidouMessage(const std::vector<uint8_t>& payload); std::basic_string<uint8_t> getCondensedBeidouMessage(std::basic_string_view<uint8_t> payload);
int beidouBitconv(int their); int beidouBitconv(int their);
/* Geostationary, so D2, so not to be parsed by this parser: /* Geostationary, so D2, so not to be parsed by this parser:
@ -22,7 +21,7 @@ struct BeidouMessage : GPSLikeEphemeris
{ {
uint8_t strtype; uint8_t strtype;
std::vector<uint8_t> g_cond; std::basic_string_view<uint8_t> g_cond;
int bbitu(int bit, int len) int bbitu(int bit, int len)
{ {
return getbitu(&g_cond[0], beidouBitconv(bit), len); return getbitu(&g_cond[0], beidouBitconv(bit), len);
@ -35,7 +34,7 @@ struct BeidouMessage : GPSLikeEphemeris
int fraid{-1}, sow{-1}; // part of every message (thanks!) int fraid{-1}, sow{-1}; // part of every message (thanks!)
int parse(const std::vector<uint8_t>& cond, uint8_t* pageno) int parse(std::basic_string_view<uint8_t> cond, uint8_t* pageno)
{ {
g_cond = cond; g_cond = cond;
if(pageno) if(pageno)
@ -90,7 +89,7 @@ struct BeidouMessage : GPSLikeEphemeris
return {factor * cur, factor * trend}; return {factor * cur, factor * trend};
} }
void parse1(const std::vector<uint8_t>& cond) void parse1(std::basic_string_view<uint8_t> cond)
{ {
sath1 = bbitu(43,1); sath1 = bbitu(43,1);
aodc = bbitu(31+13, 5); aodc = bbitu(31+13, 5);
@ -125,7 +124,7 @@ struct BeidouMessage : GPSLikeEphemeris
return -1; return -1;
} }
void parse2(const std::vector<uint8_t>& cond) void parse2(std::basic_string_view<uint8_t> cond)
{ {
deltan = bbits(43, 16); deltan = bbits(43, 16);
cuc = bbits(67, 18); cuc = bbits(67, 18);
@ -152,7 +151,7 @@ struct BeidouMessage : GPSLikeEphemeris
double getOmega0() const { return ldexp(Omega0 * M_PI, -31); } // radians double getOmega0() const { return ldexp(Omega0 * M_PI, -31); } // radians
double getIdot() const { return ldexp(idot * M_PI, -43); } // radians/s double getIdot() const { return ldexp(idot * M_PI, -43); } // radians/s
double getOmega() const { return ldexp(omega * M_PI, -31); } // radians double getOmega() const { return ldexp(omega * M_PI, -31); } // radians
void parse3(const std::vector<uint8_t>& cond) void parse3(std::basic_string_view<uint8_t> cond)
{ {
t0eLSB = bbitu(43, 15); t0eLSB = bbitu(43, 15);
i0 = bbits(66, 32); i0 = bbits(66, 32);
@ -208,7 +207,7 @@ struct BeidouMessage : GPSLikeEphemeris
} alma; } alma;
// 4 is all almanac // 4 is all almanac
int parse4(const std::vector<uint8_t>& cond) int parse4(std::basic_string_view<uint8_t> cond)
{ {
alma.sqrtA = bbitu(51, 24); alma.sqrtA = bbitu(51, 24);
alma.a1 = bbits(91, 11); alma.a1 = bbits(91, 11);
@ -255,7 +254,7 @@ struct BeidouMessage : GPSLikeEphemeris
} }
int parse5(const std::vector<uint8_t>& cond) int parse5(std::basic_string_view<uint8_t> cond)
{ {
alma.pageno = bbitu(44, 7); alma.pageno = bbitu(44, 7);
if(alma.pageno == 9) { if(alma.pageno == 9) {

View file

@ -6,7 +6,7 @@
#include "galileo.hh" #include "galileo.hh"
using namespace std; using namespace std;
void FixHunter::reportInav(const vector<uint8_t>& inav, int32_t gst) void FixHunter::reportInav(const basic_string<uint8_t>& inav, int32_t gst)
{ {
int wtype = getbitu(&inav[0], 0, 6); int wtype = getbitu(&inav[0], 0, 6);
@ -181,7 +181,7 @@ void FixHunter::tryFix(int32_t gst)
struct GalileoMessage FixHunter::fillGMFromRS(const std::string& out) struct GalileoMessage FixHunter::fillGMFromRS(const std::string& out)
{ {
// we need to reconstruct words 1, 2, 3 and 4 and feed them to the parser // we need to reconstruct words 1, 2, 3 and 4 and feed them to the parser
vector<uint8_t> inav[5]; basic_string<uint8_t> inav[5];
string inavraw[5]; string inavraw[5];
inavraw[4] = out.substr(0, 14); inavraw[4] = out.substr(0, 14);
inavraw[3] = out.substr(14, 14); inavraw[3] = out.substr(14, 14);
@ -198,7 +198,7 @@ struct GalileoMessage FixHunter::fillGMFromRS(const std::string& out)
for(int n=0; n < 14; ++n) for(int n=0; n < 14; ++n)
setbitu(tmp, 16 + n*8, 8, getbitu((unsigned char*) inavraw[1].c_str(), 16 + n*8, 8)); setbitu(tmp, 16 + n*8, 8, getbitu((unsigned char*) inavraw[1].c_str(), 16 + n*8, 8));
inav[1]= makeVec(tmp, 16); inav[1].assign(tmp, 16);
struct GalileoMessage gm={}; struct GalileoMessage gm={};
gm.parse(inav[1]); gm.parse(inav[1]);
@ -210,7 +210,7 @@ struct GalileoMessage FixHunter::fillGMFromRS(const std::string& out)
setbitu(tmp, 6, 10, getbitu((unsigned char*) inav[1].c_str(), 6, 10)); // fake in IOD from inav1 setbitu(tmp, 6, 10, getbitu((unsigned char*) inav[1].c_str(), 6, 10)); // fake in IOD from inav1
for(int n=0; n < 14; ++n) for(int n=0; n < 14; ++n)
setbitu(tmp, 16 + n*8, 8, getbitu((unsigned char*) inavraw[i].c_str(), n*8, 8)); setbitu(tmp, 16 + n*8, 8, getbitu((unsigned char*) inavraw[i].c_str(), n*8, 8));
inav[i]= makeVec(tmp, 16); inav[i].assign(tmp, 16);
gm.parse(inav[i]); gm.parse(inav[i]);
cout<<"wtype: "<<(int)gm.wtype<<", iod "<<gm.iodnav<<endl; cout<<"wtype: "<<(int)gm.wtype<<", iod "<<gm.iodnav<<endl;
} }

View file

@ -5,11 +5,11 @@
class FixHunter class FixHunter
{ {
public: public:
void reportInav(const std::vector<uint8_t>& inav, int32_t gst); void reportInav(const std::basic_string<uint8_t>& inav, int32_t gst);
private: private:
void tryFix(int32_t gst); void tryFix(int32_t gst);
struct GalileoMessage fillGMFromRS(const std::string& out); struct GalileoMessage fillGMFromRS(const std::string& out);
std::vector<uint8_t> inav1, inav2, inav3, inav4, inav16, inav17, inav18, inav19, inav20; std::basic_string<uint8_t> inav1, inav2, inav3, inav4, inav16, inav17, inav18, inav19, inav20;
int d_latestiod; int d_latestiod;
uint32_t d_inav16t0r; uint32_t d_inav16t0r;
}; };

View file

@ -1,7 +1,7 @@
#include "bits.hh" #include "bits.hh"
#include "galileo.hh" #include "galileo.hh"
bool getTOWFromInav(const std::vector<uint8_t>& inav, uint32_t *satTOW, uint16_t *wn) bool getTOWFromInav(std::basic_string_view<uint8_t> inav, uint32_t *satTOW, uint16_t *wn)
{ {
unsigned int wtype = getbitu(&inav[0], 0, 6); unsigned int wtype = getbitu(&inav[0], 0, 6);
if(wtype==0) { if(wtype==0) {
@ -25,7 +25,7 @@ bool getTOWFromInav(const std::vector<uint8_t>& inav, uint32_t *satTOW, uint16_t
return false; return false;
} }
int GalileoMessage::parseFnav(const std::vector<uint8_t>& page) int GalileoMessage::parseFnav(std::basic_string_view<uint8_t> page)
{ {
const uint8_t* ptr = &page[0]; const uint8_t* ptr = &page[0];
int offset=0; int offset=0;

View file

@ -7,13 +7,13 @@
#include "ephemeris.hh" #include "ephemeris.hh"
#include "bits.hh" #include "bits.hh"
bool getTOWFromInav(const std::vector<uint8_t>& inav, uint32_t *satTOW, uint16_t *wn); bool getTOWFromInav(std::basic_string_view<uint8_t> inav, uint32_t *satTOW, uint16_t *wn);
struct GalileoMessage : GPSLikeEphemeris struct GalileoMessage : GPSLikeEphemeris
{ {
uint8_t wtype; uint8_t wtype;
typedef void (GalileoMessage::*func_t)(const std::vector<uint8_t>& page); typedef void (GalileoMessage::*func_t)(std::basic_string_view<uint8_t> page);
std::map<int, func_t> parsers{ std::map<int, func_t> parsers{
{0, &GalileoMessage::parse0}, {0, &GalileoMessage::parse0},
{1, &GalileoMessage::parse1}, {1, &GalileoMessage::parse1},
@ -34,7 +34,7 @@ struct GalileoMessage : GPSLikeEphemeris
}; };
int parse(const std::vector<uint8_t>& page) int parse(std::basic_string_view<uint8_t> page)
{ {
wtype = getbitu(&page[0], 0, 6); wtype = getbitu(&page[0], 0, 6);
if(!parsers.count(wtype)) { if(!parsers.count(wtype)) {
@ -46,7 +46,7 @@ struct GalileoMessage : GPSLikeEphemeris
return wtype; return wtype;
} }
int parseFnav(const std::vector<uint8_t>& page); int parseFnav(std::basic_string_view<uint8_t> page);
uint8_t sparetime{0}; uint8_t sparetime{0};
uint16_t wn{0}; uint16_t wn{0};
@ -58,7 +58,7 @@ struct GalileoMessage : GPSLikeEphemeris
// spare word, only contains a WN and a TOW, but only if the 'time' field is set to 2 // spare word, only contains a WN and a TOW, but only if the 'time' field is set to 2
void parse0(const std::vector<uint8_t>& page) void parse0(std::basic_string_view<uint8_t> page)
{ {
sparetime = getbitu(&page[0], 6, 2); sparetime = getbitu(&page[0], 6, 2);
if(sparetime == 2) { if(sparetime == 2) {
@ -164,7 +164,7 @@ struct GalileoMessage : GPSLikeEphemeris
// an ephemeris word // an ephemeris word
void parse1(const std::vector<uint8_t>& page) void parse1(std::basic_string_view<uint8_t> page)
{ {
iodnav = getbitu(&page[0], 6, 10); iodnav = getbitu(&page[0], 6, 10);
t0e = getbitu(&page[0], 16, 14); t0e = getbitu(&page[0], 16, 14);
@ -174,7 +174,7 @@ struct GalileoMessage : GPSLikeEphemeris
} }
// another ephemeris word // another ephemeris word
void parse2(const std::vector<uint8_t>& page) void parse2(std::basic_string_view<uint8_t> page)
{ {
iodnav = getbitu(&page[0], 6, 10); iodnav = getbitu(&page[0], 6, 10);
omega0 = getbits(&page[0], 16, 32); omega0 = getbits(&page[0], 16, 32);
@ -184,7 +184,7 @@ struct GalileoMessage : GPSLikeEphemeris
} }
// yet another ephemeris word // yet another ephemeris word
void parse3(const std::vector<uint8_t>& page) void parse3(std::basic_string_view<uint8_t> page)
{ {
iodnav = getbitu(&page[0], 6, 10); iodnav = getbitu(&page[0], 6, 10);
omegadot = getbits(&page[0], 16, 24); omegadot = getbits(&page[0], 16, 24);
@ -264,7 +264,7 @@ struct GalileoMessage : GPSLikeEphemeris
// can't get enough of that ephemeris // can't get enough of that ephemeris
void parse4(const std::vector<uint8_t>& page) void parse4(std::basic_string_view<uint8_t> page)
{ {
iodnav = getbitu(&page[0], 6, 10); iodnav = getbitu(&page[0], 6, 10);
cic = getbits(&page[0], 22, 16); cic = getbits(&page[0], 22, 16);
@ -277,7 +277,7 @@ struct GalileoMessage : GPSLikeEphemeris
} }
// ionospheric disturbance, health, group delay, time // ionospheric disturbance, health, group delay, time
void parse5(const std::vector<uint8_t>& page) void parse5(std::basic_string_view<uint8_t> page)
{ {
ai0 = getbitu(&page[0], 6, 11); ai0 = getbitu(&page[0], 6, 11);
ai1 = getbits(&page[0], 17, 11); // ai1 & 2 are signed, 0 not ai1 = getbits(&page[0], 17, 11); // ai1 & 2 are signed, 0 not
@ -300,7 +300,7 @@ struct GalileoMessage : GPSLikeEphemeris
} }
// time stuff // time stuff
void parse6(const std::vector<uint8_t>& page) void parse6(std::basic_string_view<uint8_t> page)
{ {
a0 = getbits(&page[0], 6, 32); a0 = getbits(&page[0], 6, 32);
a1 = getbits(&page[0], 38, 24); a1 = getbits(&page[0], 38, 24);
@ -315,7 +315,7 @@ struct GalileoMessage : GPSLikeEphemeris
} }
// almanac // almanac
void parse7(const std::vector<uint8_t>& page) void parse7(std::basic_string_view<uint8_t> page)
{ {
iodalmanac = getbitu(&page[0], 6, 4); iodalmanac = getbitu(&page[0], 6, 4);
alma1.wnalmanac = wnalmanac = getbitu(&page[0], 10, 2); alma1.wnalmanac = wnalmanac = getbitu(&page[0], 10, 2);
@ -331,7 +331,7 @@ struct GalileoMessage : GPSLikeEphemeris
} }
// almanac // almanac
void parse8(const std::vector<uint8_t>& page) void parse8(std::basic_string_view<uint8_t> page)
{ {
iodalmanac = getbitu(&page[0], 6, 4); iodalmanac = getbitu(&page[0], 6, 4);
alma1.af0 = getbits(&page[0], 10, 16); alma1.af0 = getbits(&page[0], 10, 16);
@ -350,7 +350,7 @@ struct GalileoMessage : GPSLikeEphemeris
} }
// almanac // almanac
void parse9(const std::vector<uint8_t>& page) void parse9(std::basic_string_view<uint8_t> page)
{ {
iodalmanac = getbitu(&page[0], 6, 4); iodalmanac = getbitu(&page[0], 6, 4);
alma2.wnalmanac = wnalmanac = getbitu(&page[0], 10, 2); alma2.wnalmanac = wnalmanac = getbitu(&page[0], 10, 2);
@ -371,7 +371,7 @@ struct GalileoMessage : GPSLikeEphemeris
} }
// almanac + more time stuff (GPS) // almanac + more time stuff (GPS)
void parse10(const std::vector<uint8_t>& page) void parse10(std::basic_string_view<uint8_t> page)
{ {
iodalmanac = getbitu(&page[0], 6, 4); iodalmanac = getbitu(&page[0], 6, 4);
alma3.Omega0 = getbits(&page[0], 10, 16); alma3.Omega0 = getbits(&page[0], 10, 16);
@ -391,7 +391,7 @@ struct GalileoMessage : GPSLikeEphemeris
// reduced clock and ephemeris data (redced) // reduced clock and ephemeris data (redced)
void parse16(const std::vector<uint8_t>& page) void parse16(std::basic_string_view<uint8_t> page)
{ {
deltaAred = getbits(&page[0], 6, 5); deltaAred = getbits(&page[0], 6, 5);
exred = getbits(&page[0], 11, 13); exred = getbits(&page[0], 11, 13);
@ -404,7 +404,7 @@ struct GalileoMessage : GPSLikeEphemeris
} }
// reed-solomon data // reed-solomon data
void parseRS(const std::vector<uint8_t>& page) void parseRS(std::basic_string_view<uint8_t> page)
{ {
// see 5.1.13.2 of the Galileo SIS ICD 2.0 // see 5.1.13.2 of the Galileo SIS ICD 2.0
rs2bitiod = getbitu(&page[0], 6+8, 2); rs2bitiod = getbitu(&page[0], 6+8, 2);

View file

@ -4,12 +4,11 @@
#include "navmon.hh" #include "navmon.hh"
#include "fmt/format.h" #include "fmt/format.h"
#include "fmt/printf.h" #include "fmt/printf.h"
#include "ext/powerblog/h2o-pp.hh"
#include <variant> #include <variant>
#include "CLI/CLI.hpp" #include "CLI/CLI.hpp"
#include "version.hh" #include "version.hh"
#include <nlohmann/json.hpp>
static char program[]="galmonmon"; static char program[]="galmonmon";

View file

@ -3,7 +3,6 @@
#include <string.h> #include <string.h>
#include <chrono> #include <chrono>
#include <iostream> #include <iostream>
#include "navmon.hh"
using std::cout; using std::cout;
using std::endl; using std::endl;
@ -13,7 +12,7 @@ static const double J2 = 1082625.75E-9; // IERS: 1.0826359
static const double oe = 7.2921151467E-5; // rad/s // IERS: 7.292115 static const double oe = 7.2921151467E-5; // rad/s // IERS: 7.292115
// this strips out spare bits + parity, and leaves 10 clean 24 bit words // this strips out spare bits + parity, and leaves 10 clean 24 bit words
std::vector<uint8_t> getGlonassMessage(const std::vector<uint8_t>& payload) std::basic_string<uint8_t> getGlonassMessage(std::basic_string_view<uint8_t> payload)
{ {
uint8_t buffer[4*4]; uint8_t buffer[4*4];
@ -21,7 +20,7 @@ std::vector<uint8_t> getGlonassMessage(const std::vector<uint8_t>& payload)
setbitu(buffer, 32*w, 32, getbitu(&payload[0], w*32, 32)); setbitu(buffer, 32*w, 32, getbitu(&payload[0], w*32, 32));
} }
return makeVec(buffer, 16); return std::basic_string<uint8_t>(buffer, 16);
} }

View file

@ -5,16 +5,14 @@
#include <iostream> #include <iostream>
#include <math.h> #include <math.h>
#include <stdint.h> #include <stdint.h>
#include <vector>
#include "minivec.hh" #include "minivec.hh"
std::vector<uint8_t> getGlonassessage(const std::vector<uint8_t>& payload); std::basic_string<uint8_t> getGlonassessage(std::basic_string_view<uint8_t> payload);
struct GlonassMessage struct GlonassMessage
{ {
uint8_t strtype; uint8_t strtype;
int parse(const std::vector<uint8_t>& gstr) int parse(std::basic_string_view<uint8_t> gstr)
{ {
strtype = getbitu(&gstr[0], 1, 4); strtype = getbitu(&gstr[0], 1, 4);
if(strtype == 1) { if(strtype == 1) {
@ -62,7 +60,7 @@ struct GlonassMessage
double getRadius() { return sqrt(getX()*getX() + getY()*getY() + getZ()*getZ()); } double getRadius() { return sqrt(getX()*getX() + getY()*getY() + getZ()*getZ()); }
void parse1(const std::vector<uint8_t>& gstr) void parse1(std::basic_string_view<uint8_t> gstr)
{ {
hour = getbitu(&gstr[0], 9, 5); hour = getbitu(&gstr[0], 9, 5);
minute = getbitu(&gstr[0], 14, 6); minute = getbitu(&gstr[0], 14, 6);
@ -80,7 +78,7 @@ struct GlonassMessage
An interval is 15 minutes long, plus a spacer of length described by P1. If P1 is zero, there is no spacer. An interval is 15 minutes long, plus a spacer of length described by P1. If P1 is zero, there is no spacer.
*/ */
void parse2(const std::vector<uint8_t>& gstr) void parse2(std::basic_string_view<uint8_t> gstr)
{ {
Bn = getbitu(&gstr[0], 85-80, 3); // Health bit, only look at MSB, ignore the rest. 0 is ok. Bn = getbitu(&gstr[0], 85-80, 3); // Health bit, only look at MSB, ignore the rest. 0 is ok.
Tb = getbitu(&gstr[0], 85-76, 7); Tb = getbitu(&gstr[0], 85-76, 7);
@ -95,7 +93,7 @@ struct GlonassMessage
bool l_n; bool l_n;
bool P, P3; bool P, P3;
uint16_t gamman; uint16_t gamman;
void parse3(const std::vector<uint8_t>& gstr) void parse3(std::basic_string_view<uint8_t> gstr)
{ {
z = getbitsglonass(&gstr[0], 85-35, 27); // 2^-11 z = getbitsglonass(&gstr[0], 85-35, 27); // 2^-11
dz = getbitsglonass(&gstr[0], 85-64, 24); // 2^-20 dz = getbitsglonass(&gstr[0], 85-64, 24); // 2^-20
@ -123,7 +121,7 @@ struct GlonassMessage
return 1000*ldexp(1000000.0*taun, -30); return 1000*ldexp(1000000.0*taun, -30);
} }
void parse4(const std::vector<uint8_t>& gstr) void parse4(std::basic_string_view<uint8_t> gstr)
{ {
NT = getbitu(&gstr[0], 85-26, 11); NT = getbitu(&gstr[0], 85-26, 11);
FT = getbitu(&gstr[0], 85-33, 4); FT = getbitu(&gstr[0], 85-33, 4);
@ -159,7 +157,7 @@ struct GlonassMessage
int32_t taugps; int32_t taugps;
int32_t tauc; int32_t tauc;
void parse5(const std::vector<uint8_t>& gstr) void parse5(std::basic_string_view<uint8_t> gstr)
{ {
n4=getbitu(&gstr[0], 85-36, 5); n4=getbitu(&gstr[0], 85-36, 5);
taugps = getbitsglonass(&gstr[0], 85-31, 22); taugps = getbitsglonass(&gstr[0], 85-31, 22);
@ -177,7 +175,7 @@ struct GlonassMessage
return ldexp(tlambdana, -5); return ldexp(tlambdana, -5);
} }
void parse7_9_11_13_15(const std::vector<uint8_t>& gstr) void parse7_9_11_13_15(std::basic_string_view<uint8_t> gstr)
{ {
l_n = getbitu(&gstr[0], 85 - 9, 1); l_n = getbitu(&gstr[0], 85 - 9, 1);
omegana = getbitsglonass(&gstr[0], 85-80, 16); omegana = getbitsglonass(&gstr[0], 85-80, 16);
@ -209,7 +207,7 @@ struct GlonassMessage
return M_PI*63.0/180 + ldexp(M_PI* deltaina, -20); return M_PI*63.0/180 + ldexp(M_PI* deltaina, -20);
} }
void parse6_8_10_12_14(const std::vector<uint8_t>& gstr) void parse6_8_10_12_14(std::basic_string_view<uint8_t> gstr)
{ {
CnA = getbitu(&gstr[0], 85-80, 1); CnA = getbitu(&gstr[0], 85-80, 1);
nA = getbitu(&gstr[0], 85-77, 5); nA = getbitu(&gstr[0], 85-77, 5);

9
gps.cc
View file

@ -1,7 +1,7 @@
#include "gps.hh" #include "gps.hh"
// this strips out spare bits + parity, and leaves 10 clean 24 bit words // this strips out spare bits + parity, and leaves 10 clean 24 bit words
std::vector<uint8_t> getCondensedGPSMessage(const std::vector<uint8_t>& payload) std::basic_string<uint8_t> getCondensedGPSMessage(std::basic_string_view<uint8_t> payload)
{ {
uint8_t buffer[10*24/8]; uint8_t buffer[10*24/8];
@ -10,11 +10,12 @@ std::vector<uint8_t> getCondensedGPSMessage(const std::vector<uint8_t>& payload)
setbitu(buffer, 24*w, 24, getbitu(&payload[0], 2 + w*32, 24)); setbitu(buffer, 24*w, 24, getbitu(&payload[0], 2 + w*32, 24));
} }
return std::vector<uint8_t>(buffer, buffer+30); return std::basic_string<uint8_t>(buffer, 30);
} }
// expects input as 24 bit read to to use messages, returns frame number // expects input as 24 bit read to to use messages, returns frame number
int GPSState::parseGPSMessage(const std::vector<uint8_t>& cond, uint8_t* pageptr) int GPSState::parseGPSMessage(std::basic_string_view<uint8_t> cond, uint8_t* pageptr)
{ {
using namespace std; using namespace std;
int frame = getbitu(&cond[0], 24+19, 3); int frame = getbitu(&cond[0], 24+19, 3);
@ -38,8 +39,6 @@ int GPSState::parseGPSMessage(const std::vector<uint8_t>& cond, uint8_t* pageptr
wn = 2048 + getbitu(&cond[0], 2*24, 10); wn = 2048 + getbitu(&cond[0], 2*24, 10);
ura = getbitu(&cond[0], 2*24+12, 4); ura = getbitu(&cond[0], 2*24+12, 4);
gpshealth = getbitu(&cond[0], 2*24+16, 6); gpshealth = getbitu(&cond[0], 2*24+16, 6);
iodc = getbitu(&cond[0], 2*24 +22, 2) * 256;
iodc += getbitu(&cond[0], 7*24, 8);
// cerr<<"GPS Week Number: "<< wn <<", URA: "<< (int)ura<<", health: "<< // cerr<<"GPS Week Number: "<< wn <<", URA: "<< (int)ura<<", health: "<<
// (int)gpshealth <<endl; // (int)gpshealth <<endl;

7
gps.hh
View file

@ -6,9 +6,8 @@
#include <iostream> #include <iostream>
#include <math.h> #include <math.h>
#include "ephemeris.hh" #include "ephemeris.hh"
#include <vector>
std::vector<uint8_t> getCondensedGPSMessage(const std::vector<uint8_t>& payload); std::basic_string<uint8_t> getCondensedGPSMessage(std::basic_string_view<uint8_t> payload);
struct GPSAlmanac : GPSLikeEphemeris struct GPSAlmanac : GPSLikeEphemeris
@ -134,17 +133,15 @@ struct GPSState : GPSLikeEphemeris
uint16_t wnLSF{0}; uint16_t wnLSF{0};
uint8_t dn; // leap second day number uint8_t dn; // leap second day number
// 1 2^-31 2^-43 2^-55 16 second // 1 2^-31 2^-43 2^-55 16 second
int iodc;
int ura; int ura;
int gpsiod{-1}; int gpsiod{-1};
int getIOD() const int getIOD() const
{ {
return gpsiod; return gpsiod;
} }
int parseGPSMessage(const std::vector<uint8_t>& cond, uint8_t* pageptr=0); int parseGPSMessage(std::basic_string_view<uint8_t> cond, uint8_t* pageptr=0);
}; };
template<typename T> template<typename T>

View file

@ -1,7 +1,6 @@
#pragma once #pragma once
#include <bitset> #include <bitset>
#include <string> #include <string>
#include <vector>
#include <map> #include <map>
#include "bits.hh" #include "bits.hh"
#include <iostream> #include <iostream>
@ -186,7 +185,7 @@ std::pair<double, double> getGPSCNavUTCOffset(int tow, int wn, const T& eph)
template<typename T> template<typename T>
int parseGPSCNavMessage(const std::vector<uint8_t>& msg, T& out) int parseGPSCNavMessage(std::basic_string_view<uint8_t> msg, T& out)
{ {
using namespace std; using namespace std;
int type = getbitu(&msg[0], 14, 6); int type = getbitu(&msg[0], 14, 6);

View file

@ -1,5 +1,7 @@
var repeat; var repeat;
moment.relativeTimeThreshold('m', 120);
function maketable(str, arr) function maketable(str, arr)
{ {
var table=d3.select(str); var table=d3.select(str);
@ -102,7 +104,8 @@ function maketable(str, arr)
if(row[column] != null) { if(row[column] != null) {
ret.value = row[column].toFixed(0) + " minutes ago"; var b = moment.duration(-row[column], 'm');
ret.value = b.humanize(true);
} }
else else
ret.value=""; ret.value="";
@ -150,11 +153,8 @@ function maketable(str, arr)
} }
else if(column == "last-seen-s") { else if(column == "last-seen-s") {
var seconds = row[column].toFixed(0); var b = moment.duration(row[column], 's');
if(seconds < 30) ret.value = b.humanize();
ret.value = "a few seconds ago";
else
ret.value = (seconds/60) + " minutes ago";
} }
else if(column == "best-tle") { else if(column == "best-tle") {
ret.value = "<small>"+row[column]+"</small>"; ret.value = "<small>"+row[column]+"</small>";
@ -351,14 +351,9 @@ function update()
str += ", "+d["leap-seconds"]+"</b> leap seconds (GPS/Galileo)"; str += ", "+d["leap-seconds"]+"</b> leap seconds (GPS/Galileo)";
d3.select('#facts').html(str); d3.select('#facts').html(str);
var ageSeconds = (Date.now() - 1000*d["last-seen"])/1000; lastseen = moment(1000*d["last-seen"]);
var ageString; d3.select("#freshness").html(lastseen.fromNow());
if(ageSeconds < 60)
ageString = "a few seconds ago";
else
ageString = (ageSeconds/60).toFixed(0) +" minutes ago";
d3.select("#freshness").html(ageString);
str = d["total-live-receivers"]+" receivers active, tracking "; str = d["total-live-receivers"]+" receivers active, tracking ";
str += d["total-live-svs"] + " satellites via " ; str += d["total-live-svs"] + " satellites via " ;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 399 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 399 B

Some files were not shown because too many files have changed in this diff Show more