Update workstation UI, ROS task control and device integration
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
from types import SimpleNamespace
|
||||
from unittest import TestCase
|
||||
import numpy as np
|
||||
from arm_application.tactile_flow import tactile_devices,select_source,flow_preview,read_sample
|
||||
|
||||
|
||||
class TactileFlowTest(TestCase):
|
||||
def test_discovery_filters_realsense_and_duplicate_interfaces(self):
|
||||
with tempfile.TemporaryDirectory() as folder:
|
||||
root=Path(folder);sys=root/'class';sys.mkdir()
|
||||
for name,vendor,index in [('video0','8086','0'),('video1','1bcf','0'),('video2','1bcf','1'),('video3','0bda','0')]:
|
||||
entry=sys/name;entry.mkdir();(entry/'index').write_text(index)
|
||||
usb=root/('usb-'+name);usb.mkdir();(usb/'idVendor').write_text(vendor)
|
||||
(entry/'device').symlink_to(usb,target_is_directory=True)
|
||||
found=tactile_devices(sys,Path('/dev'))
|
||||
self.assertEqual(found,['/dev/video1'])
|
||||
self.assertEqual(select_source('left',{},found),'/dev/video1')
|
||||
self.assertIsNone(select_source('right',{},found))
|
||||
self.assertEqual(select_source('right',{'right_video':'/dev/v4l/by-path/sensor'},found),'/dev/v4l/by-path/sensor')
|
||||
|
||||
def test_actual_vector_field_changes_preview_and_rejects_bad_shapes(self):
|
||||
flow=np.zeros((64,64,2),np.float32)
|
||||
rest=flow_preview(flow);flow[...,0]=12
|
||||
motion=flow_preview(flow)
|
||||
self.assertEqual(motion.shape,(360,360,3));self.assertFalse(np.array_equal(rest,motion))
|
||||
with self.assertRaises(ValueError):flow_preview(np.zeros((8,8)))
|
||||
|
||||
def test_uses_raw_force_channels_and_reads_flow_only_once(self):
|
||||
info=SimpleNamespace(FPS=1,FNORMAL=2,FSHEARX=3,FSHEARY=4,FNORMAL_RAW=5,FSHEARX_RAW=6,FSHEARY_RAW=7,VRAW=8)
|
||||
calls=[]
|
||||
def read(*keys):
|
||||
calls.append(keys);return 30.,200.,3.,-4.,np.zeros((8,8,2))
|
||||
row=read_sample(SimpleNamespace(info=info,read_info=read))
|
||||
self.assertEqual(calls,[(1,5,6,7,8)])
|
||||
self.assertEqual(row['fnormal'],200.);self.assertEqual(row['fsheary'],-4.)
|
||||
|
||||
def test_preview_polling_is_independent_of_slow_state_poll(self):
|
||||
import base64,threading,time
|
||||
from unittest.mock import patch
|
||||
from station.runtime_client import RuntimeClient
|
||||
client=RuntimeClient.__new__(RuntimeClient)
|
||||
client._lock=threading.RLock();client._stop=threading.Event()
|
||||
from collections import deque
|
||||
client._force_history={'left':deque(maxlen=1800),'right':deque(maxlen=1800)}
|
||||
client._force_cursors={};client._force_epochs={}
|
||||
client._snapshot={'view':{'on':True}};client._frames={};client.socket=Path('/unused')
|
||||
calls=[]
|
||||
def rpc_call(*args,**kwargs):
|
||||
calls.append(args[1]);return {'frames':{'left_shear':base64.b64encode(b'jpeg').decode()},
|
||||
'samples':{'left':[{'seq':1,'t':time.time(),'fnormal':.5,'fshearx':.2,'fsheary':-.3}]},'epochs':{'left':0}}
|
||||
with patch('station.runtime_client.rpc.call',side_effect=rpc_call):
|
||||
thread=threading.Thread(target=client._poll_frames);thread.start()
|
||||
time.sleep(.16);client._stop.set();thread.join(1)
|
||||
self.assertGreaterEqual(len(calls),3)
|
||||
self.assertEqual(set(calls),{'tactile_preview'})
|
||||
self.assertEqual(client._frames['left_shear'],b'jpeg')
|
||||
self.assertEqual(len(client._force_history['left']),1)
|
||||
self.assertEqual(client._force_cursors['left'],1)
|
||||
Reference in New Issue
Block a user