usr/lib/km/downloadkeymaze300.py

00001 #!/usr/bin/python
00002 
00003 # The aim of this script is to download recorded information on the keymaze300 GPS
00004 #Python script to download trackpoints and waypoints form a KeyMaze 300 GPS.
00005     #Copyright (C) 2008  Julien TOUS
00006 
00007     #This program is free software: you can redistribute it and/or modify
00008     #it under the terms of the GNU General Public License as published by
00009     #the Free Software Foundation, either version 3 of the License, or
00010     #(at your option) any later version.
00011 
00012     #This program is distributed in the hope that it will be useful,
00013     #but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015     #GNU General Public License for more details.
00016 
00017     #You should have received a copy of the GNU General Public License
00018     #along with this program.  If not, see <http://www.gnu.org/licenses/>.
00019 
00020 ## @package gpsd4
00021 #  This package provides an esay to use interface to KeyMaze gps.
00022 #
00023 #  More details.
00024 
00025 import struct
00026 import kml
00027 import sys
00028 import getopt
00029 import os, pwd
00030 
00031 ## Test the presence of pyserial
00032 # @return If pyserial is not present, the user is invited to install it.
00033 
00034 
00035 try:
00036         import serial
00037 except ImportError:
00038         print("You need to have python-serial installed to run km.")
00039         print("Get it from your package manager or http://pyserial.sourceforge.net.")
00040         sys.exit(2)
00041 
00042 
00043 download_dir = os.getenv('HOME') # We may want to add an option to put the downloaded file in a specific location instead of ~
00044 
00045 def file_to_serial(f, s):
00046         """Send the given file (f) to the given open serial port (s)"""
00047         Str=f.read()
00048         s.write(Str)        
00049 
00050 def read_waypoints(ser):
00051         # Asking for WayPoints     
00052         f=open('../../share/km/waypoints.bin','rb') # This file contains the command to upload the WayPoints
00053         file_to_serial(f, ser)
00054         f.close()
00055 
00056         binary_garbage = open(download_dir + '/waypoint_garbage.bin', 'ab') # All WayPoints information which isn't used goes there
00057         ways = open(download_dir + '/waypoints.text','a')
00058         # Getting something
00059         binary_garbage.write(ser.read(3)) 
00060         waypoint_count = 0 # Don't know yet if waypoint_count and waypoint_number will always be the same              
00061         while True:
00062                 # Getting the WayPoint number
00063                 temp_hundredth = struct.unpack(">B", ser.read(1))[0]
00064                 # If the last waypoint was the last we got, next read will give ''                
00065                 # If not it's the tenth value of the waypoint number                
00066                 check_next = ser.read(1)
00067                 if check_next == '':
00068                         break
00069                 else:
00070                         waypoint_count = waypoint_count + 1
00071                 temp_tenth = struct.unpack(">B", check_next)[0]
00072                 temp_unit = struct.unpack(">B", ser.read(1))[0]
00073                 waypoint_number = (temp_hundredth - 48) * 100 + (temp_tenth - 48) * 10 + (temp_unit - 48) * 1 
00074                 ways.write('\n')
00075                 ways.write(str(waypoint_number))
00076                 # Getting 00 41 4C. Don't know what it means !
00077                 binary_garbage.write(ser.read(3))  
00078                 # Getting "icon". Don't know what it is either !
00079                 icon = struct.unpack(">H", ser.read(2))[0]
00080                 ways.write(' ')
00081                 ways.write(str(icon))
00082                 # Getting elevation
00083                 elevation = struct.unpack(">H", ser.read(2))[0]
00084                 ways.write(' ')
00085                 ways.write(str(elevation))                
00086                 # Getting waypoint location
00087                 x = struct.unpack(">i", ser.read(4))[0]
00088                 ways.write(' ')
00089                 ways.write(str(x))                     
00090                 y = struct.unpack(">i", ser.read(4))[0]
00091                 ways.write(' ')
00092                 ways.write(str(y))
00093         ways.close()
00094         binary_garbage.close()  
00095         print "  Got ", waypoint_count, " WayPoints."                
00096   
00097 def read_track(ser):
00098         tracks = open(download_dir + '/trackpoints.text','a') # Text file with all understood informations
00099         tracks.write('\n\n')
00100         binary_garbage = open(download_dir + '/trackpoint_garbage.bin', 'ab') # All TrackPoints information which isn't used goes there
00101         # Getting 0x80. Don't what it is for
00102         binary_garbage.write(ser.read(1))
00103         # Getting something. This changes all the time but i haven't corelated this to anything yet.
00104         binary_garbage.write(ser.read(2))
00105         # Getting the year
00106         year = struct.unpack(">B", ser.read(1))[0]
00107         tracks.write('20'+str(year))
00108         tracks.write('-')
00109         # Getting the month
00110         month = struct.unpack(">B", ser.read(1))[0]        
00111         tracks.write(str(month))
00112         tracks.write('-')
00113         # Getting the day
00114         day = struct.unpack(">B", ser.read(1))[0]
00115         tracks.write(str(day))
00116         tracks.write(':')
00117         # Getting the hour
00118         hour = struct.unpack(">B", ser.read(1))[0]
00119         tracks.write(str(hour))
00120         tracks.write(':')
00121         # Getting the minute
00122         minute = struct.unpack(">B", ser.read(1))[0]
00123         tracks.write(str(minute))
00124         tracks.write(':')
00125         # Getting the second
00126         second = struct.unpack(">B", ser.read(1))[0]
00127         tracks.write(str(second))
00128         tracks.write(' ')
00129         # Getting the training duration
00130         duration = struct.unpack(">i", ser.read(4))[0] # Need to verify it realy uses 4 bytes (actualy it begins with 0x00 0x00)
00131 
00132         kml_name = download_dir+ '/20' + str(year) + '-' + str(month) + '-' + str(day) + 'T' + str(hour) + ':' + str(minute) + ':' + str(second)
00133         # Creating a .kml file 
00134         kml_file = kml.kml(kml_name)
00135 
00136         tracks.write(' \nTraining duration : ')
00137         tracks.write(str(duration))
00138         # Getting the training distance
00139         distance = struct.unpack(">i", ser.read(4))[0] # Need to verify it realy uses 4 bytes (actualy it begins with 0x00 0x00)
00140         tracks.write(' \nTraining distance : ')
00141         tracks.write(str(distance))        
00142         # Getting the number of point
00143         number_of_points = struct.unpack(">H", ser.read(2))[0] # Need to verify it realy uses 2 bytes (actualy it begins with 0x00)
00144         tracks.write(' \nNumber of points : ')
00145         tracks.write(str(number_of_points + 1))
00146         # Getting something
00147         binary_garbage.write(ser.read(2))
00148         # Getting all the trackpoints locations
00149         for i in range(0,number_of_points):
00150                 x = struct.unpack(">i", ser.read(4))[0]
00151                 tracks.write(' \n')
00152                 tracks.write(str(i))
00153                 tracks.write(' : ')
00154                 tracks.write(str(x))
00155                 y = struct.unpack(">i", ser.read(4))[0]
00156                 tracks.write(' ')
00157                 tracks.write(str(y))
00158                 # Adding point to the .kml file
00159                 kml_file.add_point(y/100000.0, x/100000.0)
00160                 
00161         # Getting the last byte 
00162         binary_garbage.write(ser.read(1)) # Should sort out what is it for.
00163         kml_file.close()
00164         binary_garbage.close()
00165         tracks.close()
00166         print "    Got ", number_of_points + 1, " points." 
00167         return (year + month + day + hour + minute + second + duration + distance + number_of_points)
00168 
00169 
00170 def read_trackpoints(ser):
00171         print("  Getting TrackPoints set 1.")
00172         # Asking for the first TrackPoints set
00173         f=open('../../share/km/firsttrackpoints.bin','rb') # This file contains the command to upload the first TrackPoints set
00174         file_to_serial(f, ser)
00175         f.close()
00176 
00177         # Receiveing the first TrackPoints set
00178         is_valid = read_track(ser)
00179 
00180         trackpoints_count = 1
00181         # Testing the validity of the previous TrackPoints set.
00182         # 0 means it was the last.
00183         while is_valid != 0:
00184                 # Asking for the next training data
00185                 trackpoints_count = trackpoints_count + 1
00186                 print "  Getting TrackPoints set ", trackpoints_count        
00187                 f=open('../../share/km/nexttrackpoints.bin','rb') # This file contains the command to upload any TrackPoints set but the first
00188                 file_to_serial(f, ser)
00189                 f.close()
00190                 is_valid = read_track(ser)
00191 
00192 
00193 def configure_serial_port(which_port):
00194         try:               
00195                 ser = serial.Serial(which_port, 4800)
00196         except serial.serialutil.SerialException:
00197                 print "Serial port ", which_port, "can't be opened."
00198                 print("You can specify which serial port to use with -d option.")
00199                 sys.exit(2)         
00200         print("Configuring serial port")                
00201         ser.bytesize=serial.EIGHTBITS
00202         ser.parity=serial.PARITY_NONE
00203         ser.stopbits=serial.STOPBITS_ONE
00204         ser.timeout=2
00205         ser.xonxoff=0
00206         ser.rtscts=0
00207         ser.flushInput()
00208         ser.flushOutput()
00209         return ser
00210 
00211 
00212 def usage():
00213         print("Usage km-downloader [OPTION]")
00214         print("    -h, --help               print this help and exit")
00215         print("    -v, --version            print version information and exit.")
00216         print("    -d, --device             specify which serial device to use.")
00217         print("    -o, --output-directory   specify where to write output files.")
00218         print("    -w, --waypoints          download waypoints.")
00219         print("    -t, --trackpoints        download trackpoints.")
00220         print("For more informations, please see:")
00221         print("<http://gpsd4.tuxfamily.org>.")
00222 
00223 
00224 def version():
00225         print("km 0.9")
00226         print("Copyright (C) 2008 Julien TOUS.")
00227         print("This is free software; see the source for copying conditions.  There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.")
00228         print("Written by Julien TOUS and Vincent-Xavier JUMEL") # I believe a simple way to parse the AUTHOR file exist ?
00229 
00230 
00231 def main(argv):
00232         try:
00233                 opts, args = getopt.getopt(argv, "hvd:o:wt", ["help", "version", "device=", "output-directory=", "waypoints", "trackpoints"])
00234         except  getopt.GetoptError:
00235                 usage()
00236                 sys.exit(2)
00237         
00238         # Should use a better default name
00239         # select from /dev/ttyUSB0 for linux, COM1 for windows and anything that suit well MacOS 
00240         serial_port = '/dev/ttyUSB0' 
00241 
00242         #get_trackpoints and get_waypoints *must* be initialized (to false)
00243         get_waypoints = False
00244         get_trackpoints = False
00245         # Adapting behaviour to option and arguments
00246         for opt, arg in opts:
00247                 if opt in ("-h", "--help"):
00248                         usage()                     
00249                         sys.exit()                  
00250                 elif opt in ("-v", "--version"):
00251                         version()
00252                         sys.exit()               
00253                 elif opt in ("-d", "--device"):
00254                         serial_port = arg
00255                 elif opt in ("-w", "--waypoints"):
00256                         get_waypoints = True
00257                 elif opt in ("-t", "--trackpoints"):
00258                         get_trackpoints = True
00259                 elif opt in ("-o", "--output-directory"):
00260                         download_dir = arg
00261 
00262         # If none of -t or -w has been passed download both TrackPoints and WayPoints
00263         if ( (get_trackpoints == False) and (get_waypoints == False) ):
00264                 get_waypoints = True
00265                 get_trackpoints = True
00266 
00267         # Configuring serial port
00268         # udev should call the script with the appropriate device name using -d
00269         ser = configure_serial_port(serial_port) 
00270 
00271         if get_trackpoints:
00272                 # Asking for TrackPoints
00273                 print "Getting TrackPoints"
00274                 read_trackpoints(ser)        
00275 
00276         if get_waypoints:        
00277                 # Asking for WayPoints
00278                 print "Getting WayPoints"
00279                 read_waypoints(ser)
00280 
00281         # Closing serial port
00282         ser.close()
00283 
00284         # Finishing
00285         quit()
00286 
00287 if __name__ == '__main__':
00288         main(sys.argv[1:])

Generated on Wed May 21 15:14:04 2008 for KeyMaze interface by  doxygen 1.5.4