ASTLAB © 2004
A PSINAV GPS navigátor shell scriptjei
1. startnav.sh
A script feladata a soros device felprogramozása és a navigációs processzek elindítása. A script a
navtty.work file-ban tárolja, hogy melyik terminálon
indították el. Erre az infóra a stopnav.sh-nak lesz majd szüksége.
ty=`tty | awk '{print(substr($0,length($0),1))}'`
echo "tty"$ty > navtty.work
echo "Setup serial device"
stty -F /dev/ttyAM1 19200 -echo
echo "Starting navigator"
navparser.sh &
echo "Starting display"
navdisplay.sh &
2. stopnav.sh
Ezzel a scripttel lehet a navigációs processzeket leállítani. A script a navtty.work
file-ból kiolvassa annak a terminálnak a nevét amin a navigációs display futott, kilövi az arról a terminálról indított
processzeket, majd a terminált letörli és búcsúüzenetet küld ki rá.
ty=`cat navtty.work`
echo "Stopping navigator processes"
P2=`ps -ef | grep $ty | grep -v gre | awk '{ print $2}'`
echo "PIDs: "$P2
kill $P2
echo "" | awk '{print"\033[?25h\033[?0c"}' >/dev/$ty
echo "" | awk '{print"\033[H\033[J"}' >/dev/$ty
echo "" | awk '{print"PSILINUX NAVIGATOR STOPPED.\nThank you for usage.\nASTLAB PRUSOFT c 2004"}' >/dev/$ty
3. navparser.sh
Ez a script a háttérben fut, és folyamatosan olvassa a soros device-t. Az olvasott adatokat awk-al szétszedjük, azaz
kivesszük belőle a navigációhoz szükséges koordinátákat sebesség és haladási irány adatokat. Mivel a GPS engine
a koordinátákat az elfuserált fok-perc formátumban adja, ezeket is átszámoljuk decimálfokba. A kapott adatsort minden
másodpercben az actdata.nav file-ba írjuk le.
cat /dev/ttyAM1 | awk -W interactive '
BEGIN{FS=","
OFMT="%f"
}
/\$GPGLL/{
LATE=substr($2,1,2)
LATT=substr($2,3,7)
RLAT=LATE+LATT/60
if ($3=="S") LAT=(-1)*LAT
LONE=substr($4,1,3)
LONT=substr($4,4,7)
RLON=LONE+LONT/60
if ($5=="W") LON=(-1)*LON;
}
/\$GPVTG/{
VTGANG=$2
SPEED=$8
outfile="actdata.nav"
print RLAT,RLON,int(VTGANG),int(SPEED) > outfile
close(outfile)
}
'
4. navdisplay.sh
Ez a legösszetettebb script, mert igen sok feladat hárul rá. Először is letörli a terminált, majd a statikusan megjelenítendő
dolgokat az iránykijelző keretet és a felső szöveget írja ki rá. Ezek után indul egy végtelen ciklus, ami felolvassa
az actdata.nav file-ból az aktuális bemenő adatokat és ezeket átadja
egy awk-nak. Ebben az awk-ban van az összes terminál-grafikus rajzoló függvény is megírva. A
printbunko felelős az iránykijelző kocka kiírásáért. A
printbignum egyetlen nagy számot tud rajzolni a terminál megadott pontjára.
A printbignumber már egy egész karaktersornyi számot kiír az előző
függvény segítségével a terminál megadott pontjától kezdődően. A printdirection
a megadott szögérték helyét számítja ki az iránykijelző keretben és ki is rajzolja azt. Ezek után következik az a matematikai
függvény nevezetesen az abs(x), ami nincs benne az awk-ban, de szükséges használni. A függvények után jön a főprogram ami minden körben lefut.
Ez először a target.nav file-ból felolvassa a cél adatait és elvégzi
a navigációs számításokat, amelyek eredménye a cél pillanatnyi távolsága és iránya. A számítás végeztével a kapott eredményeket
a terminálra írja. A kiírások, mint az a kódból látszik, vezérlő karakterek segítségével történnek. A vezérlő karakterek
használatáról bővebb információt úgy kaphatsz, hogy bevered a gépedbe az infocmp
parancsot.
clear
echo "" | awk -W interactive '{print("\033[?25l\033[?1c")}'
echo "" | awk -W interactive '
function printborder(x,y)
{
print("\033["y";"x"H -------------------- ");y++
print("\033["y";"x"H| |");y++
print("\033["y";"x"H| |");y++
print("\033["y";"x"H| |");y++
print("\033["y";"x"H| |");y++
print("\033["y";"x"H| |");y++
print("\033["y";"x"H| |");y++
print("\033["y";"x"H| |");y++
print("\033["y";"x"H| |");y++
print("\033["y";"x"H| |");y++
print("\033["y";"x"H| |");y++
print("\033["y";"x"H| |");y++
print("\033["y";"x"H| |");y++
print("\033["y";"x"H| |");y++
print("\033["y";"x"H| |");y++
print("\033["y";"x"H| |");y++
print("\033["y";"x"H| |");y++
print("\033["y";"x"H| |");y++
print("\033["y";"x"H| |");y++
print("\033["y";"x"H| |");y++
print("\033["y";"x"H| |");y++
print("\033["y";"x"H -------------------- ");y++
}
{
print("\033["1";"16"HPSILINUX GPS NAVIGATOR V1.0 ASTLAB-PRUSOFT c 2004")
print("\033["4";"13"HTARGET DIRECTION TARGET DISTANCE IN METERS")
printborder(10,5)
}
'
while true
do
DATA=`cat actdata.nav`
RLAT=`echo $DATA | awk -W interactive '{print $1}'`
RLON=`echo $DATA | awk -W interactive '{print $2}'`
VTGA=`echo $DATA | awk -W interactive '{print $3}'`
SPD=`echo $DATA | awk -W interactive '{print $4}'`
echo"" | awk -W interactive -v RLAT=$RLAT -v RLON=$RLON -v VTGANG=$VTGA -v SPEED=$SPD '
BEGIN{FS=","
OFMT="%f"
LINLON=0.761
LINLAT=1.112
print("\033[?25l\033[?1c")
}
#Functions:
function printbunko(x,y,r)
{
if (r==1) print("\033[7m")
print("\033["y";"x"H ");y++
print("\033["y";"x"H ")
if (r==1) print("\033[0;10m")
}
function printbignum(x,y,num)
{
if (num==0){
print("\033["y";"x"H ");y++
print("\033["y";"x"H ");
print("\033["y";"x+3"H ");
print("\033["y";"x"H ");y++
print("\033["y";"x+3"H ");
print("\033["y";"x"H ");y++
print("\033["y";"x+3"H ");
print("\033["y";"x"H ");y++
print("\033["y";"x+3"H ");
print("\033["y";"x"H ");y++
print("\033["y";"x+3"H ");
print("\033["y";"x"H ");y++
print("\033["y";"x+3"H ");
print("\033["y";"x"H ");y++
}
if (num==1){
print("\033["y";"x+3"H ");y++
print("\033["y";"x+3"H ");y++
print("\033["y";"x+3"H ");y++
print("\033["y";"x+3"H ");y++
print("\033["y";"x+3"H ");y++
print("\033["y";"x+3"H ");y++
print("\033["y";"x+3"H ");y++
}
if (num==2){
print("\033["y";"x"H ");y++
print("\033["y";"x+3"H ");y++
print("\033["y";"x+3"H ");y++
print("\033["y";"x"H ");y++
print("\033["y";"x"H ");y++
print("\033["y";"x"H ");y++
print("\033["y";"x"H ");y++
}
if (num==3){
print("\033["y";"x"H ");y++
print("\033["y";"x+3"H ");y++
print("\033["y";"x+3"H ");y++
print("\033["y";"x"H ");y++
print("\033["y";"x+3"H ");y++
print("\033["y";"x+3"H ");y++
print("\033["y";"x"H ");y++
}
if (num==4){
print("\033["y";"x"H ")
print("\033["y";"x+3"H ");y++
print("\033["y";"x"H ")
print("\033["y";"x+3"H ");y++
print("\033["y";"x"H ")
print("\033["y";"x+3"H ");y++
print("\033["y";"x"H ");y++
print("\033["y";"x+3"H ");y++
print("\033["y";"x+3"H ");y++
print("\033["y";"x+3"H ");y++
}
if (num==5){
print("\033["y";"x"H ");y++
print("\033["y";"x"H ");y++
print("\033["y";"x"H ");y++
print("\033["y";"x"H ");y++
print("\033["y";"x+3"H ");y++
print("\033["y";"x+3"H ");y++
print("\033["y";"x"H ");y++
}
if (num==6){
print("\033["y";"x"H ");y++
print("\033["y";"x"H ");y++
print("\033["y";"x"H ");y++
print("\033["y";"x"H ");y++
print("\033["y";"x"H ")
print("\033["y";"x+3"H ");y++
print("\033["y";"x"H ")
print("\033["y";"x+3"H ");y++
print("\033["y";"x"H ");y++
}
if (num==7){
print("\033["y";"x"H ");y++
print("\033["y";"x+3"H ");y++
print("\033["y";"x+3"H ");y++
print("\033["y";"x+3"H ");y++
print("\033["y";"x+3"H ");y++
print("\033["y";"x+3"H ");y++
print("\033["y";"x+3"H ");y++
}
if (num==8){
print("\033["y";"x"H ");y++
print("\033["y";"x"H ");
print("\033["y";"x+3"H ");
print("\033["y";"x"H ");y++
print("\033["y";"x+3"H ");
print("\033["y";"x"H ");y++
print("\033["y";"x"H ");y++
print("\033["y";"x+3"H ");
print("\033["y";"x"H ");y++
print("\033["y";"x+3"H ");
print("\033["y";"x"H ");y++
print("\033["y";"x+3"H ");
print("\033["y";"x"H ");y++
}
if (num==9){
print("\033["y";"x"H ");y++
print("\033["y";"x"H ");
print("\033["y";"x+3"H ");
print("\033["y";"x"H ");y++
print("\033["y";"x+3"H ");
print("\033["y";"x"H ");y++
print("\033["y";"x"H ");y++
print("\033["y";"x+3"H ");y++
print("\033["y";"x+3"H ");y++
print("\033["y";"x"H ");y++
}
}
function printbignumber(px,py,number)
{
lnum=int(5*length(number)/2)
kpx=px-lnum
for(ty=py;ty<py+7;ty++){
print("\033["ty";33H ")
}
print("\033[7m")
l=length(number)
for (hi=1;hi<=l;hi++){
printbignum(kpx,py,substr(number,hi,1))
kpx+=5
}
print("\033[0;10m")
}
function printdirection(bx,by,direction)
{
for(ji=by+1;ji<by+21;ji++){
print("\033["ji";"bx+1"H ")
}
k=int(direction/5)+1
if (k<=10){
px=bx+9+k
py=by+1
}
if((k>10) && (k<=27)){
px=bx+19
py=by-10+k
}
if((k>27) && (k<=46)){
px=bx+47-k
py=by+19
}
if((k>46) && (k<=63)){
px=bx+1
py=by+66-k
}
if(k>63){
px=bx-63+k
py=by+1
}
if (length(direction)==1)
print("\033["by+10";"bx+9"H00"direction"\260");
if (length(direction)==2)
print("\033["by+10";"bx+9"H0"direction"\260");
if (length(direction)==3)
print("\033["by+10";"bx+9"H"direction"\260");
printbunko(px,py,1)
}
function abs(x)
{
if (x<0) x=(-1)*x
return x
}
#Main program
{
infile="cat target.nav"
infile | getline id
close(infile)
split (id,TA,",");
TLAT=TA[2]
TLON=TA[3]
TNAME=TA[1]
DDS=0
DTLAT=TLAT*100000-RLAT*100000
if (DTLAT<0) DDS=DDS+1
DTLATM=abs(DTLAT)*LINLAT
DTLON=TLON*100000-RLON*100000
if (DTLON<0) DDS=DDS+2
DTLONM=abs(DTLON)*LINLON
DDSF=0
DISTM=sqrt((DTLONM^2)+(DTLATM^2))
if ((DTLONM!=0) && (DTLATM!=0)){
if (DTLATM/DTLONM<1){
ALFA=atan2(DTLATM,DTLONM)*180/3.141592
}
else{
ALFA=90-(atan2(DTLONM,DTLATM)*180/3.141592)
}
}
if (DTLONM==0) ALFA=90
if (DTLATM==0) ALFA=0
if (DDS==0) DIR=90-ALFA
if (DDS==1) DIR=90+ALFA
if (DDS==2) DIR=270+ALFA
if (DDS==3) DIR=270-ALFA
CSRDIR=DIR-VTGANG
if (CSRDIR<0) CSRDIR+=360
if (SPEED>5) printdirection(10,5,int(CSRDIR))
if (DISTM<500000) printbignumber(52,6,int(DISTM))
print("\033["15";"47"HTARGET DATA")
print("\033["16";"42"HNAME: "TNAME" ")
print("\033["17";"42"HLAT : "TLAT" ")
print("\033["18";"42"HLON : "TLON" ")
print("\033["20";"45"HACTUAL LOCATION")
print("\033["21";"42"HLAT : "RLAT" ")
print("\033["22";"42"HLON : "RLON" ")
print("\033["24";"42"HCOURSING SPEED "int(SPEED)" Km/h ")
print("\033[25;33H ")
}
'
done
5. chtrg.sh
Ez a script teszi lehetővé, hogy a ./locationdata könyvtárban elhelyezett
adatfile-okból kiválaszthassuk a megfelelő célt. A script ellenőrzi a megadott adatfile meglétét, majd leindexeli annak
tartalmát, hogy lehessen a felsorolt célok közül választani. Ha a file 66 elemnél többet tartalmaz, akkor szűkítési feltételt
kell megadni, mert a maximálisan kiírható célok száma 66. Ha a script a kiválasztott célt megtalálta, akkor azt leírja a
target.nav file-ba. Ezután a navdisplay.sh-nak
ez lesz az érvényes cél.
if test -z "$1"
then
echo " "
echo "chtrg.sh cannot run. Parameter expected!"
echo "Usage: chtrg.sh target_file [qualifier_string]"
echo " "
exit
else
clear
echo "Target loader started"
echo "Indexing database..."
if test -z "$2"
then
cat $1 | sort | awk '
BEGIN {
FS=","
indx=0
}
{
indx++
if (indx<10){
print ("0"indx, substr($1,1,22))
}
else{
print (indx, substr($1,1,22))
}
}' > trgindexed.dat
else
cat $1 | sort | awk ' BEGIN {FS=","} {print $1}' | grep "${2}" | awk '
BEGIN {
FS=","
indx=0
}
{
indx++
if (indx<10){
print ("0"indx, substr($1,1,22))
}
else{
print (indx, substr($1,1,22))
}
}' > trgindexed.dat
fi
sleep 1
clear
TNUM=`cat trgindexed.dat | wc -l`
if test $TNUM -gt 66
then
clear
echo "Too many items found in database. You have to use any qualifier as the following:"
echo " "
echo "chtrg.sh [qualifier_string]"
echo " "
echo "for example: chtrg.sh mycoords.dat Ma will display targets only from mycoords.dat which are contain the string Ma"
echo " "
echo " "
exit
fi
if test $TNUM -eq 0
then
echo " "
echo "String \""$2"\" not found in database!"
echo "Done."
exit
else
cat trgindexed.dat | awk '
BEGIN{
xpos=1
ypos=0
}
{
ypos++
if ((ypos>22) && (xpos==1)){
ypos=1
xpos=27
}
if ((ypos>22) && (xpos==27)){
ypos=1
xpos=54
}
print("\033["ypos";"xpos"H"$0)
}'
echo -e "\033[24;1HChoice:"
read TRGNUM
SSTRING=`cat trgindexed.dat | awk -v TRGNUM=$TRGNUM '
BEGIN{
bv=0
}
{ if (TRGNUM==substr($0,1,2)){
print(substr($0,4,length($0)-2))
bv=1
}
}
END{
if (bv==0) print("NONE")
}'`
TE=`cat $1 | grep "$SSTRING" | wc -l`
clear
if test $TE -eq 1
then
cat $1 | grep "$SSTRING" >target.nav
echo "Target loaded. Ready to navigation."
echo " "
else
echo "Something wrong! Target not loaded!"
echo " "
fi
fi
fi
Így néz ki a script működés közben:
small:~/navigator# chtrg.sh locationdata/mycoords.dat
Target loader started
Indexing database...
01 Andor u. 23 Petofi híd
02 Arpad hid 24 Szabadsag hid
03 Auchan 25 Szabhegy
04 Budagyongye 26 Szent Laszlo IV.ker
05 Don pepe pizza 27 Szentendrei ut
06 Erzsebet hid 28 Veres Peter ut
07 Erzsebet ter
08 Ferihegy2
09 Florian ter
10 Gazdagreti ter
11 Gilicze ter
12 Gubacsi hid
13 Hiedkuti ut
14 Kos Karoly ter
15 Kosztolanyi D. ter
16 Lagymanyosi hid
17 Lanchid
18 Margit hid
19 Nagyszenas ter
20 Nagytetenyi Bfok
21 Orban ter
22 Osztyapenko
Choice:
18
Target loaded. Ready to navigation.
small:~/navigator#
Vagy ha szűkítési feltételt is megadunk:
small:~/navigator# chtrg.sh locationdata/mycoords.dat Sz
Target loader started
Indexing database...
01 Szabadsag hid
02 Szabhegy
03 Szent Laszlo IV.ker
04 Szentendrei ut
Choice:
01
Target loaded. Ready to navigation.
small:~/navigator#
6. nearest.sh
Ezzel a scriptttel lehet megkeresni egy adott adatfile-ban a hozzánk legközelebb álló objektumot. A paraméterként megadott
adatfile-t be cat-oljuk egy awk-ba, aminek átadjuk az aktuális koordinátát. Az awk minden a bemenő file-ban levő
pontra kiszámítja a távolságot és elraktározza egy tömbben. Az awk END szekvenciájában a tömb elemeit növekvő sorrendbe
rakjuk, majd az első négy elemet a TRGNAME változóba írjuk. A TRGNAME következő awk-ban való szétparszolása lehetővé
teszi a megfelelő cél kiválasztását. A választáshoz tartozó adatokat a
target.nav file-ba helyezi. Ezután a navdisplay.sh-nak
ez lesz az érvényes cél. Ha a q-t választjuk akkor a script a cél módosítását nem hajtja végre.
if test -z "$1"
then
echo " "
echo "nearest.sh cannot run. Parameter expected!"
echo "Usage: nearest.sh target_file"
echo " "
exit
else
clear
echo "Searching the nearest object from here in file "$1"..."
echo " "
NI=`cat $1 | wc -l`
echo $NI" items found. Sorting, please wait..."
DATA=`cat actdata.nav`
RLAT=`echo $DATA | awk '{print $1}'`
RLON=`echo $DATA | awk '{print $2}'`
TRGNAME=`cat $1 | awk -v RLAT=$RLAT -v RLON=$RLON '
BEGIN{FS=","
OFMT="%f"
LINLON=0.761
LINLAT=1.112
INDX=0
}
#Functions:
function abs(x)
{
if (x<0) x=(-1)*x
return x
}
#Main program
{
split ($0,TA,",");
TNAME=TA[1]
TLAT=TA[2]
TLON=TA[3]
DTLAT=TLAT*100000-RLAT*100000
DTLATM=abs(DTLAT)*LINLAT
DTLON=TLON*100000-RLON*100000
DTLONM=abs(DTLON)*LINLON
DISTM=sqrt((DTLONM^2)+(DTLATM^2))
if (DISTM<500000){
DISTS[INDX]=int(DISTM)
NAMES[INDX]=TNAME
}
else{
DISTS[INDX]=600000
NAMES[INDX]="TOO FAR"
}
INDX++
}
END{
for(i=0;i<INDX;i++){
for(j=0;j<INDX-1;j++){
if (DISTS[j]>DISTS[j+1]){
DDEPO=DISTS[j]
DISTS[j]=DISTS[j+1]
DISTS[j+1]=DDEPO
NDEPO=NAMES[j]
NAMES[j]=NAMES[j+1]
NAMES[j+1]=NDEPO
}
}
}
print(NAMES[0]","DISTS[0]","NAMES[1]","DISTS[1]","NAMES[2]","DISTS[2]","NAMES[3]","DISTS[3]",")
}
'`
echo " "
echo $TRGNAME | awk '
BEGIN{ FS=","}
{
print("1.) "$1" "$2" m")
print("2.) "$3" "$4" m")
print("3.) "$5" "$6" m")
print("4.) "$7" "$8" m")
}'
echo "q.) To quit."
echo " "
echo "Enter your choice:"
read ch
if test $ch = "q"
then
echo " "
exit
else
case $ch in
"1") SSS=`echo $TRGNAME | awk 'BEGIN{FS=","} {print $1}'`;;
"2") SSS=`echo $TRGNAME | awk 'BEGIN{FS=","} {print $3}'`;;
"3") SSS=`echo $TRGNAME | awk 'BEGIN{FS=","} {print $5}'`;;
"4") SSS=`echo $TRGNAME | awk 'BEGIN{FS=","} {print $7}'`;;
esac
fi
echo " "
TE=`cat $1 | grep "$SSS" | wc -l`
if test $TE -eq 1
then
cat $1 | grep "$SSS" >target.nav
echo "Location of "$SSS" loaded. Ready to navigation."
echo " "
else
echo "Something wrong! Target not loaded!"
echo " "
fi
fi
7. store.sh
Ezzel a scripttel bármelyik adatfile-hoz hozzáadhatjuk a pillanatnyi pozíciónkat. A script induláskor megnézi a paraméterek
meglétét és csak akkor indul el, ha mindkét paramétert megadtuk. A hely nevének megadásakor arra kell figyelni, ha az space karaktereket
tartalmaz, akkor a teljes nevet "" közé kell tenni!
if test -z "$1" || test -z "$2"
then
echo " "
echo "store.sh cannot run. Parameter expected!"
echo "Usage: store.sh target_file_name target_name"
echo " "
exit
fi
LDATA=`cat actdata.nav`
LAT=`echo $LDATA | awk '{print $1}'`
LON=`echo $LDATA | awk '{print $2}'`
if test -f "$1"
then
echo $2","$LAT","$LON >>$1
else
echo $2","$LAT","$LON >$1
fi
echo " "
echo "Location stored to "$1
echo " "
Példa:
small:~/navigator# chtrg.sh locationdata/mycoords.dat Vilagitotorony
vagy
small:~/navigator# chtrg.sh locationdata/mycoords.dat "Deak Ferenc utca"
8. csron.sh
Ez egy rendkívül egyszerű egysoros script, ami vezérlőkarakterek kiírásával visszaadja a kurzort.
echo "" | awk '{print"\033[?25h\033[?0c"}'
9. setupengine.sh
Ez a script szolgál a GPS engine felprogramozására. Az alapvetően bináris adatkommunikációs módban és 19200 baud-os
adatátviteli sebességgel felálló engine-t megtanítja arra, hogy 19200 baud NMEA formátumot és GPGLL,GPVTG mondatokat
adjon ki magából. A tanítás végén lehetőség van az engine működésének ellenőrzésére, amiből a ctrl-c
vel léphetünk ki.
clear
echo "Sending Setup to U-BLOX GPS engine..."
echo " "
echo "Switching to NMEA protocol."
stty -F /dev/ttyAM1 19200
sleep 1
cat swnmea.dat >/dev/ttyAM1
sleep 4
echo "Setting communication speed to 19200 baud."
stty -F /dev/ttyAM1 4800
sleep 1
cat swbr192.dat >/dev/ttyAM1
sleep 3
cat swbr192.dat >/dev/ttyAM1
sleep 1
stty -F /dev/ttyAM1 19200
sleep 1
echo "Switching off GSV query control."
cat swoffgsvqc.dat >/dev/ttyAM1
sleep 2
echo "Switching off GSA query control."
cat swoffgsaqc.dat >/dev/ttyAM1
sleep 2
echo "Switching off GGA query control."
cat swoffggaqc.dat >/dev/ttyAM1
sleep 2
echo "Switching on GLL query control."
cat swongllqc.dat >/dev/ttyAM1
sleep 2
echo "Switching on VTG query control."
cat swonvtgqc.dat >/dev/ttyAM1
sleep 2
echo " "
echo "GPS engine ready to use."
echo " "
echo "Do you want to test it? (y/n)"
read ch
if test $ch = "y"
then
echo " "
echo "If you are getting NMEA sentences within 5 seconds, GPS engine is working."
echo "You can exit with ctrl-c."
sleep 5
cat /dev/ttyAM1
fi