182 lines
6.5 KiB
Python
182 lines
6.5 KiB
Python
#!/usr/bin/env python3
|
|
# GladeVcp Widget - override widget
|
|
# This widgets controls linuxcnc's override rate
|
|
#
|
|
# Copyright (c) 2015 Chris Morley
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
|
|
import sys,os
|
|
import linuxcnc
|
|
|
|
import gi
|
|
gi.require_version('Gtk', '3.0')
|
|
from gi.repository import Gtk
|
|
from gi.repository import GObject
|
|
from gi.repository import GLib
|
|
|
|
INIPATH = os.environ.get('INI_FILE_NAME', '/dev/null')
|
|
|
|
class Override(Gtk.HScale):
|
|
__gtype_name__ = 'Override'
|
|
__gproperties__ = {
|
|
'override_type' : ( GObject.TYPE_INT, 'Override Type', '0: Feed 1: Rapid 2: Spindle 3: Max velocity',
|
|
0, 3, 0, GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT),
|
|
}
|
|
__gproperties = __gproperties__
|
|
|
|
def __init__(self, *a, **kw):
|
|
Gtk.HScale.__init__(self, *a, **kw)
|
|
self.emc = linuxcnc
|
|
self.status = self.emc.stat()
|
|
self.cmd = linuxcnc.command()
|
|
self.override_type = 0
|
|
self.override = 1.0
|
|
self.max_vel_convert = 100
|
|
self.adjustment = Gtk.Adjustment(value=100, lower=0, upper=200, step_incr=1, page_incr=0, page_size=0)
|
|
self.set_type(self.override_type)
|
|
self.set_adjustment(self.adjustment)
|
|
self.set_digits(0)
|
|
self.set_value_pos(Gtk.PositionType.LEFT)
|
|
#self.add_mark(100.0,Gtk.PositionType.LEFT,'')
|
|
self.connect('value-changed',self.update_value)
|
|
# The update time: every 100 milliseconds
|
|
GLib.timeout_add(100, self.periodic)
|
|
|
|
# we set the adjustment limits based on the INI entries
|
|
def set_type(self, data=0):
|
|
adjustment = self.get_adjustment()
|
|
self.override_type = data
|
|
self.inifile = self.emc.ini(INIPATH)
|
|
if self.override_type == 0:
|
|
MAXFEED = float(self.inifile.find("DISPLAY","MAX_FEED_OVERRIDE") or 2.0)
|
|
#print 'feed',MAXFEED
|
|
adjustment.set_upper(MAXFEED*100)
|
|
adjustment.set_lower(0)
|
|
elif self.override_type == 1:
|
|
#print 'rapid'
|
|
adjustment.set_upper(100)
|
|
adjustment.set_lower(0)
|
|
elif self.override_type == 2:
|
|
MINSPINDLE = float(self.inifile.find("DISPLAY","MIN_SPINDLE_OVERRIDE") or .5)
|
|
#print 'mins',MINSPINDLE
|
|
MAXSPINDLE = float(self.inifile.find("DISPLAY","MAX_SPINDLE_OVERRIDE") or 1.5)
|
|
#print 'maxs',MAXSPINDLE
|
|
adjustment.set_upper(MAXSPINDLE*100)
|
|
adjustment.set_lower(MINSPINDLE*100)
|
|
elif self.override_type == 3:
|
|
MAXVEL = float(self.inifile.find("TRAJ","MAX_LINEAR_VELOCITY") or 100)
|
|
#print 'maxv',MAXVEL,MAXVEL/100.0
|
|
self.max_vel_convert = MAXVEL/100.0
|
|
adjustment.set_upper(100)
|
|
adjustment.set_lower(0)
|
|
|
|
# This is a signal callback that commands linuxcnc based on the current
|
|
# scale position
|
|
def update_value(self, widget):
|
|
data = widget.get_value()
|
|
if not self.override_type == 3:
|
|
data=data/100
|
|
else:
|
|
data=data*self.max_vel_convert
|
|
#print data,self.override_type ,self.adjustment
|
|
if self.override_type == 0:
|
|
self.cmd.feedrate(data)
|
|
elif self.override_type == 1:
|
|
self.cmd.rapidrate(data)
|
|
elif self.override_type == 2:
|
|
self.cmd.spindleoverride(data)
|
|
elif self.override_type == 3:
|
|
self.cmd.maxvel(data)
|
|
return True
|
|
|
|
# This runs runs at the gooject timeout rate
|
|
# it polls linuxcnc to get the current data
|
|
# and updates the scale to refleck the current value.
|
|
# in this way if eg HALUI is used to set an override the
|
|
# scale will track it.
|
|
def periodic(self):
|
|
try:
|
|
self.status.poll()
|
|
if self.override_type == 0:
|
|
self.override = self.status.feedrate
|
|
elif self.override_type == 1:
|
|
self.override = self.status.rapidrate
|
|
elif self.override_type == 2:
|
|
self.override = self.status.spindlerate
|
|
elif self.override_type == 3:
|
|
self.override = self.status.max_velocity
|
|
# max velocity is not based on % so must be converted
|
|
if not self.override_type == 3:
|
|
self.set_value(self.override*100)
|
|
else:
|
|
self.set_value(self.override/self.max_vel_convert)
|
|
except:
|
|
pass
|
|
return True
|
|
|
|
# This is so GLADE can get the values for the editor
|
|
# A user can use this too using goobject
|
|
def do_get_property(self, property):
|
|
name = property.name.replace('-', '_')
|
|
if name in list(self.__gproperties.keys()):
|
|
return getattr(self, name)
|
|
else:
|
|
raise AttributeError('unknown property %s' % property.name)
|
|
|
|
# This is used by GLADE editor to set values
|
|
def do_set_property(self, property, value):
|
|
name = property.name.replace('-', '_')
|
|
if name in list(self.__gproperties.keys()):
|
|
setattr(self, name, value)
|
|
if name == 'override_type':
|
|
self.set_type(value)
|
|
else:
|
|
raise AttributeError('unknown property %s' % property.name)
|
|
|
|
# for testing without glade editor:
|
|
def main():
|
|
window = Gtk.Dialog("My dialog",
|
|
None,
|
|
Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,
|
|
(Gtk.STOCK_CANCEL, Gtk.ResponseType.REJECT,
|
|
Gtk.STOCK_OK, Gtk.ResponseType.ACCEPT))
|
|
t = Gtk.Table(rows=4, columns=1, homogeneous=True)
|
|
window.vbox.add(t)
|
|
|
|
offset1 = Override()
|
|
offset1.set_type(0)
|
|
t.attach(offset1, 0, 1, 0, 1)
|
|
|
|
offset2 = Override()
|
|
offset2.set_type(1)
|
|
t.attach(offset2, 0, 1, 1, 2)
|
|
|
|
offset3 = Override()
|
|
offset3.set_type(2)
|
|
t.attach(offset3, 0, 1, 2, 3)
|
|
|
|
offset4 = Override()
|
|
offset4.set_type(3)
|
|
t.attach(offset4, 0, 1, 3, 4)
|
|
|
|
window.connect("destroy", Gtk.main_quit)
|
|
|
|
window.show_all()
|
|
response = window.run()
|
|
if response == Gtk.ResponseType.ACCEPT:
|
|
print("ok")
|
|
else:
|
|
print("cancel")
|
|
|
|
if __name__ == "__main__":
|
|
main()
|
|
|