[Tinyos-commits] CVS: tinyos-1.x/tools/python/apps Oscope.py, NONE,
1.1 OscopeAlternate.py, NONE, 1.1 PytosShell.py, NONE, 1.1
Kamin Whitehouse
kaminw at users.sourceforge.net
Fri Sep 23 03:20:35 PDT 2005
- Previous message: [Tinyos-commits] CVS: tinyos-1.x/tools/python/pytos Comm.py, NONE,
1.1 __init__.py, NONE, 1.1
- Next message: [Tinyos-commits] CVS: tinyos-1.x/tools/python/util convertPath.py,
NONE, 1.1 pytosProfile, NONE, 1.1 windowsPythonEnvironment.sh,
NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvsroot/tinyos/tinyos-1.x/tools/python/apps
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5850/apps
Added Files:
Oscope.py OscopeAlternate.py PytosShell.py
Log Message:
pytos is a python-based toolchain for tinyos with a dynamic typing system. it automatically imports the enums, types, message formats, modules, variables, and rpc functions from applications that are compiled with the 'rpc' and 'nescDecls' targets.
--- NEW FILE: Oscope.py ---
#!/usr/bin/python
#$Id: Oscope.py,v 1.1 2005/09/23 10:20:33 kaminw Exp $
# "Copyright (c) 2000-2003 The Regents of the University of California.
# All rights reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose, without fee, and without written agreement
# is hereby granted, provided that the above copyright notice, the following
# two paragraphs and the author appear in all copies of this software.
#
# IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
# DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
# OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY
# OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
# ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
# PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
#
# @author Shawn Schaffert <sms at eecs.berkeley.edu>
# @author Kamin Whitehouse
#
# This is the default Oscope application, which shows how a very simple
# python script should use the pytos tools. Some other versions of Oscope
# exist, which show special cases (eg. how to use mig msgs instead of python
# msgs, or how to use event-driven programming instead of threaded apps)
#
# To debug this application, run it with the -i option passed to python
# and then close the Tk frame.
import sys, time, os
import pytos.util.nescDecls as nescDecls #the nescTypes stuff
from pylab import * #the matplotlib stuff
from matplotlib.numerix import arange, sin, pi, array
from pytos.Comm import Comm #the python comm stack
from pytos.Comm import MessageQueue #the message queue
import Tkinter as Tk #the gui stuff
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
import threading
from copy import deepcopy
class Oscope( object ) :
"""Oscope is a class that opens a window and prints out data
being passed in by a mote running the tinyos-1.x/apps/Oscilloscope
application. You must indicate where the build directory is
Usage:
Oscope.py [platform directory] [comm port]
Both parameters can be contained in environment variables. Example usage:
from the shell command line:
python OscopeThreaded.py ~/tinyos-1.x/apps/Oscope/build/telosb serial at COM1:telos
or
cd ~/tinyos-1.x/apps/Oscope
python OscopeThreaded.py telosb serial at COM1:telos
or
export MOTECOM = serial at COM1:telos
export DEFAULT_PLATFORM
cd ~/tinyos-1.x/apps/Oscope
python OscopeThreaded.py
from the python command line:
(note, it's slow and loses packets as a module... why?)
from OscopeThreaded import Oscope
oscope = Oscope('serial at COM1:telos')
or
from pytos.Comm import Comm
myComm = Comm()
myComm.connect('serial at COM1:telos')
oscope = Oscope(comm=myComm)
and/or (you can use combinations of comm and tkRoot)
import Tkinter as Tk
root = Tk.Tk()
oscope = Oscope(rkRoot = root)
root.mainloop()
"""
def __init__( self , buildDir="", motecom=None, tkRoot=None, comm=None ) :
#first, import all types, msgs, and enums from the nesc app
self.app = nescDecls.nescApp(buildDir, "Oscope")
#use the user's comm and tkroot, if they passed it in
if tkRoot == None:
self.tkRoot = Tk.Tk()
else :
self.tkRoot = tkRoot
if comm == None:
comm = Comm()
comm.connect( motecom ) #defaults to MOTECOM env variable if undefined
self.comm = comm
self.initializeGui()
#create a queue for receiving oscope messages and register it for messages
oscopeMsgQueue = MessageQueue(1)
self.comm.register( deepcopy(self.app.msgs.OscopeMsg) , oscopeMsgQueue )
#start a thread to process the messages (make daemon so it dies when tk is killed)
msgThread = threading.Thread(target=self.processMessages,
args=(oscopeMsgQueue,))
msgThread.setDaemon(True)
msgThread.start()
# start the GUI thread if we own it
if tkRoot == None:
self.tkRoot.mainloop()
print "Oscope.py exited normally"
def initializeGui(self) :
# create the frame where all the widgets will go
self.frame = Tk.Frame( self.tkRoot )
self.frame.pack()
# create the matplotlib figure for displaying the oscope msg payload
self.fig = figure()
self.axes = subplot(111)
self.axes.plot([0],[0],'b')
#we create a line that holds sensor data so that we can update it later
self.line, = self.axes.lines
self.line.set_data([],[])
#remember the current axis limits
self.xlim = self.axes.get_xlim()
self.ylim = self.axes.get_ylim()
# start/stop button
self.startButton = Tk.Button( self.frame , text="start" ,
command = self.toggleStart )
self.startButton.pack( side = Tk.LEFT )
# reset button
self.resetButton = Tk.Button( self.frame , text="reset" ,
command = self.reset )
self.resetButton.pack( side = Tk.LEFT )
#container object for the figure instance
self.canvas = FigureCanvasTkAgg( self.fig , master = self.tkRoot )
self.canvas.show()
self.canvas.get_tk_widget().pack( side = Tk.TOP , fill = Tk.BOTH ,
expand = 1 )
self.toolbar = NavigationToolbar2TkAgg( self.canvas , self.tkRoot )
self.toolbar.update()
self.canvas._tkcanvas.pack( side=Tk.TOP , fill=Tk.BOTH , expand=1)
def reset( self ) :
self.comm.send(self.app.enums.TOS_BCAST_ADDR, self.app.msgs.OscopeResetMsg )
self.line.set_data([],[])
self.canvas.draw()
def toggleStart( self ) :
if self.startButton["text"] == "start" :
self.startButton["text"] = "stop"
else :
self.startButton["text"] = "start"
def processMessages(self, msgQueue) :
while True :
(addr,msg) = msgQueue.get()
if self.startButton["text"] == "stop" :
self.receivedOscopeMsg(msg)
def receivedOscopeMsg( self , msg ) :
print "Received new data #%d from %d" % (msg.lastSampleNumber,
msg.sourceMoteID )
#update the old line with the new data
newData = list(msg.data)
xdata = self.line.get_xdata().tolist()
ydata = self.line.get_ydata().tolist()
xdata.extend(range(len(xdata), len(xdata)+len(newData)))
ydata.extend(newData)
self.line.set_data(xdata, ydata)
#now, if the user isn't zooming or something, update the axis limits
if self.xlim == self.axes.get_xlim() and \
self.ylim == self.axes.get_ylim() :
self.axes.set_xlim(min(xdata), max(xdata))
self.axes.set_ylim(min(ydata), max(ydata))
self.xlim = self.axes.get_xlim()
self.ylim = self.axes.get_ylim()
self.canvas.draw()
if __name__ == "__main__":
#if the user is running this as a script as opposed to an imported module
if len(sys.argv) == 3 :
oscope = Oscope(buildDir = sys.argv[1], motecom = sys.argv[2], )
elif len(sys.argv) == 2 :
oscope = Oscope(buildDir = sys.argv[1], )
else:
oscope = Oscope()
--- NEW FILE: OscopeAlternate.py ---
#!/usr/bin/python
#$Id: OscopeAlternate.py,v 1.1 2005/09/23 10:20:33 kaminw Exp $
# "Copyright (c) 2000-2003 The Regents of the University of California.
# All rights reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose, without fee, and without written agreement
# is hereby granted, provided that the above copyright notice, the following
# two paragraphs and the author appear in all copies of this software.
#
# IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
# DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
# OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY
# OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
# ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
# PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
#
# @author Shawn Schaffert <sms at eecs.berkeley.edu>
# @author Kamin Whitehouse
#
# This application is an alternate implementation of the main Oscope application.
# The differences are:
# 1. this application uses java MIG messages instead of python TosMsg objects
# 2. This application uses event-driven message processing instead of threads
#
import sys, time, os
from pylab import * #the matplotlib stuff
from matplotlib.numerix import arange, sin, pi, array
from pytos.Comm import Comm #the python comm stack
from jpype import jimport #java messages
import Tkinter as Tk #the gui stuff
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
tinyos = jimport.net.tinyos
class Oscope( object ) :
"""Oscope is a class that opens a window and prints out data
being passed in by a mote running the tinyos-1.x/apps/Oscilloscope
application.
Usage:
from the shell command line:
python Oscope.py serial at COM1:telos
or
export MOTECOM = serial at COM1:telos
python Oscope.py
from the python command line:
(note, it's slow and loses packets as a module... why?)
from Oscope import Oscope
oscope = Oscope('serial at COM1:telos')
or
from pytos.Comm import Comm
myComm = Comm()
myComm.connect('serial at COM1:telos')
oscope = Oscope(comm=myComm)
and/or (you can use combinations of comm and tkRoot)
import Tkinter as Tk
root = Tk.Tk()
oscope = Oscope(rkRoot = root)
root.mainloop()
"""
def __init__( self , motecom=None, tkRoot=None, comm=None ) :
#use the user's tk root, if they passed it in
if tkRoot == None:
self.tkRoot = Tk.Tk()
else:
self.tkRoot = tkRoot
#use the user's comm, if they passed it in
if comm != None:
self.comm = comm
#if no comm passed, create one
else:
# connect using motecom first, then MOTECOM environment var
self.comm = Comm()
if motecom != None :
self.comm.connect( motecom )
elif "MOTECOM" in os.environ :
self.comm.connect( os.environ["MOTECOM"] )
else:
sys.stderr.write("No serial port specified\n")
#register a listener for my message
self.comm.register( tinyos.oscope.OscopeMsg() , self )
# start/stop state
self.started = False
# create the frame where all the widgets will go
self.frame = Tk.Frame( self.tkRoot )
self.frame.pack()
# create the matplotlib figure for displaying the oscope msg payload
#self.fig = Figure()
#self.axes = self.fig.add_subplot(111)
self.fig = figure()
self.axes = subplot(111)
self.axes.plot([0],[0],'b')
#we create a line that holds sensor data
#so that we can update it later
self.line, = self.axes.lines
self.line.set_data([],[])
#remember the current axis limits
self.xlim = self.axes.get_xlim()
self.ylim = self.axes.get_ylim()
# start/stop button
self.startButton = Tk.Button( self.frame , text="start" ,
command = self.toggleStart )
self.startButton.pack( side = Tk.LEFT )
# reset button
self.resetButton = Tk.Button( self.frame , text="reset" ,
command = self.reset )
self.resetButton.pack( side = Tk.LEFT )
#container object for the figure instance
self.canvas = FigureCanvasTkAgg( self.fig , master = self.tkRoot )
self.canvas.show()
self.canvas.get_tk_widget().pack( side = Tk.TOP , fill = Tk.BOTH ,
expand = 1 )
self.toolbar = NavigationToolbar2TkAgg( self.canvas , self.tkRoot )
self.toolbar.update()
self.canvas._tkcanvas.pack( side=Tk.TOP , fill=Tk.BOTH , expand=1)
# start the GUI if I created it
if tkRoot == None:
self.tkRoot.mainloop()
def reset( self ) :
self.comm.send(65535, tinyos.oscope.OscopeResetMsg() )
self.line.set_data([],[])
self.canvas.draw()
def toggleStart( self ) :
self.started = not self.started
if self.started :
self.startButton["text"] = "stop"
else :
self.startButton["text"] = "start"
def messageReceived( self , addr , msg ) :
# Because callbacks via jpype give awful errors, catch
# and print errors here
try:
if self.started :
if isinstance( msg , tinyos.oscope.OscopeMsg ) :
self.receivedOscopeMsg( msg )
else :
sys.stderr.write("message of unknown type received\n")
except Exception,inst :
print inst
sys.exit(1)
def receivedOscopeMsg( self , msg ) :
print "Received new data #%d from %d" % (msg.get_lastSampleNumber(),
msg.get_sourceMoteID() )
#update the old line with the new data
newData = list(msg.get_data())
xdata = self.line.get_xdata().tolist()
ydata = self.line.get_ydata().tolist()
xdata.extend(range(len(xdata), len(xdata)+len(newData)))
ydata.extend(newData)
self.line.set_data(xdata, ydata)
#now, if the user isn't zooming or something, update the axis limits
if self.xlim == self.axes.get_xlim() and \
self.ylim == self.axes.get_ylim() :
self.axes.set_xlim(min(xdata), max(xdata))
self.axes.set_ylim(min(ydata), max(ydata))
self.xlim = self.axes.get_xlim()
self.ylim = self.axes.get_ylim()
self.canvas.draw()
if __name__ == "__main__":
#if the user is running this as a script
if len(sys.argv) == 2 :
oscope = Oscope(motecom = sys.argv[1])
else:
oscope = Oscope()
--- NEW FILE: PytosShell.py ---
#!/usr/bin/python -i
# "Copyright (c) 2000-2003 The Regents of the University of California.
# All rights reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose, without fee, and without written agreement
# is hereby granted, provided that the above copyright notice, the following
# two paragraphs and the author appear in all copies of this software.
#
# IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
# DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
# OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY
# OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
# ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
# PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
#
# @author Kamin Whitehouse
#
# This script loads the basic pytos environment for a specific application.
#
# The script must be run in the application directory or told where it is,
# and must be told which platform to import (first parameter). It will then import all
# nesc types, enums, and messages defined in the application.
#
# If the user has a node running this application and indicates how to connect to
# that node (second parameter), the script will also load any rpc functions and ram symbols
# in the application and present them to the user.
#
# In lieu of the first and second parameters, the TINYOS_DEFAULT_PLATFORM and MOTECOM
# environment variables can be used.
#
# usage:
# $ Pytos.py [buildDir] [motecom]
#
# Where "buildDir" is
# 1. only a platform name, eg "pc" or "telosb"
# 2. a path to the build dir, eg. "../../TestRpc/build/telosb"
#
# And where motecom is the standard comm port definition, eg "sf at localhost:9001"
#
# Once the application is loaded, the "app" variable will be available, from which you
# can access all imported enums, types, messages, rpc functions or ram symbols.
#
# Be sure to set the tosbase variable below if you are using a TosBase
import sys
import pytos.tools.Rpc as Rpc
import pytos.tools.RamSymbols as RamSymbols
import pytos.util.NescApp as NescApp
buildDir = None
if len(sys.argv) > 1:
buildDir = sys.argv[1]
port = None
if len(sys.argv) > 2:
port = sys.argv[2]
# import the enums and types in the nesc app that I am working with
app = NescApp.NescApp(buildDir, port, tosbase=True)
- Previous message: [Tinyos-commits] CVS: tinyos-1.x/tools/python/pytos Comm.py, NONE,
1.1 __init__.py, NONE, 1.1
- Next message: [Tinyos-commits] CVS: tinyos-1.x/tools/python/util convertPath.py,
NONE, 1.1 pytosProfile, NONE, 1.1 windowsPythonEnvironment.sh,
NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the Tinyos-commits
mailing list