linuxcnc/lib/python/gladevcp/overridewidget.py

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()