File: overridewidget.py

package info (click to toggle)
linuxcnc 2.9.0~pre1%2Bgit20230208.f1270d6ed7-1%2Bdeb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 274,984 kB
  • sloc: python: 142,166; ansic: 103,241; cpp: 99,140; tcl: 16,045; xml: 10,608; sh: 10,124; makefile: 1,229; javascript: 226; sql: 72; asm: 15
file content (182 lines) | stat: -rw-r--r-- 6,607 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#!/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()