Op deze pagina worden de mogelijkheden van GPS voor een robot op een rijtje gezet. GPS is eenvoudig en relatief goedkoop. GPS werkt echter nooit binnenhuis. Buitenhuis biedt het een uitstekend referentie kader. Bij Trimble is er een heldere en bijna volledige uitleg te vinden over de technische werking van GPS. Gps information.net biedt vele links naar diverse GPS sites.
Ik werk zelf met een Geko 201 handheld GPS van Garmin. Om compatible met Google Earth te zijn zal u zelf de de Graden, Minuten, Seconden moeten omzetten in decimale graden.
GPS bestaat in diverse smaken en iedere smaak heeft zijn eigen beperkingen en mogelijkheden. Hieronder een klein overzicht over geschatte nauwkeurigheden voor diverse GPS smaken, door verschillende websites:
Type |
Nauwkeurigheid |
Opmerking |
Kowoma.de |
Vele |
Site gebaseerd op werkelijk technische/natuurkundige GPS mogelijkheden |
Wieringermeersite |
0,5 - 30 cm |
Wishfull thinking van Automaatje |
GPS standaard |
10 - 100m |
15 - 30 m lijkt normaler |
DGPS (wiki) |
5 - 50 cm |
Klinkt als onzin |
RTK-GPS (wiki) |
0,5 - 30 cm |
Gebruikt extreem dure en onzeker locale hulpzenders, nauwkeurigheid onzeker |
GPS standaard met SA |
100 m |
Met USA defense "Selective Availability" ingeschakeld |
GPS standaard zonder SA |
15 m |
Zonder klok storing (uitgeschakeld sinds 1 mei 2000) |
DGPS |
3 - 5 m |
Typische waarde |
WAAS/EGNOS |
1 - 3 m |
Typische waarde (test signaal beschikbaar sinds april 2003) |
GPS is ontwikkeld door de VS voor militaire doeleinden. Omdat het werkt met signalen van satellieten die door iedereen over de gehele wereld kunnen worden ontvangen werd er in de beginperiode een soort storing toegevoegd: de zogenaamde "Selectiv Availability". Deze maakte het systeem bewust onnauwkeuriger voor niet geautoriseerde gebruikers. SA is onder druk van de amerikaanse niet-militaire industrie sinds 2000 uitgeschakeld. Omdat het systeem toch al betaald was (door de amerikaanse belastingbetalers) is het systeem nu gratis beschikbaar voor iedereen ter wereld. Echter, zoals uit de bovenstaande tabel blijkt is GPS niet nauwkeurig genoeg voor absolute positiebepaling van een robot.
Er bestaan verbeterde versies van standaard GPS zoals Differentiele GPS(= DGPS). DGPS neemt een extra (vierde) satelliet om zo de afwijking te berekenen en haalt al veel betere nauwkeurigheden dan standaard GPS. Dit wordt ook wel 3D genoemd en werkt eigenlijk in ieder modern GPS systeem met voldoende ontvangst.
De luchtvaart wenst een GPS systeem, dat wereldwijd nauwkeurig genoeg is om een vliegtuig zonder zicht te kunnen laten opstijgen en landen. Vergelijkbare systemen bestaan al wel, maar uitsluitend lokaal. Dat wil zeggen dat zowel vliegveld als vliegtuig beschikking moesten hebben over congruente, dure apparatuur. Gelukkig kan de nauwkeurigheid van GPS met een (kleine) verbetering hiervoor worden gebruikt. Deze (kleine) verbetering bestaat uit een verbeterde GPS software in combinatie met extra satellieten. In de USA is dit concept al enkele jaren geimplementeerd onder de naam: WAAS. Het is nog steeds niet goedgekeurd voor landingen zonder zicht, maar het komt in de buurt. In Europa is het WAAS-compatible signaal sinds 1 april 2003 van start gegeaan onder de naam Egnos. In Japan is het hele project vertraagd doordat het lanceren van de benodigde satellieten mislukte. Voor optimale nauwkeurigheid is EGNOS enabled handig. Sinds 1 mei 2003 is het EGNOS signaal WAAS compatible en zou het dus ook in Nedeland moeten werken. Testen in het open veld lijken dit te bevestigen, met een maximale nauwkeurigheid van 3 meter volgens de GPS. Dit is misschien genoeg om een vliegtuig te kunnen laten landen, maar veel te weinig voor een robot. Het is wel de hoogst haalbare nauwkeurigheid van GPS voor een robot.
RTK-GPS heeft wel de gewenste nauwkeurigheid, maar is volstrekt onbruikbaar. Het maakt gebruik van een heel duur netwerk van speciale steunzenders. Niet alleen de zendmasten zijn ontzettend duur per gebruiker, maar ook de jaarlijkse rechten voor het gebruik van de frequentie kosten veel per gebruiker. Bovendien is de apparatuur in de ontvanger veel duurder dan bij gewone GPS. Daarom bestaan deze steunzenders nog niet in Nederland behoudens proefprojecten. Het is ook niet te verwachten dat deze techniek in de toekomst universeel zal worden omdat deze techniek enkel nodig is voor online metingen, want offline metingen kunnen via het onderstaande systeem worden gemeten met een vergelijkbare nauwkeurigheid. Kortom, dit systeem is geen oplossing voor een robot.
Er bestaat in Nederland namelijk wel een systeem dat wel volgens nauwkeurige standaards werkt en bovendien aansluit bij europese- en zelfs wereldstandaards. Dit systeem wordt geexploiteerd door het kadaster en heet agrs.nl. Dit systeem werkt in 3D en claimt een nauwkeurigheid van 25 cm voor navigatiesystemen. Het is echter niet bruikbaar voor een robot omdat het niet online werkt. De metingen worden opgeslagen en kunnen na 24 uur worden gecorrigeerd met de informatie over de afwijkingen in de satellietbanen en andere variabelen. Dit maakt dat agrs.nl weinig zinvol is voor Farmbot. Bovendien is de toegang tot dit systeem niet gratis. Het is ook nog maar de vraag of dit systeem zich laat implementeren in een mobiel systeem, want alle meetapparatuur ziet er uit als een oversized dinosaurus. Kortom, ook dit systeem is geen oplossing voor een robot.
-
Upgrades firmware
Het lijkt zonder meer verstandig om de software updates regelmatig te bekijken en te volgen. Hiertoe wordt de nieuwste versie als *.exe gedownload. Deze zal 3 bestandjes unzippen naar de directory C:Garmin als hij gestart wordt. Ik heb me overigens geabboneerd op een emailservice die een mailtje stuurt naar mijn hotmail account zodra de software van deze GPS wordt geupdate door Garmin. Let op dat de interface setting van de GPS op Garmin moet worden gezet, waar hij bij mij normaal op NMEA staat. Start het programma updater.exe. Dit is weer 1 van die slechte programmas die echt niets mochten kosten en kan dus enkel COM1: tot COM4: vinden en geen verdere poorten. Let hier op bij het aansluiten van de configuratie. Op COM1: werkt het geheel echter verder uitstekend. Tijdens het updaten laat ook de Geko zien dat hij aan het updaten is.
-
RS232 / NMEA0183 (met RTCM?)
Deze GPS communiceert met mijn robot via een RS232 poort. Zie hiervoor ook de pagina over NMEA.
Legacy
Ik gebruik een 2GB kaartje voor datalogging van mijn GPS. Een single raw datablock bevat 512 bytes. Dat is, indien geformateerd met FAT32, 1.969.479.680 bytes vrije ruimte. Een dataregel van 128 bytes laat dus plaats voor 15.734.187 entries. Indien er per 5 seconden een entry wordt gemaakt is er dus plaats voor meer dan 2 jaar aan data-logging.
Naam |
Voorbeeld |
Betekenis |
Bron |
Lengte |
Totaal |
Datum |
20080403 |
3 april 2008 UTC+1 |
DS1307 |
8 |
8 |
Tijd |
235959 |
23:59:59 UTC+1 |
DS1307 |
6 |
14 |
Latitude |
52023055N |
52 graden, 02min, 30sec, 55msec Noorderbreedte |
GPS |
9 |
23 |
Longitude |
004287853E |
004graden, 28min, 78sec, 53msec Oosterlengte |
GPS |
10 |
33 |
Horizontale error |
0150 |
15 m geschat |
GPS |
4 |
37 |
Altitude |
10000 |
Hoogte in voet |
GPS |
5 |
42 |
Verticale error |
0450 |
45 m geschat |
GPS |
4 |
46 |
Snelheid |
0005 |
0,5 knoop over de grond |
GPS |
4 |
50 |
Koers |
0547 |
54,7 graden over de grond CMG |
GPS |
4 |
54 |
Richting |
0526 |
52,6 richting van de boot |
CMPS03 |
4 |
58 |
//This is an include, so no parsing needed
$qry2 = ("SELECT onderdelen.*,
soortonderdeel.id
FROM onderdelen
JOIN soortonderdeel ON onderdelen.idsrtodd = soortonderdeel.id
WHERE onderdelen.partid = $idpart
;");
$result2 = pg_query($con1, $qry2);
$row4 = pg_fetch_array($result2); //Make the fields accesible
foreach( $row4 AS $key => $val ){
$$key = stripslashes( $val );
}
$jaar = substr($changeddate,0,4);
$maand = substr($changeddate,5,2);
$dag = substr($changeddate,8,2);
$lastupdate = ("$jaar $maand $dag");
$prtsrttxt = get_txt($con1, 26, 1, $idsrtodd);
$jaar = substr($createddate,0,4);
$maand = substr($createddate,5,2);
$dag = substr($createddate,8,2);
$create_stamp = ("$dag $maand $jaar");
//GENERAL INFO FOR EVERY USER **************************************************
echo (" ");
echo (""); //Header
$tmp = get_txt($con1, 9, $koekje[2], 3923); //Fieldname at screen
if ($koekje[3]=="1") { //If this user wants to translate then
echo ("$tmp"); //If desired
}else{ echo ("$tmp"); } //Else just show if no need to translate
if ($koekje[0]>0 and $koekje[3]>0){ //User is logged in and translates
echo (" (edit)");
}
echo ("Algemene informatie test | ");
if ($codetext) { //Code like KY-026 or NA-41
echo ("");
$tmp = get_txt($con1, 9, $koekje[2], 3739); //Fieldname at screen
if ($koekje[3]=="1") { //If this user wants to translate then
echo ("$tmp"); //Class for colour
}else{ //So you are not allowed to translate
echo $tmp; //Show screenname of this field in user language
} //End of If you want to translate this fieldname at screen
echo ("  | ");
if ($codelink) {
echo ("$codetext");
}else{
echo ("$codetext");
} //End of if ($pinoutlink)
echo (" | ");
} //End of if ($codetext)
$tmp = get_txt($con1, 9, $koekje[2], 3741); //Fieldname at screen
if ($prijseurinclbtw > 0){ //Show price indication
$prijs_formatted = number_format($prijseurinclbtw / 100, 2, ',', '.');
echo ("$tmp   | ");
echo ("");
if ($urlprijs){
echo ("€  $prijs_formatted");
}else{
echo ("€  $prijs_formatted");
} //End of if ($urlprijs > "")
echo (" | ");
} //End of if ($prijseurinclbtw > 0)
if ($sketchtext) { //Link to OWN SOFTWARE
$tmp = get_txt($con1, 9, $koekje[2], 3738); //Fieldname at screen
echo ("$tmp   | ");
if ($sketchlink) {
echo ("$sketchtext");
}else{
echo ("$sketchtext");
} //End of if ($sketchlink)
echo (" | ");
} //End of if ($sketchtext)
$tmp = get_txt($con1, 9, $koekje[2], 3744); //Fieldname at screen
if ($pinouttext) { //Pinout
echo ("$tmp   | ");
if ($pinoutlink) {
echo ("$pinouttext");
}else{
echo ("$pinouttext");
} //End of if ($pinoutlink)
echo (" | ");
}
$tmp = get_txt($con1, 9, 1, 3735); //Fieldname at screen
$tmp2 = get_txt($con1, 26, 1, $row4[16]); //Group name in its language
echo ("$tmp   | "); //MENU GROUP
echo ("");
echo ("$tmp2 | ");
if ($koekje[0]>0 and $koekje[3]>0){ //User is logged in and translates
$tmp = get_txt($con1, 9, $koekje[2], 3918); //Fieldname at screen LANGUAGE
if ($row4[26] == 1) {$imgname = "nederland.png";}
if ($row4[26] == 2) {$imgname = "deutschland.png";}
if ($row4[26] == 3) {$imgname = "uk.png";}
if ($row4[26] == 4) {$imgname = "france.png";}
echo ("$tmp | ");
echo ("");
echo (" | ");
$tmp = get_txt($con1, 9, $row4[27], 3919); //Fieldname at screen
$statuskey = get_status_key($con1, $status);
$tmp2 = get_txt($con1, 61, $koekje[2], $statuskey); //Fieldname at screen
echo ("$tmp   | "); //STATUS
echo ("$status $tmp2 | ");
}
$tmp = get_txt($con1, 9, 1, 3966); //Fieldname at screen
echo ("$tmp   | "); //LAST CHANGED
$tmp = substr($changeddate, 0, 10);
echo ("$tmp | ");
echo (" ");
return;
////////////////////////////////////////////////////////////////////////////////
function get_status_key($con, $num){
$qry = ("SELECT id FROM status WHERE nr = $num ;");
$result = pg_query($con, $qry);
$row = pg_fetch_array($result);
return ("$row[0]");
}
// LIST ALL SOFTWARE THAT WILL RUN OM THIS PART *****************************
// INCLUDED IN ALL ROBOTS TO CHECK THEIR DIRECTORY
$qry2=("SELECT tblsystext.txtname
, software.urlmain
, software.sftname
, software.sftid
, software.controller
FROM software
LEFT JOIN tblsystext ON software.controller = tblsystext.recordid
WHERE position(' $idpart ' in software.prtlst) > 0
AND software.rstid = 2
AND tblsystext.lanid = $koekje[2]
AND tblsystext.txlid = 19
ORDER BY sftname ASC
, controller ASC
;");
$result = pg_query($con1, $qry2);
if (pg_num_rows($result)>0) { //Only if at least 1 program exists
echo (' ');
echo (""); //Header
$tmp = get_txt($con1, 9, $koekje[2], 3922); //Fieldname at screen
if ($koekje[3]=="1") { //If this user wants to translate then
echo ("$tmp"); //If desired
}else{ echo ("$tmp"); } //Else just show if no need to translate
echo (" |
---|
");
while($col = pg_fetch_array($result)){
$col[0] = ("$col[0]");
echo (" ");
echo ("$col[2]   | ");
echo ("$col[0] | ");
if ($koekje[0] > 0 and $koekje[3]>0){ //User is logged in and translates
echo ("");
echo ("(Edit) | ");
}
echo (' ');
}
echo (' ');
}
?>
// LIST ALL ROBOTS THAT INCLUDE THIS PART ***********************************
// $idpart
// INCLUDED IN ALL ROBOTS TO CHECK THEIR DIRECTORY
$qry_bpp=("SELECT farmbotversie.id
, farmbotversie.part_list
, tblsystext.txtname
FROM farmbotversie
LEFT JOIN tblsystext ON farmbotversie.id = tblsystext.recordid
WHERE tblsystext.txlid = 27
AND tblsystext.lanid = $koekje[2]
ORDER BY tblsystext.txtname ASC
;");
$result_bpp = pg_query($con1, $qry_bpp);
$header = 0;
while($colbpp = pg_fetch_array($result_bpp)){ //Only if at least 1 robot exists
if(substr_count($colbpp[1], " $idpart ") > 0){
if ($header == 0) {
echo ("");
echo (""); //Header
$tmp = get_txt($con1, 9, $koekje[2], 3879); //Fieldname at screen
if ($koekje[3]=="1") { //If this user wants to translate then
echo ("$tmp"); //If desired
}else{ echo ("$tmp"); } //Else just show if no need to translate
echo (" | ");
$header++;
} //End of if ($header == 0)
echo ("");
echo ("$colbpp[2]");
//Show software van deze bot
$qry=("SELECT software_basedir
FROM farmbotversie
WHERE id = $colbpp[0];");
$result = pg_query($con1, $qry);
$col = pg_fetch_array ($result ,0);
$dir1 = "/var/www/html/robotigs/software/$col[0]";
$arr1 = glob($dir1, GLOB_ONLYDIR);
if (isset($arr1[0])){
$folder = $arr1[0];
$countertmp = 0;
echo ("");
foreach (scandir($folder, 1) as $filename) {
if ($filename<>"." AND $filename <>".."){
if ($countertmp == 0){
$countertmp++;
} //End of if ($countertmp == 0)
$tmp = "/";
$dir = substr($folder, 14) ."/";
$link = $tmp .$dir .$filename;
$showname = substr($filename, 0 ,-4);
echo ("- ");
echo "$showname";
echo ("
");
} //End of if ($filename<>"." AND $filename <>".."){
} //End of foreach (scandir($folder, 1) as $filename)
echo ("");
} //End of if (isset($arr1[0]))
echo (" | ");
}
}
if ($header > 0){
echo (" ");
}
?>
Warning: include(/var/www/html/robotigs/includes/wishlistperpart.php): Failed to open stream: No such file or directory in /var/www/html/robotigs/includes/parts_header.php on line 128
Warning: include(): Failed opening '/var/www/html/robotigs/includes/wishlistperpart.php' for inclusion (include_path='.:/usr/share/php') in /var/www/html/robotigs/includes/parts_header.php on line 128
| //Location:/robotigs/includes/ picts_show.php
// Requieres: $pict_list and several picture handling javascript routines
//*** FROM HERE ON THE PICTURE CORNER STARTS -----------------------------------
if ($pict_list){ //There are 1 or more pictures to be printed
echo ("");
$counter = 0;
$aantal = str_word_count($pict_list, 0, "0123456789");
$lijst = str_word_count($pict_list, 1, "0123456789");
while($counter < $aantal){
$pictkey = $lijst[$counter];
$qryy1 = ("SELECT *
FROM illustrations
WHERE ill_id = $pictkey
;");
$resulty1 = pg_query($con1, $qryy1);
while($row = pg_fetch_array($resulty1)){ //Fields accesible by their name
foreach( $row AS $key => $val ){
$$key = stripslashes( $val );
}
}
$image = ("/robotigs/documentatie/plaatjes/$ill_name");
$pictfull = str_replace('_small', '', $image); //Pictfull=biggest version
$alt = ("Just wait till your 57....");
$txtname = get_txt($con1, 18, $koekje[2], $ill_id); //Robot illustrations subtitles
echo ("");
echo (' ');
$nummer = $counter + 1;
$txtAfb = get_txt($con1, 9, $koekje[2], 3865); //Pic Afb
if ($koekje[0]>0 and $koekje[3]>0){ //User is logged in and translates
echo ("$txtAfb $nummer: ");
echo ("$txtname");
echo (" ");
echo ("Ontkoppelen ");
if ($counter==0){
echo ("Up ");
}else{
echo ("Up ");
}
if ($nummer == $aantal){
echo ("Down");
}else{
echo ("Down");
}
}else{ //Else of if Meaning the current useer is logged in
echo ("$txtAfb $nummer: $txtname");
}
echo (''); //End of this picture
$counter++; //Prepair for next picture
}
echo (' | '); //All pictures are printed
} //End of if there are 1 or more pictures to be printed ----------------------
?>