Centroiding Visualizer Tool
The centroiding visualizer tool is constructed by a webplot server, which
processes JSON-format data to HTML plotter through web socket, and TCP socket
receiver, which grabs centroiding results and raw data by TCP socket sent from
testing device through USB cable running adb (Android Debug Bridge).
In the main function of centroiding_main.py, it will automatically find the
testing device connection (via USB cable), build up TCP socket tunnel, and open
webplot server daemon and socket receiver to show centroiding data from device
to plotter. After then You can go and check the visualizing demo on the
browser.
Usage example:
python centroiding_main.py -s 127.0.0.1 -p 8080 -c tango.conf
Server will load centroiding/tango.conf as config, and build tunnel with
default port (12345).
Then go to http://127.0.0.1:8080 on the browser, you can see the visualizing
centroiding results.
Add argument -l to record centroiding data into file.
Note: this program needs to run adb inside the chroot. You can use
"sudo emerge android-tools" to get adb binary.
BUG=None
TEST=tested on tango and nexus 9 devices.
Change-Id: I0c2e1f4d90f1992da199fa49d10ed1d1cb80169e
Reviewed-on: https://chromium-review.googlesource.com/295820
Commit-Ready: Pin-chih Lin <johnylin@chromium.org>
Tested-by: Pin-chih Lin <johnylin@chromium.org>
Reviewed-by: Shyh-In Hwang <josephsih@chromium.org>
diff --git a/webplot/webplot.py b/webplot/webplot.py
index 25a6986..2df21ff 100755
--- a/webplot/webplot.py
+++ b/webplot/webplot.py
@@ -25,6 +25,7 @@
from ws4py.server.cherrypyserver import WebSocketPlugin, WebSocketTool
from ws4py.websocket import WebSocket
+from centroiding import CentroidingDataReceiver, CentroidingDevice
from remote import ChromeOSTouchDevice, AndroidTouchDevice
@@ -216,7 +217,7 @@
self.ShutdownWhenNoConnections()
-class Root(object):
+class TouchRoot(object):
"""A class to handle requests about docroot."""
def __init__(self, ip, port, touch_min_x, touch_max_x, touch_min_y,
@@ -258,6 +259,45 @@
state.IncCount()
+class CentroidingRoot(object):
+ """A class to handle requests about docroot."""
+
+ def __init__(self, ip, port, data_scale, data_offset,
+ data_width, data_height):
+ self.ip = ip
+ self.port = port
+ self.data_scale = data_scale
+ self.data_offset = data_offset
+ self.data_width = data_width
+ self.data_height = data_height
+ self.scheme = 'ws'
+ cherrypy.log('Root address: (%s, %s)' % (ip, str(port)))
+ cherrypy.log('scheme: %s' % self.scheme)
+
+ @cherrypy.expose
+ def index(self):
+ """This is the default index.html page."""
+ websocket_dict = {
+ 'websocketUrl': '%s://%s:%s/ws' % (self.scheme, self.ip, self.port),
+ 'dataScale': str(self.data_scale),
+ 'dataOffset': str(self.data_offset),
+ 'dataWidth': str(self.data_width),
+ 'dataHeight': str(self.data_height),
+ }
+ print websocket_dict
+ root_page = os.path.join(os.path.abspath(os.path.dirname(__file__)),
+ 'centroiding.html')
+ with open(root_page) as f:
+ return f.read() % websocket_dict
+
+ @cherrypy.expose
+ def ws(self):
+ """This handles the request to create a new web socket per client."""
+ cherrypy.log('A new client requesting for WS')
+ cherrypy.log('WS handler created: %s' % repr(cherrypy.request.ws_handler))
+ state.IncCount()
+
+
class Webplot(threading.Thread):
"""The server handling the Plotting of finger traces.
@@ -297,11 +337,13 @@
"""
def __init__(self, server_addr, server_port, device, saved_file=SAVED_FILE,
- logging=False, is_behind_iptables_firewall=False):
+ logging=False, is_behind_iptables_firewall=False,
+ is_centroiding=False):
self._server_addr = server_addr
self._server_port = server_port
self._device = device
self._saved_file = saved_file
+ self._is_centroiding = is_centroiding
super(Webplot, self).__init__(name='webplot thread')
self.daemon = True
@@ -334,20 +376,30 @@
# If the cherrypy server exits for whatever reason, close the device
# for required cleanup. Otherwise, there might exist local/remote
# zombie processes.
- cherrypy.engine.subscribe('exit', self._device.__del__)
+ if not self._is_centroiding:
+ cherrypy.engine.subscribe('exit', self._device.__del__)
cherrypy.engine.signal_handler.handlers['SIGINT'] = InterruptHandler
cherrypy.engine.signal_handler.handlers['SIGTERM'] = InterruptHandler
def run(self):
"""Start the cherrypy engine."""
- x_min, x_max = self._device.RangeX()
- y_min, y_max = self._device.RangeY()
- p_min, p_max = self._device.RangeP()
+ if not self._is_centroiding:
+ x_min, x_max = self._device.RangeX()
+ y_min, y_max = self._device.RangeY()
+ p_min, p_max = self._device.RangeP()
+ root = TouchRoot(self._server_addr, self._server_port,
+ x_min, x_max, y_min, y_max, p_min, p_max)
+ else:
+ data_scale = self._device.data_scale
+ data_offset = self._device.data_offset
+ data_width = self._device.width
+ data_height = self._device.height
+ root = CentroidingRoot(self._server_addr, self._server_port,
+ data_scale, data_offset, data_width, data_height)
cherrypy.quickstart(
- Root(self._server_addr, self._server_port,
- x_min, x_max, y_min, y_max, p_min, p_max),
+ root,
'',
config={
'/': {
@@ -413,7 +465,8 @@
def AddSnapshot(self, snapshot):
"""Convert the snapshot to a proper format and publish it to clients."""
- snapshot = self._ConvertNamedtupleToDict(snapshot)
+ if not self._is_centroiding:
+ snapshot = self._ConvertNamedtupleToDict(snapshot)
cherrypy.engine.publish('websocket-broadcast', json.dumps(snapshot))
return snapshot
@@ -514,11 +567,25 @@
parser.add_argument('-s', '--server_addr', default='127.0.0.1',
help='the address the webplot http server listens to')
parser.add_argument('-t', '--dut_type', default='chromeos', type=str.lower,
- help='dut type: chromeos, android')
+ help='dut type: chromeos, android, centroiding')
parser.add_argument('--automatically_start_browser', action='store_true',
help=('When this flag is set the script will try to '
'start a web browser automatically once webplot '
'is ready, instead of waiting for the user to.'))
+
+ # Arguments especial for centroiding visualizing tool.
+ # Please set "--dut_type centroiding" for centroiding utility.
+ parser.add_argument('-f', '--dut_forward_port', default=12345, type=int,
+ help='the forwarding port for centroiding socket server '
+ '(default: 12345) (only needed for centroiding)')
+ parser.add_argument('-c', '--config', default='tango.conf', type=str,
+ help='Config file name of device for centroiding '
+ 'visualizing tool parameters.')
+ parser.add_argument('--fps', default=0, type=int,
+ help='the target frame rate of visualizer plotting, set '
+ '0 for keeping same as centroiding processing frame '
+ 'rate.')
+
args = parser.parse_args()
args.grab = not args.nograb
@@ -534,10 +601,16 @@
args = _ParseArguments()
print '\n' + '-' * 70
- cherrypy.log('dut machine type: %s' % args.dut_type)
- cherrypy.log('dut\'s touch device: %s' %
- ('touchscreen' if args.is_touchscreen else 'touchpad'))
- cherrypy.log('dut address: %s' % args.dut_addr)
+ if args.dut_type == 'centroiding':
+ cherrypy.log('**** Centroiding Data Visualizing Tool ****')
+ cherrypy.log('dut config file: %s' % args.config)
+ cherrypy.log('dut address: %s' % args.dut_addr)
+ cherrypy.log('dut socket forwarding port: %d' % args.dut_forward_port)
+ else:
+ cherrypy.log('dut machine type: %s' % args.dut_type)
+ cherrypy.log('dut\'s touch device: %s' %
+ ('touchscreen' if args.is_touchscreen else 'touchpad'))
+ cherrypy.log('dut address: %s' % args.dut_addr)
cherrypy.log('web server address: %s' % args.server_addr)
cherrypy.log('web server port: %s' % args.server_port)
cherrypy.log('grab the touch device: %s' % args.grab)
@@ -567,13 +640,18 @@
if args.dut_type == 'chromeos':
addr = args.dut_addr if args.dut_addr else '127.0.0.1'
device = ChromeOSTouchDevice(addr, args.is_touchscreen, grab=args.grab)
- else:
+ elif args.dut_type == 'android':
device = AndroidTouchDevice(args.dut_addr, True)
+ else: # args.dut_type == 'centroiding'
+ device = CentroidingDevice(args.config)
+ # Specify Webplot for centroiding purpose.
+ is_centroiding = args.dut_type == 'centroiding'
# Instantiate a webplot server daemon and start it.
webplot = Webplot(args.server_addr, args.server_port, device, logging=True,
- is_behind_iptables_firewall=args.behind_firewall)
+ is_behind_iptables_firewall=args.behind_firewall,
+ is_centroiding=is_centroiding)
webplot.start()
if args.automatically_start_browser:
@@ -586,8 +664,13 @@
print 'Please navigate to "%s" in a browser manually, instead' % url
print '!' * 80
- # Get touch snapshots from the touch device and have clients plot them.
- webplot.GetAndPlotSnapshots()
+ if not is_centroiding:
+ # Get touch snapshots from the touch device and have clients plot them.
+ webplot.GetAndPlotSnapshots()
+ else:
+ receiver = CentroidingDataReceiver(
+ '127.0.0.1', args.dut_forward_port, webplot, plot_fps=args.fps)
+ receiver.StartReceive()
if __name__ == '__main__':