fingertip_panel.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 # Software License Agreement (BSD License)
3 #
4 # Copyright (c) 2008, Willow Garage, Inc.
5 # All rights reserved.
6 #
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions
9 # are met:
10 #
11 # * Redistributions of source code must retain the above copyright
12 # notice, this list of conditions and the following disclaimer.
13 # * Redistributions in binary form must reproduce the above
14 # copyright notice, this list of conditions and the following
15 # disclaimer in the documentation and/or other materials provided
16 # with the distribution.
17 # * Neither the name of the Willow Garage nor the names of its
18 # contributors may be used to endorse or promote products derived
19 # from this software without specific prior written permission.
20 #
21 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 # POSSIBILITY OF SUCH DAMAGE.
33 #
34 
35 PKG = 'fingertip_pressure'
36 
37 import roslib
38 roslib.load_manifest(PKG)
39 
40 import sys
41 import rospy
42 from pr2_msgs.msg import PressureState
43 import math
44 
45 from fingertip_pressure.colormap import color255
46 from fingertip_pressure.msg import PressureInfo
47 from geometry_msgs.msg import Vector3
48 
49 import wxversion
50 wxversion.ensureMinimal("2.8")
51 
52 import wx
53 import threading
54 from wx import xrc
55 
56 NUMSENSORS = 22
57 RATE = 5. #Hz
58 
59 def txtcolor(data):
60  (r,g,b)=color255(data)
61  if r + g + b < 3 *128:
62  (rt,gt,bt) = (255,255,255)
63  else:
64  (rt,gt,bt) = (0,0,0)
65  return ("#%02x%02x%02x"%(r,g,b),"#%02x%02x%02x"%(rt,gt,bt))
66 
67 class GripperPressurePanel(wx.Panel):
68  def __init__(self, parent, topic):
69  wx.Panel.__init__(self, parent, wx.ID_ANY)
70 
71  # Set up UI
72  sizer = wx.BoxSizer(wx.HORIZONTAL)
75  sizer.Add(self.panel0.panel, 1, wx.EXPAND)
76  sizer.AddSpacer(5)
77  sizer.Add(self.panel1.panel, 1, wx.EXPAND)
78  self.SetSizer(sizer)
79 
80  # Set up subscription
81  self._mutex = threading.Lock()
82  self.new_message_ = None
83  self.new_info_ = None
84  rospy.Subscriber(topic, PressureState, self.message_callback)
85  rospy.Subscriber(topic+"_info", PressureInfo, self.info_callback)
86 
87  self.timer = wx.Timer(self, 1)
88  self.Bind(wx.EVT_TIMER, self.on_timer, self.timer)
89 
90  def info_callback(self, message):
91  self._mutex.acquire()
92  self.new_info_ = message
93  self._mutex.release()
94 
95  def message_callback(self, message):
96  #print 'message_callback'
97  self._mutex.acquire()
98 
99  self.new_message_ = message
100 
101  if not self.timer.IsRunning():
102  self.timer.Start(1000./RATE, True)
103  wx.CallAfter(self.display)
104 
105  self._mutex.release()
106 
107  def on_timer(self, event):
108  #print 'timer'
109  pass
110 
111  def display(self):
112  self._mutex.acquire()
113 
114  if self.new_message_ != None:
115  #print 'newmsg'
116 
117  self.panel0.new_message(self.new_message_.l_finger_tip)
118  self.panel1.new_message(self.new_message_.r_finger_tip)
119 
120  self.new_message_ = None
121 
122  self.Refresh()
123 
124  if self.new_info_ != None:
125  self.panel0.set_info(self.new_info_.sensor[0])
126  self.panel1.set_info(self.new_info_.sensor[1])
127  self.new_info_ = None
128  self.Refresh()
129 
130  self._mutex.release()
131 
133  Newton = 'N';
134  kPascal = 'kPa';
135 
136  def __init__(self, parent):
137  self._mutex = threading.Lock()
138  xrc_path = roslib.packages.get_pkg_dir(PKG) + '/ui/fingertip_panel.xrc'
139  panelxrc = xrc.XmlResource(xrc_path)
140 
141  self.panel = panelxrc.LoadPanel(parent, 'FingertipPressurePanel')
142 
143  bag =self.panel.GetSizer()
144  bag.SetEmptyCellSize(wx.Size(0,0))
145 
146  self.scalings = None
147  self.zeros = [0 for i in range(0,22)]
148  self.recentmean = [0 for i in range(0,22)]
149 
150  self.pad = []
151  for i in range(0, NUMSENSORS):
152  self.pad.append(xrc.XRCCTRL(self.panel, 'pad%i'%i))
153  self.pad[i].SetEditable(False)
154  font = self.pad[i].GetFont()
155  font.SetPointSize(6)
156  self.pad[i].SetFont(font)
157  self.pad[i].SetMinSize(wx.Size(40,35))
158  self.frame_id_box = xrc.XRCCTRL(self.panel, 'frame_id')
159 
160  self.panel.Bind(wx.EVT_RADIOBUTTON, self.set_Newton, id=xrc.XRCID('button_N'))
161  self.panel.Bind(wx.EVT_RADIOBUTTON, self.set_kPascal, id=xrc.XRCID('button_kPa'))
162  self.unit = self.Newton
163 
164  self.panel.Bind(wx.EVT_CHECKBOX, self.set_Zero, id=xrc.XRCID('button_Zero'))
165 
166  def set_Newton(self, event):
167  self._mutex.acquire()
168  self.unit = self.Newton
169  self._mutex.release()
170 
171  def set_kPascal(self, event):
172  self._mutex.acquire()
173  self.unit = self.kPascal
174  self._mutex.release()
175 
176  def set_Zero(self, event):
177  self._mutex.acquire()
178  cb = event.GetEventObject()
179  if cb.IsChecked():
180  self.zeros = list(self.recentmean);
181  else:
182  self.zeros = [0 for i in range(0,22)]
183  self._mutex.release()
184 
185  def calc_area(self,u,v):
186  w = Vector3()
187  w.x = u.y * v.z - u.z * v.y
188  w.y = u.z * v.x - u.x * v.z
189  w.z = u.x * v.y - u.y * v.x
190  return math.sqrt(w.x*w.x + w.y*w.y + w.z*w.z)
191 
192  def set_info(self, info):
193  self._mutex.acquire()
194  self.scalings = info.force_per_unit
195  self.areas = [self.calc_area(info.halfside1[i], info.halfside2[i]) * 4 for i in range(0,22)]
196  self.frame_id_box.SetValue(info.frame_id)
197  self._mutex.release()
198 
199  def new_message(self, data):
200  self._mutex.acquire()
201  #print "FingertipPressurePanel new_message"
202  for i in range(0, NUMSENSORS):
203  #print repr(color(data[i]))
204  #print txtcolor(data[i])
205  self.recentmean[i] = 0.8 * self.recentmean[i] + 0.2 * data[i]
206  dat = data[i] - self.zeros[i]
207  if self.scalings != None:
208  if self.unit == self.kPascal:
209  val = dat / self.scalings[i] / self.areas[i] / 1e3
210  colval = val / 30.
211  scaled = '%.0f'%val
212  else:
213  val = dat / self.scalings[i]
214  colval = val / 3.
215  scaled = '%.2f'%val
216  else:
217  val = dat
218  colval = val / 6000.
219  scaled = '??'
220  (colb,colf)=txtcolor(colval)
221  self.pad[i].SetBackgroundColour(colb)
222  self.pad[i].SetForegroundColour(colf)
223  self.pad[i].SetValue('#%i\n%i\n%s %s'%(i,dat,scaled,self.unit))
224  self._mutex.release()
225 


fingertip_pressure
Author(s): Blaise Gassend
autogenerated on Fri Mar 15 2019 02:53:38