Compare commits

..
Author SHA1 Message Date
bert hubert
f9f2f4f262 geo updates from martin 2019-09-30 16:11:23 +02:00
170 changed files with 14378 additions and 98718 deletions

View file

@ -4,15 +4,15 @@ on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
submodules: "recursive"
- uses: actions/checkout@v1
- name: deps
run: |
sudo apt-get update
sudo apt-get install protobuf-compiler libh2o-dev libcurl4-openssl-dev libssl-dev libprotobuf-dev libh2o-evloop-dev libwslay-dev libncurses5-dev libeigen3-dev libzstd-dev libfec-dev libfmt-dev
run: sudo apt-get install protobuf-compiler libh2o-dev libcurl4-openssl-dev libssl-dev libprotobuf-dev libh2o-evloop-dev libwslay-dev
- name: submodules
run: git submodule update --init --recursive
- name: config
run: echo WSLAY=-lwslay > Makefile.local
- name: make

View file

@ -1,32 +0,0 @@
name: Build and publish Docker image
on:
push:
branches: master
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Checkout submodules
run: git submodule update --init --recursive
- name: Set up docker qemu
id: qemu
uses: docker/setup-qemu-action@v4
- name: Set up docker buildx
id: buildx
uses: docker/setup-buildx-action@v4
- name: Login to docker registry
run: |
docker login --username ${{ secrets.DOCKER_USERNAME }} --password ${{ secrets.DOCKER_TOKEN }}
- name: Run buildx
run: |
docker buildx build \
--tag berthubert/galmon \
--platform linux/386,linux/amd64,linux/arm/v7,linux/arm64/v8 \
--output "type=registry" \
--build-arg MAKE_FLAGS=-j1 \
--file Dockerfile \
.

19
.gitignore vendored
View file

@ -1,24 +1,5 @@
# - created by protoc
navmon.pb.cc
navmon.pb.h
# - created by Makefile
navcat
navdisplay
navdump
navnexus
navrecv
testrunner
tlecatch
ubxtool
# - created by update-tles
active.txt
beidou.txt
galileo.txt
glo-ops.txt
gps-ops.txt
# - git version internals
githash.h
#
*.csv
# Prerequisites
*.d

1
.gitmodules vendored
View file

@ -4,4 +4,3 @@
[submodule "ext/sgp4"]
path = ext/sgp4
url = https://github.com/dnwrnr/sgp4.git
ignore = untracked

View file

@ -1,19 +0,0 @@
Raspberry Pi 3B+
---------------
Building more than ubxtool, navdump, and navparse will require quite a bit of available RAM.
In the Raspbian image, the default swap file size for _/var/swap_ is only 100MB.
More swap space will be needed if you want the compiling to finish without it seeming
to take a geologic age.
The swap file is configured in _/etc/dphys-swapfile_ and managed using the __/sbin/dphys-swapfile__ utility.
Assuming the output of _df -h_ and _free_ indicate you have sufficient free file space and
the swap file is indeed 100MB (respectively), and you do not have Chromium running (it eats
RAM), you edit the config file (suggest changing 100 to 960) and then (as root):
```
/sbin/dphys-swapfile swapoff
echo Be Patient. This could take a while
/sbin/dphys-swapfile setup
/sbin/dphys-swapfile swapon
```

View file

@ -1,41 +0,0 @@
#
# First stage - builder
#
FROM debian:10-slim AS builder
ENV DEBIAN_FRONTEND=noninteractive
ENV LC_ALL=C.UTF-8
# This allows you to use a local Debian mirror
ARG APT_URL=http://archive.debian.org/debian
ARG MAKE_FLAGS=-j2
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 install -y protobuf-compiler libh2o-dev libcurl4-openssl-dev \
libssl-dev libprotobuf-dev libh2o-evloop-dev libwslay-dev \
libeigen3-dev libzstd-dev libfmt-dev libncurses-dev libfmt-dev \
make gcc g++ git build-essential curl autoconf automake help2man
# Build
ADD . /galmon-src/
RUN cd /galmon-src/ \
&& make $MAKE_FLAGS \
&& prefix=/galmon make install
#
# Second stage - contains just the binaries
#
FROM debian:10-slim
COPY --from=builder /etc/apt/sources.list /etc/apt/sources.list
RUN apt-get update && apt-get -y upgrade \
&& apt-get install -y libcurl4 libssl1.1 libprotobuf17 libh2o-evloop0.13 \
libncurses6 \
&& apt-get -y clean \
&& rm -rf /var/lib/apt/lists/*
COPY --from=builder /galmon/ /galmon/
ENV PATH=/galmon/bin:${PATH}
ENV LC_ALL=C.UTF-8
WORKDIR /galmon/bin

147
Makefile
View file

@ -1,30 +1,12 @@
CFLAGS = -O3 -Wall -ggdb
CXXFLAGS:= -std=gnu++17 -Wall -O3 -ggdb -MMD -MP -fno-omit-frame-pointer -Iext/CLI11 \
-Iext/powerblog/ext/simplesocket -Iext/powerblog/ext/ \
CXXFLAGS:= -std=gnu++17 -Wall -O3 -MMD -MP -ggdb -fno-omit-frame-pointer -Iext/CLI11 \
-Iext/fmt-5.2.1/include/ -Iext/powerblog/ext/simplesocket -Iext/powerblog/ext/ \
-I/usr/local/opt/openssl/include/ \
-Iext/sgp4/libsgp4/ \
-I/usr/local/include
# CXXFLAGS += -Wno-delete-non-virtual-dtor
# If unset, create a variable for the path or binary to use as "install" for debuild.
INSTALL ?= install
# If unset, create a variable with the path used by "make install"
prefix ?= /usr/local/ubxtool
# If unset, create a variable for a path underneath $prefix that stores html files
htdocs ?= /share/package
ifneq (,$(wildcard ubxsec.c))
EXTRADEP = ubxsec.o
else ifneq (,$(wildcard ubxsec.o))
EXTRADEP = ubxsec.o
endif
CHEAT_ARG := $(shell ./update-git-hash-if-necessary)
PROGRAMS = navparse ubxtool navnexus navcat navrecv navdump testrunner navdisplay tlecatch reporter sp3feed \
galmonmon rinreport rinjoin rtcmtool gndate septool navmerge
PROGRAMS = navparse ubxtool navnexus navrecv navdump testrunner navdisplay tlecatch
all: navmon.pb.cc $(PROGRAMS)
@ -32,106 +14,39 @@ all: navmon.pb.cc $(PROGRAMS)
-include *.d
navmon.pb.h: navmon.proto
protoc --cpp_out=./ navmon.proto
clean:
rm -f *~ *.o *.d ext/*/*.o $(PROGRAMS) navmon.pb.h navmon.pb.cc
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
navparse: navparse.o ext/fmt-5.2.1/src/format.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
$(CXX) -std=gnu++17 $^ -o $@ -pthread -L/usr/local/lib -L/usr/local/opt/openssl/lib/ -lh2o-evloop -lssl -lcrypto -lz -lcurl -lprotobuf $(WSLAY)
navdump: navdump.o ext/fmt-5.2.1/src/format.o bits.o navmon.pb.o gps.o ephemeris.o beidou.o glonass.o navmon.o $(patsubst %.cc,%.o,$(wildcard ext/sgp4/libsgp4/*.cc)) tle.o sp3.o
$(CXX) -std=gnu++17 $^ -o $@ -L/usr/local/lib -pthread -lprotobuf
navdisplay: navdisplay.o ext/fmt-5.2.1/src/format.o bits.o navmon.pb.o gps.o ephemeris.o beidou.o glonass.o ephemeris.o navmon.o
$(CXX) -std=gnu++17 $^ -o $@ -L/usr/local/lib -pthread -lprotobuf -lncurses
navnexus: navnexus.o ext/fmt-5.2.1/src/format.o $(SIMPLESOCKETS) ubx.o bits.o navmon.pb.o storage.o
$(CXX) -std=gnu++17 $^ -o $@ -L/usr/local/lib -pthread -lprotobuf
navrecv: navrecv.o ext/fmt-5.2.1/src/format.o $(SIMPLESOCKETS) navmon.pb.o storage.o
$(CXX) -std=gnu++17 $^ -o $@ -L/usr/local/lib -pthread -lprotobuf
tlecatch: tlecatch.o $(patsubst %.cc,%.o,$(wildcard ext/sgp4/libsgp4/*.cc))
$(CXX) -std=gnu++17 $^ -o $@ -L/usr/local/lib -pthread -lprotobuf
navmon.pb.cc: navmon.proto
protoc --cpp_out=./ navmon.proto
ubxtool: navmon.pb.o ubxtool.o ubx.o bits.o ext/fmt-5.2.1/src/format.o galileo.o gps.o beidou.o navmon.o ephemeris.o $(SIMPLESOCKETS)
$(CXX) -std=gnu++17 $^ -o $@ -L/usr/local/lib -lprotobuf -pthread
SIMPLESOCKETS=ext/powerblog/ext/simplesocket/swrappers.o ext/powerblog/ext/simplesocket/sclasses.o ext/powerblog/ext/simplesocket/comboaddress.o
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 ext/sgp4/libsgp4/*.d ext/powerblog/ext/simplesocket/*.d
help2man:
$(INSTALL) -m 755 -d $(DESTDIR)$(prefix)/share/man/man1
HELP2MAN_DESCRIPTION="Open-source GNSS Monitoring Project"
$(foreach binaryfile,$(PROGRAMS),help2man -N -n "$(HELP2MAN_DESCRIPTION)" ./$(binaryfile) | gzip > $(DESTDIR)$(prefix)/share/man/man1/$(binaryfile).1.gz;)
@echo until these binaries support --help and --version remove the broken output
rm -f $(DESTDIR)$(prefix)/share/man/man1/rinreport.1.gz
rm -f $(DESTDIR)$(prefix)/share/man/man1/rtcmtool.1.gz
rm -f $(DESTDIR)$(prefix)/share/man/man1/testrunner.1.gz
install: $(PROGRAMS) help2man
$(INSTALL) -m 755 -d $(DESTDIR)$(prefix)/bin
$(foreach binaryfile,$(PROGRAMS),$(INSTALL) -s -m 755 -D ./$(binaryfile) $(DESTDIR)$(prefix)/bin/$(binaryfile);)
@echo "using cp instead of install because recursive directories of ascii"
mkdir -p $(DESTDIR)$(prefix)$(htdocs)/galmon
cp -a html $(DESTDIR)$(prefix)$(htdocs)/galmon/
decrypt: decrypt.o bits.o
$(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
$(CXX) -std=gnu++17 $^ -o $@ -pthread -L/usr/local/lib -L/usr/local/opt/openssl/lib/ -lz -lcurl -lprotobuf -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
$(CXX) -std=gnu++17 $^ -o $@ -pthread -L/usr/local/lib -lprotobuf -lcurl -lfmt
sp3feed: sp3feed.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 influxpush.o githash.o sp3.o
$(CXX) -std=gnu++17 $^ -o $@ -pthread -L/usr/local/lib -lprotobuf -lcurl -lfmt
tracker: tracker.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
$(CXX) -std=gnu++17 $^ -o $@ -pthread -L/usr/local/lib -lprotobuf -lcurl -lfmt
galmonmon: galmonmon.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
$(CXX) -std=gnu++17 $^ -o $@ -pthread -L/usr/local/lib -lprotobuf -lcurl -lfmt
# rs.o fixhunter.o
navdump: navdump.o bits.o navmon.pb.o gps.o ephemeris.o beidou.o glonass.o navmon.o $(patsubst %.cc,%.o,$(wildcard ext/sgp4/libsgp4/*.cc)) tle.o sp3.o osen.o trkmeas.o githash.o rinex.o sbas.o rtcm.o galileo.o ${EXTRADEP}
$(CXX) -std=gnu++17 $^ -o $@ -L/usr/local/lib -pthread -lprotobuf -lz -lfmt
# -lfec
navdisplay: navdisplay.o bits.o navmon.pb.o gps.o ephemeris.o beidou.o glonass.o ephemeris.o navmon.o osen.o githash.o
$(CXX) -std=gnu++17 $^ -o $@ -L/usr/local/lib -pthread -lprotobuf -lncurses -lfmt
navnexus: navnexus.o $(SIMPLESOCKETS) bits.o navmon.pb.o storage.o githash.o
$(CXX) -std=gnu++17 $^ -o $@ -L/usr/local/lib -pthread -lprotobuf -lfmt
navcat: navcat.o $(SIMPLESOCKETS) ubx.o bits.o navmon.pb.o storage.o navmon.o githash.o
$(CXX) -std=gnu++17 $^ -o $@ -L/usr/local/lib -pthread -lprotobuf -lfmt
navrecv: navrecv.o $(SIMPLESOCKETS) navmon.pb.o storage.o githash.o zstdwrap.o navmon.o
$(CXX) -std=gnu++17 $^ -o $@ -L/usr/local/lib -pthread -lprotobuf -lzstd -lfmt
navmerge: navmerge.o $(SIMPLESOCKETS) navmon.pb.o storage.o githash.o zstdwrap.o navmon.o nmmsender.o
$(CXX) -std=gnu++17 $^ -o $@ -L/usr/local/lib -pthread -lprotobuf -lzstd -lfmt
tlecatch: tlecatch.o $(patsubst %.cc,%.o,$(wildcard ext/sgp4/libsgp4/*.cc)) githash.o
$(CXX) -std=gnu++17 $^ -o $@ -L/usr/local/lib -pthread -lprotobuf
rinreport: rinreport.o rinex.o githash.o navmon.o ephemeris.o osen.o
$(CXX) -std=gnu++17 $^ -o $@ -lz -pthread -lfmt
rinjoin: rinjoin.o rinex.o githash.o navmon.o ephemeris.o osen.o
$(CXX) -std=gnu++17 $^ -o $@ -lz -pthread -lfmt
rtcmtool: rtcmtool.o navmon.pb.o githash.o bits.o nmmsender.o $(SIMPLESOCKETS) navmon.o rtcm.o zstdwrap.o
$(CXX) -std=gnu++17 $^ -o $@ -L/usr/local/lib -lz -pthread -lprotobuf -lzstd -lfmt
ubxtool: navmon.pb.o ubxtool.o ubx.o bits.o galileo.o gps.o beidou.o navmon.o ephemeris.o $(SIMPLESOCKETS) osen.o githash.o nmmsender.o zstdwrap.o
$(CXX) -std=gnu++17 $^ -o $@ -L/usr/local/lib -lprotobuf -pthread -lzstd -lfmt
septool: navmon.pb.o septool.o bits.o galileo.o gps.o beidou.o navmon.o ephemeris.o $(SIMPLESOCKETS) osen.o githash.o nmmsender.o zstdwrap.o
$(CXX) -std=gnu++17 $^ -o $@ -L/usr/local/lib -lprotobuf -pthread -lzstd -lfmt
testrunner: navmon.pb.o testrunner.o ubx.o bits.o galileo.o gps.o beidou.o ephemeris.o sp3.o osen.o navmon.o rinex.o githash.o
$(CXX) -std=gnu++17 $^ -o $@ -L/usr/local/lib -lprotobuf -lz -pthread -lfmt
gndate: gndate.o githash.o navmon.o
$(CXX) -std=gnu++17 $^ -o $@ -L/usr/local/lib -lfmt
testrunner: navmon.pb.o testrunner.o ubx.o bits.o ext/fmt-5.2.1/src/format.o galileo.o gps.o beidou.o ephemeris.o sp3.o
$(CXX) -std=gnu++17 $^ -o $@ -L/usr/local/lib -lprotobuf
check: testrunner
./testrunner

View file

@ -1,54 +0,0 @@
Hi!
Many thanks for joining the galmon.eu project as an observer and station operator!
Here are some ground rules to follow once you have locally tested your galmon station:
* Please ask bert@hubertnet.nl or [ahu on
IRC](https://webchat.oftc.net/?channels=galileo) or
[@PowerDNS_Bert](https://twitter.com/PowerDNS_Bert) for a station ID and receiver
hostname.
* Please do not randomly pick a station ID!! Project data quality and integrity
depends on your cooperation.
* The rule is: one station ID per receiver. Do not under any circumstances
use the same ID on multiple receivers, even if you think it should be
fine. We have 2^64 IDs available, just ask for more IDs.
* Even if you think it should be fine to reuse the same ID, for example
because your observer page on galmon.eu will look nicer, DO NOT DO IT!
It messes up our algorithms which track the clock of your receiver.
* Please set the --owner and --remark fields - they help with administration.
These fields will show up on https://galmon.eu/observers.html
* Ublox8 based receivers support (GPS AND Galileo) + (BeiDou OR GLONASS). They can't
process all four systems at the same time. GPS and Galileo share a slot. BeiDou or GLONASS
share a second slot. See
[here](https://www.geospatialworld.net/blogs/gnss-frequency-bands-for-constellations/)
for some more information.
* If you want to know if you should add BeiDou or GLONASS, you can either use your own
preference or ask us what we are missing in your region.
Downtime
--------
The project is grateful for every bit you can provide. Don't feel bad about
downtime either because your family needs the power plug for Christmas
decorations (this happened) or for whatever reason.
A good way to increase uptime is to use the Systemd file to ensure automatic
startup on reboots. Some stations with bad power, bad hardware or bad cables
have had great success enabling the Raspberry Pi watchdog.
(need instruction here how to do that for various Raspberries, it differs)
Upgrades
--------
From time to time we upgrade the ubxtool receiver software. Old data also
works but typically if you upgrade, the value to the network increases.
Improving reception
-------------------
A good view of the sky can help tremendously, although as noted, we are
happy with every bit we receive. It helps to put your receiver on a "ground
plate" which is a fancy word for a piece of metal (or mesh even).
In addition, if you are in a northerly region, your view to the south is
most important. Conversely, if you are in the south, more action will be to
the north.

View file

@ -1,112 +0,0 @@
# .deb Package Overview
2020-01-20: Initial Commit
## Important Information
This section is a step-by-step tutorial.
### Basic Installation
Pick either debian (almost everything) or raspbian (special armv6 build for older models) and create the source file.
```sh
echo "deb https://ota.bike/raspbian/ buster main" > /etc/apt/sources.list.d/galmon.list
echo "deb https://ota.bike/debian/ buster main" > /etc/apt/sources.list.d/galmon.list
```
Install the file used to ensure the software is verified.
```sh
apt-key adv --fetch-keys https://ota.bike/public-package-signing-keys/86E7F51C04FBAAB0.asc
```
Update your package list and install galmon. Then create a configuration file and start the daemon.
If you have a typical device using the onboard USB at /dev/ttyACM0, drop the directory element
and refer to ttyACM0 in both the default variable file and the unit name.
```sh
apt-get update && apt-get install -y galmon
cp /etc/default/galmon /etc/default/ubxtool-ttyACM0
systemctl enable --now ubxtool@ttyACM0
```
Alternate or multiple devices just repeats that, updating the device name:
```sh
cp /etc/default/galmon /etc/default/ubxtool-ttyACM3
systemctl enable --now ubxtool@ttyACM3
```
Both the ubxtool-ttyXYZn file and /dev/ttyXYZn device must exist for the unit file conditions to pass.
### Automatic Updates
Armbian and Raspbian have apt-daily timers enabled by default.
However, most configurations for unattended installs require customization.
A simple timer is included that will apply any galmon upgrades every three days:
```sh
systemctl enable --now galmon-upgrade.timer
```
You can perform an immediate update by hand:
```sh
apt-get update && apt-get -y install galmon && systemctl restart ubxtool@*
```
## Reference Information
You can stop reading here if your interest was limited to installing a compiled package.
### One time steps for bootstrapping package build on a fresh git repo
Run debmake in the source directory. It tries to autocreate 90% of everything you need in the debian folder.
Key files: copyright, changelog, control, and anything else that looks interesting to cat. Once they exist, we're done.
Refer to the manual's [tutorial](https://www.debian.org/doc/manuals/debmake-doc/ch04.en.html).
### One time steps for creating package-specific files and scripts
Inside the debian directory are files that begin with galmon, the name of the package as defined in the control file.
- galmon.postinst: this script is run after installation to verify a system account exists.
- galmon.default: this file is installed as /etc/default/galmon
- galmon.ubxtool@.service: this unit file uses %i as a reference to the device for computers with multiple inputs.
### How to build the package locally
In short you need to set some variables, refer to profile-debuild.sh in the debian/ directory.
After that, use debuild to install the package. Signing of the end result may fail and creating
GPG key pairs is beyond the scope of this document but just make sure you match the email in the changelog.
```sh
apt-get install -y build-essential devscripts lintian diffutils patch patchutils
git clone $flags galmon.git ; cd galmon
./make-githash.h
# create and source variables in /etc/profile.d/debuild.sh
debuild
dpkg -i ../*.deb
```
### Future maintenance considerations
The githash.h files cannot change after the debuild process has started.
For now, the Makefile used by debuild does not run that script and
the files must be created before starting the debuild process.
### Real World Build Results in January 2020
Avoid compiling on arm6 computers, it is slow. The arm6 used in cheap Raspberry Pi models is an expensive model to support
relative to the much faster arm7 and arm8 computers available. Compiling approaches 90 minutes at O3.
The arm7 and arm8 both compile in 20 to 30 minutes at -j1 -O3 but the 64 bit arm8 has approximately
double the RAM requirements during compilation. To avoid swapping, increasing compile time 150%,
use hardware with at least 1GB of RAM. The NanoPi Neo2 and NanoPi ZeroPi models with 512MB of RAM
are perfect clients, but the OrangePi PCs with 1GB of RAM and the Allwinner H3 or H5 are
better suited for smooth building. For comparison, a VM on a low-end AMD Ryzen 3 2200G builds the package at -j1 in about two minutes.
These are fast multi-core computers but we turn off parallel compiles because of limited RAM.
Limiting optimizations to -O0 cuts the compile time in half approximately.
### Why do this?
Convenience, uniformity, and scalability:
Hand-compiling software is fun, but vendor package management solutions
exist to give us reliable unattended installations for free.
### Signing key
GPG Public Key [86E7F51C04FBAAB0](debian/86E7F51C04FBAAB0.asc)

400
README.md
View file

@ -1,62 +1,22 @@
# galmon
galileo/GPS/GLONASS/BeiDou open source monitoring. GPL3 licensed.
(C) AHU Holding BV - bert@hubertnet.nl - https://berthub.eu/
(C) AHU Holding BV - bert@hubertnet.nl - https://ds9a.nl/
Live website: https://galmon.eu/
Multi-vendor, with support for U-blox 8 and 9 chipsets and many Septentrio
devices. Navilock NL-8012U receiver works really well, as does the U-blox
evaluation kit for the 8MT. In addition, many stations have reported
success with this very cheap [AliExpress sourced
device](https://www.aliexpress.com/item/32816656706.html).
Theoretically multi-vendor, although currently only the U-blox 8 chipset is
supported. Navilock NL-8012U receiver works really well, as does the U-blox evaluation kit for the 8MT.
For ublox, there is good support for the F9P, several of us use the
[ArdusimpleRTK2B](https://www.ardusimple.com/simplertk2b/) board. It adds
the Galileo E5b band.
Septentrio devices support even more bands.
An annotated presentation about our project aimed at GNSS professionals can
be found [here](https://berthub.eu/galileo/The%20galmon.eu%20project.pdf).
> NOTE: One of our programs is called 'ubxtool'. Sadly, we did not do our
> research, and there is another '[ubxtool](https://gpsd.io/ubxtool.html)' already, part of
> [gpsd](https://gpsd.io). You might have ended up on our page by mistake.
> Sorry!
To deliver data to the project, please read
[The Galmon GNSS Monitoring Project](https://berthub.eu/articles/posts/galmon-project/)
and consult the rules outlined in [the operator
guidelines](https://github.com/berthubert/galmon/blob/master/Operator.md).
Highlights
----------
* Support for Septentrio and U-blox.
Highlights:
* Processes raw frames/strings/words from GPS, GLONASS, BeiDou and Galileo
* All-band support (E1, E5a, E5b, B1I, B2I, Glonass L1, Glonass L2, GPS L1C/A)
so far.
* Calculate ephemeris positions
* Comparison of ephemerides to independent SP3 data to determine SISE
* Globally, locally, worst user location
* Record discontinuities between subsequent ephemerides (in time and space)
* Record discontinuities between subsequent ephemerides
* Compare doppler shift as reported by receiver with that expected from ephemeris
* Track atomic clock & report jumps
* Coverage maps (number of satellites >5, >10, >20 elevation)
* HDOP/VDOP/PDOP maps
* Compare orbit to TLE, match up to best matching satellite
* Tear out every bit that tells us how well an SV is doing
* Full almanac processing to see what _should_ be transmitting
* Distributed receivers, combined into a single source of all messages
* Ready to detect/report spoofing/jamming
Data is made available as JSON, as a user-friendly website and as a
time-series database. This time-series database is easily mated to the
industry standard Matplotlib/Pandas/Jupyter combination (details
[here](https://github.com/berthubert/galmon/blob/master/influxdb.md).
There is also tooling to extract raw frames/strings/words from specific
timeframes.
Goals:
@ -70,75 +30,30 @@ Goals:
5) Populate an InfluxDB timeseries database with raw measurements and higher
order calculations
Works on Linux (including Raspbian Buster on Pi Zero W), OSX and OpenBSD.
Works on Linux (including Raspbian on Pi Zero W), OSX and OpenBSD.
Build locally (Linux, Debian, Ubuntu)
-------------------------------------
To get started, make sure you have a C++17 compiler, git, protobuf-compiler.
Then run 'make ubxtool navdump' to build the receiver-only tools.
To get started, make sure you have a C++17 compiler (like g++ 8 or higher),
git, protobuf-compiler. Then run 'make ubxtool navdump' to build the
receiver-only tools.
To also run the webserver locally, intall libh2o-dev and run 'make'.
To build everything, including the webserver, try:
To build everything, try:
```
apt-get install protobuf-compiler libcurl4-openssl-dev libssl-dev libprotobuf-dev \
libncurses5-dev libeigen3-dev libzstd-dev g++ libfmt-dev
git clone https://github.com/berthubert/galmon.git --recursive
apt-get install protobuf-compiler libh2o-dev libcurl4-openssl-dev libssl-dev libprotobuf-dev libh2o-evloop-dev libwslay-dev
git clone https://github.com/ahupowerdns/galmon.git --recursive
cd galmon
make
```
Building on OSX
---------------
With thanks to a contributor from Prague. First make sure you've installed
brew, which you can get [here](https://brew.sh/). Then do:
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:
```
brew install protobuf lzlib zstd eigen
echo WSLAY=-lwslay > Makefile.local
```
And then:
```
git clone https://github.com/berthubert/galmon.git --recursive
cd galmon
make
```
Running in Docker
-----------------
We publish official Docker images for galmon on
[docker hub](https://hub.docker.com/r/berthubert/galmon) for multiple architectures.
To run a container with a shell in there (this will also expose a port so you
can view the UI too and assumes a ublox GPS device too -
you may need to tweak as necessary):
```
docker run -it --rm --device=/dev/ttyACM0 -p 10000:10000 berthubert/galmon
```
Running a daemonized docker container reporting data to a remote server
might look like:
```
docker run -d --restart=always --device=/dev/ttyACM0 --name=galmon berthubert/galmon ubxtool --wait --port /dev/ttyACM0 --gps --galileo --glonass --destination [server] --station [station-id] --owner [owner]
```
To make your docker container update automatically you could use a tool such as
[watchtower](https://containrrr.github.io/watchtower/).
Running
-------
On u-blox:
Once compiled, run for example `./ubxtool --wait --port /dev/ttyACM0
--station 1 --stdout --galileo | ./navparse --bind [::1]:10000`
For Septentrio, try: `nc 192.168.1.1 29000 | ./septool --station x --stdout |
./navparse --bind [::1]:10000`, assuming your Septentrio can be reached on
192.168.1.1.1 and you have defined an SBF stream on port 29000. For more
details, please see below.
Once compiled, run for example `./ubxtool --wait /dev/ttyACM0 1 | ./ubxparse 10000 html null`
Next up, browse to http://[::1]:10000 (or try http://localhost:10000/ and
you should be in business. ubxtool changes (non-permanently) the
@ -146,41 +61,20 @@ configuration of your u-blox receiver so it emits the required frames for
GPS and Galileo. If you have a u-blox timing receiver it will also enable
the doppler frames.
By default the ublox receiver module will be configured to use the USB port,
if you want to use a different interface port on the ublox module then add
the `--ubxport <id>` option using one of the following numeric IDs:
0 : DDC (aka. I2C)
1 : UART[1]
2 : UART2
3 : USB (default)
4 : SPI
To see what is going on, try:
```
./ubxtool --wait --port /dev/ttyACM0 --station 1 --stdout --galileo | ./navdump
./ubxtool --wait /dev/ttyACM0 1 | ./navdump
```
To distribute data to a remote `navrecv`, use:
```
./ubxtool --wait --port /dev/ttyACM0 --galileo --station 255 --destination 127.0.0.1
```
This will send protobuf to 127.0.0.1:29603. You can add as many destinations
as you want, they will buffer and automatically reconnect. To also send data
to stdout, add `--stdout`.
Setting up a distributed setup is slightly more complicated & may still
change.
Tooling:
* ubxtool: can configure a u-blox 8/9/10 chipset, parses its output & will
* ubxtool: can configure a u-blox 8 chipset, parses its output & will
convert it into a protbuf stream of GNSS NAV frames + metadata
Adds 64-bit timestamps plus origin information to each message
* septool: ingests the Septentrio binary format (SBF) and converts it to our
protobuf format. Supports same protocol as ubxtool.
* rtcmtool: ingest ntripclient output, decodes RTCM messages and converts
them to our protobuf format
* xtool: if you have another chipset, build something that extracts NAV
frames & metadata. Not done yet.
* navrecv: receives GNSS NAV frames and stores them on disk, split out per
@ -193,109 +87,17 @@ Tooling:
computations on ephemerides.
* grafana dashboard: makes pretty graphs
Per device notes
----------------
The "SparkFun GNSS L1/L5 Breakout - NEO-F10N, SMA" needs '-u1 -b 38400
--wait'.
Linux Systemd
-------------
First make sure 'ubxtool' has been compiled (run: make ubxtool). Then, as
root:
```
mkdir /usr/local/ubxtool
cp ubxtool ubxtool.sh /usr/local/ubxtool/
cp ubxtool.service /etc/systemd/system/
```
Then please reach out as indicated in [Operator.md](Operator.md) to obtain your
station ID and the receiver hostname and run:
```
echo RECEIVER-NAME > /usr/local/ubxtool/destination
echo STATION-NUMBER > /usr/local/ubxtool/station
```
Then start up the service (as root):
```
systemctl enable ubxtool
systemctl start ubxtool
```
To check if it is all working, do 'service ubxtool status'.
> NOTE! If you don't use one of the AliExpress or Navilock devices, it may
> be that your U-blox is not connected to the USB-port of the U-blox chip
> but to the UART1 or UART2 port. If so, you'll need to edit the script so
> it finds your USB-to-serial adapter. At the very least you'll have to
> update the DEVICE line. You'll likely also have to add --ubxport 1 at the
> end, and likely also the baudrate (-b) and/or --rtscts=0.
To change the default constellations, create a file called
/usr/local/ubxtool/constellations and set your favorites. To set all four
constellations (which only F9-receivers support), do as root:
```
echo --gps --glonass --beidou --galileo > /usr/local/ubxtool/constellations
```
And then 'service ubxtool restart'.
Distributed setup
-----------------
Run `navrecv -b :: --storage ./storage` to receive frames on port 29603 of
::, aka all your IPv6 addresses (and IPv4 too on Linux). This allows anyone
to send you frames, so be aware.
Run `navrecv :: ./storage` to receive frames on port 29603 of ::, aka all your IPv6 addresses (and IPv4 too on Linux).
This allows anyone to send you frames, so be aware.
Next up, run `navnexus --storage ./storage -b ::`, which will serve your
recorded data from port 29601. It will merge messages coming in from all
sources and serve them in time order.
Next up, run `navnexus ./storage ::`, which will serve your recorded data from port 29601. It will merge messages
coming in from all sources and serve them in time order.
Finally, you can do `nc 127.0.0.1 29601 | ./navdump`, which will give you all messages over the past 24 hours, and stream you more.
This also works for `navparse` for the pretty website and influx storage, `nc 127.0.0.1 29601 | ./navparse --influxdb=galileo`,
Finally, you can do `nv 127.0.0.1 29601 | ./navdump`, which will give you all messages over the past 24 hours, and stream you more.
This also works for `navparse` for the pretty website and influx storage, `nc 127.0.0.1 29601 | ./navparse 127.0.0.0:10000 html galileo`,
if you have an influxdb running on localhost with a galileo database in there.
The default URL is http://127.0.0.1:29599/
Septentrio specifics
--------------------
Unlike `ubxtool`, our `septool` does not (re)configure your Septentrio
device. Instead, the tool expects Septentrio Binary Format (SBF) on input,
and that this stream includes at least the following messages:
* MeasEpoch
* PVTCartesian
We currently parse and understand:
* GALRawFNAV
* GALRawINAV
Support will be added soon for:
* GPSRawCA
* GPSRawL2C
* GPSRawL5
* GLORawCA
* BDSRaw
* BDSRawB1C
* BDSRawB2a
A typical invocation of `septool` looks like this:
```
nc 192.168.1.1 29000 | ./septool --station x --destination galmon-eu-server.example.com
```
Or to test, try:
```
nc 192.168.1.1 29000 | ./septool --station x --stdout | ./navdump
```
This is assuming that you can reach your Septentrio on 192.168.1.1 and that
you have defined a TCP server stream on port 29000.
Septool will also accept input from a serial port or basically anything that
can provide SBF. Please let us know if our tooling can make your life
easier.
Internals
---------
@ -321,146 +123,26 @@ Documents
* [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
precise orbit determinations.
* [GPS](https://www.navcen.uscg.gov/sites/default/files/pdf/gps/IS-GPS-200N.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)
* [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.pdfhttps://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 10 interface specification](https://content.u-blox.com/sites/default/files/documents/u-blox-F10-SPG-6.00_InterfaceDescription_UBX-23002975.pdf)
* [U-blox 9 integration manual](https://www.u-blox.com/sites/default/files/ZED-F9P_IntegrationManual_%28UBX-18010802%29.pdf)
Data sources
------------
The software can interpret SP3 files, good sources:
* ESA/ESOC: http://navigation-office.esa.int/products/gnss-products/ - pick the
relevant GPS week number, and then a series (.sp3 extension):
* ESU = ultra rapid, 2-8h delay, only GPS and GLONASS
* ESR = rapid, 2-26h delay, only GPS and GLONASS
* ESM = finals, 6-13d delay, GPS, GLONASS, Galileo, BeiDou, QZSS
* File format is esXWWWWD.sp3 - where X is U, R or M, WWWW is the
(non-wrapping) GPS week number and D is day of week, Sunday is 0.
* Further description: http://navigation-office.esa.int/GNSS_based_products.html
* GFZ Potsdam: ftp://ftp.gfz-potsdam.de/GNSS/products/mgnss
* The GBM series covers GPS, GLONASS, Galileo, BeiDou, QZSS and appears
to have less of a delay than the ESA ESM series.
* GBU = ultra rapid, still a few days delay, but much more recent.
Big TODO
--------
To get SP3 GBM from GFZ Potsdam for GPS week number 2111:
* Dual goals: completeness, liveness, not the same
For forensics, great if the packet is there
For display, not that bad if we missed a message
* In general, consider refeed strategy
Raw serial
Protobuf
Influxdb
".csv files"
* Delivery needs to be bit more stateful (queue)
```
WN=2111
lftp -c "mget ftp://ftp.gfz-potsdam.de/GNSS/products/mgnss/${WN}/gbm*sp3.Z"
gunzip gbm*sp3.Z
```
To feed data, use:
```
./sp3feed --sp3src=gbm --influxdb=galileo gbm*sp3
```
This will populate the sp3 tables in the database. A subsequent run of
`reporter`, while setting the `--sp3src` parameter, will provide SP3
deviation statistics, and fill out the `sp3delta` table in there, which
stores deviations from the SP3 provided position, per sp3src.
Further interesting (ephemeris) data is on http://mgex.igs.org/IGS_MGEX_Products.php
RTCM
----
RTCM is the Radio Technical Commission for Maritime Services, and
confusingly, also the name of a protocol.
This protocol is proprietary, but search for a file called `RTCM3.2.pdf` or
`104-2013-SC104-STD - Vers. 3.2.docx` and you might find a copy.
This project can parse RTCM 10403.1 messages, and currently processes State
Space Representation (SSR) messages, specifically types 1057/1240
(GPS/Galileo Orbit corrections to broadcast ephemeris) and 1058/1241
(GPS/Galileo Clock corrections to broadcast ephemeris).
RTCM messages need to be converted to protobuf format, and the `rtcmtool` is
provided for this purpose.
RTCM is frequently transmitted over the internet using 'ntrip', a typical
commandline to process RTCM in our project is:
```
$ ntripclient ntrip:CLKA0_DEU1/user:password@navcast.spaceopal.com:2101 | ./rtcmtool --station x --destination y
```
User and password can be obtained from https://spaceopal.com/navcast/ - the
Galileo operating company.
The IGS also offers excellent streams, but without Galileo. Information is
[here](http://www.igs.org/rts/products). A typical commandline is:
```
$ ntripclient ntrip:IGS01/user:password@products.igs-ip.net:2101 | ./rtcmtool --station x --destination y
```
User and password can be requested through http://www.igs.org/rts/access
An interesting list is here: http://products.igs-ip.net/
There are many other sources of RTCM but currently not many offer the SSR
messages we can use.
Tooling
-------
* ubxtool: Configure and use a Ublox chip to gather messages, and send as
protobuf to standard output or a remote server (with buffering).
* navdump: convert protobuf format data into a textual display of messages
* navparse: consume protobuf and turn into a webserver with data, plus
optionally fill an influxdb time-series database for graphing and analysis
purposes.
* navrecv: receive protobuf messages over the network and store them on
disk
* navnexus: serve protobuf messages from disk over the network
* navcat: serve protobuf messages from disk directly to stdout
* reporter: make "the galmon.eu weekly galileo report"
* rinreport: rinex analysis tooling (not generically useful yet)
* galmonmon: monitor a navparse instance for changes, tweet them out
* navdisplay: some eye-candy that converts protobuf into a live display
(not very good)
* rtcmtool: accepts RTCM messages on standard input (for example coming
from ntripclient) and transmits them as protobuf messages, either to
stdout or to a navrecv server. This is the equivalent of 'ubxtool'
except for submitting RTCM messages.
Sample command lines
--------------------
Look at old data:
```
$ ./navcat storage "2020-01-01 00:00" "2020-01-02 00:00" | ./navdump
```
Global coverage (via volunteers)
--------------------------------
In alphabetical order:
* Austria (Vienna area)
* Brazil
* Holland (Nootdorp, Hilversum, etc)
* India (New Delhi area)
* Israel (Jerusalem)
* Italy (Rome)
* New Zealand (Auckland area)
* Rusia (Moscow area)
* Singapore
* South Africa (Cape Town area)
* Spain
* Tonga
* USA
* Alaska (Anchorage)
* California (Santa Cruz, Los Angeles area, etc)
* Massachusetts (Boston area)
* Uruguay
Additional sites are welcome (and encouraged) as the more data receiving sites that exist, then more accurate data and absolute coverage of each constellation can be had.
The galmon project is very grateful to all its volunteering receiving stations.
* Semantics definition for output of Navnexus
"we'll never surprise you with old data"
ubxtool
-------

View file

@ -1,84 +0,0 @@
Architecture
------------
The galmon project consists of several components. Core of what we do are
protobuf messages that are (mostly) device independent and contain satellite
data and metadata.
All protobuf messages are 'NavMonMessages', of which there are 15 types.
These messages are:
* Navigation messages from satellites, various types
* Device / software metadata
* Reception strength details
* Doppler, carrier phase data
* RTCM messages
For every supported receiver type, there is a tool to convert the device
specific protocol to these protobuf messages. Currently we only have
'ubxtool' that does this for many u-blox devices. In addition, 'rtcmtool'
converts a RTCM to protobuf.
Components
----------
Core components:
* ubxtool/rtcmtool: generate protobuf messages, transmit them over network
* navrecv: receive protobuf messages over the network and store them on
disk
* navnexus: serve protobuf messages from disk over the network
* navparse: consume protobuf and turn into a webserver with data, plus
optionally fill an influxdb time-series database for graphing and analysis
purposes.
This offers a complete suite for:
* generating protobuf messages and transmitting them
* reception & long-term storage
* serving protobuf messages
* analysing them for display & storing statistics for analysis
Non-core tools:
* navdump: convert protobuf format data into a textual display of messages
* navcat: serve protobuf messages from disk directly to stdout
* reporter: make "the galmon.eu weekly galileo report", based on the
time-series database filled by navparse
* rinreport: rinex analysis tooling (not generically useful yet)
* galmonmon: monitor a navparse instance for changes, tweet them out
* navdisplay: some eye-candy that converts protobuf into a live display
(not very good)
Transmission details
--------------------
Messages are sent as protobuf messages with an intervening magic value and a
length field.
Both rtcmtool and ubxtool can send data over TCP/IP, but also to standard
output. This standard output mode makes it possible to pipe the output of
these tools straight into navdump or navparse.
There are two transport protocols, one uncompressed, which consists of the 4
byte magic value, a 2 byte length field, and then the message. This protocol
has been deprecated for TCP, but it is still there for --stdout output.
The second protocol is zstd compressed, and features acknowledgements. The
protocol is an initial 4 byte magic value "RNIE", followed by 8 reserved
bytes which are currently ignored. Then zstd compression starts, each
message consists of a 4 byte message number, followed by a two byte length
field, followed by the message. There are no further magic values beyond the
first one.
The receiver is expected to return the 4 byte message number for each
message received. Messages which have not been acknowledged like this will
be retransmitted on reconnect.
Storage details
---------------
Storage is very simplistic but robust. For every receiver, for every hour,
there is a file with protobuf messages. That's it. The goal is for the
receiver to never ever go down.
navnexus and navcat can consume data from this simplistic storage and serve
it over TCP/IP or to standard output.

View file

@ -1,8 +1,6 @@
#include "beidou.hh"
#include "bits.hh"
#include <iostream>
#include <vector>
#include "navmon.hh"
using namespace std;
@ -31,7 +29,7 @@ static int checkbds(int bits)
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
@ -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));
}
return makeVec(buffer, 28);
return std::basic_string<uint8_t>(buffer, 28);
}

View file

@ -4,10 +4,9 @@
#include "bits.hh"
#include <math.h>
#include <stdexcept>
#include <vector>
#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);
/* Geostationary, so D2, so not to be parsed by this parser:
@ -18,11 +17,11 @@ int beidouBitconv(int their);
C05 (58.75E)
*/
struct BeidouMessage : GPSLikeEphemeris
struct BeidouMessage
{
uint8_t strtype;
std::vector<uint8_t> g_cond;
std::basic_string_view<uint8_t> g_cond;
int bbitu(int bit, int 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 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;
if(pageno)
@ -73,7 +72,7 @@ struct BeidouMessage : GPSLikeEphemeris
int wn{-1}, a0, a1, a2;
// 2^17 2^30
uint32_t getT0c() const
uint32_t getT0c()
{
return 8 * t0c;
}
@ -90,7 +89,7 @@ struct BeidouMessage : GPSLikeEphemeris
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);
aodc = bbitu(31+13, 5);
@ -120,12 +119,8 @@ struct BeidouMessage : GPSLikeEphemeris
double getCrs() const { return ldexp(crs, -6); } // meters
double getM0() const { return ldexp(m0 * M_PI, -31); } // radians
int getIOD() const
{
return -1;
}
void parse2(const std::vector<uint8_t>& cond)
void parse2(std::basic_string_view<uint8_t> cond)
{
deltan = bbits(43, 16);
cuc = bbits(67, 18);
@ -152,7 +147,7 @@ struct BeidouMessage : GPSLikeEphemeris
double getOmega0() const { return ldexp(Omega0 * M_PI, -31); } // radians
double getIdot() const { return ldexp(idot * M_PI, -43); } // radians/s
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);
i0 = bbits(66, 32);
@ -208,7 +203,7 @@ struct BeidouMessage : GPSLikeEphemeris
} alma;
// 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.a1 = bbits(91, 11);
@ -229,8 +224,7 @@ struct BeidouMessage : GPSLikeEphemeris
// 2^-30 2^-50
int a0gps, a1gps, a0gal, a1gal, a0glo, a1glo, a0utc, a1utc;
int8_t deltaTLS, deltaTLSF;
uint8_t wnLSF, dn;
int8_t deltaTLS;
// in Beidou the offset is a0utc + SOW * a1utc
std::pair<double, double> getUTCOffset(int tow) const
@ -255,7 +249,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);
if(alma.pageno == 9) {
@ -270,9 +264,6 @@ struct BeidouMessage : GPSLikeEphemeris
a0utc = bbits(91, 32);
a1utc = bbits(131, 24);
deltaTLS = bbits(31+12+1+7, 8);
deltaTLSF = bbits(61+6, 8);
wnLSF = bbits(61+6+8, 8);
dn = bbits(151+12, 8);
}
else {
alma.sqrtA = bbitu(51, 24);

View file

@ -1,143 +0,0 @@
#include <map>
#include "galileo.hh"
#include "minivec.hh"
#include "navmon.hh"
#include "navparse.hh"
#include "ephemeris.hh"
#include "fmt/format.h"
#include "fmt/printf.h"
#include <fstream>
#include <eigen3/Eigen/Dense>
using Eigen::MatrixXd;
using namespace std;
xDOP getDOP(Point& us, vector<Point> sats)
{
xDOP ret;
if(sats.size() < 4) {
return ret;
}
MatrixXd G(sats.size(), 4); // 4 columns
// (x1 - x)/R1 (y1 -y)/R1 (z1 - z)/R1 -1
for(size_t n = 0 ; n < sats.size(); ++n) {
const auto& s = sats[n];
auto R = Vector(us, s).length();
G(n, 0) = (s.x - us.x)/R;
G(n, 1) = (s.y - us.y)/R;
G(n, 2) = (s.z - us.z)/R;
G(n, 3) = -1;
}
// cout<<"Matrix: "<<endl;
// cout<<G<<endl;
MatrixXd Q = (G.transpose() * G).inverse();
auto [lambda, phi] = getLongLat(us.x, us.y, us.z);
// https://gssc.esa.int/navipedia/index.php/Positioning_Error
Eigen::Matrix3d Renu;
Renu <<
(-sin(lambda)) , (-sin(phi)*cos(lambda)) , (cos(phi)*cos(lambda)),
(cos(lambda)) , (-sin(phi)*sin(lambda)) , (cos(phi)*sin(lambda)),
(0.0) , (cos(phi)) , (sin(phi));
Eigen::Matrix3d Qxyz;
for(int x=0; x<3; ++x) // feels like there should be a better way for this, but not sure
for(int y=0; y<3; ++y)
Qxyz(x,y) = Q(x,y);
Eigen::Matrix3d Qenu = Renu.transpose()*Qxyz*Renu;
// if(Qenu(0,0) < 0 || Qenu(1,1) < 0 || Qenu(2,2) < 0)
// cout << "Original: \n"<<Qxyz<<"\nRotated: \n"<<Qenu<<endl;
ret.pdop = sqrt(Q(0,0) + Q(1,1) + Q(2,2)); // already squared
// ret.pdop = sqrt(Qenu(0,0) + Qenu(1,1) + Qenu(2,2)); // already squared
ret.tdop = sqrt(Q(3,3));
ret.gdop = sqrt(ret.pdop*ret.pdop + ret.tdop*ret.tdop);
if(Qenu(0,0) >=0 && Qenu(1,1) >=0)
ret.hdop = sqrt(Qenu(0,0) + Qenu(1,1));
if(Qenu(2,2)>=0)
ret.vdop = sqrt(Qenu(2,2));
return ret;
};
// in covmap:
// 0
// lon,
// 1 2 3
// numsats5, numsats10, numsats20
// 4 5 6
// pdop5, pdop10, pdop20
// hdop5, hdop10, hdop10
// vdop5, vdop10, vdop20
covmap_t emitCoverage(const vector<Point>& sats)
{
covmap_t ret;
// ofstream cmap("covmap.csv");
// cmap<<"latitude longitude count5 count10 count20"<<endl;
double R = 6371000;
for(double latitude = 90 ; latitude > -90; latitude-=2) { // north-south
double phi = M_PI* latitude / 180;
double longsteps = 1 + 360.0 * cos(phi);
double step = 4*180.0 / longsteps;
// this does sorta equi-distanced measurements
vector<tuple<double, int, int, int, double, double, double, double, double, double,double, double, double>> latvect;
for(double longitude = -180; longitude < 180; longitude += step) { // east - west
Point p;
// phi = latitude, lambda = longitude
double lambda = M_PI* longitude / 180;
p.x = R * cos(phi) * cos(lambda);
p.y = R * cos(phi) * sin(lambda);
p.z = R * sin(phi);
if(longitude == -180) {
// auto longlat = getLongLat(p.x, p.y, p.z);
// cout<<fmt::sprintf("%3.0f ", 180.0*longlat.second/M_PI);
}
int numsats5=0, numsats10=0, numsats20=0;
vector<Point> satposs5, satposs10, satposs20;
for(const auto& s : sats) {
// double getElevationDeg(const Point& sat, const Point& our);
double elev = getElevationDeg(s, p);
if(elev > 5.0) {
satposs5.push_back(s);
numsats5++;
}
if(elev > 10.0) {
satposs10.push_back(s);
numsats10++;
}
if(elev > 20.0) {
satposs20.push_back(s);
numsats20++;
}
}
latvect.push_back(make_tuple(longitude,
numsats5, numsats10, numsats20,
getDOP(p, satposs5).pdop,
getDOP(p, satposs10).pdop,
getDOP(p, satposs20).pdop,
getDOP(p, satposs5).hdop,
getDOP(p, satposs10).hdop,
getDOP(p, satposs20).hdop,
getDOP(p, satposs5).vdop,
getDOP(p, satposs10).vdop,
getDOP(p, satposs20).vdop
));
// cmap << longitude <<" " <<latitude <<" " << numsats5 << " " <<numsats10<<" "<<numsats20<<endl;
}
ret.push_back(make_pair(latitude, latvect));
}
return ret;
}

View file

@ -1,87 +0,0 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
J7VNNdmxD1RF3zsMFsPTQWY=
=fqVo
-----END PGP PUBLIC KEY BLOCK-----

View file

@ -1,9 +0,0 @@
galmon for Debian
This directory contains files created by debmake and
required by debuild to create Debian packages.
For further instruction, review the Guide for Debian Maintainers
by Osamu Aoki: https:/www.debian.org/doc/manuals/debmake-doc/
-- Patrick Tudor <debian@ptudor.net> Sun, 19 Jan 2020 22:52:16 +0000

5
debian/changelog vendored
View file

@ -1,5 +0,0 @@
galmon (0.20191231-1) stable; urgency=low
* Initial release.
-- Patrick Tudor <debian@ptudor.net> Tue, 31 Dec 2019 00:00:00 +0000

1
debian/compat vendored
View file

@ -1 +0,0 @@
11

24
debian/control vendored
View file

@ -1,24 +0,0 @@
Source: galmon
Section: net
Priority: optional
Maintainer: Patrick Tudor <debian@ptudor.net>
Build-Depends: debhelper (>=11~), help2man, libzstd-dev, adduser
Standards-Version: 4.3.0
Homepage: https://github.com/ahupowerdns/galmon/
Package: galmon
Architecture: any
Multi-Arch: foreign
Conflicts: gpsd-clients
Depends: ${misc:Depends}, ${shlibs:Depends}
Description: galmon GNSS Monitoring Project software
88
88
88
,adPPYb,d8 ,adPPYYba, 88 88,dPYba,,adPYba, ,adPPYba, 8b,dPPYba,
a8" `Y88 "" `Y8 88 88P' "88" "8a a8" "8a 88P' `"8a
8b 88 ,adPPPPP88 88 88 88 88 8b d8 88 88
"8a, ,d88 88, ,88 88 88 88 88 "8a, ,a8" 88 88
`"YbbdP"Y8 `"8bbdP"Y8 88 88 88 88 `"YbbdP"' 88 88
aa, ,88
"Y8bbdP"

45
debian/copyright vendored
View file

@ -1,45 +0,0 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: galmon
Source: https://github.com/ahupowerdns/galmon
Files: *
Copyright: AHU Holding BV - bert@hubertnet.nl - https://berthub.eu/
License: GPL-3
This package is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
.
This package is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License
along with this package; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
.
On Debian systems, the complete text of the GNU General
Public License can be found in `/usr/share/common-licenses/GPL-3'.
Files: minicurl.cc
minicurl.hh
Copyright: 2018-2019 powerdns.com bv
License: Expat
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.

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