Salta al contenuto principale
Working from scratch, following simplicity

Rilievo del traffico con una app per S60

Due anni fa dovevo fare diversi rilievi del traffico lungo una strada trafficata di Rovigo, durante le ore di punta: al mattino presto e nel tardo pomeriggio. In pratica il mio compito era quello di contare il numero di auto e veicoli pesanti nei due sensi di marcia in alcune stazioni e in orari prestabiliti (15 minuti per ogni stazione). Per fare questo ho scritto un programma in Python per il mio cellulare: un Nokia N78 (dotato di Symbian 60v3). Ecco la storia completa, il codice e come funziona.

Cosa dovevo fare

Il lavoro non era per niente difficile, ma stressante e ripetitivo e consisteva nel:

  • fissare le stazioni e il momento migliore per le indagini in una mappa, cioè individuare le ore di punta e la posizione utile per contare i veicoli;
  • fare una relazione fotografica e soprattutto contare i veicoli in un intervallo di 15 minuti, segnalando la diversa direzione di marcia e le due tipologie di veicolo (normale e lungo).
Stations on the map
Le stazioni sulla mappa

Traffic survey on sheet of paperAvevo solo un piccolo problema: come avrei dovuto contare i veicoli?

I miei colleghi mettevano una croce su un foglio di carta tutte le volte che vedevano passare una macchina (vedi l'esempio a sinistra), ma per me era inconcepibile e per niente pratico.

Come venirne a capo? Per prima cosa ho pensato ad un contatore manuale come questo, ma me ne servivano quattro, non sarebbe stato agevole usarli contemporaneamente e soprattutto avrei dovuto comprarli! Poi ho guardato il mio telefono, era obsoleto, ma si trattava sempre di un piccolo computer e probabilmente avrei potuto trovare un'applicazione in internet utile per semplificarmi la vita, ma niente da fare!

My final python app for S60 phones

L'unica soluzione era quella di scrivermi direttamente un programma per il mio telefono. Sapevo che esisteva una versione di Python per S60 e così l'ho scaricata ed installata, scoprendo però che solo la versione 1.4.5 funzionava, mentre le più recenti non si installano correttamente[fn]Python for S60 in Wikipedia[/fn].

Ho trovato il pacchetto per il mio cellulare qui e in questi siti ho imparato i primi veloci rudimenti per scrivere il mio programmino:

Python è facile da imparare, ha una grande comunità e molti libri gratuiti in rete, uno di questi è senza dubbio Think Python. Ho solo avuto diversi problemi con l'indentazione, che non avevo mai avuto il piacere di conoscere prima di allora! E un altro odioso contrattempo è stata l'installazione dell'SDK di Nokia per rendere il processo più veloce.

Non ricordo esattamente, ma penso di averci messo 2 o 3 pomeriggi per imparare e scrivere il software, perché la semplicità e leggibilità di Python sono davvero impressionanti. Ho pubblicato sia il codice e il software in un zip, ma sono sicuro che al giorno d'oggi nessuno sia in grado di provarlo. In quanti hanno oggi un telefono cellulare con S60? Probabilmente solo il sottoscritto! Così ho messo un breve video della mia App prima che si estingua del tutto.

Codice sorgente: Traffic_Surveys.zip (NOTA: questi file vanno messi tutti in C:\Python\, se si usano altri percorsi devono essere aggiornati a mano nel programma).

Come funziona

Sotto c'è un video che mostra come funziona la mia applicazione direttamente dal cellulare, se però la si vuole provare direttamente dal proprio browser si può andare qui.

A typical saved file with the results
Un breve videoI risultati del conteggio salvati automaticamente dal programma

Codice di Traffic_Surveys.py

# 
# Manual Traffic Surveys
# Python App for Nokia S60 Phones
#
# Software open source by Nicola Rainiero, under GPLv3 license
# \\---> rainnic.altervista.org <---//

import os
import sys
import time
import appuifw
from appuifw import *
import e32
from key_codes import *
# use this to get your graphics stuff in
from graphics import *
os.path=os.getcwd()

class Keyboard(object):
def __init__(self,onevent=lambda:None):
self._keyboard_state={}
self._downs={}
self._onevent=onevent
def handle_event(self,event):
if event['type'] == appuifw.EEventKeyDown:
code=event['scancode']
if not self.is_down(code):
self._downs[code]=self._downs.get(code,0)+1
self._keyboard_state[code]=1
elif event['type'] == appuifw.EEventKeyUp:
self._keyboard_state[event['scancode']]=0
self._onevent()
def is_down(self,scancode):
return self._keyboard_state.get(scancode,0)
def pressed(self,scancode):
if self._downs.get(scancode,0):
self._downs[scancode]-=1
return True
return False

keyboard=Keyboard()



def quit():
global running
running=0
appuifw.app.set_exit()


appuifw.app.screen='full'
# create an empty image (appears as white image)
#img=Image.new((240,320))
appuifw.app.title=u'Manual_traffic_surveys'
appuifw.app.body= None
appuifw.note(u'Manual Traffic Surveys by\nNicola Rainiero\n- rainnic.altervista.org-','info')
appuifw.note(u'The keys are: 1 3 7 9 for counting, left & right command key for exiting','info')
tempo_stazionamento = appuifw.query(u'Put the time of survey in minutes','number')

iniziale = time.clock()
data = time.localtime
dt = str(time.localtime()[0])+'_'+str(time.localtime()[1])+'_'+str(time.localtime()[2])+'_'+str(time.localtime()[3])+'-'+str(time.localtime()[4])
a1 = 0
a3 = 0
a7 = 0
a9 = 0
exit = 0

# define a function that redraws the screen, in this case the image shall be
# drawn again and again (use the .blit function for this)
def handle_redraw(rect):
canvas.blit(img)

running=1

# define the canvas and include the redraw function as callback, and also the key scanning function (keyboard.handle_event)
canvas=appuifw.Canvas(event_callback=keyboard.handle_event, redraw_callback=handle_redraw)
# set the application body as canvas
appuifw.app.body=canvas

appuifw.app.exit_key_handler = lambda: None # it doesn't exit with the right key
# app.exit_key_handler= # to exit with the right key
# keycapture.all_keys

# create a loop to define stuff in it that needs to be run through again and again
while running:
# clear the image (put as a white image)
img = Image.open('C:\\Python\\background_app.png')
# define a point and add it to the image, define its: current x,y coordinate, and its colour and size
img.text((19,72),u'%04d'%a1,fill = 0xffd700, font = 'title')
img.text((162,72),u'%04d'%a3,fill = 0xffd700, font = 'title')
img.text((19,297),u'%04d'%a7,fill = 0xffd700, font = 'title')
img.text((162,297),u'%04d'%a9,fill = 0xffd700, font = 'title')
adesso = time.clock()
rimasto = tempo_stazionamento*60 - (adesso - iniziale)
img.text((75,170),u'%01d seconds'%rimasto,fill = 0xff0000, font = 'title')
if exit:
img.text((20,190),u'(To escape ''left command key'')',fill = 0xc0c0c0, font = 'dense') # redraw the image
# redraw the image
handle_redraw(())
# this is needed to start a short scheduler to allow checking for key events
e32.ao_yield()
# if left arrow key is pressed, change the x coordinate of the point by 1 dot
if keyboard.pressed(EScancode1):
a1 = a1 + 1

if keyboard.pressed(EScancode3):
a3 = a3 + 1

# if down arrow key is pressed, change the y coordinate of the point by 1 dot
if keyboard.pressed(EScancode7):
a7 = a7 + 1

if keyboard.pressed(EScancode9):
a9 = a9 + 1

if keyboard.pressed(EScancodeRightSoftkey):
exit = 1

if (exit and keyboard.pressed(EScancodeLeftSoftkey)):
# define the directory and file name to write the file into
imagedir=u'C:\\Python\\Survey_'+dt+'.txt'
passato= (adesso - iniziale)
passato=int(passato)

# create the file
file = open(imagedir,'w')

# write some text into it
file.write('Manual Traffic Survey\n')
file.write('On '+dt+' \n')
file.write(' \n')
file.write('CARS\n')
file.write('(down) '+str(a1)+' (up) '+str(a3)+' \n')
file.write(' \n')
file.write('TIME ELAPSED:\n')
file.write(str(passato)+' seconds\n')
file.write(' \n')
file.write('HEAVY VEHICLES\n')
file.write('(down) '+str(a7)+' (up) '+str(a9)+'\n')

# close the file
file.close()
quit()

Aggiungi un commento

Il contenuto di questo campo è privato e non verrà mostrato pubblicamente.

Plain text

  • Nessun tag HTML consentito.
  • Indirizzi web ed indirizzi e-mail diventano automaticamente dei link.
  • Linee e paragrafi vanno a capo automaticamente.
CAPTCHA
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.

Aggiungi un commento

Il contenuto di questo campo è privato e non verrà mostrato pubblicamente.

Plain text

  • Nessun tag HTML consentito.
  • Indirizzi web ed indirizzi e-mail diventano automaticamente dei link.
  • Linee e paragrafi vanno a capo automaticamente.
CAPTCHA
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.
Sponsored Links
Pubblicità

Nicola Rainiero

Ingegnere civile specializzato in geotecnica con l'ambizione di facilitare la propria attività lavorativa usando e creando software libero per un sapere condiviso e collettivo. Mi occupo anche di energie rinnovabili ed in particolare di geotermia a bassa entalpia. Sono da sempre appassionato di web design e modellazione 3D.