somewhat usable RS92 decoder

This commit is contained in:
Hansi, dl9rdz 2019-06-02 21:19:57 +02:00
parent 01cccdcb75
commit 561da4fe3e
12 changed files with 260 additions and 97 deletions

View File

@ -14,7 +14,8 @@
#include <Scanner.h>
#include <aprs.h>
#include "version.h"
#include <geteph.h>
#include "geteph.h"
#include "rs92gps.h"
// UNCOMMENT one of the constructor lines below
U8X8_SSD1306_128X64_NONAME_SW_I2C *u8x8 = NULL; // initialize later after reading config file
@ -407,9 +408,13 @@ struct st_configitems config_list[] = {
{"tcp.idformat", "DFM ID Format", -2, &sonde.config.tcpfeed.idformat},
{"tcp.highrate", "Rate limit", 0, &sonde.config.tcpfeed.highrate},
{"---", "---", -1, NULL},
/* RS41 decoder settings */
/* decoder settings */
{"rs41.agcbw", "RS41 AGC bandwidth", 0, &sonde.config.rs41.agcbw},
{"rs41.rxbw", "RS41 RX bandwidth", 0, &sonde.config.rs41.rxbw},
{"rs92.rxbw", "RS92 RX (and AGC) bandwidth", 0, &sonde.config.rs92.rxbw},
{"rs92.alt2d", "RS92 2D fix default altitude", 0, &sonde.config.rs92.alt2d},
{"dfm.agcbw", "DFM6/9 AGC bandwidth", 0, &sonde.config.dfm.agcbw},
{"dfm.rxbw", "DFM6/9 RX bandwidth", 0, &sonde.config.dfm.rxbw},
{"---", "---", -1, NULL},
/* Hardware dependeing settings */
{"oled_sda", "OLED SDA (needs reboot)", 0, &sonde.config.oled_sda},
@ -857,7 +862,7 @@ void sx1278Task(void *parameter) {
resetup = false;
sonde.setup();
}
Serial.println("rx task: calling sonde.receive()");
//Serial.println("rx task: calling sonde.receive()");
sonde.receive();
delay(20);
}
@ -1481,7 +1486,7 @@ void wifiConnect(int16_t res) {
static int wifi_cto;
void loopWifiBackground() {
Serial.printf("WifiBackground: state %d\n", wifi_state);
// Serial.printf("WifiBackground: state %d\n", wifi_state);
// handle Wifi station mode in background
if (sonde.config.wifi == 0 || sonde.config.wifi == 2) return; // nothing to do if disabled or access point mode
@ -1648,6 +1653,7 @@ void loopWifiScan() {
sonde.updateDisplayIP();
wifi_state = WIFI_CONNECTED;
geteph();
get_eph("/brdc");
delay(3000);
}
enableNetwork(true);

View File

@ -2,8 +2,8 @@
# Hardware depending settings
#-------------------------------#
# pin: 255=disabled; x=button x+128=touch button
button_pin=0
button2_pin=255
button_pin=130
button2_pin=142
# LED port
led_pout=9
# OLED Setup is depending on hardware of LoRa board
@ -38,9 +38,17 @@ call=N0CALL
passcode=12345
#-------------------------------#
# Sonde specific settings: bandwidth
# valid values: 3100, 3900, 5200, 6300, 7800, 10400, 12500,
# 15600, 20800, 25000, ...
# other values will be rounded up to the next valid value
# rs92.alt2d: default altitude used by RS92 decoder if only 3 sats available
#-------------------------------#
rs41.agcbw=6300
rs41.agcbw=12500
rs41.rxbw=6300
rs92.rxbw=12500
rs92.alt2d=480
dfm.agcbw=20800
dfm.rxbw=10400
#-------------------------------#
# axudp for sending to aprsmap
#-------------------------------#

View File

@ -542,7 +542,7 @@ int32_t SX1278FSK::getFEI()
{
int32_t FEI;
int16_t regval = (readRegister(REG_FEI_MSB)<<8) | readRegister(REG_FEI_LSB);
Serial.printf("feireg: %04x\n", regval);
//Serial.printf("feireg: %04x\n", regval);
FEI = (int32_t)(regval * SX127X_FSTEP);
return FEI;
}
@ -554,7 +554,7 @@ int32_t SX1278FSK::getAFC()
{
int32_t AFC;
int16_t regval = (readRegister(REG_AFC_MSB)<<8) | readRegister(REG_AFC_LSB);
Serial.printf("afcreg: %04x\n", regval);
//Serial.printf("afcreg: %04x\n", regval);
AFC = (int32_t)(regval * SX127X_FSTEP);
return AFC;
}

View File

@ -36,14 +36,14 @@ int DFM::setup(float frequency, int inv)
Serial.println(br);
#endif
if(sx1278.setAFCBandwidth(25000)!=0) {
DFM_DBG(Serial.println("Setting AFC bandwidth 25 kHz FAILED"));
return 1;
}
if(sx1278.setRxBandwidth(12000)!=0) {
DFM_DBG(Serial.println("Setting RX bandwidth 12kHz FAILED"));
return 1;
}
if(sx1278.setAFCBandwidth(sonde.config.dfm.agcbw)!=0) {
DFM_DBG(Serial.printf("Setting AFC bandwidth %d Hz FAILED", sonde.config.dfm.agcbw));
return 1;
}
if(sx1278.setRxBandwidth(sonde.config.dfm.rxbw)!=0) {
DFM_DBG(Serial.printf("Setting RX bandwidth to %d Hz FAILED", sonde.config.dfm.rxbw));
return 1;
}
// Enable auto-AFC, auto-AGC, RX Trigger by preamble
if(sx1278.setRxConf(0x1E)!=0) {
DFM_DBG(Serial.println("Setting RX Config FAILED"));

View File

@ -32,11 +32,12 @@ static unsigned char kmh_tiles[] U8X8_PROGMEM = {
static unsigned char ms_tiles[] U8X8_PROGMEM = {
0x1F, 0x02, 0x04, 0x02, 0x1F, 0x40, 0x20, 0x10, 0x08, 0x04, 0x12, 0xA4, 0xA4, 0xA4, 0x40, 0x00
};
static unsigned char stattiles[4][4] = {
static unsigned char stattiles[5][4] = {
0x00, 0x1F, 0x00, 0x00 , // | == ok
0x00, 0x10, 0x10, 0x00 , // . == no header found
0x1F, 0x15, 0x15, 0x00 , // E == decode error
0x00, 0x00, 0x00, 0x00 }; // ' ' == unknown/unassigned
0x00, 0x00, 0x00, 0x00 , // ' ' == unknown/unassigned
0x07, 0x05, 0x07, 0x00 }; // ° = rx ok, but no valid position
//static uint8_t halfdb_tile[8]={0x80, 0x27, 0x45, 0x45, 0x45, 0x39, 0x00, 0x00};

View File

@ -103,11 +103,11 @@ int RS41::setup(float frequency)
#endif
if(sx1278.setAFCBandwidth(sonde.config.rs41.agcbw)!=0) {
RS41_DBG(Serial.println("Setting AFC bandwidth 25 kHz FAILED"));
RS41_DBG(Serial.printf("Setting AFC bandwidth %d Hz FAILED", sonde.config.rs41.agcbw));
return 1;
}
if(sx1278.setRxBandwidth(sonde.config.rs41.rxbw)!=0) {
RS41_DBG(Serial.println("Setting RX bandwidth 12kHz FAILED"));
RS41_DBG(Serial.printf("Setting RX bandwidth to %d Hz FAILED", sonde.config.rs41.rxbw));
return 1;
}
// Enable auto-AFC, auto-AGC, RX Trigger by preamble

View File

@ -76,6 +76,20 @@ static void Gencrctab(void)
} /* end for */
} /* end Gencrctab() */
static byte data1[512]={0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x10};
static byte data2[512]={0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x10};
static byte *dataptr=data1;
static uint8_t rxbitc;
static int32_t asynst[10]={0};
static uint16_t rxbyte;
int rxp=0;
static int haveNewFrame = 0;
static int lastFrame = 0;
static int headerDetected = 0;
int RS92::setup(float frequency)
{
#if RS92_DEBUG
@ -84,7 +98,7 @@ int RS92::setup(float frequency)
if(!initialized) {
Gencrctab();
initrsc();
get_eph("/brdc.19n");
// not here for now.... get_eph("/brdc.19n");
initialized = true;
}
@ -105,15 +119,15 @@ int RS92::setup(float frequency)
Serial.print("Exact bitrate is ");
Serial.println(br);
#endif
if(sx1278.setAFCBandwidth(sonde.config.rs92.rxbw)!=0) {
RS92_DBG(Serial.printf("Setting AFC bandwidth %d Hz FAILED", sonde.config.rs92.rxbw));
return 1;
}
if(sx1278.setRxBandwidth(sonde.config.rs92.rxbw)!=0) {
RS92_DBG(Serial.printf("Setting RX bandwidth to %d Hz FAILED", sonde.config.rs92.rxbw));
return 1;
}
if(sx1278.setAFCBandwidth(sonde.config.rs41.agcbw)!=0) {
RS92_DBG(Serial.println("Setting AFC bandwidth 25 kHz FAILED"));
return 1;
}
if(sx1278.setRxBandwidth(sonde.config.rs41.rxbw)!=0) {
RS92_DBG(Serial.println("Setting RX bandwidth 12kHz FAILED"));
return 1;
}
// Enable auto-AFC, auto-AGC, RX Trigger by preamble
if(sx1278.setRxConf(0x1E)!=0) {
RS92_DBG(Serial.println("Setting RX Config FAILED"));
@ -345,8 +359,10 @@ void RS92::decodeframe92(uint8_t *data)
//int calok;
//int mesok;
//uint32_t calibok;
Serial.printf("rs corr is %d\n", corr);
print_frame(data, 240);
lastFrame = (dataptr==data1)?1:2;
Serial.printf("rs corr is %d --- data:%p data1:%p data2:%p lastframe=%d\n", corr, data, data1, data2, lastFrame);
dataptr = (dataptr==data1)?data2:data1;
//print_frame(data, 240);
#if 0
/* from sondemod*/
int p=6;
@ -458,19 +474,10 @@ static uint8_t scramble[64] = {150U,131U,62U,81U,177U,73U,8U,152U,50U,5U,89U,
193U};
#endif
static byte data[5000]={0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x10};
static uint8_t rxbitc;
static int32_t asynst[10]={0};
static uint16_t rxbyte;
int rxp=0;
static int haveNewFrame = 0;
static int headerDetected = 0;
void RS92::stobyte92(uint8_t b)
{
data[rxp] = b;
dataptr[rxp] = b;
if(rxp>=5 || b=='*') rxp++; else rxp=0;
if(rxp==6) { // header detected
headerDetected = 1;
@ -478,7 +485,7 @@ void RS92::stobyte92(uint8_t b)
if(rxp>=240) { // frame complete... (240 byte)
rxp=0;
//printRaw(data, 240);
decodeframe92(data);
decodeframe92(dataptr);
haveNewFrame = 1;
}
} /* end stobyte92() */
@ -506,9 +513,9 @@ void RS92::process8N1data(uint8_t dt)
int rssi=sx1278.getRSSI();
int fei=sx1278.getFEI();
int afc=sx1278.getAFC();
Serial.print("Test: RSSI="); Serial.println(rssi);
Serial.print("Test: FEI="); Serial.println(fei);
Serial.print("Test: AFC="); Serial.println(afc);
Serial.print("Test: RSSI="); Serial.print(rssi);
Serial.print(" FEI="); Serial.print(fei);
Serial.print(" AFC="); Serial.println(afc);
sonde.si()->rssi = rssi;
sonde.si()->afc = afc;
}
@ -516,14 +523,14 @@ void RS92::process8N1data(uint8_t dt)
rxbitc = (rxbitc+1)%20;
if(rxbitc == 0) { // got startbit, 8 data bit, stop bit
//Serial.printf("%03x ",rxbyte);
data[rxp++] = (rxbyte>>1)&0xff;
if(rxp==7 && data[6] != 0x65) {
Serial.printf("wrong start: %02x\n",data[6]);
dataptr[rxp++] = (rxbyte>>1)&0xff;
if(rxp==7 && dataptr[6] != 0x65) {
Serial.printf("wrong start: %02x\n",dataptr[6]);
rxsearching = true;
}
if(rxp>=240) {
rxsearching = true;
decodeframe92(data);
decodeframe92(dataptr);
haveNewFrame = 1;
}
}
@ -602,6 +609,19 @@ int RS92::receive() {
#define RS92MAXLEN (240)
int RS92::waitRXcomplete() {
// called after complete...
Serial.printf("decoding frame %d\n", lastFrame);
print_frame(lastFrame==1?data1:data2, 240);
SondeInfo *si = sonde.sondeList+sonde.currentSonde;
si->lat = gpx.lat;
si->lon = gpx.lon;
si->alt = gpx.alt;
si->vs = gpx.vU;
si->hs = gpx.vH;
si->dir = gpx.vD;
si->validPos = 0x3f;
#if 0
int res=0;
uint32_t t0 = millis();

View File

@ -67,8 +67,12 @@ Sonde::Sonde() {
config.marker=0;
config.showafc=0;
config.freqofs=0;
config.rs41.agcbw=25000;
config.rs41.rxbw=12000;
config.rs41.agcbw=12500;
config.rs41.rxbw=6300;
config.rs92.rxbw=12500;
config.rs92.alt2d=480;
config.dfm.agcbw=20800;
config.dfm.rxbw=10400;
config.udpfeed.active = 1;
config.udpfeed.type = 0;
strcpy(config.udpfeed.host, "192.168.42.20");
@ -145,6 +149,14 @@ void Sonde::setConfig(const char *cfg) {
config.rs41.agcbw = atoi(val);
} else if(strcmp(cfg,"rs41.rxbw")==0) {
config.rs41.rxbw = atoi(val);
} else if(strcmp(cfg,"dfm.agcbw")==0) {
config.dfm.agcbw = atoi(val);
} else if(strcmp(cfg,"dfm.rxbw")==0) {
config.dfm.rxbw = atoi(val);
} else if(strcmp(cfg,"rs92.alt2d")==0) {
config.rs92.alt2d= atoi(val);
} else if(strcmp(cfg,"rs92.rxbw")==0) {
config.rs92.rxbw = atoi(val);
} else if(strcmp(cfg,"axudp.active")==0) {
config.udpfeed.active = atoi(val)>0;
} else if(strcmp(cfg,"axudp.host")==0) {
@ -326,23 +338,20 @@ rxloop:
}
rxtask.receiveResult = 0xFFFF;
Serial.printf("waitRXcomplete returning %04x (%s)\n", res, RXstr[res&0xff]);
#if 0
//currently not used...
{
int res;
switch(sondeList[rxtask.currentSonde].type) {
// currently used only by RS92
// TODO: rxtask.currentSonde might not be the right thing (after sonde channel change)
switch(sondeList[/*rxtask.*/currentSonde].type) {
case STYPE_RS41:
res = rs41.waitRXcomplete();
rs41.waitRXcomplete();
break;
case STYPE_RS92:
res = rs92.waitRXcomplete();
rs92.waitRXcomplete();
break;
case STYPE_DFM06:
case STYPE_DFM09:
res = dfm.waitRXcomplete();
dfm.waitRXcomplete();
break;
}
#endif
memmove(sonde.si()->rxStat+1, sonde.si()->rxStat, 17);
sonde.si()->rxStat[0] = res;
return res;

View File

@ -7,7 +7,7 @@
// RX_TIMEOUT: no header detected
// RX_ERROR: header detected, but data not decoded (crc error, etc.)
// RX_OK: header and data ok
enum RxResult { RX_OK, RX_TIMEOUT, RX_ERROR, RX_UNKNOWN };
enum RxResult { RX_OK, RX_TIMEOUT, RX_ERROR, RX_UNKNOWN, RX_NOPOS };
#define RX_UPDATERSSI 0xFFFE
// Events that change what is displayed (mode, sondenr)
@ -70,6 +70,14 @@ struct st_rs41config {
int agcbw;
int rxbw;
};
struct st_rs92config {
int rxbw;
int alt2d;
};
struct st_dfmconfig {
int agcbw;
int rxbw;
};
typedef struct st_rdzconfig {
int button_pin; // PIN port number menu button (+128 for touch mode)
@ -96,6 +104,8 @@ typedef struct st_rdzconfig {
char call[9]; // APRS callsign
char passcode[9]; // APRS passcode
struct st_rs41config rs41; // configuration options specific for RS41 receiver
struct st_rs92config rs92;
struct st_dfmconfig dfm;
// for now, one feed for each type is enough, but might get extended to more?
struct st_feedinfo udpfeed; // target for AXUDP messages
struct st_feedinfo tcpfeed; // target for APRS-IS TCP connections
@ -103,7 +113,7 @@ typedef struct st_rdzconfig {
typedef struct st_sondeinfo {
// receiver configuration
bool active;
bool active;
SondeType type;
float freq;
// decoded ID
@ -116,7 +126,7 @@ typedef struct st_sondeinfo {
float alt; // altitude
float vs; // vertical speed
float hs; // horizontal speed
float dir; // 0..360
float dir; // 0..360
uint8_t validPos; // bit pattern for validity of above 6 fields
// RSSI from receiver
int rssi; // signal strength
@ -128,7 +138,7 @@ typedef struct st_sondeinfo {
uint32_t viewStart; // millis() timestamp of viewinf this sonde with current display
int8_t lastState; // -1: disabled; 0: norx; 1: rx
} SondeInfo;
// rxStat: 0=undef[empty] 1=timeout[.] 2=errro[E] 3=ok[1]
// rxStat: 3=undef[empty] 1=timeout[.] 2=errro[E] 3=ok[1] 5=no valid position[°]
#define MAXSONDE 99

View File

@ -384,6 +384,20 @@ EPHEM_t *read_RNXpephs(const char *file) {
ephem.week = 1; // ephem.gpsweek
Serial.printf("Reading ephem for prn %d\n", ui);
if(ui<33) {
#if 0
// no need to do it the difficult way, most recent data is at end of file :-)
double tdiff;
if(te[ui].prn!=ui) {
tdiff = WEEKSEC;
} else {
tdiff = now - te[ui].toe;
if(tdiff>WEEKSEC/2) tdiff -= WEEKSEC;
if(tdiff<-WEEKSEC/2) tdiff += WEEKSEC;
}
double td = now - ephem.toe;
if(td>WEEKSEC/2) td -= WEEKSEC;
if(td<-WEEKSEC/2) td += WEEKSEC;
#endif
te[ui] = ephem;
} else {
Serial.printf("bad prn: %d\n", ui);

View File

@ -50,28 +50,10 @@
#include <SPIFFS.h>
#include "nav_gps_vel.h"
#ifdef CYGWIN
#include <fcntl.h> // cygwin: _setmode()
#include <io.h>
#endif
#include "rs92gps.h"
#include "Sonde.h"
typedef struct {
int frnr;
char id[11];
int week; int gpssec;
int jahr; int monat; int tag;
int wday;
int std; int min; float sek;
double lat; double lon; double alt;
double vH; double vD; double vU;
int sats[4];
double dop;
int freq;
unsigned short aux[4];
double diter;
} gpx_t;
gpx_t gpx;
@ -91,6 +73,7 @@ int option_verbose = 0, // ausfuehrliche Anzeige
rawin = 0;
double dop_limit = 9.9;
double d_err = 10000;
//double fixalt2d = 480; // bei mir zu Hause :-) TODO: make it configurable
int rollover = 0,
err_gps = 0;
@ -550,6 +533,7 @@ int get_GPStime() {
gpstime /= 1000;
gpx.gpssec = gpstime;
Serial.printf("GPS time is %04x (%d)\n", gpstime, gpstime);
day = (gpstime / (24 * 3600)) % 7; // besser CRC-check, da auch
//if ((day < 0) || (day > 6)) return -1; // gpssec=604800,604801 beobachtet
@ -901,6 +885,8 @@ const double df = 299792.458/1023.0/1024.0; //0.286183844 // c=299792458m/s, 102
// dl = L1/(chips/sec)/4
const double dl = 1575.42/1.023/4.0; //385.0 // GPS L1 1575.42MHz=154*10.23MHz, dl=154*10/4
double pr_ofs;
double GPSsatAlt = 20200e3;
int get_pseudorange() {
uint32_t gpstime;
@ -919,10 +905,12 @@ int get_pseudorange() {
memcpy(&gpstime, gpstime_bytes, 4);
// Sat Status
Serial.print("Sat status: ");
for (i = 0; i < 12; i++) {
sat_status[i] = framebyte(posGPS_STATUS + i);
Serial.printf("sat status %d: %d\n", i, sat_status[i]);
Serial.printf("%d:%d ", i, sat_status[i]);
}
Serial.print("\n");
// PRN-Nummern
for (i = 0; i < 4; i++) {
@ -953,7 +941,7 @@ int get_pseudorange() {
pseudobytes[i] = frame[posGPS_DATA+8*j+i];
}
memcpy(&chipbytes, pseudobytes, 4);
Serial.printf("Chipbytes(%d): %04x\n",j, chipbytes);
//Serial.printf("Chipbytes(%d): %04x\n",j, chipbytes);
// delta_pseudochips / 385
for (i = 0; i < 3; i++) {
@ -985,9 +973,9 @@ int get_pseudorange() {
continue;
}
*/
Serial.printf("j=%d: prns=%d status=%d dist=%f\n", j, prns[j], sat_status[j], dist(sat[prns[j]].X, sat[prns[j]].Y, sat[prns[j]].Z, 0, 0, 0));
int o=prns[j];
Serial.printf("x=%f y=%f z=%f\n", sat[o].X, sat[o].Y, sat[o].Z);
Serial.printf("j=%d: prns=%d status=%d dist=%f\n ", j, prns[j], sat_status[j], dist(sat[prns[j]].X, sat[prns[j]].Y, sat[prns[j]].Z, 0, 0, 0));
//int o=prns[j];
//Serial.printf("x=%f y=%f z=%f\n", sat[o].X, sat[o].Y, sat[o].Z);
if ( (prns[j] > 0) && ((sat_status[j] & 0x0F) == 0xF)
&& (dist(sat[prns[j]].X, sat[prns[j]].Y, sat[prns[j]].Z, 0, 0, 0) > 6700000) )
{
@ -1020,12 +1008,13 @@ int get_pseudorange() {
prj = sat[prn[j]].pseudorange + sat[prn[j]].clock_corr;
if (prj < pr0) pr0 = prj;
}
for (j = 0; j < k; j++) sat[prn[j]].PR = sat[prn[j]].pseudorange + sat[prn[j]].clock_corr - pr0 + 20e6;
for (j = 0; j < k; j++) sat[prn[j]].PR = sat[prn[j]].pseudorange + sat[prn[j]].clock_corr - pr0 + GPSsatAlt;
// es kann PRNs geben, die zeitweise stark abweichende PR liefern;
// eventuell Standardabweichung ermitteln und fehlerhafte Sats weglassen
for (j = 0; j < k; j++) { // sat/sat1s... PR-check
sat1s[prn[j]].PR = sat1s[prn[j]].pseudorange + sat[prn[j]].clock_corr - pr0 + 20e6;
sat1s[prn[j]].PR = sat1s[prn[j]].pseudorange + sat[prn[j]].clock_corr - pr0 + GPSsatAlt;
}
pr_ofs = pr0;
return k;
}
@ -1049,6 +1038,80 @@ int get_GPSvel(double lat, double lon, double vel_ecef[3],
double DOP[4];
int naiv_2Dfix(int N, SAT_t sats[], double alt) {
// simple 2D fix: 3 Sats & Alt above ellipsoid
//
// - fuer 3 unbekannte lat, lon, t braucht man mind. 3 Satelliten
// - fuer Iteration braucht man jedoch einen Startwert
// - es gibt direkte Methoden
// - hier werden die vorhandenen Funktionen benutzt:
// - der 4. Satellit im Erdmittelpunkt
// - seine pseudorange(+clock) wird grob geschaetzt
// (pseudochips liefern erst Rueckschluesse, wenn man Position kennt)
// - dann approximieren, bis Hoehe stimmt
// - bei 3-4 Satelliten ist die DOP-Konstellation oft schlecht
// - moeglicherweise ist in einigen Faellen die 2. Loesung besser
double radius = 6371e3 + alt; // wird dann approximiert
double lat2d, lon2d, alt2d,
pos_ecef[3], rx_cl_bias,
dpos_ecef[3];
//double d;
double rofs = 200000.0, rdiff = 0.0;
int k, k_limit;
double gdop = -1;
sats[3].X = sats[3].Y = sats[3].Z = 0;
k = 0;
k_limit = 100;
if (N >= 3) {
do
{
// PR = pseudorange + clock_corr - pr_ofs + GPSsatAlt
sats[3].X = sats[3].Y = sats[3].Z = 0;
sats[3].PR = radius - rofs;
sats[3].pseudorange = sats[3].PR + pr_ofs - GPSsatAlt;
NAV_bancroft1(4, sats, pos_ecef, &rx_cl_bias);
//NAV_bancroft3(4, sats, pos_ecef1, &rx_cl_bias1, pos_ecef2, &rx_cl_bias2);
ecef2elli(pos_ecef[0], pos_ecef[1], pos_ecef[2], &lat2d, &lon2d, &alt2d);
rdiff = alt-alt2d;
rofs -= rdiff*1.2;
k += 1;
} while (k < k_limit && fabs(rdiff) > 1.0);
NAV_LinP(4, sats, pos_ecef, rx_cl_bias, dpos_ecef, &rx_cl_bias);
// for (j=0;j<3;j++) pos_ecef[j] += dpos_ecef[j];
// NAV_LinP(4, sats, pos_ecef, rx_cl_bias, dpos_ecef, &rx_cl_bias);
// d = dist(0, 0, 0, dpos_ecef[0], dpos_ecef[1], dpos_ecef[2]);
}
if (calc_DOPn(4, sats, pos_ecef, DOP) == 0) {
gdop = sqrt(DOP[0]+DOP[1]+DOP[2]+DOP[3]);
}
//if (gdop > 2*dop_limit) gdop = -1;
//if (gdop < 0) gdop = -1;
gpx.lat = lat2d;
gpx.lon = lon2d;
gpx.alt = alt2d;
gpx.dop = gdop;
if ( fabs(alt2d-alt) > 1000.0 ) return -1;
if ( k == k_limit ) return 0;
return 1;
}
int get_GPSkoord(int N) {
double lat, lon, alt, rx_cl_bias;
double vH, vD, vU;
@ -1281,8 +1344,8 @@ int get_GPSkoord(int N) {
int print_position() { // GPS-Hoehe ueber Ellipsoid
int j, k, n = 0;
int err1, err2;
int j, k = 0, n = 0;
int err1, err2, fix2d = 0;
err1 = 0;
if (!option_verbose) err1 = err_gps;
@ -1293,13 +1356,22 @@ int print_position() { // GPS-Hoehe ueber Ellipsoid
//err2 |= get_GPSweek();
err2 |= get_GPStime();
#if 0
Serial.printf("ephem=%d\n",ephem);
Serial.printf("print_position: ephs is %p\n", ephs);
#endif
if (!err2 && (almanac || ephem)) {
k = get_pseudorange();
Serial.printf("k=%d\n", k);
if (k >= 4) {
n = get_GPSkoord(k);
}
if (k == 3) {
SAT_t Sat_A[4];
for (j = 0; j < 3; j++) { Sat_A[j] = sat[prn[j]]; }
fix2d = naiv_2Dfix( 3, Sat_A, sonde.config.rs92.alt2d);
}
}
if (!err1) {
@ -1316,7 +1388,11 @@ int print_position() { // GPS-Hoehe ueber Ellipsoid
fprintf(stdout, "%s ", weekday[gpx.wday]); // %04.1f: wenn sek >= 59.950, wird auf 60.0 gerundet
fprintf(stdout, "%02d:%02d:%06.3f", gpx.std, gpx.min, gpx.sek);
if (n > 0) {
if (k == 3 && fix2d > 0 && gpx.dop > 0 && gpx.dop < 2*dop_limit) {
fprintf(stdout, " 2D lat: %.5f lon: %.5f alt: %.1f ", gpx.lat, gpx.lon, gpx.alt);
fprintf(stdout, " DOP[%02d,%02d,%02d,0] %.1f ", prn[0], prn[1], prn[2], gpx.dop);
}
else if (n > 0) {
fprintf(stdout, " ");
if (almanac) fprintf(stdout, " lat: %.4f lon: %.4f alt: %.1f ", gpx.lat, gpx.lon, gpx.alt);
@ -1386,7 +1462,8 @@ void print_frame(uint8_t *data, int len) {
}
fprintf(stdout, "\n");
}
else print_position();
//Serial.printf("print_frame: ephs is %p\n", ephs);
print_position();
}
void get_eph(const char *file) {
@ -1395,7 +1472,7 @@ void get_eph(const char *file) {
ephem = 1;
almanac = 0;
}
Serial.printf("reading RNX done, result is %d\n", ephem);
Serial.printf("reading RNX done, result is %d, ephs=%p\n", ephem, ephs);
if (!option_der) d_err = 1000;
}

View File

@ -1,3 +1,21 @@
typedef struct {
int frnr;
char id[11];
int week; int gpssec;
int jahr; int monat; int tag;
int wday;
int std; int min; float sek;
double lat; double lon; double alt;
double vH; double vD; double vU;
int sats[4];
double dop;
int freq;
unsigned short aux[4];
double diter;
} gpx_t;
extern gpx_t gpx;
void print_frame(uint8_t *data, int len);
void get_eph(const char *file);