Ticket #63: scalesgui.py

File scalesgui.py, 6.4 KB (added by micolous, 6 years ago)

Simple PyGame? app to read your weight and leaning position

Line 
1#!/usr/bin/python
2"""scalesgui.py
3"""
4
5import sys
6
7try:
8        import pygame
9except:
10        print "Sorry, I can't seem to import pygame for some reason."
11        print "Please check that the python-pygame package is installed, or get the latest version of pygame from http://www.pygame.org/"
12        sys.exit(1)
13       
14try:
15        import cwiid
16except:
17        print "Sorry, I can't seem to import cwiid for some reason."
18        print "Please check that it and it's python bindings are installed, and also the balance board patch from:"
19        print "http://abstrakraft.org/cwiid/ticket/63"
20        sys.exit(1)
21
22import os, math, random
23import time as ptime
24from pygame.locals import *
25from ConfigParser import ConfigParser
26from threading import Thread
27
28class WeightSprite(pygame.sprite.Sprite):
29        """This class describes a sprite containing the weight."""
30        def __init__(self):
31                pygame.sprite.Sprite.__init__(self)
32                self.weight = 0.0
33                self.update()
34               
35        def update(self):
36                global screen_res, sys_font_weight_fgcolour, sys_font_weight, screen_res
37               
38                if self.weight > 2:
39                        self.text = "%.2f" % self.weight
40                else:
41                        self.text = "_.__"
42                        #print "LESS THAN 2"
43                #while len(self.text) < 4:
44                #       self.text = "0" + self.text
45                       
46                self.image = sys_font_weight.render(self.text, True, sys_font_weight_fgcolour)
47
48                self.rect = self.image.get_rect()
49                self.rect.bottomright = screen_res
50
51def quit_app():
52        pygame.quit()
53        sys.exit(0)
54       
55def calcweight( readings, calibrations ):
56        """
57        Determine the weight of the user on the board in hundredths of a kilogram
58        """
59        weight = 0
60        for sensor in ('right_top', 'right_bottom', 'left_top', 'left_bottom'):
61                reading = readings[sensor]
62                calibration = calibrations[sensor]
63                #if reading < calibration[0]:
64                #       print "Warning, %s reading below lower calibration value" % sensor
65                if reading > calibration[2]:
66                        print "Warning, %s reading above upper calibration value" % sensor
67                # 1700 appears to be the step the calibrations are against.
68                # 17kg per sensor is 68kg, 1/2 of the advertised Japanese weight limit.
69                if reading < calibration[1]:
70                        weight += 1700 * (reading - calibration[0]) / (calibration[1] - calibration[0])
71                else:
72                        weight += 1700 * (reading - calibration[1]) / (calibration[2] - calibration[1]) + 1700
73
74        return weight
75       
76def gsc(readings, pos):
77        global named_calibration
78        reading = readings[pos]
79        calibration = named_calibration[pos]
80       
81        if reading < calibration[1]:
82                return 1700 * (reading - calibration[0]) / (calibration[1] - calibration[0])
83        else:
84                return 1700 * (reading - calibration[1]) / (calibration[2] - calibration[1]) + 1700
85               
86       
87print "Please press the red 'connect' button on the balance board, inside the battery compartment."
88print "Do not step on the balance board."
89
90global wiimote
91if len(sys.argv) > 1:
92        wiimote = cwiid.Wiimote(sys.argv[1])
93else:
94        wiimote = cwiid.Wiimote()
95
96wiimote.rpt_mode = cwiid.RPT_BALANCE | cwiid.RPT_BTN
97wiimote.request_status()
98
99if wiimote.state['ext_type'] != cwiid.EXT_BALANCE:
100        print 'This program only supports the Wii Balance Board'
101        wiimote.close()
102        sys.exit(1)
103
104balance_calibration = wiimote.get_balance_cal()
105named_calibration = { 'right_top': balance_calibration[0],
106                                          'right_bottom': balance_calibration[1],
107                                          'left_top': balance_calibration[2],
108                                          'left_bottom': balance_calibration[3],
109                                        }
110
111system_file = "system.ini"
112
113if not os.path.lexists(system_file):
114        print "Problem: System configuration file (system.ini) doesn't exist."
115        sys.exit(1)
116
117sconf = ConfigParser()
118sconf.read(system_file)
119
120
121xdisplay = sconf.get("display", "xdisplay")
122if len(xdisplay) > 1:
123        # using alternate display.
124        print "Attempting to use device", xdisplay, "instead of the default."
125        os.putenv("DISPLAY", xdisplay)
126
127pygame.init()
128
129sys_font_weight = pygame.font.SysFont(sconf.get("font_weight", "face"), int(sconf.get("font_weight", "size")))
130
131sys_font_weight.set_italic(False)
132sys_font_weight.set_underline(False)
133
134bgcolour = (0, 0, 0)
135sys_font_weight_fgcolour = (255, 255, 255)
136screen_res = (int(sconf.get("display", "width")), int(sconf.get("display", "height")))
137refresh_delay = int(sconf.get("display", "refresh_delay"))
138
139screen_options = 0
140if int(sconf.get("display", "fullscreen")) >= 1 and len(xdisplay) <= 1:
141        screen_options = screen_options | pygame.FULLSCREEN
142
143if int(sconf.get("display", "double_buffers")) >= 1:
144        screen_options = screen_options | pygame.DOUBLEBUF
145
146if int(sconf.get("display", "hardware_surface")) >= 1:
147        screen_options = screen_options | pygame.HWSURFACE
148
149if int(sconf.get("display", "opengl")) >= 1:
150        screen_options = screen_options | pygame.OPENGL
151
152screen = pygame.display.set_mode(screen_res, screen_options)
153pygame.display.set_caption("scales application")
154
155weight_sprite = WeightSprite()
156weight_sprite.weight = 40.33
157frame = 0
158while True:
159        for event in pygame.event.get():
160                if event.type == KEYDOWN:
161                        if event.key == K_F12:
162                                quit_app()
163                               
164        wiimote.request_status()
165        frame = frame + 1
166        if frame == 50:
167                frame = 0
168                weight = (calcweight(wiimote.state['balance'], named_calibration) / 100.0)
169                #print "%.2fkg" % weight
170                weight_sprite.weight = weight
171       
172       
173        readings = wiimote.state['balance']
174       
175        try:
176                x_balance = (float(gsc(readings,'right_top')+gsc(readings,'right_bottom'))) / (float(gsc(readings,'left_top')+gsc(readings,'left_bottom')))
177                if x_balance > 1:
178                        x_balance = (((float(gsc(readings,'left_top')+gsc(readings,'left_bottom'))) / (float(gsc(readings,'right_top')+gsc(readings,'right_bottom'))))*-1.)+1.
179                else:
180                        x_balance = x_balance -1.
181                y_balance = (float(gsc(readings,'left_bottom')+gsc(readings,'right_bottom'))) / (float(gsc(readings,'left_top')+gsc(readings,'right_top')))
182                if y_balance > 1:
183                        y_balance = (((float(gsc(readings,'left_top')+gsc(readings,'right_top'))) / (float(gsc(readings,'left_bottom')+gsc(readings,'right_bottom'))))*-1.)+1.
184                else:
185                        y_balance = y_balance -1.
186        except:
187                x_balance = 1.
188                y_balance = 1.
189       
190        #print "readings:",readings
191
192        screen.fill(bgcolour) # blank the screen.
193       
194        # line up the lines
195        pygame.draw.line(screen, (0,0,255), (screen_res[0]/2,0), (screen_res[0]/2,screen_res[1]), 2)
196        pygame.draw.line(screen, (0,0,255), (0,screen_res[1]/2), (screen_res[0],screen_res[1]/2), 2)
197       
198        weight_sprite.update()
199       
200        screen.blit(weight_sprite.image, weight_sprite.rect)
201       
202        xpos = (x_balance * (screen_res[0]/2)) + (screen_res[0]/2)
203        ypos = (y_balance * (screen_res[1]/2)) + (screen_res[1]/2)
204               
205        #print "balance:", x_balance, y_balance
206        #print "position:", xpos,ypos
207        pygame.draw.circle(screen, (255,0,0), (int(xpos), int(ypos)), 5)
208        pygame.display.flip()
209        pygame.time.wait(refresh_delay) 
210
211