Rebase imet, m10 decoders, add output of telemetry-determined sonde frequency for RS41/RS92.

pull/581/head
Mark Jessop 2021-10-26 14:57:25 +10:30
rodzic 5316aa2304
commit 5607f17462
8 zmienionych plików z 114 dodań i 12 usunięć

Wyświetl plik

@ -17,7 +17,7 @@ except ImportError:
# MINOR - New sonde type support, other fairly big changes that may result in telemetry or config file incompatability issus.
# PATCH - Small changes, or minor feature additions.
__version__ = "1.5.6"
__version__ = "1.5.7-beta1"
# Global Variables

Wyświetl plik

@ -1360,6 +1360,9 @@ class SondeDecoder(object):
# Calculate estimated frequency error from where we expected the sonde to be.
_telemetry["f_error"] = _telemetry["f_centre"] - self.sonde_freq
# TODO - Compare the frequency estimate with any frequency information supplied in the sonde telemetry.
# If there is a large difference (> 5 kHz or so), log a warning.
# Try and generate an APRS callsign for this sonde.
# Doing this calculation here allows us to pass it to the web interface to generate an appropriate link
try:

Wyświetl plik

@ -93,6 +93,8 @@ def decode_dfm_subtype(subtype):
if subtype == "0x6":
return "DFM06"
elif subtype == "0x7":
return "PS-15"
elif subtype == "0xA":
return "DFM09"
elif subtype == "0xB":

Wyświetl plik

@ -271,8 +271,11 @@ class SondehubUploader(object):
_output["snr"] = telemetry["snr"]
if "f_centre" in telemetry:
_freq = round(telemetry["f_centre"] / 1e3)
_output["frequency"] = _freq / 1e3
_freq = round(telemetry["f_centre"] / 1e3) # Hz -> kHz
_output["frequency"] = _freq / 1e3 # kHz -> MHz
if "tx_frequency" in telemetry:
_output["tx_frequency"] = telemetry["tx_frequency"] / 1e3 # kHz -> MHz
return _output

Wyświetl plik

@ -224,6 +224,61 @@ static ui8_t hamming(int opt_ecc, ui8_t *cwb, ui8_t *sym) {
return ret; // { 0, 1, 0xF0 }
}
static int crc32ok(ui8_t *bytes, int len) {
ui32_t poly0 = 0x0EDB;
ui32_t poly1 = 0x8260;
//[105 , 7, 0x8EDB, 0x8260],
//[104 , 0, 0x48EB, 0x1ACA]
int n = 104;
int b = 0;
ui32_t c0 = 0x48EB;
ui32_t c1 = 0x1ACA;
ui32_t nx_c0 = c0;
ui32_t nx_c1 = c1;
ui32_t data_c0 = (bytes[100]<<8) | bytes[101];
ui32_t data_c1 = (bytes[106]<<8) | bytes[107];
ui32_t crc0 = 0;
ui32_t crc1 = 0;
if (len < 108) return 0;
while (n >= 0) {
if (n < 100 || (n > 101 && n < 106)) {
if ((bytes[n]>>b) & 1) {
crc0 ^= c0;
crc1 ^= c1;
}
}
if (c1 & 0x8000) {
nx_c0 ^= poly0;
nx_c1 ^= poly1;
}
nx_c0 <<= 1;
nx_c1 <<= 1;
if ( c1 & 0x8000) nx_c0 |= 1;
if ((c1^c0) & 0x8000) nx_c1 |= 1;
nx_c0 &= 0xFFFF;
c0 = nx_c0;
c1 = nx_c1;
if (b < 7) b += 1;
else {
b = 0;
if (n % 4 == 3) n -= 7;
else n += 1;
}
}
crc0 ^= data_c0^0x5000;
crc1 ^= data_c1^0x1DAD;
if (crc1 == 0 && (crc0 & 0xF000) == 0) return 1;
return 0;
}
/* ------------------------------------------------------------------------------------ */
@ -303,6 +358,12 @@ static int get_GPS(gpx_t *gpx) {
val = i4be(gpx->frame+pos_GPSalt);
gpx->alt = val / 1e1;
// plausibility checks
if (gpx->timems < 0.0 || gpx->timems > 235959999) return -1;
if (gpx->lat < -90.0 || gpx->lat > 90.0) return -2;
if (gpx->lon < -180.0 || gpx->lon > 180.0) return -2;
if (gpx->alt < -400.0 || gpx->alt > 60000.0) return -2;
return 0;
}
@ -332,7 +393,10 @@ static int get_PTU(gpx_t *gpx) {
val = i4be(gpx->frame + pos_PTU_T);
if (*f > -120.0f && *f < 80.0f) gpx->T = *f;
else gpx->T = -273.15f;
if (val == 0x4E6E6B28) count_1e9 += 1;
if (val == 0x4E6E6B28) {
gpx->T = -273.15f;
count_1e9 += 1;
}
// raw RH?
// water vapor saturation pressure (Hyland and Wexler)?
@ -341,13 +405,19 @@ static int get_PTU(gpx_t *gpx) {
if (*f < 0.0f) gpx->_RH = 0.0f;
else if (*f > 100.0f) gpx->_RH = 100.0f;
else gpx->_RH = *f;
if (val == 0x4E6E6B28) count_1e9 += 1;
if (val == 0x4E6E6B28) {
gpx->_RH = -1.0f;
count_1e9 += 1;
}
// temperatur of r.h. sensor?
val = i4be(gpx->frame + pos_PTU_Trh);
if (*f > -120.0f && *f < 80.0f) gpx->Trh = *f;
else gpx->Trh = -273.15f;
if (val == 0x4E6E6B28) count_1e9 += 1;
if (val == 0x4E6E6B28) {
gpx->Trh = -273.15f;
count_1e9 += 1;
}
// (Hyland and Wexler)
if (gpx->T > -273.0f && gpx->Trh > -273.0f) {
@ -389,10 +459,13 @@ static int print_position(gpx_t *gpx, int len, int ecc_frm, int ecc_gps) {
prnPTU = 0,
prnSTS = 0;
int ptu1e9 = 0;
int tp_err = 0;
int pos_ok = 0,
frm_ok = 0;
frm_ok = 0,
crc_ok = 0;
int rs_type = 54;
crc_ok = crc32ok(gpx->frame, len);
pos_ok = (ecc_frm >= 0 && len > pos_STATUS+2);
frm_ok = (ecc_frm >= 0 && len > pos_F8);
@ -401,8 +474,9 @@ static int print_position(gpx_t *gpx, int len, int ecc_frm, int ecc_gps) {
if (len > pos_GPSalt+4)
{
get_SN(gpx);
get_GPS(gpx);
prnGPS = 1;
tp_err = get_GPS(gpx);
if (tp_err == 0) prnGPS = 1;
else frm_ok = 0;
}
if (len > pos_PTU_Trh+4)
{
@ -441,6 +515,10 @@ static int print_position(gpx_t *gpx, int len, int ecc_frm, int ecc_gps) {
if (gpx->RH > -0.5f) fprintf(stdout, " RH=%.0f%% ", gpx->RH);
}
if (gpx->option.vbs) {
if ( crc_ok ) fprintf(stdout, " [OK]"); else fprintf(stdout, " [NO]");
}
// (imet54:GPS+PTU) status: 003E , (imet50:GPS); 0030
if (gpx->option.vbs && prnSTS) {
fprintf(stdout, " [%04X] ", gpx->status);
@ -456,8 +534,9 @@ static int print_position(gpx_t *gpx, int len, int ecc_frm, int ecc_gps) {
}
// prnGPS,prnTPU
if (gpx->option.jsn && frm_ok && (gpx->status&0x30)==0x30) {
if (gpx->option.jsn && frm_ok && crc_ok && (gpx->status&0x30)==0x30) {
char *ver_jsn = NULL;
//char *subtype = (rs_type == 54) ? "IMET54" : "IMET50";
char *subtype = (rs_type == 54) ? "iMet-54" : "iMet-50";
unsigned long count_day = (unsigned long)(gpx->std*3600 + gpx->min*60 + gpx->sek+0.5); // (gpx->timems/1e3+0.5) has gaps
fprintf(stdout, "{ \"type\": \"%s\"", "IMET5");
@ -539,6 +618,7 @@ static void print_frame(gpx_t *gpx, int len, int b2B) {
if (gpx->option.raw == 4 && i % 4 == 3) fprintf(stdout, " ");
}
}
if ( crc32ok(gpx->frame, len) ) fprintf(stdout, " [OK]"); else fprintf(stdout, " [NO]");
if (gpx->option.ecc && ecc_frm != 0) {
fprintf(stdout, " # (%d)", ecc_frm);
fprintf(stdout, " [%d]", ecc_gps);

Wyświetl plik

@ -1001,8 +1001,11 @@ static int print_pos(gpx_t *gpx, int csOK) {
fprintf(stdout, "{ \"type\": \"%s\"", "M10");
fprintf(stdout, ", \"frame\": %lu, ", (unsigned long)(sec_gps0+0.5));
fprintf(stdout, "\"id\": \"%s\", \"datetime\": \"%04d-%02d-%02dT%02d:%02d:%06.3fZ\", \"lat\": %.5f, \"lon\": %.5f, \"alt\": %.5f, \"vel_h\": %.5f, \"heading\": %.5f, \"vel_v\": %.5f, \"sats\": %d",
sn_id, utc_jahr, utc_monat, utc_tag, utc_std, utc_min, utc_sek, gpx->lat, gpx->lon, gpx->alt, gpx->vH, gpx->vD, gpx->vV, gpx->numSV);
fprintf(stdout, "\"id\": \"%s\", \"datetime\": \"%04d-%02d-%02dT%02d:%02d:%06.3fZ\", \"lat\": %.5f, \"lon\": %.5f, \"alt\": %.5f, \"vel_h\": %.5f, \"heading\": %.5f, \"vel_v\": %.5f",
sn_id, utc_jahr, utc_monat, utc_tag, utc_std, utc_min, utc_sek, gpx->lat, gpx->lon, gpx->alt, gpx->vH, gpx->vD, gpx->vV);
if (gpx->type == t_M10) {
fprintf(stdout, ", \"sats\": %d", gpx->numSV);
}
// APRS id, 9 characters
aprs_id[0] = gpx->frame_bytes[pos_SN+2];
aprs_id[1] = gpx->frame_bytes[pos_SN] & 0xF;

Wyświetl plik

@ -1848,6 +1848,12 @@ static int print_position(gpx_t *gpx, int ec) {
if (gpx->freq > 0) fq_kHz = gpx->freq;
fprintf(stdout, ", \"freq\": %d", fq_kHz);
}
// Include frequency derived from subframe information if available.
if (gpx->freq > 0){
fprintf(stdout, ", \"tx_frequency\": %d", gpx->freq );
}
#ifdef VER_JSN_STR
ver_jsn = VER_JSN_STR;
#endif

Wyświetl plik

@ -1518,6 +1518,11 @@ static int print_position(gpx_t *gpx, int ec) { // GPS-Hoehe ueber Ellipsoid
//if (gpx->freq > 0) fq_kHz = gpx->freq; // L-band: option.ngp ?
fprintf(stdout, ", \"freq\": %d", fq_kHz);
}
// Include frequency derived from subframe information if available.
if (gpx->freq > 0){
fprintf(stdout, ", \"tx_frequency\": %d", gpx->freq);
}
#ifdef VER_JSN_STR
ver_jsn = VER_JSN_STR;
#endif