GPS L1 Qualität Abschätzung Berechnungsmethode (Geodäsie/Vermessung)

Ulrich, Donnerstag, 09. Februar 2017, 15:08 (vor 11 Tagen)

Hallo GEO-Forum,
Ich zeichne mit Ashtech ProMark2 Empfängern L1 Rohdaten auf und werte sie per Postprocessing aus. Eine sehr wichtige Funktion dabei ist die „Entfernungsanzeige“ die angibt für welche Länge der Basislinienberechnung bereits Daten gesammelt wurden (5km, 10km, 20+km). Diese Anzeige arbeitet sehr zuverlässig, denn je nach Aufstellort/-zeit sind die Messzeiten unterschiedlich bedingt durch Abschattung, Satellitenkonstellation etc. . Werden z.B. 5km angezeigt sind genügend gut Rohdaten gesammelt um Basislinien zu weiteren L1 Empfängern bis zu einer Entfernung von 5km zu berechnen (Genauigkeit 5mm+1ppm). Diese Anzeige ist in 99% aller Fälle zuverlässig. Weiss jemand im Forum welche Berechnungsmethode hinter dieser „Abschätzung“ der Datenqualität steht die ja während der Messung die Rohdaten auswertet?

Beste Grüße

Ulrich

GPS L1 Qualität Abschätzung Berechnungsmethode

Ulrich, Freitag, 10. Februar 2017, 13:00 (vor 10 Tagen) @ Ulrich

Falls es hilft, hier ein Link zum Manual des ProMark2.

ProMark2 Manual

Der survey status screen den ich meine ist auf Seite 55 zu finden. Dort sind beim Obs.timer "0 MI" zu sehen. Da müssen noch einige Daten gesammelt werden.

Um ein System ähnlich dem ProMark2 zusammenzustellen sollte wohl ein U-Blox M8P Modul mit Arduinoanbindung (Screen & SD-card) und eine geod. L1-Antenne ausreichend sein?

GPS L1 Qualität Abschätzung Berechnungsmethode

Ulrich, Montag, 13. Februar 2017, 10:59 (vor 7 Tagen) @ Ulrich

Eigentlich hatte ich mir das einfacher vorgestellt hier eine Antwort zu bekommen, denn es geht ja um Mathematik und Statistik, hier nun die Puzzleteile die ich gefunden habe:

zum allgemeinen Thema Genauigkeiten beim GPS: http://www.kowoma.de/gps/Genauigkeit.htm

Mich interessiert aber die Abschätzung der Qualität der gesammelten GPS Epochen nach einer Standzeit (z.B. 20 Minuten) zum berechnen einer Basislinie zwischen zwei statischen GPS (L1 Messung). Hier muß also etwas Statistik getrieben werden. Die anfallenden Informationen pro Epoche müssen ausgewertet werden, aber nach welcher Methode? Ist es SEP - Spherical Error Probability wie z.B. hier beschrieben: GPS accuracies and errors

Hat jemand Erfahrung hiermit?

Avatar

GPS L1 Qualität Abschätzung Berechnungsmethode

MichaeL ⌂, Bad Vilbel, Montag, 13. Februar 2017, 11:08 (vor 7 Tagen) @ Ulrich

Hallo,

Eigentlich hatte ich mir das einfacher vorgestellt hier eine Antwort zu bekommen, denn es geht ja um Mathematik und Statistik

Nein, es geht um eine Blackbox, für die Du gern eine Whitebox hättest. Einzig der Hersteller wird Dir zuverlässig sagen können, was er konkret umgesetzt hat. Warum fragst Du dort nicht einfach mal nach, wenn Dir die Dokumentation aus dem Handbuch nicht reicht?

/Micha

--
freie Tools zur Netzausgleichung, Transformation und Formanalyse

GPS L1 Qualität Abschätzung Berechnungsmethode

Ulrich, Montag, 13. Februar 2017, 11:55 (vor 7 Tagen) @ MichaeL

Hallo Michael,
vielen Dank für Deine Anregung Herrn Spectra Precision alias Ashtech zu fragen wer hier welchen Algorithmus 1993 beim Promark2 verwendet hat, das habe ich bereits auf so einigen Intergeo's probiert. Ohne Erfolg.

Wie ein Polygonzug gerechnet wird weiß heute jeder, wie ein Nivellement ausgeglichen wird auch. Wie Netze mit GPS gemessen werden...na da hapert es schon ein wenig. Hier sind fast alle Vermesser die ich draußen mit L1/L2 RTK Ausrüstung treffe reine Bediener. Lediglich die lokale Transformation scheint noch nachvollzogen zu werden.

Wie messe ich Netze kostengünstig in Gegenden in denen ich kein RTK (GSM-Netz) zur Verfügung habe? Von Basel bis Offenburg, deutsche + französiche Seite ? Einfachste Lösung Statisch mit L1 Empfängern. Langsam aber präzise!! Einfachste Bedienung !!!

Nehme ich heute einen U-Blox Empfänger (z.B. von Drotek M8P board) eine geodätische L1-Antenne und einen Arduino zur Datenspeicherung/Display/Bedieneinheit, dann habe ich eine Einheit die sehr gut für statische Messungen geeignet ist und als Ergebnis RINEX Daten liefert die problemlos in ein Ausgleichungsprogramm einfließen können.

Das hat jetzt nichts mehr mit "Blackbox" zu tun sondern mich interessiert die Mathematik die dahinter steckt ausreichend GPS Epochen gesammelt zu haben. Das sollte heute genauso nachvollziehbar sein wie ein Nivellement?! Die Darstellung im ProMark 2 von damals ist lediglich ein Beispiel.

Avatar

GPS L1 Qualität Abschätzung Berechnungsmethode

MichaeL ⌂, Bad Vilbel, Montag, 13. Februar 2017, 12:10 (vor 7 Tagen) @ Ulrich

Hallo,

Wie ein Polygonzug gerechnet wird weiß heute jeder, wie ein Nivellement ausgeglichen wird auch. Wie Netze mit GPS gemessen werden...na da hapert es schon ein wenig.

Nunja, ich finde, der Vergleich hinkt. Bei den ersten beiden "Verfahren" arbeitest Du mit den Größen, die Dir das Instrument bereits aufbereitet hat und ausgibt. Dich interessiert aber nicht, _wie_ diese Werte zustandegekommen sind bzw. hinterfragst Du es nicht. Du arbeitest also bereits mit vorprozessierten Daten und nimmst das so hin. Deine Frage zielt aber genau auf diese interne Vorprozessierung ab. Theoretisch wird ein räumlicher Bogenschnitt bestimmt aber das wird Dich bei Deiner Fragestellung nicht weiterbringen. Die Zuverlässigkeit wird durch Mehrfachmessung erreicht, die im einfachsten Fall dann gemittelt wird. Aus dieser lassen sich Konfidenzbereiche bestimmen. Das sind die mathematischen und statischen Verfahren aber wie konkret diese in Deinem Empfänger umgesetzt sind, wird hierdurch eben nicht ersichtlich, weshalb nur der Hersteller Dir hier zielführend eine Auskunft geben kann.

Viele Grüße
Micha

--
freie Tools zur Netzausgleichung, Transformation und Formanalyse

GPS L1 Qualität Abschätzung Berechnungsmethode

Ulrich, Freitag, 17. Februar 2017, 16:40 (vor 3 Tagen) @ MichaeL

Hallo Michael,

GPS ist schon lange keine "blackbox" mehr sondern die verschiedenen Chips liefern standardisierte Daten die geodätisch ausgewertet werden können. U-Blox chips (z.B. M8P) für einen sehr erschwinglichen Preis liefern bereits mm Genauigkeit sogar in RTK Anwendungen U-box Präzision für den Massenmarkt.

Diese billigen Chips liefern für statische Beobachtungen RINEX Daten die mit Standardanwendungen (RTKLIB) im Postprocessing ausgewertet werden können. Da ist nichts proprietär. Nach einer Stunde statischer Beobachtung auf einem Punkt kommt man gut in den mm Bereich einer Basislinie zwischen zwei GPS Antennen (bis 2km).

Neben den präzisen Daten liefern diese Chips aber auch die NMEA Datensätze und ich hatte mir erhofft das sich jemand damit beschäftigt mittels dieser einfachen NMEA Meldungen einen Beobachtungstimer, der während Messung abgelesen wird, entwickelt zu haben.

Na ja, wenn ich eine Lösung gefunden habe werde ich es hier posten.

Bis dahin

Gruß

Ulrich

Avatar

GPS L1 Qualität Abschätzung Berechnungsmethode

MichaeL ⌂, Bad Vilbel, Freitag, 17. Februar 2017, 17:02 (vor 3 Tagen) @ Ulrich

Hallo,

GPS ist schon lange keine "blackbox" mehr sondern die verschiedenen Chips liefern standardisierte Daten die geodätisch ausgewertet werden können.

Das habe ich auch nicht angezweifelt. Dennoch kommst Du, wie Du selbst schon zugegeben hast, eben nicht an die Datenverarbeitung heran, die von der Firmware vorgenommen wird.

Diese billigen Chips liefern für statische Beobachtungen RINEX Daten die mit Standardanwendungen (RTKLIB) im Postprocessing ausgewertet werden können.

Ich weiß, aber das sind ja bereits Daten, die intern Aufbereitet wurden durch die Firmeware. Ich hatte Deine Frage so verstanden, dass Du wissen willst, nach welchen Kriterien entscheiden wird, Basislinien bestimmter Länge zu prozessieren.

Neben den präzisen Daten liefern diese Chips aber auch die NMEA Datensätze und ich hatte mir erhofft das sich jemand damit beschäftigt mittels dieser einfachen NMEA Meldungen einen Beobachtungstimer, der während Messung abgelesen wird, entwickelt zu haben.

Das Auslesen von bspw. u-blox stellt ja auch kein Problem dar und habe ich auch schon gemacht und die NMEA abgegriffen mit bspw. 1 Hz. Und natürlich kann ich nun diese Daten über einen Zeitraum sammeln und dann mitteln und Dir eine Genauigkeit ausrechnen. Dass kann ich Dir gern zur Verfügung stellen, wenn es Dir weiterhilft - siehe unten.

Viele Grüße
Micha

package com.derletztekick.geodesy.instrument.gnss.ublox;
 
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
import java.util.TooManyListenersException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import gnu.io.UnsupportedCommOperationException;
 
import com.derletztekick.geodesy.instrument.gnss.GNSSLogger;
import com.derletztekick.geodesy.instrument.gnss.GNSSPosition;
 
public class TEPUB353 extends GNSSLogger {
 private class SerialReader implements SerialPortEventListener {
  // http://aprs.gids.nl/nmea/
  private String responseMessageGPGGA = "";
  private Calendar systemDate = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
  @Override
 
  public synchronized void serialEvent(SerialPortEvent event) {   
   if (event.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
    byte[] readBuffer = new byte[0xFFFF];
 
    try {
     int readBytes;
     String resStr = new String();
     while (inputStream.available() > 0) {
      readBytes = inputStream.read(readBuffer);
      resStr = new String(readBuffer, 0, readBytes);
      this.responseMessageGPGGA += resStr;
     }
 
     int beginIndex = this.responseMessageGPGGA.lastIndexOf("$GPGGA");
     int endIndex   = this.responseMessageGPGGA.lastIndexOf("\n");
     this.systemDate = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
 
     if (beginIndex != -1 && endIndex != -1 && beginIndex < endIndex) {
      lastPosition = exploidResponse(this.responseMessageGPGGA.substring(beginIndex, endIndex));
      this.responseMessageGPGGA = "";
     }
    } 
    catch (IOException e) {
     this.responseMessageGPGGA = "";
     System.err.println("Fehler beim Datenempfang!");
     e.printStackTrace();
    }
   }
  }
  // $GPGGA,hhmmss.ss,llll.ll,a,yyyyy.yy,a
  // $GPGGA,153933.00,5011.28964,N,00844.51181,E,1,08,1.08,103.7,M,47.5,M,,*50
  private GNSSPosition exploidResponse(String response) {
   GNSSPosition gnssPosition = null;
   Calendar receivedDate = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
   String regexp = new String("^\\$GPGGA,(\\d{2})(\\d{2})(\\d{2})\\.(\\d*),");
   Pattern pattern = Pattern.compile(regexp);
   Matcher matcher = pattern.matcher(response);
   if (matcher != null && matcher.find() && matcher.groupCount() >= 4) { // 10
    int hh    = Integer.parseInt(matcher.group(1), 10);
    int mm    = Integer.parseInt(matcher.group(2), 10);
    int ss    = Integer.parseInt(matcher.group(3), 10);
    int SS    = Integer.parseInt(matcher.group(4), 10)*10;
 
    receivedDate.set(Calendar.HOUR_OF_DAY, hh);
    receivedDate.set(Calendar.MINUTE, mm);
    receivedDate.set(Calendar.SECOND, ss);
    receivedDate.set(Calendar.MILLISECOND, SS);
 
    double latitude = 0, longitude = 0;
    char ns = 'N', ew = 'E';
    gnssPosition = new GNSSPosition(
      latitude, 
      GNSSPosition.GeographicDirectionLatitude.getGeographicDirectionLatitudeByChar(ns),
      longitude, 
      GNSSPosition.GeographicDirectionLongitude.getGeographicDirectionLongitudeByChar(ew), 
      new Date(receivedDate.getTimeInMillis()), 
      new Date(systemDate.getTimeInMillis()));
   }
 
   return gnssPosition;
 
  }  
 }
 
 private GNSSPosition lastPosition;
 private int baudRate = 9600; //4800; //9600;
 private int dataBits = SerialPort.DATABITS_8;
 private int stopBits = SerialPort.STOPBITS_1;
 private int parity   = SerialPort.PARITY_NONE;
 private CommPortIdentifier portId;
 private SerialPort serialPort;
 
 private InputStream  inputStream;
 private OutputStream outputStream;
 
 public CommPortIdentifier getCommPortIdentifier() {
  return portId;
 }
 
 public int getBaudRate() {
  return baudRate;
 }
 
 public int getDataBits() {
  return dataBits;
 }
 
 public int getStopBits() {
  return stopBits;
 }
 
 public int getParity() {
  return parity;
 }
 
 public void setBaudRate(int baudRate) {
  this.baudRate = baudRate;
 }
 
 public void setDataBits(int dataBits) {
  this.dataBits = dataBits;
 }
 
 public void setStopBits(int stopBits) {
  this.stopBits = stopBits;
 }
 
 public void setParity(int parity) {
  this.parity = parity;
 }
 
 public void setCommPortIdentifier(CommPortIdentifier portId) {
  this.portId = portId;
 }
 
 @Override
 public boolean connect() {
  try {
   if (portId == null || baudRate % 1200 != 0 || dataBits < 5 || dataBits > 8 || stopBits < 1 || stopBits > 2 || parity < 0 || parity > 2) {
    System.err.println(this.getClass().getSimpleName() + " Fehler, invalide Verbindungseinstellungen!");
    return false;
   }
 
   if (portId.isCurrentlyOwned() ) {
    System.err.println(this.getClass().getSimpleName() + " Fehler, PORT " + portId.getName() + " wird bereits verwendet von " + portId.getCurrentOwner() + "!");
    return false;
   }
 
   CommPort commPort = portId.open(this.getClass().getSimpleName(),2000);
   if (commPort instanceof SerialPort) {
    this.serialPort = (SerialPort)commPort;
 
    this.serialPort.setSerialPortParams(
      baudRate, 
      dataBits, 
      stopBits, 
      parity
    );
 
    this.inputStream  = serialPort.getInputStream();
    this.outputStream = serialPort.getOutputStream();
 
    this.serialPort.removeEventListener();
    this.serialPort.addEventListener(new SerialReader());
    this.serialPort.notifyOnDataAvailable(true);
   }
   else {
    System.err.println(this.getClass().getSimpleName() + " Fehler, PORT " + portId.getName() + " ist kein SerialPort!");
    //             this.fireErrorOccurred("WRONG_PORT_TYPE");
    return false;
   }
  } catch (PortInUseException e) {
   e.printStackTrace();
   return false;
  } catch (UnsupportedCommOperationException e) {
   e.printStackTrace();
   return false;
  } catch (TooManyListenersException e) {
   e.printStackTrace();
   return false;
  } catch (IOException e) {
   e.printStackTrace();
   return false;
  }
  return true;
 }
 
 @Override
 public boolean disconnect() {
  ExecutorService executorService = Executors.newSingleThreadExecutor();
  executorService.execute(new Runnable() {
   @Override
   public void run() {
    try {if (outputStream != null) outputStream.close();} catch (IOException e) {e.printStackTrace();}
    try {if (inputStream != null) inputStream.close(); } catch (IOException e) {e.printStackTrace();}
    try {
     if (serialPort != null) {
      synchronized(this){
       serialPort.removeEventListener();
       serialPort.addEventListener(null);    
       serialPort.close();
      }
     }
    } catch (Exception e) {e.printStackTrace();}
   }
  });
 
  executorService.shutdown();
  try {
   executorService.awaitTermination(5, TimeUnit.SECONDS);
   if (!executorService.awaitTermination(5, TimeUnit.SECONDS)) {
    executorService.shutdownNow(); // Cancel currently executing tasks
    if (!executorService.awaitTermination(5, TimeUnit.SECONDS))
     System.err.println(this.getClass().getSimpleName() + " PORT closing did not terminate!");
   }
  } catch (InterruptedException e) {
   executorService.shutdownNow(); // (Re-)Cancel if current thread also interrupted
   Thread.currentThread().interrupt(); // Preserve interrupt status
   return false;
  }
  return true;
 }
 
 @Override
 public GNSSPosition getLastPosition() {
  return lastPosition;
 }
 
 public static void main (String args[]) throws Exception {
  SimpleDateFormat simpleDateFormat = new SimpleDateFormat("hh:mm:ss.SSS");
  TEPUB353 usbLogger = new TEPUB353();
  usbLogger.setCommPortIdentifier(CommPortIdentifier.getPortIdentifier("COM5")); 
  usbLogger.connect();
 
  int i=1;
  while (i++ > 0) {
   Thread.sleep(100);
   GNSSPosition pos = usbLogger.getLastPosition();
 
   if (pos != null)
    System.out.println(i+"  "+(pos.getReceivedDate().getTime() - pos.getSystemDate().getTime())+"  "+simpleDateFormat.format(pos.getReceivedDate())+"    "+simpleDateFormat.format(pos.getSystemDate()));
  }
  usbLogger.disconnect();
 }
 
}
package com.derletztekick.geodesy.instrument.gnss;
 
public abstract class GNSSLogger {
 
 
 public abstract boolean connect();
 
 public abstract boolean disconnect();
 
 public abstract GNSSPosition getLastPosition();
 
}


package com.derletztekick.geodesy.instrument.gnss;
 
import java.util.Date;
 
public class GNSSPosition {
 public enum GeographicDirectionLatitude {
  NORTH, SOUTH;
 
  public static GeographicDirectionLatitude getGeographicDirectionLatitudeByChar(char c) {
   return c == 'N' || c == 'n' ? NORTH : SOUTH;
  }
 }
 
 public enum GeographicDirectionLongitude {
  EAST, WEST;
 
  public static GeographicDirectionLongitude getGeographicDirectionLongitudeByChar(char c) {
   return c == 'E' || c == 'e' ? EAST : WEST;
  }
 }
 
 private double longitude, latitude;
 private GeographicDirectionLatitude  oriLat;
 private GeographicDirectionLongitude oriLon;
 private Date receivedDate, systemDate;
 public GNSSPosition(double latitude, GeographicDirectionLatitude oriLat, double longitude, GNSSPosition.GeographicDirectionLongitude oriLon, Date receivedDate, Date systemDate) {
  this.longitude = longitude;
  this.latitude = latitude;
  this.oriLat = oriLat;
  this.oriLon = oriLon;
  this.receivedDate = receivedDate;
  this.systemDate = systemDate;
 }
 public double getLongitude() {
  return longitude;
 }
 public double getLatitude() {
  return latitude;
 }
 public Date getReceivedDate() {
  return receivedDate;
 }
 public Date getSystemDate() {
  return systemDate;
 }
 @Override
 public String toString() {
  return "GNSSPosition [longitude=" + longitude + "(" + oriLon + "), latitude="
    + latitude + "(" + oriLat + "), receivedDate=" + receivedDate + ", systemDate="
    + systemDate + "]";
 }
}

--
freie Tools zur Netzausgleichung, Transformation und Formanalyse

RSS-Feed dieser Diskussion