offsetwidget.py
1 #!/usr/bin/env python 2 # GladeVcp Widget - DRO label widget 3 # This widgets displays linuxcnc axis position information. 4 # 5 # Copyright (c) 2012 Chris Morley 6 # 7 # This program is free software: you can redistribute it and/or modify 8 # it under the terms of the GNU General Public License as published by 9 # the Free Software Foundation, either version 2 of the License, or 10 # (at your option) any later version. 11 # 12 # This program is distributed in the hope that it will be useful, 13 # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 # GNU General Public License for more details. 16 17 import sys,os,pango 18 import linuxcnc 19 20 try: 21 import gobject,gtk 22 except: 23 print('GTK not available') 24 sys.exit(1) 25 # we put this in a try so there is no error in the glade editor 26 # linuxcnc is probably not running then 27 try: 28 INIPATH = os.environ['INI_FILE_NAME'] 29 except: 30 pass 31 32 class HAL_Offset(gtk.Label): 33 __gtype_name__ = 'HAL_Offset' 34 __gproperties__ = { 35 'display_units_mm' : ( gobject.TYPE_BOOLEAN, 'Display Units', 'Display in metric or not', 36 False, gobject.PARAM_READWRITE | gobject.PARAM_CONSTRUCT), 37 'mm_text_template' : ( gobject.TYPE_STRING, 'Text template for Metric Units', 38 'Text template to display. Python formatting may be used for one variable', 39 "%10.3f", gobject.PARAM_READWRITE|gobject.PARAM_CONSTRUCT), 40 'imperial_text_template' : ( gobject.TYPE_STRING, 'Text template for Imperial Units', 41 'Text template to display. Python formatting may be used for one variable', 42 "%9.4f", gobject.PARAM_READWRITE|gobject.PARAM_CONSTRUCT), 43 'joint_number' : ( gobject.TYPE_INT, 'Joint Number', '0:X 1:Y 2:Z etc', 44 0, 8, 0, gobject.PARAM_READWRITE | gobject.PARAM_CONSTRUCT), 45 'reference_type' : ( gobject.TYPE_INT, 'Reference Type', '0: G5X 1:Tool 2:G92 3:XY Rotation', 46 0, 3, 0, gobject.PARAM_READWRITE | gobject.PARAM_CONSTRUCT), 47 } 48 __gproperties = __gproperties__ 49 50 def __init__(self, *a, **kw): 51 gtk.Label.__init__(self, *a, **kw) 52 self.emc = linuxcnc 53 self.status = self.emc.stat() 54 self.display_units_mm=0 55 self.machine_units_mm=0 56 self.unit_convert=[1]*9 57 # The update time: every 500 milliseonds 58 gobject.timeout_add(500, self.periodic) 59 60 # check the ini file if UNITS are set to mm 61 # first check the global settings 62 # else then the X axis units 63 try: 64 self.inifile = self.emc.ini(INIPATH) 65 units=self.inifile.find("TRAJ","LINEAR_UNITS") 66 if units==None: 67 units=self.inifile.find("AXIS_X","UNITS") 68 except: 69 units = "inch" 70 71 # now setup the conversion array depending on the machine native units 72 if units=="mm" or units=="metric" or units == "1.0": 73 self.machine_units_mm=1 74 self.conversion=[1.0/25.4]*3+[1]*3+[1.0/25.4]*3 75 else: 76 self.machine_units_mm=0 77 self.conversion=[25.4]*3+[1]*3+[25.4]*3 78 79 # This is so GLADE can get the values for the editor 80 # A user can use this too using goobject 81 def do_get_property(self, property): 82 name = property.name.replace('-', '_') 83 if name in self.__gproperties.keys(): 84 return getattr(self, name) 85 else: 86 raise AttributeError('unknown property %s' % property.name) 87 88 # This is used by GLADE editor to set values 89 def do_set_property(self, property, value): 90 name = property.name.replace('-', '_') 91 if name in ('mm_text_template','imperial_text_template'): 92 try: 93 v = value % 0.0 94 except Exception, e: 95 print "Invalid format string '%s': %s" % (value, e) 96 return False 97 if name in self.__gproperties.keys(): 98 setattr(self, name, value) 99 self.queue_draw() 100 else: 101 raise AttributeError('unknown property %s' % property.name) 102 103 # This runs runs at the gooject timeout rate 104 # it polls linuxcnc gets the offsets in correct units 105 # and displays them according to the formatting entered 106 def periodic(self): 107 try: 108 self.status.poll() 109 g5x,tool,g92,rot = self.get_offsets() 110 except: 111 rot = 0 112 g5x = tool = g92 = [9999.999,0,0,0,0,0,0,0,0] 113 if self.display_units_mm: 114 tmpl = lambda s: self.mm_text_template % s 115 else: 116 tmpl = lambda s: self.imperial_text_template % s 117 if self.reference_type == 0: 118 self.set_text(tmpl(g5x[self.joint_number])) 119 elif self.reference_type == 1: 120 self.set_text(tmpl(tool[self.joint_number])) 121 elif self.reference_type == 2: 122 self.set_text(tmpl(g92[self.joint_number])) 123 elif self.reference_type == 3: 124 self.set_text(tmpl(rot)) 125 return True 126 127 # Get the offsets and convert the units if the display 128 # is not in machine native units 129 def get_offsets(self): 130 g5x = self.status.g5x_offset 131 tool = self.status.tool_offset 132 g92 = self.status.g92_offset 133 rot = self.status.rotation_xy 134 135 if self.display_units_mm != self.machine_units_mm: 136 g5x = self.convert_units(g5x) 137 tool = self.convert_units(tool) 138 g92 = self.convert_units(g92) 139 140 return g5x,tool,g92,rot 141 142 # This does the units conversion 143 # it just mutiplies the two arrays 144 def convert_units(self,v): 145 c = self.conversion 146 return map(lambda x,y: x*y, v, c) 147 148 # helper function to set the units to inch 149 def set_to_inch(self): 150 self.display_units_mm = 0 151 152 # helper function to set the units to mm 153 def set_to_mm(self): 154 self.display_units_mm = 1 155 156 # for testing without glade editor: 157 def main(): 158 window = gtk.Dialog("My dialog", 159 None, 160 gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, 161 (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, 162 gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)) 163 offset = HAL_Offset() 164 window.vbox.add(offset) 165 window.connect("destroy", gtk.main_quit) 166 167 window.show_all() 168 response = window.run() 169 if response == gtk.RESPONSE_ACCEPT: 170 print "ok" 171 else: 172 print "cancel" 173 174 if __name__ == "__main__": 175 main() 176 177