Skip to content

Commit 9c97f7e

Browse files
committed
add bridgeui folder for HALUI
1 parent ffee136 commit 9c97f7e

2 files changed

Lines changed: 305 additions & 0 deletions

File tree

lib/python/bridgeui/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
2+
3+

lib/python/bridgeui/bridge.py

Lines changed: 302 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,302 @@
1+
#!/usr/bin/env python3
2+
3+
import os
4+
import sys
5+
import time
6+
7+
import json
8+
import signal
9+
10+
import hal
11+
from qtvcp.qt_halobjects import Qhal
12+
from common.iniinfo import _IStat as IStatParent
13+
from common import logger
14+
15+
# LOG is for running code logging
16+
LOG = logger.initBaseLogger('HAL bridge', log_file=None,
17+
log_level=logger.WARNING, logToFile=False)
18+
19+
# Force the log level for this module
20+
LOG.setLevel(logger.DEBUG) # One of DEBUG, INFO, WARNING, ERROR, CRITICAL
21+
22+
try:
23+
import zmq
24+
ZMQ = True
25+
except:
26+
LOG.critical('ZMQ python library problem - Is python3-zmq installed?')
27+
ZMQ = False
28+
29+
class Info(IStatParent):
30+
_instance = None
31+
_instanceNum = 0
32+
33+
def __new__(cls, *args, **kwargs):
34+
if not cls._instance:
35+
cls._instance = IStatParent.__new__(cls, *args, **kwargs)
36+
return cls._instance
37+
38+
# Instantiate the library with global reference
39+
40+
41+
class Bridge(object):
42+
def __init__(self, readAddress = "tcp://127.0.0.1:5690",
43+
writeAddress = "tcp://127.0.0.1:5691"):
44+
super(Bridge, self).__init__()
45+
self.INFO = Info()
46+
47+
self.currentSelectedAxis = 'None'
48+
self.axesSelected = {'X':0,'Y':0,'Z':0,'A':0,'B':0,'C':0,
49+
'U':0,'V':0,'W':0}
50+
self.readAddress = readAddress
51+
self.writeAddress = writeAddress
52+
LOG.debug('read port: {}'.format(readAddress))
53+
LOG.debug('write port: {}'.format(writeAddress))
54+
55+
self.readTopic = ""
56+
self.writeTopic = "STATUSREQUEST"
57+
58+
# catch control c and terminate signals
59+
signal.signal(signal.SIGTERM, self.shutdown)
60+
signal.signal(signal.SIGINT, self.shutdown)
61+
62+
self.init_hal()
63+
if ZMQ:
64+
self.init_read()
65+
self.init_write()
66+
67+
def update(self, *arg):
68+
print(self, arg)
69+
raw=arg[0]; row=arg[1];column=arg[2];state=arg[3]
70+
LOG.debug('raw {}, row {}, col {}, state {}'.format(raw,row,column,state))
71+
print ('raw',raw,'row:',row,'column:',column,'state:',state)
72+
self.writeMsg('set_selected_axis','Y')
73+
self.activeJoint.set(10)
74+
75+
def init_hal(self):
76+
self.comp = h = hal.component("bridge")
77+
QHAL = Qhal(comp=self.comp, hal=hal)
78+
79+
self.jogRate = QHAL.newpin("jog-rate", hal.HAL_FLOAT, hal.HAL_OUT)
80+
self.jogRateIn = QHAL.newpin("jog-rate-in", hal.HAL_FLOAT, hal.HAL_IN)
81+
self.jogRateIn.pinValueChanged.connect(self.pinChanged)
82+
83+
self.jogRateAngular = QHAL.newpin("jog-rate-angular", hal.HAL_FLOAT, hal.HAL_OUT)
84+
self.jogRateAngularIn = QHAL.newpin("jog-rate-angular-in", hal.HAL_FLOAT, hal.HAL_OUT)
85+
self.jogRateAngularIn.pinValueChanged.connect(self.pinChanged)
86+
87+
self.jogIncrement = QHAL.newpin("jog-increment", hal.HAL_FLOAT, hal.HAL_OUT)
88+
self.jogIncrementAngular = QHAL.newpin("jog-increment-angular", hal.HAL_FLOAT, hal.HAL_OUT)
89+
self.activeJoint = QHAL.newpin('joint-selected', hal.HAL_S32, hal.HAL_OUT)
90+
91+
for i in (self.INFO.AVAILABLE_AXES):
92+
let = i.lower()
93+
# input
94+
self['axis{}Select'.format(let)] = QHAL.newpin('axis-%s-select'%let, hal.HAL_BIT, hal.HAL_IN)
95+
self['axis{}Select'.format(let)].pinValueChanged.connect(self.pinChanged)
96+
# output
97+
self['Axis{}IsSelected'.format(let)] = QHAL.newpin('axis-%s-is-selected'%let, hal.HAL_BIT, hal.HAL_OUT)
98+
99+
self.cycle_start = QHAL.newpin('cycle-start-in',QHAL.HAL_BIT, QHAL.HAL_IN)
100+
self.cycle_start.pinValueChanged.connect(self.pinChanged)
101+
self.cycle_pause = QHAL.newpin('cycle-pause-in',QHAL.HAL_BIT, QHAL.HAL_IN)
102+
self.cycle_pause.pinValueChanged.connect(self.pinChanged)
103+
104+
for i in self.INFO.MDI_COMMAND_DICT:
105+
LOG.debug('{} {}'.format(i,self.INFO.MDI_COMMAND_DICT.get(i)))
106+
self[i] = QHAL.newpin('ini-mdi-cmd-{}'.format(i),QHAL.HAL_BIT, QHAL.HAL_IN)
107+
self[i].pinValueChanged.connect(self.runMacroChanged)
108+
109+
for i in self.INFO.INI_MACROS:
110+
name = i.split()[0]
111+
LOG.debug('{} {}'.format(name,i))
112+
self[name] = QHAL.newpin('ini-macro-cmd-{}'.format(name),QHAL.HAL_BIT, QHAL.HAL_IN)
113+
self[name].pinValueChanged.connect(self.runMacroChanged)
114+
115+
QHAL.setUpdateRate(100)
116+
h.ready()
117+
118+
def init_write(self):
119+
context = zmq.Context()
120+
self.writeSocket = context.socket(zmq.PUB)
121+
self.writeSocket.bind(self.writeAddress)
122+
123+
def init_read(self):
124+
# ZeroMQ Context
125+
self.readContext = zmq.Context()
126+
127+
# Define the socket using the "Context"
128+
self.readSocket = self.readContext.socket(zmq.SUB)
129+
130+
# Define subscription and messages with topic to accept.
131+
self.readSocket.setsockopt_string(zmq.SUBSCRIBE, self.readTopic)
132+
self.readSocket.connect(self.readAddress)
133+
134+
# callback from ZMQ read socket
135+
def readMsg(self, msg):
136+
if self.readSocket.getsockopt(zmq.EVENTS) & zmq.POLLIN:
137+
while self.readSocket.getsockopt(zmq.EVENTS) & zmq.POLLIN:
138+
# get raw message
139+
topic, data = self.readSocket.recv_multipart()
140+
# convert from json object to python object
141+
y = json.loads(data)
142+
self. action(y.get('MESSAGE'),y.get('ARGS'))
143+
144+
# set our output HAL pins from messages from hal_glib
145+
def action(self, msg, data):
146+
LOG.debug('{} {}'.format(msg, data))
147+
if msg == 'jograte-changed':
148+
self.jogRate.set(float(data[0]))
149+
elif msg == 'jograte-angular-changed':
150+
self.jogRateAngular.set(float(data[0]))
151+
elif msg == 'jogincrements-changed':
152+
self.jogIncrement.set(float(data[0][0]))
153+
elif msg == 'jogincrement-angular-changed':
154+
self.jogIncremtAngular.set(float(data[0][0]))
155+
elif msg == 'joint-selection-changed':
156+
self.activeJoint.set(int(data[0]))
157+
elif msg == 'axis-selection-changed':
158+
flag = 1
159+
for i in(self.INFO.AVAILABLE_AXES):
160+
if data[0] == i:
161+
state = True
162+
self.currentSelectedAxis = data[0]
163+
flag = 0
164+
else:
165+
state = False
166+
self['Axis{}IsSelected'.format(i.lower())].set(state)
167+
self.axesSelected[i] = int(state)
168+
if flag:
169+
self.currentSelectedAxis = 'None'
170+
#print ('axis state', self.axesSelected)
171+
172+
# send msg to hal_glib
173+
def writeMsg(self, msg, data):
174+
print('Write Msg called')
175+
if ZMQ:
176+
topic = self.writeTopic
177+
message = json.dumps({'FUNCTION':msg,'ARGS':data})
178+
LOG.debug('Sending ZMQ Message:{} {}'.format(topic, message))
179+
self.writeSocket.send_multipart(
180+
[bytes(topic.encode('utf-8')),
181+
bytes((message).encode('utf-8'))])
182+
183+
# callback from HAL input pins
184+
def pinChanged(self, pinObject, value):
185+
LOG.debug('Pin name:{} changed value to {}'.format(pinObject.text(), value))
186+
#print(type(value))
187+
# Axis selction change request
188+
if 'select' in pinObject.text():
189+
if bool(value) == False:
190+
pass
191+
#print('Not true state')
192+
return
193+
for i in (self.INFO.AVAILABLE_AXES):
194+
if '-{}-'.format(i.lower()) in pinObject.text():
195+
self.writeMsg('set_selected_axis', i)
196+
break
197+
else:
198+
if 'None' in pinObject.text():
199+
self.writeMsg('set_selected_axis', '')
200+
201+
# cycle start
202+
elif self.cycle_start == pinObject:
203+
if value:
204+
self.writeMsg('request_cycle_start', value)
205+
206+
# cycle pause
207+
elif self.cycle_pause == pinObject:
208+
#if value:
209+
self.writeMsg('request_cycle_pause', value)
210+
211+
# linear jog rate
212+
elif self.jogRateIn == pinObject:
213+
self.writeMsg('set_jograte', value)
214+
215+
# angular jog rate
216+
elif self.jogRateAngularIn == pinObject:
217+
self.writeMsg('set_jograte_angular', value)
218+
219+
# catch all default
220+
else:
221+
self.writeMsg(pinObject.text(),value)
222+
223+
# callback; request to run a specific macro
224+
def runMacroChanged(self, pinObject, value):
225+
LOG.debug('Macro Pin name:{} changed value to {}'.format(pinObject.text(), value))
226+
#LOG.debug(type(value))
227+
name = pinObject.text().strip('macro-cmd-')
228+
if value:
229+
self.writeMsg('request_macro_call', name)
230+
231+
def shutdown(self,signum=None,stack_frame=None):
232+
LOG.debug('shutdown')
233+
global app
234+
app.quit()
235+
236+
def getJogRate(self):
237+
return self.jogRate.get()
238+
def setJogRate(self, value):
239+
self.writeMsg('set_jograte', value)
240+
241+
def getJogRateAngular(self):
242+
return self.jogRateAngular.get()
243+
def setJogRateAngular(self, value):
244+
self.writeMsg('set_jograte_angular', value)
245+
246+
def getSelectedAxis(self):
247+
name = self.currentSelectedAxis
248+
if name == 'None':
249+
index = -1
250+
else:
251+
index = 'XYZABCUVW'.index(name)
252+
return index
253+
def setSelectedAxis(self, value):
254+
if value < 0:
255+
letter = 'None'
256+
else:
257+
letter ='XYZABCUVW'[value]
258+
self.writeMsg('set_selected_axis', letter)
259+
260+
def isAxisSelected(self, index):
261+
letter = 'XYZABCUVW'[index]
262+
return int(self.axesSelected[letter])
263+
264+
def __getitem__(self, item):
265+
return getattr(self, item)
266+
def __setitem__(self, item, value):
267+
return setattr(self, item, value)
268+
269+
if __name__ == "__main__":
270+
import sys
271+
import getopt
272+
from PyQt5.QtWidgets import QApplication
273+
274+
letters = 'dh' # the : means an argument needs to be passed after the letter
275+
keywords = ['readport=', 'writeport=' ] # the = means that a value is expected after
276+
# the keyword
277+
278+
opts, extraparam = getopt.getopt(sys.argv[1:],letters,keywords)
279+
# starts at the second element of argv since the first one is the script name
280+
# extraparms are extra arguments passed after all option/keywords are assigned
281+
# opts is a list containing the pair "option"/"value"
282+
283+
readport = "tcp://127.0.0.1:5690"
284+
writeport = "tcp://127.0.0.1:5691"
285+
286+
for o,p in opts:
287+
if o in ['-d']:
288+
LOG.setLevel(logger.DEBUG)
289+
elif o in ['--readport']:
290+
readport = p
291+
elif o in ['--writeport']:
292+
writeport = p
293+
elif o in ['-h','--help']:
294+
print('HAL bridge: GUI to HAL interface using ZMQ')
295+
print('option "-d" = debug print mode')
296+
print('option "--readport=" read socket address')
297+
print('option "--writeport=" write socket address')
298+
print('example: hal_bridge -d --readport=tcp://127.0.0.1:5692')
299+
300+
app = QApplication(sys.argv)
301+
test = Bridge(readport, writeport)
302+
sys.exit(app.exec_())

0 commit comments

Comments
 (0)