[Openstreetmap] How do I talk to the GPS to get the info we need?
Petter Reinholdtsen
pere at hungry.com
Sat Nov 13 00:51:19 GMT 2004
[Jo Walsh]
> slightly arcane format, but there you are. gpsbabel definitely
> supports this. as for post-facto DGPS correction it's a good idea; the
> nearest DPGS server to london that i know of it in italy though. we'd
> toyed with the idea of having a whip-round to set one up in
> limehouse...
Do you know how to query the GPS using NMEA-0183 v2.20 in a way that
get it to report accuracy info and enough info to be able to
post-process the collected data with DGPS corrections?
At the moment, I use this perl script, but it do not collect accuracy
information and have no idea about the raw satellite measurements.
#!/usr/bin/perl
#
# Author: Petter Reinholdtsen
# Date: 2004-10-07
# License: GPL
#
# Connect to gpsd, and store coordinate info into an SQL database.
use strict;
use warnings;
use DBI;
use Socket;
use Getopt::Std;
use vars qw($debug $gpsdhost $gpsdport %opts);
getopt("dh:", \%opts);
$debug = $opts{'d'} || 0;
$gpsdhost = $opts{h} | "localhost";
$gpsdport = "2947";
my $period = 1; # How many seconds between each position check?
# Connect to gpsd
my $socket = tcp_connect($gpsdhost, $gpsdport);
# Turn off buffering on $socket
my $old_fh = select($socket);
$| = 1;
select($old_fh);
# Connect to database
my $dbname |= "pere";
my $dbuser |= "" ; # "pere";
my $dbpass |= "" ; # "pere";
my $dbtable |= "tempPoints";
my $dbh = DBI->connect("dbi:Pg:dbname=$dbname", $dbuser, $dbpass,
{'AutoCommit' => 1}) ||
die "Unable to connect to database";
# Turn off buffering on stdout
$| = 1;
print "Starting $0\n";
while (1) {
print $socket "aps\n";
# flush socket
my $line = <$socket>;
if ( ! defined $line) {
$socket->close();
$socket = tcp_connect();
next;
}
$line =~ s/\r\n//;
print "\nL: '$line'\n" if $debug;
my ($x, $y, $altitude, $status);
my @token = split(/,/, $line);
for (@token) {
if (m/^P=(\S+) (\S+)/) {
$x = $1;
$y = $2;
}
$altitude = $1 if (m/^A=(\S+)/);
$status = $1 if (m/^S=(\d+)/);
}
if (1 == $status) { # Satellites in view
# This SQL is PostgreSQL specific
my $sql = "INSERT INTO $dbtable (g, altitude) VALUES ".
"('($x, $y)'::point, '$altitude');";
$dbh->do($sql) || print "S: '$sql'\n";
print ".";
} else {
print "_";
}
sleep $period;
}
sub tcp_connect {
my ($iaddr, $paddr, $proto);
if ($gpsdport =~ /\D/) { $gpsdport = getservbyname($gpsdport, 'tcp') }
die "No port" unless $gpsdport;
$iaddr = inet_aton($gpsdhost) || die "no host: $gpsdhost";
$paddr = sockaddr_in($gpsdport, $iaddr);
$proto = getprotobyname('tcp');
socket(SOCK, PF_INET, SOCK_STREAM, $proto) || die "socket: $!";
connect(SOCK, $paddr) || die "connect: $!";
return *SOCK;
}
sub createTable {
my $dbh = shift;
# Postgresql table
$dbh->do("CREATE TABLE $dbtable (g point, altitude float4,".
"stamp datetime default now());");
}
More information about the talk
mailing list