linuxcnc/lib/python/hal_glib.py
2023-01-04 22:57:00 -08:00

1223 lines
50 KiB
Python

#!/usr/bin/env python3
# vim: sts=4 sw=4 et
import _hal, hal
import linuxcnc
import os
import math
from gi.repository import GObject
from gi.repository import GLib
# constants
JOGJOINT = 1
JOGTELEOP = 0
# add try for QtVCP Designer and probably GTK GLADE editor too
# The INI file is not available then
try:
inifile = linuxcnc.ini(os.environ['INI_FILE_NAME'])
trajcoordinates = inifile.find("TRAJ", "COORDINATES").lower().replace(" ", "")
jointcount = int(inifile.find("KINS", "JOINTS"))
except:
pass
try:
# get cycle time which could be in ms or seconds
# convert to ms - use this to set update time
ct = float(inifile.find('DISPLAY', 'CYCLE_TIME') or 100)
if ct < 1:
CYCLE_TIME = int(ct * 1000)
else:
CYCLE_TIME = int(ct)
except:
CYCLE_TIME = 100
class GPin(GObject.Object, hal.Pin):
__gtype_name__ = 'GPin'
__gsignals__ = {'value-changed': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, ())}
REGISTRY = []
UPDATE = False
def __init__(self, *a, **kw):
GObject.Object.__init__(self)
hal.Pin.__init__(self, *a, **kw)
self._item_wrap(self._item)
self._prev = None
self.REGISTRY.append(self)
self.update_start()
def update(self):
tmp = self.get()
if tmp != self._prev:
self.emit('value-changed')
self._prev = tmp
@classmethod
def update_all(self):
if not self.UPDATE:
return
kill = []
for p in self.REGISTRY:
try:
p.update()
except:
kill.append(p)
print("Error updating pin %s; Removing" % p)
for p in kill:
self.REGISTRY.remove(p)
return self.UPDATE
@classmethod
def update_start(self, timeout=100):
if GPin.UPDATE:
return
GPin.UPDATE = True
GLib.timeout_add(timeout, self.update_all)
@classmethod
def update_stop(self, timeout=100):
GPin.UPDATE = False
class GComponent:
def __init__(self, comp):
if isinstance(comp, GComponent):
comp = comp.comp
self.comp = comp
def newpin(self, *a, **kw): return GPin(_hal.component.newpin(self.comp, *a, **kw))
def getpin(self, *a, **kw): return GPin(_hal.component.getpin(self.comp, *a, **kw))
def exit(self, *a, **kw): return self.comp.exit(*a, **kw)
def __getitem__(self, k): return self.comp[k]
def __setitem__(self, k, v): self.comp[k] = v
class _GStat(GObject.GObject):
'''Emits signals based on linuxcnc status '''
__gsignals__ = {
'periodic': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, ()),
'state-estop': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, ()),
'state-estop-reset': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, ()),
'state-on': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, ()),
'state-off': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, ()),
'homed': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, (GObject.TYPE_STRING,)),
'unhomed': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, (GObject.TYPE_STRING,)),
'all-homed': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, ()),
'not-all-homed': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, (GObject.TYPE_STRING,)),
'override-limits-changed': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, (GObject.TYPE_BOOLEAN, GObject.TYPE_PYOBJECT,)),
'hard-limits-tripped': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, (GObject.TYPE_BOOLEAN, GObject.TYPE_PYOBJECT,)),
'mode-manual': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, ()),
'mode-auto': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, ()),
'mode-mdi': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, ()),
'command-running': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, ()),
'command-stopped': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, ()),
'command-error': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, ()),
'interp-run': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, ()),
'interp-idle': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, ()),
'interp-paused': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, ()),
'interp-reading': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, ()),
'interp-waiting': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, ()),
'jograte-changed': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, (GObject.TYPE_FLOAT,)),
'jograte-angular-changed': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, (GObject.TYPE_FLOAT,)),
'jogincrement-changed': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, (GObject.TYPE_FLOAT, GObject.TYPE_STRING)),
'jogincrement-angular-changed': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, (GObject.TYPE_FLOAT, GObject.TYPE_STRING)),
'joint-selection-changed': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, (GObject.TYPE_INT,)),
'axis-selection-changed': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, (GObject.TYPE_STRING,)),
'program-pause-changed': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, (GObject.TYPE_BOOLEAN,)),
'optional-stop-changed': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, (GObject.TYPE_BOOLEAN,)),
'block-delete-changed': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, (GObject.TYPE_BOOLEAN,)),
'file-loaded': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, (GObject.TYPE_STRING,)),
'reload-display': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, ()),
'line-changed': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, (GObject.TYPE_INT,)),
'tool-in-spindle-changed': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, (GObject.TYPE_INT,)),
'tool-prep-changed': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, (GObject.TYPE_INT,)),
'tool-info-changed': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, (GObject.TYPE_PYOBJECT,)),
'current-tool-offset': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, (GObject.TYPE_PYOBJECT,)),
'motion-mode-changed': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, (GObject.TYPE_INT,)),
'motion-type-changed': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, (GObject.TYPE_INT,)),
'spindle-control-changed': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE,
(GObject.TYPE_INT, GObject.TYPE_BOOLEAN, GObject.TYPE_INT, GObject.TYPE_BOOLEAN)),
'current-feed-rate': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, (GObject.TYPE_FLOAT,)),
'current-x-rel-position': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, (GObject.TYPE_FLOAT,)),
'current-position': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, (GObject.TYPE_PYOBJECT,GObject.TYPE_PYOBJECT,
GObject.TYPE_PYOBJECT, GObject.TYPE_PYOBJECT,)),
'current-z-rotation': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_FLOAT,)),
'requested-spindle-speed-changed': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_FLOAT,)),
'actual-spindle-speed-changed': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_FLOAT,)),
'spindle-override-changed': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_FLOAT,)),
'feed-override-changed': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_FLOAT,)),
'rapid-override-changed': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_FLOAT,)),
'max-velocity-override-changed': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_FLOAT,)),
'feed-hold-enabled-changed': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_BOOLEAN,)),
'g90-mode': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_BOOLEAN,)),
'g91-mode': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_BOOLEAN,)),
'itime-mode': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_BOOLEAN,)),
'fpm-mode': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_BOOLEAN,)),
'fpr-mode': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_BOOLEAN,)),
'css-mode': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_BOOLEAN,)),
'rpm-mode': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_BOOLEAN,)),
'radius-mode': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_BOOLEAN,)),
'diameter-mode': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_BOOLEAN,)),
'flood-changed': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_BOOLEAN,)),
'mist-changed': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_BOOLEAN,)),
'm-code-changed': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_STRING,)),
'g-code-changed': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_STRING,)),
'f-code-changed': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_FLOAT,)),
'blend-code-changed': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_FLOAT, GObject.TYPE_FLOAT)),
'metric-mode-changed': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_BOOLEAN,)),
'user-system-changed': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_STRING,)),
'mdi-line-selected': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_STRING, GObject.TYPE_STRING)),
'gcode-line-selected': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_INT,)),
'graphics-line-selected': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_INT,)),
'graphics-loading-progress': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_INT,)),
'graphics-gcode-error': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_STRING,)),
'graphics-gcode-properties': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_PYOBJECT,)),
'graphics-view-changed': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_STRING, GObject.TYPE_PYOBJECT)),
'mdi-history-changed': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, ()),
'machine-log-changed': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, ()),
'update-machine-log': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_STRING, GObject.TYPE_STRING)),
'move-text-lineup': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, ()),
'move-text-linedown': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, ()),
'dialog-request': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_PYOBJECT,)),
'focus-overlay-changed': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_BOOLEAN, GObject.TYPE_STRING,
GObject.TYPE_PYOBJECT)),
'play-sound': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, (GObject.TYPE_STRING,)),
'virtual-keyboard': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, (GObject.TYPE_STRING,)),
'dro-reference-change-request': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, (GObject.TYPE_INT,)),
'system_notify_button_pressed': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE,
(GObject.TYPE_STRING, GObject.TYPE_BOOLEAN)),
'show-preference': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, ()),
'shutdown': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, ()),
'error': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, (GObject.TYPE_INT, GObject.TYPE_STRING)),
'general': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, (GObject.TYPE_PYOBJECT,)),
'forced-update': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, ()),
'progress': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE, (GObject.TYPE_INT, GObject.TYPE_PYOBJECT)),
'following-error': (GObject.SignalFlags.RUN_FIRST , GObject.TYPE_NONE,(GObject.TYPE_PYOBJECT,)),
}
STATES = { linuxcnc.STATE_ESTOP: 'state-estop'
, linuxcnc.STATE_ESTOP_RESET: 'state-estop-reset'
, linuxcnc.STATE_ON: 'state-on'
, linuxcnc.STATE_OFF: 'state-off'
}
MODES = { linuxcnc.MODE_MANUAL: 'mode-manual'
, linuxcnc.MODE_AUTO: 'mode-auto'
, linuxcnc.MODE_MDI: 'mode-mdi'
}
INTERP = { linuxcnc.INTERP_WAITING: 'interp-waiting'
, linuxcnc.INTERP_READING: 'interp-reading'
, linuxcnc.INTERP_PAUSED: 'interp-paused'
, linuxcnc.INTERP_IDLE: 'interp-idle'
}
TEMPARARY_MESSAGE = 255
OPERATOR_ERROR = linuxcnc.OPERATOR_ERROR
OPERATOR_TEXT = linuxcnc.OPERATOR_TEXT
NML_ERROR = linuxcnc.NML_ERROR
NML_TEXT = linuxcnc.NML_TEXT
MANUAL = linuxcnc.MODE_MANUAL
AUTO = linuxcnc.MODE_AUTO
MDI = linuxcnc.MODE_MDI
STATE_ESTOP = linuxcnc.STATE_ESTOP
STATE_ESTOP_RESET = linuxcnc.STATE_ESTOP_RESET
STATE_ON = linuxcnc.STATE_ON
STATE_OFF = linuxcnc.STATE_OFF
def __init__(self, stat = None):
GObject.Object.__init__(self)
self.stat = stat or linuxcnc.stat()
self.cmd = linuxcnc.command()
self._status_active = False
self.old = {}
self.old['tool-prep-number'] = 0
try:
self.stat.poll()
self.merge()
except:
pass
self.current_jog_rate = 15
self.current_angular_jog_rate = 360
self.current_jog_distance = 0
self.current_jog_distance_text =''
self.current_jog_distance_angular= 0
self.current_jog_distance_angular_text =''
self.selected_joint = -1
self.selected_axis = ''
self._is_all_homed = False
self.set_timer()
# we put this in a function so qtvcp
# can override it to fix a seg fault
def set_timer(self):
GLib.timeout_add(CYCLE_TIME, self.update)
def merge(self):
self.old['command-state'] = self.stat.state
self.old['state'] = self.stat.task_state
self.old['mode'] = self.stat.task_mode
self.old['interp']= self.stat.interp_state
# Only update file if call level is 0, which
# means we are not executing a subroutine/remap
# This avoids emitting signals for bogus file names below
if self.stat.call_level == 0:
self.old['file'] = self.stat.file
self.old['paused']= self.stat.paused
self.old['line'] = self.stat.motion_line
self.old['homed'] = self.stat.homed
self.old['tool-in-spindle'] = self.stat.tool_in_spindle
try:
if hal.get_value('iocontrol.0.tool-prepare'):
self.old['tool-prep-number'] = hal.get_value('iocontrol.0.tool-prep-number')
except RuntimeError:
self.old['tool-prep-number'] = -1
self.old['motion-mode'] = self.stat.motion_mode
self.old['motion-type'] = self.stat.motion_type
self.old['spindle-or'] = self.stat.spindle[0]['override']
self.old['feed-or'] = self.stat.feedrate
self.old['rapid-or'] = self.stat.rapidrate
self.old['max-velocity-or'] = self.stat.max_velocity
self.old['feed-hold'] = self.stat.feed_hold_enabled
self.old['g5x-index'] = self.stat.g5x_index
self.old['spindle-enabled'] = self.stat.spindle[0]['enabled']
self.old['spindle-direction'] = self.stat.spindle[0]['direction']
self.old['block-delete']= self.stat.block_delete
self.old['optional-stop']= self.stat.optional_stop
try:
self.old['actual-spindle-speed'] = hal.get_value('spindle.0.speed-in') * 60
except RuntimeError:
self.old['actual-spindle-speed'] = 0
try:
self.old['spindle-at-speed'] = hal.get_value('spindle.0.at-speed')
except RuntimeError:
self.old['spindle-at-speed'] = False
self.old['flood']= self.stat.flood
self.old['mist']= self.stat.mist
self.old['current-z-rotation'] = self.stat.rotation_xy
self.old['current-tool-offset'] = self.stat.tool_offset
# override limits / hard limits
or_limit_list=[]
hard_limit_list = []
ferror = []
hard_limit = False
or_limit_set = False
for j in range(0, self.stat.joints):
or_limit_list.append( self.stat.joint[j]['override_limits'])
or_limit_set = or_limit_set or self.stat.joint[j]['override_limits']
min_hard_limit = self.stat.joint[j]['min_hard_limit']
max_hard_limit = self.stat.joint[j]['max_hard_limit']
hard_limit = hard_limit or min_hard_limit or max_hard_limit
hard_limit_list.append([min_hard_limit,max_hard_limit])
ferror.append(self.stat.joint[j]['ferror_current'])
self.old['override-limits'] = or_limit_list
self.old['override-limits-set'] = bool(or_limit_set)
self.old['hard-limits-tripped'] = bool(hard_limit)
self.old['hard-limits-list'] = hard_limit_list
self.old['ferror-current'] = ferror
# active G-codes
active_gcodes = []
codes =''
for i in sorted(self.stat.gcodes[1:]):
if i == -1: continue
if i % 10 == 0:
active_gcodes.append("G%d" % (i/10))
else:
active_gcodes.append("G%d.%d" % (i/10, i%10))
for i in active_gcodes:
codes = codes +('%s '%i)
self.old['g-code'] = codes
# extract specific G-code modes
itime = fpm = fpr = css = rpm = metric = False
radius = diameter = adm = idm = False
for num,i in enumerate(active_gcodes):
if i == 'G90': adm = True
elif i == 'G91': idm = True
elif i == 'G93': itime = True
elif i == 'G94': fpm = True
elif i == 'G95': fpr = True
elif i == 'G96': css = True
elif i == 'G97': rpm = True
elif i == 'G21': metric = True
elif i == 'G7': diameter = True
elif i == 'G8': radius = True
self.old['g90'] = adm
self.old['g91'] = idm
self.old['itime'] = itime
self.old['fpm'] = fpm
self.old['fpr'] = fpr
self.old['css'] = css
self.old['rpm'] = rpm
self.old['metric'] = metric
self.old['radius'] = radius
self.old['diameter'] = diameter
if css:
try:
self.old['spindle-speed']= hal.get_value('spindle.0.speed-out')
except RuntimeError:
self.old['spindle-speed']= self.stat.spindle[0]['speed']
else:
self.old['spindle-speed']= self.stat.spindle[0]['speed']
# active M-codes
active_mcodes = []
mcodes = ''
for i in sorted(self.stat.mcodes[1:]):
if i == -1: continue
active_mcodes.append("M%d"%i )
for i in active_mcodes:
mcodes = mcodes + ("%s "%i)
#active_mcodes.append("M%s "%i)
self.old['m-code'] = mcodes
self.old['tool-info'] = self.stat.tool_table[0]
settings = self.stat.settings
self.old['f-code'] = settings[1]
self.old['blend-tolerance-code'] = settings[3]
self.old['nativecam-tolerance-code'] = settings[4]
def update(self):
try:
self.stat.poll()
except:
self._status_active = False
# some things might not need linuxcnc status but do need periodic
self.emit('periodic')
# Reschedule
return True
self._status_active = True
old = dict(self.old)
self.merge()
cmd_state_old = old.get('command-state')
cmd_state_new = self.old['command-state']
if cmd_state_new != cmd_state_old:
if cmd_state_new == linuxcnc.RCS_EXEC:
self.emit('command-running')
elif cmd_state_new == linuxcnc.RCS_DONE:
self.emit('command-stopped')
elif cmd_state_new == linuxcnc.RCS_ERROR:
self.emit('command-error')
state_old = old.get('state', 0)
state_new = self.old['state']
if state_new != state_old:
# set machine estop/clear
if state_old == linuxcnc.STATE_ESTOP and state_new == linuxcnc.STATE_ESTOP_RESET:
self.emit('state-estop-reset')
self.emit('interp-idle')
elif state_new == linuxcnc.STATE_ESTOP:
self.emit('state-estop')
self.emit('interp-idle')
# set machine on/off
if state_new == linuxcnc.STATE_ON:
self.emit('state-on')
elif state_old == linuxcnc.STATE_ON and state_new < linuxcnc.STATE_ON:
self.emit('state-off')
# reset modes/interpreter on machine on
if state_new == linuxcnc.STATE_ON:
old['mode'] = 0
old['interp'] = 0
mode_old = old.get('mode', 0)
mode_new = self.old['mode']
if mode_new != mode_old:
self.emit(self.MODES[mode_new])
interp_old = old.get('interp', 0)
interp_new = self.old['interp']
if interp_new != interp_old:
if not interp_old or interp_old == linuxcnc.INTERP_IDLE:
self.emit('interp-run')
self.emit(self.INTERP[interp_new])
# paused
paused_old = old.get('paused', None)
paused_new = self.old['paused']
if paused_new != paused_old:
self.emit('program-pause-changed',paused_new)
# block delete
block_delete_old = old.get('block-delete', None)
block_delete_new = self.old['block-delete']
if block_delete_new != block_delete_old:
self.emit('block-delete-changed',block_delete_new)
# optional_stop
optional_stop_old = old.get('optional-stop', None)
optional_stop_new = self.old['optional-stop']
if optional_stop_new != optional_stop_old:
self.emit('optional-stop-changed',optional_stop_new)
# file changed
file_old = old.get('file', None)
file_new = self.old['file']
if file_new != file_old:
# if interpreter is reading or waiting, the new file
# is a remap procedure, with the following test we
# partly avoid emitting a signal in that case, which would cause
# a reload of the preview and sourceview widgets. A signal could
# still be emitted if aborting a program shortly after it ran an
# external file subroutine, but that is fixed by not updating the
# file name if call level != 0 in the merge() function above.
# do avoid that a signal is emitted in that case, causing
# a reload of the preview and sourceview widgets
if self.stat.interp_state == linuxcnc.INTERP_IDLE:
self.emit('file-loaded', file_new)
#ToDo : Find a way to avoid signal when the line changed due to
# a remap procedure, because the signal do highlight a wrong
# line in the code
# current line
line_old = old.get('line', None)
line_new = self.old['line']
if line_new != line_old:
self.emit('line-changed', line_new)
tool_old = old.get('tool-in-spindle', None)
tool_new = self.old['tool-in-spindle']
if tool_new != tool_old:
self.emit('tool-in-spindle-changed', tool_new)
tool_num_old = old.get('tool-prep-number')
tool_num_new = self.old['tool-prep-number']
if tool_num_new != tool_num_old:
self.emit('tool-prep-changed', tool_num_new)
motion_mode_old = old.get('motion-mode', None)
motion_mode_new = self.old['motion-mode']
if motion_mode_new != motion_mode_old:
self.emit('motion-mode-changed', motion_mode_new)
motion_type_old = old.get('motion-type', None)
motion_type_new = self.old['motion-type']
if motion_type_new != motion_type_old:
self.emit('motion-type-changed', motion_type_new)
# if the homed status has changed
# check number of homed joints against number of available joints
# if they are equal send the all-homed signal
# else send the not-all-homed signal (with a string of unhomed joint numbers)
# if a joint is homed send 'homed' (with a string of homed joint number)
homed_joint_old = old.get('homed', None)
homed_joint_new = self.old['homed']
if homed_joint_new != homed_joint_old:
homed_joints = 0
unhomed_joints = ""
for joint in range(0, self.stat.joints):
if self.stat.homed[joint]:
homed_joints += 1
self.emit('homed', joint)
else:
self.emit('unhomed', joint)
unhomed_joints += str(joint)
if homed_joints == self.stat.joints:
self._is_all_homed = True
self.emit('all-homed')
else:
self._is_all_homed = False
self.emit('not-all-homed', unhomed_joints)
# override limits
or_limits_old = old.get('override-limits', None)
or_limits_new = self.old['override-limits']
or_limits_set_new = self.old['override-limits-set']
if or_limits_new != or_limits_old:
self.emit('override-limits-changed',or_limits_set_new, or_limits_new)
# hard limits tripped
t_list_old = old.get('hard-limits-list')
t_list_new = self.old['hard-limits-list']
if t_list_new != t_list_old:
hard_limits_tripped_new = self.old['hard-limits-tripped']
self.emit('hard-limits-tripped',hard_limits_tripped_new, t_list_new)
# current velocity
self.emit('current-feed-rate',self.stat.current_vel * 60.0)
# X relative position
position = self.stat.actual_position[0]
g5x_offset = self.stat.g5x_offset[0]
tool_offset = self.stat.tool_offset[0]
g92_offset = self.stat.g92_offset[0]
self.emit('current-x-rel-position',position-g5x_offset-tool_offset-g92_offset)
# calculate position offsets (native units)
p,rel_p,dtg = self.get_position()
self.emit('current-position',p, rel_p, dtg, self.stat.joint_actual_position)
# ferror
self.emit('following-error', self.old['ferror-current'])
# spindle control
spindle_enabled_old = old.get('spindle-enabled', None)
spindle_enabled_new = self.old['spindle-enabled']
spindle_direction_old = old.get('spindle-direction', None)
spindle_direction_new = self.old['spindle-direction']
up_to_speed_old = old.get('spindle-at-speed',None)
up_to_speed_new = self.old['spindle-at-speed']
if up_to_speed_new != up_to_speed_old or \
spindle_enabled_new != spindle_enabled_old or \
spindle_direction_new != spindle_direction_old:
self.emit('spindle-control-changed', 0, spindle_enabled_new, spindle_direction_new, up_to_speed_new)
# requested spindle speed
spindle_spd_old = old.get('spindle-speed', None)
spindle_spd_new = self.old['spindle-speed']
if spindle_spd_new != spindle_spd_old:
self.emit('requested-spindle-speed-changed', spindle_spd_new)
# actual spindle speed
act_spindle_spd_old = old.get('actual-spindle-speed', None)
act_spindle_spd_new = self.old['actual-spindle-speed']
if act_spindle_spd_new != act_spindle_spd_old:
self.emit('actual-spindle-speed-changed', act_spindle_spd_new)
# spindle override
spindle_or_old = old.get('spindle-or', None)
spindle_or_new = self.old['spindle-or']
if spindle_or_new != spindle_or_old:
self.emit('spindle-override-changed',spindle_or_new * 100)
# feed override
feed_or_old = old.get('feed-or', None)
feed_or_new = self.old['feed-or']
if feed_or_new != feed_or_old:
self.emit('feed-override-changed',feed_or_new * 100)
# rapid override
rapid_or_old = old.get('rapid-or', None)
rapid_or_new = self.old['rapid-or']
if rapid_or_new != rapid_or_old:
self.emit('rapid-override-changed',rapid_or_new * 100)
# max-velocity override
max_velocity_or_old = old.get('max-velocity-or', None)
max_velocity_or_new = self.old['max-velocity-or']
if max_velocity_or_new != max_velocity_or_old:
# work around misconfigured config (missing MAX_LINEAR_VELOCITY in TRAJ)
if max_velocity_or_new != 1e99:
self.emit('max-velocity-override-changed',max_velocity_or_new * 60)
# feed hold
feed_hold_old = old.get('feed-hold', None)
feed_hold_new = self.old['feed-hold']
if feed_hold_new != feed_hold_old:
self.emit('feed-hold-enabled-changed',feed_hold_new)
# mist
mist_old = old.get('mist', None)
mist_new = self.old['mist']
if mist_new != mist_old:
self.emit('mist-changed',mist_new)
# flood
flood_old = old.get('flood', None)
flood_new = self.old['flood']
if flood_new != flood_old:
self.emit('flood-changed',flood_new)
# rotation around Z
z_rot_old = old.get('current-z-rotation', None)
z_rot_new = self.old['current-z-rotation']
if z_rot_new != z_rot_old:
self.emit('current-z-rotation',z_rot_new)
# current tool offsets
tool_off_old = old.get('current-tool-offset', None)
tool_off_new = self.old['current-tool-offset']
if tool_off_new != tool_off_old:
self.emit('current-tool-offset',tool_off_new)
#############################
# Gcodes
#############################
# G-codes
g_code_old = old.get('g-code', None)
g_code_new = self.old['g-code']
if g_code_new != g_code_old:
self.emit('g-code-changed',g_code_new)
# metric mode g21
metric_old = old.get('metric', None)
metric_new = self.old['metric']
if metric_new != metric_old:
self.emit('metric-mode-changed',metric_new)
# G5x (active user system)
g5x_index_old = old.get('g5x-index', None)
g5x_index_new = self.old['g5x-index']
if g5x_index_new != g5x_index_old:
self.emit('user-system-changed',g5x_index_new)
# absolute mode g90
g90_old = old.get('g90', None)
g90_new = self.old['g90']
if g90_new != g90_old:
self.emit('g90-mode',g90_new)
# incremental mode g91
g91_old = old.get('g91', None)
g91_new = self.old['g91']
if g91_new != g91_old:
self.emit('g91-mode',g91_new)
# inverse time mode g93
itime_old = old.get('itime', None)
itime_new = self.old['itime']
if itime_new != itime_old:
self.emit('itime-mode',itime_new)
# feed per minute mode g94
fpm_old = old.get('fpm', None)
fpm_new = self.old['fpm']
if fpm_new != fpm_old:
self.emit('fpm-mode',fpm_new)
# feed per revolution mode g95
fpr_old = old.get('fpr', None)
fpr_new = self.old['fpr']
if fpr_new != fpr_old:
self.emit('fpr-mode',fpr_new)
# css mode g96
css_old = old.get('css', None)
css_new = self.old['css']
if css_new != css_old:
self.emit('css-mode',css_new)
# rpm mode g97
rpm_old = old.get('rpm', None)
rpm_new = self.old['rpm']
if rpm_new != rpm_old:
self.emit('rpm-mode',rpm_new)
# radius mode g8
radius_old = old.get('radius', None)
radius_new = self.old['radius']
if radius_new != radius_old:
self.emit('radius-mode',radius_new)
# diameter mode g7
diam_old = old.get('diameter', None)
diam_new = self.old['diameter']
if diam_new != diam_old:
self.emit('diameter-mode',diam_new)
####################################
# Mcodes
####################################
# M-codes
m_code_old = old.get('m-code', None)
m_code_new = self.old['m-code']
if m_code_new != m_code_old:
self.emit('m-code-changed',m_code_new)
tool_info_old = old.get('tool-info', None)
tool_info_new = self.old['tool-info']
if tool_info_new != tool_info_old:
self.emit('tool-info-changed', tool_info_new)
#####################################
# settings
#####################################
# feed code
f_code_old = old.get('f-code', None)
f_code_new = self.old['f-code']
if f_code_new != f_code_old:
self.emit('f-code-changed',f_code_new)
# g53 blend code
blend_code_old = old.get('blend-tolerance-code', None)
blend_code_new = self.old['blend-tolerance-code']
cam_code_old = old.get('nativecam-tolerance-code', None)
cam_code_new = self.old['nativecam-tolerance-code']
if blend_code_new != blend_code_old or \
blend_code_new != blend_code_old:
self.emit('blend-code-changed',blend_code_new, cam_code_new)
# AND DONE... Return true to continue timeout
self.emit('periodic')
return True
def forced_update(self):
try:
self.stat.poll()
except:
# Reschedule
return True
self.merge()
cmd_state_new = self.old['command-state']
if cmd_state_new == linuxcnc.RCS_EXEC:
self.emit('command-running')
elif cmd_state_new == linuxcnc.RCS_DONE:
self.emit('command-stopped')
elif cmd_state_new == linuxcnc.RCS_ERROR:
self.emit('command-error')
state_new = self.old['state']
if state_new > linuxcnc.STATE_ESTOP:
self.emit('state-estop-reset')
else:
self.emit('state-estop')
self.emit('state-off')
self.emit('interp-idle')
# override limits
or_limits_new = self.old['override-limits']
or_limits_set_new = self.old['override-limits-set']
self.emit('override-limits-changed',or_limits_set_new, or_limits_new)
# hard limits tripped
t_list_new = self.old['hard-limits-list']
hard_limits_tripped_new = self.old['hard-limits-tripped']
self.emit('hard-limits-tripped',hard_limits_tripped_new, t_list_new)
# overrides
feed_or_new = self.old['feed-or']
self.emit('feed-override-changed',feed_or_new * 100)
rapid_or_new = self.old['rapid-or']
self.emit('rapid-override-changed',rapid_or_new * 100)
max_velocity_or_new = self.old['max-velocity-or']
# work around misconfigured config (missing MAX_LINEAR_VELOCITY in TRAJ)
if max_velocity_or_new != 1e99:
self.emit('max-velocity-override-changed',max_velocity_or_new * 60)
spindle_or_new = self.old['spindle-or']
self.emit('spindle-override-changed',spindle_or_new * 100)
# spindle speed mpde
css_new = self.old['css']
self.emit('css-mode',css_new)
rpm_new = self.old['rpm']
self.emit('rpm-mode',rpm_new)
# absolute mode g90
g90_new = self.old['g90']
self.emit('g90-mode',g90_new)
# incremental mode g91
g91_new = self.old['g91']
self.emit('g91-mode',g91_new)
# feed mode:
itime_new = self.old['itime']
self.emit('itime-mode',itime_new)
fpm_new = self.old['fpm']
self.emit('fpm-mode',fpm_new)
fpr_new = self.old['fpr']
self.emit('fpr-mode',fpr_new)
# paused
paused_new = self.old['paused']
self.emit('program-pause-changed',paused_new)
# block delete
block_delete_new = self.old['block-delete']
self.emit('block-delete-changed',block_delete_new)
# optional_stop
optional_stop_new = self.old['optional-stop']
self.emit('optional-stop-changed',optional_stop_new)
# user system G5x
system_new = self.old['g5x-index']
self.emit('user-system-changed',system_new)
# radius mode g8
radius_new = self.old['radius']
self.emit('radius-mode',radius_new)
# diameter mode g7
diam_new = self.old['diameter']
self.emit('diameter-mode',diam_new)
# rotation around Z
z_rot_new = self.old['current-z-rotation']
self.emit('current-z-rotation',z_rot_new)
# current tool offsets
tool_off_new = self.old['current-tool-offset']
self.emit('current-tool-offset',tool_off_new)
# M-codes
m_code_new = self.old['m-code']
self.emit('m-code-changed',m_code_new)
flood_new = self.old['flood']
self.emit('flood-changed',flood_new)
mist_new = self.old['mist']
self.emit('mist-changed',mist_new)
# G-codes
g_code_new = self.old['g-code']
self.emit('g-code-changed',g_code_new)
# metric units G21
metric_new = self.old['metric']
self.emit('metric_mode_changed',metric_new)
# tool in spindle
tool_new = self.old['tool-in-spindle']
self.emit('tool-in-spindle-changed', tool_new)
tool_num_new = self.old['tool-prep-number']
self.emit('tool-prep-changed', tool_num_new)
# feed code
f_code_new = self.old['f-code']
self.emit('f-code-changed',f_code_new)
# g53 blend code
blend_code_new = self.old['blend-tolerance-code']
cam_code_new = self.old['nativecam-tolerance-code']
self.emit('blend-code-changed',blend_code_new, cam_code_new)
# Trajectory Motion mode
motion_mode_new = self.old['motion-mode']
self.emit('motion-mode-changed', motion_mode_new)
# Trajectory Motion type
motion_type_new = self.old['motion-type']
self.emit('motion-type-changed', motion_type_new)
# Spindle requested speed
spindle_spd_new = self.old['spindle-speed']
self.emit('requested-spindle-speed-changed', spindle_spd_new)
spindle_spd_new = self.old['actual-spindle-speed']
self.emit('actual-spindle-speed-changed', spindle_spd_new)
self.emit('spindle-control-changed', 0, False, 0, False)
self.emit('jograte-changed', self.current_jog_rate)
self.emit('jograte-angular-changed', self.current_angular_jog_rate)
self.emit('jogincrement-changed', self.current_jog_distance, self.current_jog_distance_text)
self.emit('jogincrement-angular-changed', self.current_jog_distance_angular, self.current_jog_distance_angular_text)
tool_info_new = self.old['tool-info']
self.emit('tool-info-changed', tool_info_new)
# homing
homed_joints = 0
unhomed_joints = ""
for joint in range(0, self.stat.joints):
if self.stat.homed[joint]:
homed_joints += 1
self.emit('homed', joint)
else:
self.emit('unhomed', joint)
unhomed_joints += str(joint)
if homed_joints == self.stat.joints:
self._is_all_homed = True
self.emit('all-homed')
else:
self._is_all_homed = False
self.emit('not-all-homed', unhomed_joints)
# ferror
self.emit('following-error', self.old['ferror-current'])
# update external objects
self.emit('forced-update')
# ********** Helper function ********************
def get_position(self):
p = self.stat.actual_position
mp = self.stat.position
dtg = self.stat.dtg
x = p[0] - self.stat.g5x_offset[0] - self.stat.tool_offset[0]
y = p[1] - self.stat.g5x_offset[1] - self.stat.tool_offset[1]
z = p[2] - self.stat.g5x_offset[2] - self.stat.tool_offset[2]
a = p[3] - self.stat.g5x_offset[3] - self.stat.tool_offset[3]
b = p[4] - self.stat.g5x_offset[4] - self.stat.tool_offset[4]
c = p[5] - self.stat.g5x_offset[5] - self.stat.tool_offset[5]
u = p[6] - self.stat.g5x_offset[6] - self.stat.tool_offset[6]
v = p[7] - self.stat.g5x_offset[7] - self.stat.tool_offset[7]
w = p[8] - self.stat.g5x_offset[8] - self.stat.tool_offset[8]
if self.stat.rotation_xy != 0:
t = math.radians(-self.stat.rotation_xy)
xr = x * math.cos(t) - y * math.sin(t)
yr = x * math.sin(t) + y * math.cos(t)
x = xr
y = yr
x -= self.stat.g92_offset[0]
y -= self.stat.g92_offset[1]
z -= self.stat.g92_offset[2]
a -= self.stat.g92_offset[3]
b -= self.stat.g92_offset[4]
c -= self.stat.g92_offset[5]
u -= self.stat.g92_offset[6]
v -= self.stat.g92_offset[7]
w -= self.stat.g92_offset[8]
relp = [x, y, z, a, b, c, u, v, w]
return p,relp,dtg
# check for required modes
# fail if mode is 0
# fail if machine is busy
# true if all ready in mode
# None if possible to change
def check_for_modes(self, *modes):
def running(s):
return s.task_mode == linuxcnc.MODE_AUTO and s.interp_state != linuxcnc.INTERP_IDLE
self.stat.poll()
premode = self.stat.task_mode
if not modes: return (None, premode)
try:
if self.stat.task_mode in modes[0]: return (True, premode)
except:
if self.stat.task_mode == modes[0]: return (True, premode)
if running( self.stat): return (None, premode)
return (False, premode)
def get_current_mode(self):
return self.old['mode']
# linear - in machine units
def set_jograte(self, upm):
self.current_jog_rate = upm
self.emit('jograte-changed', upm)
def get_jograte(self):
return self.current_jog_rate
def set_jograte_angular(self,rate):
self.current_angular_jog_rate = rate
self.emit('jograte-angular-changed', rate)
def get_jograte_angular(self):
return self.current_angular_jog_rate
def get_jog_increment_angular(self):
return self.current_jog_distance_angular
def set_jog_increment_angular(self, distance, text):
try:
isinstance(float(distance), float)
except:
print('error converting angular jog increment ({}) to float: staying at {}'.format(distance,self.current_jog_distance_angular))
return
self.current_jog_distance_angular = distance
self.current_jog_distance_text_angular = text
self.emit('jogincrement-angular-changed', distance, text)
# should be in machine units
def set_jog_increments(self, distance, text):
try:
isinstance(float(distance), float)
except:
print('error converting jog increment ({}) to float: staying at {}'.format(distance,self.current_jog_distance))
return
self.current_jog_distance = distance
self.current_jog_distance_text = text
self.emit('jogincrement-changed', distance, text)
def get_jog_increment(self):
return self.current_jog_distance
def get_max_velocity(self):
return self.old['max-velocity-or'] * 60
def set_selected_joint(self, data):
self.selected_joint = int(data)
self.emit('joint-selection-changed', data)
def get_selected_joint(self):
return self.selected_joint
def set_selected_axis(self, data):
self.selected_axis = str(data)
self.emit('axis-selection-changed', data)
def get_selected_axis(self):
return self.selected_axis
def is_joint_homed(self, joint):
self.stat.poll()
return bool(self.stat.homed[joint])
def is_all_homed(self):
return self._is_all_homed
def is_homing(self):
for j in range(0, self.stat.joints):
if self.stat.joint[j].get('homing'):
return True
return False
def machine_is_on(self):
return self.old['state'] > linuxcnc.STATE_OFF
def estop_is_clear(self):
self.stat.poll()
return self.stat.task_state > linuxcnc.STATE_ESTOP
def is_man_mode(self):
self.stat.poll()
return self.stat.task_mode == linuxcnc.MODE_MANUAL
def is_mdi_mode(self):
self.stat.poll()
return self.stat.task_mode == linuxcnc.MODE_MDI
def is_auto_mode(self):
self.stat.poll()
return self.stat.task_mode == linuxcnc.MODE_AUTO
def is_on_and_idle(self):
self.stat.poll()
return self.stat.task_state > linuxcnc.STATE_OFF and self.stat.interp_state == linuxcnc.INTERP_IDLE
def is_auto_running(self):
self.stat.poll()
return self.stat.task_mode == linuxcnc.MODE_AUTO and self.stat.interp_state != linuxcnc.INTERP_IDLE
def is_auto_paused(self):
return self.old['paused']
def is_interp_running(self):
self.stat.poll()
return self.stat.interp_state != linuxcnc.INTERP_IDLE
def is_interp_paused(self):
self.stat.poll()
return self.stat.interp_state == linuxcnc.INTERP_PAUSED
def is_interp_reading(self):
self.stat.poll()
return self.stat.interp_state == linuxcnc.INTERP_READING
def is_interp_waiting(self):
self.stat.poll()
return self.stat.interp_state == linuxcnc.INTERP_WAITING
def is_interp_idle(self):
self.stat.poll()
return self.stat.interp_state == linuxcnc.INTERP_IDLE
def is_file_loaded(self):
self.stat.poll()
if self.stat.file:
return True
else:
return False
def is_metric_mode(self):
return self.old['metric']
def is_spindle_on(self, num = 0):
self.stat.poll()
return self.stat.spindle[num]['enabled']
def get_spindle_speed(self, num):
self.stat.poll()
return self.stat.spindle[num]['speed']
def is_joint_mode(self):
try:
self.stat.poll()
except:
return None
return bool(self.stat.motion_mode == linuxcnc.TRAJ_MODE_FREE)
def is_status_valid(self):
return self._status_active
def is_limits_override_set(self):
return self.old['override-limits-set']
def is_hard_limits_tripped(self):
return self.old['hard-limits-tripped']
def get_current_tool(self):
self.stat.poll()
return self.stat.tool_in_spindle
def set_tool_touchoff(self,tool,axis,value):
premode = None
m = "G10 L10 P%d %s%f"%(tool,axis,value)
self.stat.poll()
if self.stat.task_mode != linuxcnc.MODE_MDI:
premode = self.stat.task_mode
self.cmd.mode(linuxcnc.MODE_MDI)
self.cmd.wait_complete()
self.cmd.mdi(m)
self.cmd.wait_complete()
self.cmd.mdi("g43")
self.cmd.wait_complete()
if premode:
self.cmd.mode(premode)
def set_axis_origin(self,axis,value):
premode = None
m = "G10 L20 P0 %s%f"%(axis,value)
self.stat.poll()
if self.stat.task_mode != linuxcnc.MODE_MDI:
premode = self.stat.task_mode
self.cmd.mode(linuxcnc.MODE_MDI)
self.cmd.wait_complete()
self.cmd.mdi(m)
self.cmd.wait_complete()
if premode:
self.cmd.mode(premode)
self.emit('reload-display')
def do_jog(self, axisnum, direction, distance=0):
jjogmode,j_or_a = self.get_jog_info(axisnum)
if direction == 0:
self.cmd.jog(linuxcnc.JOG_STOP, jjogmode, j_or_a)
else:
if axisnum in (3,4,5):
rate = self.current_angular_jog_rate
else:
rate = self.current_jog_rate/60
if distance == 0:
self.cmd.jog(linuxcnc.JOG_CONTINUOUS, jjogmode, j_or_a, direction * rate)
else:
self.cmd.jog(linuxcnc.JOG_INCREMENT, jjogmode, j_or_a, direction * rate, distance)
def get_jjogmode(self):
self.stat.poll()
if self.stat.motion_mode == linuxcnc.TRAJ_MODE_FREE:
return JOGJOINT
if self.stat.motion_mode == linuxcnc.TRAJ_MODE_TELEOP:
return JOGTELEOP
print("commands.py: unexpected motion_mode",self.stat.motion_mode)
return JOGTELEOP
def jnum_for_axisnum(self,axisnum):
if self.stat.kinematics_type != linuxcnc.KINEMATICS_IDENTITY:
print("\n%s:\n Joint jogging not supported for"
"non-identity kinematics"%__file__)
return -1 # emcJogCont() et al reject neg joint/axis no.s
jnum = trajcoordinates.index( "xyzabcuvw"[axisnum] )
if jnum > jointcount:
print("\n%s:\n Computed joint number=%d for axisnum=%d "
"exceeds jointcount=%d with trajcoordinates=%s"
%(__file__,jnum,axisnum,jointcount,trajcoordinates))
# Note: primary gui should protect for this misconfiguration
# decline to jog
return -1 # emcJogCont() et al reject neg joint/axis no.s
return jnum
def get_jog_info (self,axisnum):
jjogmode = self.get_jjogmode()
j_or_a = axisnum
if jjogmode == JOGJOINT: j_or_a = self.jnum_for_axisnum(axisnum)
return jjogmode,j_or_a
def get_probed_position_with_offsets(self) :
self.stat.poll()
probed_position=list(self.stat.probed_position)
coord=list(self.stat.probed_position)
g5x_offset=list(self.stat.g5x_offset)
g92_offset=list(self.stat.g92_offset)
tool_offset=list(self.stat.tool_offset)
for i in range(0, len(probed_position)-1):
coord[i] = probed_position[i] - g5x_offset[i] - g92_offset[i] - tool_offset[i]
angl=self.stat.rotation_xy
res=self._rott00_point(coord[0],coord[1],-angl)
coord[0]=res[0]
coord[1]=res[1]
return coord
# rotate around 0,0 point coordinates
def _rott00_point(self,x1=0.,y1=0.,a1=0.) :
coord = [x1,y1]
if a1 != 0:
t = math.radians(a1)
coord[0] = x1 * math.cos(t) - y1 * math.sin(t)
coord[1] = x1 * math.sin(t) + y1 * math.cos(t)
return coord
def shutdown(self):
self.emit('shutdown')
def __getitem__(self, item):
return getattr(self, item)
def __setitem__(self, item, value):
return setattr(self, item, value)
class GStat(_GStat):
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = _GStat.__new__(cls, *args, **kwargs)
return cls._instance