multi-touch-dev team mailing list archive
-
multi-touch-dev team
-
Mailing list archive
-
Message #00150
Re: Touch analysis
On Fri, May 07, 2010 at 06:37:20PM +0200, Ara Pulido wrote:
> On 05/07/2010 09:02 AM, Bryce Harrington wrote:
> > On Sun, Apr 11, 2010 at 07:55:43PM -0400, Rafi Rubin wrote:
> >> Added crude mt finger painting.
> >>
> >> Same url: http://ofb.net/~rafi/ts_test.tgz
> >>
> >> For multitouch mode run: ./ts_test -mt_dev /dev/input/eventNN
> >>
> >> Its really nothing fancy (not meant to be), but for some of you, this may be the
> >> first time you actually mt do anything.
> >
> > This is pretty darn sweet.
> >
> >> Please excuse the sloppy code, I'm still experimenting to decide how to
> >> code up a testing framework. In this case I just started from
> >> testsprite.py from the pygame examples.
> >
> > I did some minor tidying (see attached).
>
> Am I the only one not seeing anything attached? ;-)
Let's try that again...
#!/usr/bin/env python
# like the testsprite.c that comes with sdl, this pygame version shows
# lots of sprites moving around.
import pygame, sys, os
from pygame.locals import *
from time import time
from stats import mean, stdev
import code
##import FastRenderGroup as FRG
import pygame.sprite as FRG
from math import sin, cos, pi
from evdev import Device, Event
def usage():
print '''Usage: ts_test.py [-mt_dev MULTITOUCH_DEVICE]
The first test is a static noise test. It measures how the cursor
moves when you hold your finger steady for 5 seconds.
The second test measures noise as a circle is traced.
If the -mt_dev arg is provided and a valid multi-touch input device
specified, it registers multi-finger input.
Options:
-h This help
-flip Set the doublebuffer flag
-sw Use software surfaces
-hw Use hardware surfaces
-mt_dev <dev> Multitouch device (E.g. /dev/input/eventN)
'''
class Thingy(FRG.DirtySprite):
images = None
def __init__(self):
FRG.DirtySprite.__init__(self)
self.image = Thingy.images[0]
self.rect = self.image.get_rect()
self.dirty = 2
class Static(FRG.DirtySprite):
images = None
def __init__(self):
FRG.DirtySprite.__init__(self)
self.image = Static.images[0]
self.rect = self.image.get_rect()
self.rect.x = randint(0, 3*screen_dims[0]/4)
self.rect.y = randint(0, 3*screen_dims[1]/4)
def refresh():
if not update_rects:
screen.fill([0,0,0])
if update_rects:
sprites.clear(screen, background)
sprites.update()
rects = sprites.draw(screen)
if update_rects:
pygame.display.update(rects)
else:
pygame.display.flip()
def single_pos_noise():
global background
points = []
done = False
background = pygame.Surface(screen.get_size())
background = background.convert()
screen.fill([0,0,0])
background.fill([0,0,0])
font = pygame.font.Font(None, 32)
text = font.render("touch the green circle to begin",True,(255, 255, 255))
textpos = text.get_rect(centerx=screen.get_width()/2)
background.blit(text, textpos)
screen.blit(text, textpos)
screen_center = (screen.get_width()/2,screen.get_height()/2)
pygame.draw.circle(screen, pygame.Color("green"),screen_center,32,0)
pygame.draw.circle(background, pygame.Color("green"),screen_center,32,0)
big_circ_pos = pygame.Rect(0,0,64,64)
big_circ_pos.center = screen_center;
pygame.display.flip()
mouse_down = False
start = -1
# time to register a click
click_time = 0.5
while not done:
for event in pygame.event.get():
if event.type in [KEYDOWN, QUIT, JOYBUTTONDOWN]:
exit()
if event.type == MOUSEMOTION:
sprity.rect.center = event.pos
if event.type == MOUSEBUTTONDOWN:
mouse_down = True
points = [complex(*event.pos)]
refresh()
# must click at the center for long enough to count
if mouse_down and big_circ_pos.contains(sprity.rect):
if start < 0:
start = time()
elif (time() - start) >= click_time:
done = True
else:
start = -1
screen.fill([0,0,0])
background.fill([0,0,0])
pygame.draw.circle(screen, pygame.Color("red"),screen_center,32,0)
pygame.draw.circle(background, pygame.Color("red"),screen_center,32,0)
text = font.render("Collecting: don't move your finger",True,pygame.Color("red"))
textpos = text.get_rect(centerx=screen.get_width()/2,centery=screen.get_height()/4)
background.blit(text, textpos)
screen.blit(text, textpos)
pygame.display.flip()
# text = font.render("Time: %d" % , int(time()-start),(255, 0, 0))
# textpos = text.get_rect(centerx=screen.get_width()/2)
# screen.blit(text, textpos)
# for event in pygame.event.get():
# if event.type in [KEYDOWN, QUIT, JOYBUTTONDOWN]:
# done = True
# if event.type == MOUSEMOTION:
# sprity.rect.center = event.pos
# if event.type == MOUSEBUTTONDOWN:
# inner = True
# start = time()
inner = True
pygame.time.set_timer(1,500)
collect_time = 5
last_time = collect_time
while inner:
for event in pygame.event.get():
if time() - collect_time > start:
inner = False
break
if event.type == MOUSEMOTION:
sprity.rect.center = event.pos
points.append(complex(*event.pos))
cur_time = int(collect_time - (time() - start))
if cur_time < last_time:
last_time = cur_time
text = font.render("%d" % cur_time,True,pygame.Color("red"))
textpos = text.get_rect(centerx=screen.get_width()/2,centery=screen.get_height()/4-50)
screen.fill([0,0,0],textpos)
screen.blit(text, textpos)
pygame.display.flip()
pygame.time.set_timer(1,0)
#
#
center = mean(points)
npoints = map(lambda x: x-center,points)
## print points
## print npoints
print "Static touch summary:"
print "Collected "+str(points.__len__())+" points"
if points.__len__() > 1:
print "center (" + str(int(center.real)) + "," + str(int(center.imag)) + ")"
print "mean radius " + str(mean(map(complex.__abs__,npoints)))
print "stdev " + str(stdev(map(complex.__abs__,npoints)))
def circle_noise():
global background
points = []
done = False
background = pygame.Surface(screen.get_size())
background = background.convert()
screen.fill([0,0,0])
background.fill([0,0,0])
font = pygame.font.Font(None, 32)
text = font.render("touch the green circle to begin",True,(255, 255, 255))
textpos = text.get_rect(centerx=screen.get_width()/2)
background.blit(text, textpos)
screen.blit(text, textpos)
screen_center = screen.get_rect().center
big_circ_pos = pygame.Rect(0,0,36,36)
big_circ_pos.center = screen_center;
big_circ_pos.centery = screen.get_height()/2 - 180
pygame.draw.circle(screen, pygame.Color("green"),big_circ_pos.center,16,0)
pygame.draw.circle(background, pygame.Color("green"),big_circ_pos.center,16,0)
pygame.draw.circle(screen, pygame.Color("white"),screen_center,180,1)
pygame.draw.circle(background, pygame.Color("white"),screen_center,180,1)
pygame.display.flip()
mouse_down = False
start = -1
# time to register a click
click_time = 0.5
while not done:
for event in pygame.event.get():
if event.type in [KEYDOWN, QUIT, JOYBUTTONDOWN]:
exit()
if event.type == MOUSEMOTION:
sprity.rect.center = event.pos
if event.type == MOUSEBUTTONDOWN:
mouse_down = True
points = [complex(*event.pos)]
refresh()
# must click at the center for long enough to count
if mouse_down and big_circ_pos.contains(sprity.rect):
if start < 0:
start = time()
elif (time() - start) >= click_time:
done = True
else:
start = -1
screen.fill([0,0,0])
background.fill([0,0,0])
pygame.draw.circle(screen, pygame.Color("red"),big_circ_pos.center,16,0)
pygame.draw.circle(background, pygame.Color("red"),big_circ_pos.center,16,0)
pygame.draw.circle(screen, pygame.Color("blue"),screen_center,180,1)
pygame.draw.circle(background, pygame.Color("blue"),screen_center,180,1)
text = font.render("Collecting: please trace the circle",True,pygame.Color("red"))
textpos = text.get_rect(centerx=screen.get_width()/2,centery=screen.get_height()/4)
background.blit(text, textpos)
screen.blit(text, textpos)
check_points = []
for theta in map(lambda x:pi*x/6 + pi/2,range(1,12)):
x = int(screen.get_rect().centerx + 180 * cos(theta))
y = int(screen.get_rect().centery - 180 * sin(theta))
pos = pygame.Rect(0,0,32,32)
pos.center = (x,y)
check_points.append(pos)
pygame.draw.circle(screen, pygame.Color("red"),(x,y),6,0)
pygame.draw.circle(background, pygame.Color("red"),(x,y),6,0)
pygame.display.flip()
refresh()
# text = font.render("Time: %d" % , int(time()-start),(255, 0, 0))
# textpos = text.get_rect(centerx=screen.get_width()/2)
# screen.blit(text, textpos)
# for event in pygame.event.get():
# if event.type in [KEYDOWN, QUIT, JOYBUTTONDOWN]:
# done = True
# if event.type == MOUSEMOTION:
# sprity.rect.center = event.pos
# if event.type == MOUSEBUTTONDOWN:
# inner = True
# start = time()
dot_color = pygame.Color("purple")
inner = True
while inner:
for event in pygame.event.get():
if event.type in [KEYDOWN, QUIT, JOYBUTTONDOWN]:
exit()
if check_points.__len__() == 0 and big_circ_pos.contains(sprity.rect):
inner = False
break
if event.type == MOUSEMOTION:
sprity.rect.center = event.pos
points.append(complex(*event.pos))
pygame.draw.rect(background,dot_color,pygame.Rect(event.pos[0],event.pos[1],0,0),1)
for hit in filter(lambda p: p.collidepoint(event.pos), check_points):
pygame.draw.circle(background, pygame.Color("green"),hit.center,6,0)
check_points.remove(hit)
refresh()
#
#
center = mean(points)
npoints = map(lambda x: x-center,points)
## print points
## print npoints
print "Static touch summary:"
print "Collected "+str(points.__len__())+" points"
if points.__len__() > 0:
print "center (" + str(int(center.real)) + "," + str(int(center.imag)) + ")"
print "mean radius " + str(mean(map(complex.__abs__,npoints)))
print "stdev " + str(stdev(map(complex.__abs__,npoints)))
dot_color = pygame.Color("purple")
mt_scale_x = 0
mt_scale_y = 0
mt_x = -1
mt_y = -1
mt_maj = 1
mt_min = 1
mt_orient = 1
def draw_point(x,y):
global background, screen
#print "drawing "+str(x)+" "+str(y)
pygame.draw.rect(background,dot_color,pygame.Rect(x,y,0,0),1)
pygame.draw.rect(screen,dot_color,pygame.Rect(x,y,0,0),1)
def draw_ellipse(rect):
global background, screen
#print "drawing "+str(x)+" "+str(y)
pygame.draw.ellipse(screen,dot_color,rect)
def mt_event(event):
global mt_x, mt_y, mt_scale_x, mt_scale_y, mt_maj, mt_min, mt_orient
if event.type == 'EV_ABS':
if event.code == 'ABS_MT_POSITION_X':
mt_x = mt_scale_x * event.value
elif event.code == 'ABS_MT_POSITION_Y':
mt_y = mt_scale_y * event.value
elif event.code == 'ABS_MT_TOUCH_MAJOR':
mt_maj = event.value
elif event.code == 'ABS_MT_TOUCH_MINOR':
mt_min = event.value
elif event.code == 'ABS_MT_ORIENTATION':
mt_orient = event.value
elif event.type == 'EV_SYN':
if event.code == 'SYN_MT_REPORT':
if mt_orient == 0:
(mt_maj, mt_min) = (mt_min, mt_maj)
if mt_maj > 1:
mt_maj *= mt_scale_x*0.7
if mt_min > 1:
mt_min *= mt_scale_y*0.7
#draw_point(mt_x,mt_y)
draw_ellipse(Rect(mt_x-mt_maj/2,mt_y-mt_min/2,mt_maj,mt_min))
elif event.code == 'SYN_REPORT':
pygame.display.flip()
mt_x = mt_y = -1
def mt_draw(mt_dev):
global mt_x, mt_y, mt_scale_x, mt_scale_y, background
points = []
done = False
try:
info = mt_dev.absAxisInfo["ABS_MT_POSITION_X"]
mt_scale_x = float(screen.get_rect().width)/(info['max']-info['min'])
print "ABS_MT_POSITION_X range: " +str(info['min'])+":"+str(info['max'])
except KeyError:
return
try:
info = mt_dev.absAxisInfo["ABS_MT_POSITION_Y"]
mt_scale_y = float(screen.get_rect().height)/(info['max']-info['min'])
print "ABS_MT_POSITION_Y range: " +str(info['min'])+":"+str(info['max'])
except KeyError:
return
background = pygame.Surface(screen.get_size())
background = background.convert()
screen.fill([0,0,0])
background.fill([0,0,0])
font = pygame.font.Font(None, 32)
text = font.render("DRAW!!! (hit any key to quit)",True,(255, 255, 255))
textpos = text.get_rect(centerx=screen.get_width()/2)
background.blit(text, textpos)
screen.blit(text, textpos)
pygame.display.flip()
import thread
thread.start_new(mt_dev.listen,(mt_event,))
while not done:
ev_count = 0
for event in pygame.event.get():
ev_count+=1
if event.type in [KEYDOWN, QUIT, JOYBUTTONDOWN]:
exit()
# if event.type == MOUSEMOTION:
# sprity.rect.center = event.pos
# if event.type == MOUSEBUTTONDOWN:
# mouse_down = True
if ev_count == 0:
pygame.time.delay(100)
# refresh()
# must click at the center for long enough to count
def main():
global update_rects, flags, screen, sprites, background, sprity
# use this to use update rects or not.
# If the screen is mostly full, then update rects are not useful.
update_rects = True
use_FastRenderGroup = False
use_rle = True
mt_mode = False
screen_dims = [0, 0]
surfaces = []
flags = 0
flags ^= FULLSCREEN
if "-h" in sys.argv:
usage()
sys.exit(0)
if "-flip" in sys.argv:
flags ^= DOUBLEBUF
if "-sw" in sys.argv:
flags ^= SWSURFACE
if "-hw" in sys.argv:
flags ^= HWSURFACE
use_rle = False
if "-mt_dev" in sys.argv:
mt_mode = True
mt_dev = Device(sys.argv[sys.argv.index("-mt_dev")+1])
sprite_surface = pygame.image.load("asprite.png")
surfaces.append(sprite_surface)
pygame.display.init()
pygame.font.init()
screen = pygame.display.set_mode(screen_dims, flags)
screen.fill([0,0,0])
pygame.display.flip()
if use_rle:
map(lambda x: x.set_colorkey([0xFF, 0xFF, 0xFF], SRCCOLORKEY|RLEACCEL), surfaces)
else:
map(lambda x: x.set_colorkey([0xFF, 0xFF, 0xFF], SRCCOLORKEY), surfaces)
sprite_surface = sprite_surface.convert_alpha()
Thingy.images = [sprite_surface]
numsprites = 1
sprites = None
if use_FastRenderGroup:
sprites = FRG.LayeredDirty()
else:
if update_rects:
sprites = pygame.sprite.RenderUpdates()
else:
sprites = pygame.sprite.Group()
sprity=Thingy()
sprites.add(sprity)
background = pygame.Surface(screen.get_size())
background = background.convert()
background.fill([0,0,0])
try:
if mt_mode:
mt_draw(mt_dev)
return
single_pos_noise()
circle_noise()
except KeyboardInterrupt:
return
if __name__ == "__main__":
main()
References
-
Re: n-trig updates
From: Stéphane Chatty, 2010-04-01
-
Re: n-trig updates
From: Duncan M. McGreggor, 2010-04-07
-
Re: n-trig updates
From: Stéphane Chatty, 2010-04-07
-
Re: n-trig updates
From: Andy Whitcroft, 2010-04-09
-
Re: n-trig updates
From: Stéphane Chatty, 2010-04-09
-
Re: n-trig updates
From: Andy Whitcroft, 2010-04-10
-
Touch analysis
From: Rafi Rubin, 2010-04-11
-
Re: Touch analysis
From: Rafi Rubin, 2010-04-11
-
Re: Touch analysis
From: Bryce Harrington, 2010-05-07
-
Re: Touch analysis
From: Ara Pulido, 2010-05-07