galmon/rinex.hh

144 lines
3.0 KiB
C++

#pragma once
#include <string>
#include <time.h>
#include <stdio.h>
#include <zlib.h>
#include <fstream>
#include "navmon.hh"
#include <time.h>
#include "fmt/format.h"
#include "fmt/printf.h"
struct RINEXEntry
{
time_t t;
int gnss;
int sv;
double sisa;
int health;
int toe;
int tow;
int iodnav;
double af0, af1, af2;
double clkflags;
double BGDE1E5a, BGDE1E5b;
};
class RINEXReader
{
public:
RINEXReader(std::string_view fname);
bool get(RINEXEntry& rinex);
~RINEXReader();
private:
void skipFileHeader();
std::string d_fname;
gzFile d_fp{0};
time_t d_time{0};
};
class RINEXNavWriter
{
public:
explicit RINEXNavWriter(std::string_view fname);
template<typename T>
void emitEphemeris(const SatID& sid, const T& t);
private:
std::ofstream d_ofs;
void emit(double n)
{
if(n >= 0)
d_ofs << fmt::format(" {:18.12E}", n);
else
d_ofs << fmt::format("{:019.12E}", n);
}
};
template<typename T>
void RINEXNavWriter::emitEphemeris(const SatID& sid, const T& e)
{
/*
E01 2019 09 21 23 30 00-6.949011585675E-04-7.943867785798E-12 0.000000000000E+00
1.090000000000E+02 9.746875000000E+01 2.820474626946E-09 2.393449606726E+00
4.611909389496E-06 2.816439373419E-04 7.767230272293E-06 5.440614154816E+03
6.030000000000E+05 1.862645149231E-09-1.121206798215E+00-4.656612873077E-08
9.859399710315E-01 1.802500000000E+02-2.137974852171E+00-5.485228481783E-09
-1.789360248322E-10 5.170000000000E+02 2.071000000000E+03
3.120000000000E+00 0.000000000000E+00-1.862645149231E-09-2.095475792885E-09
6.036660000000E+05
*/
using std::endl;
time_t then = utcFromGST(e.wn, (int)e.tow);
struct tm tm;
gmtime_r(&then, &tm);
// 0
d_ofs << makeSatPartialName(sid)<<" " << fmt::sprintf("%04d %02d %02d %02d %02d %02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
emit(ldexp(e.af0, -34));
emit(ldexp(e.af1, -46));
emit(ldexp(e.af2, -59));
d_ofs<<"\n ";
// 1
emit(e.iodnav);
emit(e.getCrs());
emit(e.getDeltan());
emit(e.getM0());
d_ofs<<"\n ";
// 2
emit(e.getCuc());
emit(e.getE());
emit(e.getCus());
emit(e.getSqrtA());
d_ofs<<"\n ";
// 3
emit(e.getT0e());
emit(e.getCic());
emit(e.getOmega0());
emit(e.getCis());
d_ofs<<"\n ";
// 4
emit(e.getI0());
emit(e.getCrc());
emit(e.getOmega());
emit(e.getOmegadot());
d_ofs<<"\n ";
// 5
emit(e.getIdot());
emit(257); // bit 0 = I/NAV E1, bit 1 = F/NAV E5a, bit 2 = I/NAV E5b
// bit 8 = E1,E5a clock aka F/NAV, bit 9 = E1,E5b aka I/NAV
emit(e.wn + 1024); // so it aligns with GPS
// 6
d_ofs<<"\n ";
emit(numSisa(e.sisa));
int health=0;
health |= e.e1bdvs;
health |= (e.e1bhs << 2);
// don't have e5advs
// don't have e5ahs
health |= (e.e5bdvs << 6);
health |= (e.e5bhs << 8);
emit(health); // HEALTH
emit(ldexp(e.BGDE1E5a, -32));
emit(ldexp(e.BGDE1E5b, -32));
// 7
d_ofs<<"\n ";
emit(e.tow); // XXX
d_ofs<<std::endl;
}