Skip to content

Commit

Permalink
Significant changes based on live testing of the code on the Telit GM…
Browse files Browse the repository at this point in the history
…862-GPS

module:

1. The module does not support floating point and so the gpt2.get() function has been modified to only use integer arithmetic and thus not do conversion of latitude and longitude.  This leaves most of the returned elements as strings.  Except altitude which is needed for comparisons.

2. The main loop is wrapped in the try/except that will hide any inflight errors (although they will be logged to the log file).  I hope this will never be called.

3. The timeout on SMS message sending has been increased from the default to 30 seconds because it can take a while to send the message and this was corrupting the return from the temperature command.

4. Improved handling of timestamps to make it clearer in the SMS messages when a message occurred.

5. Modified the upload script to delete the .pyo files for uploaded .py files so that the module will recompile and not use the previous version.
  • Loading branch information
jgrahamc committed Nov 20, 2010
1 parent e4feb38 commit 2811ca6
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 52 deletions.
1 change: 1 addition & 0 deletions gaga-1/recovery/Makefile
Expand Up @@ -31,4 +31,5 @@ upload: $(UPL)
@touch $@

.PHONY: test
test:
@python gaga-1.py
5 changes: 5 additions & 0 deletions gaga-1/recovery/README
Expand Up @@ -20,3 +20,8 @@ TODO
1. Need to contact Telit and ask them what happens to GPS access above
the COCOM limit to make sure gps2 module handles the failure more
correctly.

2. Should delete all files on the Telit module with a clean Makefile
command

3. Performs check the checksum of the loaded scripts in upload
64 changes: 38 additions & 26 deletions gaga-1/recovery/gaga-1.py
Expand Up @@ -14,10 +14,12 @@

import MOD

import sys
import sms
import gps2
import phone
import util
import logger

# Given a dictionary from the GPS reports the current location via SMS
# if it is valid. Should be passed the position from gps2.get().
Expand All @@ -26,12 +28,13 @@
# for battery voltage and the current module internal temperature

def report_position(p):
global state
v = gps2.voltage()
t = util.temperature()
i = '(%dmV, %dC)' % ( v, t )
i = '(%dmV, %dC, %s)' % ( v, t, state )

if p['valid']:
send_sms( '%s %s %.2fm %.2fdeg %.2fkph %dsats %s' % ( p['latitude'],
send_sms( '%s %s %dm %sdeg %skph %ssats %s' % ( p['latitude'],
p['longitude'], p['altitude'], p['course'], p['speed'],
p['satellites'], i ) )
else:
Expand Down Expand Up @@ -70,10 +73,11 @@ def send_sms(m):
# altitude it transitions to Recovery mode.

state = ''
set_state( 'LAUNCH' )
sms.init()
gps2.init()

set_state( 'LAUNCH' )

# The rules for the states are as follows:
#
# Launch: get GPS position every 1 minute and SMS, check for
Expand All @@ -88,27 +92,35 @@ def send_sms(m):
# Recovery: get GPS position every 1 minute and SMS

while 1:
position = gps2.get()

if state == 'LAUNCH':
report_position(position)
if position['valid'] and ( position['altitude'] > ascent_altitude ):
set_state( 'ASCENT' )
elif state == 'ASCENT':
report_position(position)
if position['valid'] and ( position['altitude'] > flight_altitude ):
set_state( 'FLIGHT' )
elif state == 'FLIGHT':
if position['valid'] and ( position['altitude'] < recovery_altitude ):
set_state( 'RECOVERY' )
elif state == 'RECOVERY':
report_position(position)

if state == 'LAUNCH' or state == 'RECOVERY':
delay = 1
elif state == 'ASCENT':
delay = 2
else:
delay = 5
try:
position = gps2.get()

if state == 'LAUNCH':
report_position(position)
if position['valid'] and \
( position['altitude'] > ascent_altitude ):
set_state( 'ASCENT' )
elif state == 'ASCENT':
report_position(position)
if position['valid'] and \
( position['altitude'] > flight_altitude ):
set_state( 'FLIGHT' )
elif state == 'FLIGHT':
if position['valid'] and \
( position['altitude'] < recovery_altitude ):
set_state( 'RECOVERY' )
elif state == 'RECOVERY':
report_position(position)

if state == 'LAUNCH' or state == 'RECOVERY':
delay = 1
elif state == 'ASCENT':
delay = 2
else:
delay = 5

MOD.sleep(delay * 600)

except:
logger.log( "Caught exception in main loop: %s" % sys.exc_info()[1] )

MOD.sleep(delay * 600)
30 changes: 8 additions & 22 deletions gaga-1/recovery/gps2.py
Expand Up @@ -19,34 +19,20 @@ def init():
# The utc is the UTC time from the GPS. course is the cog, satellites
# is the nsat value. speed is the spkm (km/h) and valid indicates
# whether the GPS has a 3D fix.
#
# Conversions performed:
#
# utc, altitude, course and speed converted to float
# satellites converted to int
# longitude and latitude converted to decimal degrees

def get():
p = GPS.getActualPosition()
logger.log( 'gps2.get() -> %s' % p )
a = p.strip().split(',')
if len(a) == 11 and int(a[5]) == 3:
global lastaltitude
latd = int(a[1][0:2])
latm = float(a[1][2:-1])
latc = a[1][-1]
lat = '%.4f%s' % ( latd + latm / 60, latc )
lond = int(a[2][0:3])
lonm = float(a[2][3:-1])
lonc = a[2][-1]
lon = '%.4f%s' % ( lond + lonm / 60, lonc )
return { 'latitude' : lat,
'longitude' : lon,
'altitude' : float(a[4]),
'utc' : float(a[0]),
'course' : float(a[6]),
'satellites' : int(a[10]),
'speed' : float(a[7]),
altitude = int(a[4].split('.')[0])
return { 'latitude' : a[1],
'longitude' : a[2],
'altitude' : altitude,
'utc' : a[0],
'course' : a[6],
'satellites' : a[10],
'speed' : a[7],
'valid' : 1
}
else:
Expand Down
7 changes: 4 additions & 3 deletions gaga-1/recovery/logger.py
Expand Up @@ -3,7 +3,8 @@
# Copyright (c) 2010 John Graham-Cumming

import SER
import MOD

import util

log_file = 'gaga-1.log'

Expand All @@ -13,8 +14,8 @@
# to.

def log(m):
t = MOD.secCounter()
d = '%d: %s\r' % (t, m)
t = util.timestamp()
d = '%s: %s\r' % (t, m)
SER.send(d)
try:
f = open( log_file, 'a' )
Expand Down
7 changes: 6 additions & 1 deletion gaga-1/recovery/sms.py
Expand Up @@ -4,6 +4,7 @@

import at
import logger
import util

# Set up SMS by turning on text mode using the AT+CMGF command

Expand Down Expand Up @@ -33,13 +34,17 @@ def can():
return ( int(m[0]) != 99 ) and ( int(m[1]) != 99 )

# Send a message to a specified phone number
#
# Note that when sending the message the wait time for a response is
# increased to 30 seconds as sending the SMS may take time.

def send(phone, text):
logger.log( 'sms.send(%s...,"%s")' % ( phone[0:4], text ) )
if can():
r = at.cmd( 'AT+CMGS="%s"' % phone )
if r == '\r\n> ':
r = at.raw( '%s\x1A' % text )
t = util.timestamp()
r = at.raw( '%s: %s\x1A' % ( t, text ), 30 )
else:
r = at.raw( '\x1B' )
logger.log( 'Failed to get SMS prompt' )
Expand Down
12 changes: 12 additions & 0 deletions gaga-1/recovery/upload.pl
Expand Up @@ -60,6 +60,18 @@
die "Failed to verify that script was uploaded\n";
}

# If we are uploading a .py file instead of a .pyo check to see if
# there's a .pyo file with the same name and delete it. This is
# needed because the Telit won't recompile the .py file automatically.

if ( $ARGV[0] =~ /\.py$/ ) {
my $pyo = "$ARGV[0]o";
if ( $r =~ /#LSCRIPT: \"$pyo\"/ ) {
$r = cmd( $port, "AT#DSCRIPT=\"$pyo\"", $oke );
die "Failed to delete .pyo file\n" if ( $r !~ /OK/ );
}
}

exit 0;

sub cmd
Expand Down
21 changes: 21 additions & 0 deletions gaga-1/recovery/util.py
Expand Up @@ -2,7 +2,12 @@
#
# Copyright (c) 2010 John Graham-Cumming

import MOD

import at
import logger

epoch = -1

# Retrieves the internal temperature of the module and returns it,
# returns -1000 if something goes wrong
Expand All @@ -21,10 +26,26 @@ def temperature():

w = t.split()
if len(w) < 2:
logger.log( "Temperature read returned %s" % t )
return -1000

m = w[1].split(',')
if len(m) != 2:
logger.log( "Temperature read returned %s" % t )
return -1000
else:
return int(m[1])

# Gets the time since start in seconds and returns a string of the
# form T+nnn.

def timestamp():
t = MOD.secCounter()

global epoch
if epoch < 0:
epoch = t

t = t - epoch

return "T+%d" % t

0 comments on commit 2811ca6

Please sign in to comment.