stepconf.py

来自「CNC 的开放码,EMC2 V2.2.8版」· Python 代码 · 共 1,576 行 · 第 1/4 页

PY
1,576
字号
#!/usr/bin/python2.4# -*- encoding: utf-8 -*-#    This is stepconf, a graphical configuration editor for emc2#    Copyright 2007 Jeff Epler <jepler@unpythonic.net>##    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.##    You should have received a copy of the GNU General Public License#    along with this program; if not, write to the Free Software#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USAimport sysimport osimport pwdimport errnoimport timeimport md5import pickleimport shutilimport mathimport getoptimport textwrapimport gtkimport gtk.gladeimport gobjectimport gnome.uiimport xml.dom.minidomimport traceback# otherwise, on hardy the user is shown spurious "[application] closed# unexpectedly" messages but denied the ability to actually "report [the]# problem"def excepthook(exc_type, exc_obj, exc_tb):    try:        w = app.widgets.window1    except NameError:        w = None    lines = traceback.format_exception(exc_type, exc_obj, exc_tb)    m = gtk.MessageDialog(w,                gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,                gtk.MESSAGE_ERROR, gtk.BUTTONS_OK,                _("Stepconf encountered an error.  The following "                "information may be useful in troubleshooting:\n\n")                + "".join(lines))    m.show()    m.run()    m.destroy()sys.excepthook = excepthookBASE = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), ".."))LOCALEDIR = os.path.join(BASE, "share", "locale")import gettext;#def _(x): return xgettext.install("axis", localedir=LOCALEDIR, unicode=True)gtk.glade.bindtextdomain("axis", LOCALEDIR)gtk.glade.textdomain("axis")def iceil(x):    if isinstance(x, (int, long)): return x    if isinstance(x, basestring): x = float(x)    return int(math.ceil(x))datadir = os.path.join(os.path.abspath(os.path.dirname(__file__)), "..", "share", "emc")wizard = os.path.join(datadir, "emc2-wizard.gif")if not os.path.isfile(wizard):    wizard = os.path.join("/etc/emc2/emc2-wizard.gif")if not os.path.isfile(wizard):    wizdir = os.path.join(os.path.abspath(os.path.dirname(__file__)), "..")    wizard = os.path.join(wizdir, "emc2-wizard.gif")distdir = os.path.join(os.path.abspath(os.path.dirname(__file__)), "..", "configs", "common")if not os.path.isdir(distdir):    distdir = "/etc/emc2/sample-configs/common"(ESTOP_IN, PROBE, PPR, PHA, PHB,HOME_X, HOME_Y, HOME_Z, HOME_A,MIN_HOME_X, MIN_HOME_Y, MIN_HOME_Z, MIN_HOME_A,MAX_HOME_X, MAX_HOME_Y, MAX_HOME_Z, MAX_HOME_A,BOTH_HOME_X, BOTH_HOME_Y, BOTH_HOME_Z, BOTH_HOME_A,MIN_X, MIN_Y, MIN_Z, MIN_A,MAX_X, MAX_Y, MAX_Z, MAX_A,BOTH_X, BOTH_Y, BOTH_Z, BOTH_A,ALL_LIMIT, ALL_HOME, UNUSED_INPUT) = range(36)(XSTEP, XDIR, YSTEP, YDIR,ZSTEP, ZDIR, ASTEP, ADIR, CW, CCW, PWM,MIST, FLOOD, ESTOP, AMP, PUMP, UNUSED_OUTPUT) = range(17)hal_output_names = ("xstep", "xdir", "ystep", "ydir","zstep", "zdir", "astep", "adir","spindle-cw", "spindle-ccw", "spindle-pwm","coolant-mist", "coolant-flood", "estop-out", "xenable","charge-pump")hal_input_names = ("estop-ext", "probe-in","spindle-index", "spindle-phase-a", "spindle-phase-b","home-x", "home-y", "home-z", "home-a","min-home-x", "min-home-y", "min-home-z", "min-home-a","max-home-x", "max-home-y", "max-home-z", "max-home-a","both-home-x", "both-home-y", "both-home-z", "both-home-a","min-x", "min-y", "min-z", "min-a","max-x", "max-y", "max-z", "max-a","both-x", "both-y", "both-z", "both-a","all-limit", "all-home")human_output_names = (_("X Step"), _("X Direction"), _("Y Step"), _("Y Direction"),_("Z Step"), _("Z Direction"), _("A Step"), _("A Direction"),_("Spindle CW"), _("Spindle CCW"), _("Spindle PWM"),_("Coolant Mist"), _("Coolant Flood"), _("ESTOP Out"), _("Amplifier Enable"),_("Charge Pump"), _("Unused"))human_input_names = (_("ESTOP In"), _("Probe In"),_("Spindle Index"), _("Spindle Phase A"), _("Spindle Phase B"),_("Home X"), _("Home Y"), _("Home Z"), _("Home A"),_("Minimum Limit + Home X"), _("Minimum Limit + Home Y"),_("Minimum Limit + Home Z"), _("Minimum Limit + Home A"),_("Maximum Limit + Home X"), _("Maximum Limit + Home Y"),_("Maximum Limit + Home Z"), _("Maximum Limit + Home A"),_("Both Limit + Home X"), _("Both Limit + Home Y"),_("Both Limit + Home Z"), _("Both Limit + Home A"),_("Minimum Limit X"), _("Minimum Limit Y"),_("Minimum Limit Z"), _("Minimum Limit A"),_("Maximum Limit X"), _("Maximum Limit Y"),_("Maximum Limit Z"), _("Maximum Limit A"),_("Both Limit X"), _("Both Limit Y"),_("Both Limit Z"), _("Both Limit A"),_("All limits"), _("All home"), _("Unused"))def md5sum(filename):    try:	f = open(filename, "rb")    except IOError:	return None    else:	return md5.new(f.read()).hexdigest()class Widgets:    def __init__(self, xml):	self._xml = xml    def __getattr__(self, attr):	r = self._xml.get_widget(attr)	if r is None: raise AttributeError, "No widget %r" % attr	return r    def __getitem__(self, attr):	r = self._xml.get_widget(attr)	if r is None: raise IndexError, "No widget %r" % attr	return rclass Data:    def __init__(self):	pw = pwd.getpwuid(os.getuid())	self.machinename = _("my-mill")	self.axes = 0 # XYZ	self.units = 0 # inch	self.drivertype = 6 # Other	self.steptime = self.stepspace = 5000	self.dirhold = self.dirsetup = 20000        self.latency = 15000        self.period = 25000        self.ioaddr = "0x378"	self.manualtoolchange = 1	self.customhal = 1	self.pyvcp = 0	self.pin1inv = 0	self.pin2inv = 0	self.pin3inv = 0	self.pin4inv = 0	self.pin5inv = 0	self.pin6inv = 0	self.pin7inv = 0	self.pin8inv = 0	self.pin9inv = 0	self.pin10inv = 0	self.pin11inv = 0	self.pin12inv = 0	self.pin13inv = 0	self.pin14inv = 0	self.pin15inv = 0	self.pin16inv = 0	self.pin17inv = 0	self.pin1 = ESTOP	self.pin2 = XSTEP	self.pin3 = XDIR	self.pin4 = YSTEP	self.pin5 = YDIR	self.pin6 = ZSTEP	self.pin7 = ZDIR	self.pin8 = ASTEP	self.pin9 = ADIR	self.pin14 = CW	self.pin16 = PWM	self.pin17 = AMP	self.pin10 = BOTH_HOME_X	self.pin11 = BOTH_HOME_Y	self.pin12 = BOTH_HOME_Z	self.pin13 = BOTH_HOME_A	self.pin15 = PROBE	self.xsteprev = 200	self.xmicrostep = 2	self.xpulleynum = 1	self.xpulleyden = 1	self.xleadscrew = 20	self.xmaxvel = 1	self.xmaxacc = 30	self.xhomepos = 0	self.xminlim =  0	self.xmaxlim =  8	self.xhomesw =  0	self.xhomevel = .05	self.xlatchdir = 0	self.xscale = 0	self.ysteprev = 200	self.ymicrostep = 2	self.ypulleynum = 1	self.ypulleyden = 1	self.yleadscrew = 20	self.ymaxvel = 1	self.ymaxacc = 30	self.yhomepos = 0	self.yminlim =  0	self.ymaxlim =  8	self.yhomesw =  0	self.yhomevel = .05	self.ylatchdir = 0	self.yscale = 0	self.zsteprev = 200	self.zmicrostep = 2	self.zpulleynum = 1	self.zpulleyden = 1	self.zleadscrew = 20	self.zmaxvel = 1	self.zmaxacc = 30	self.zhomepos = 0	self.zminlim = -4	self.zmaxlim =  0	self.zhomesw = 0	self.zhomevel = .05	self.zlatchdir = 0	self.zscale = 0	self.asteprev = 200	self.amicrostep = 2	self.apulleynum = 1	self.apulleyden = 1	self.aleadscrew = 8	self.amaxvel = 360	self.amaxacc = 1200	self.ahomepos = 0	self.aminlim = -9999	self.amaxlim =  9999	self.ahomesw =  0	self.ahomevel = .05	self.alatchdir = 0	self.ascale = 0	self.spindlecarrier = 100	self.spindlecpr = 100	self.spindlespeed1 = 100	self.spindlespeed2 = 800	self.spindlepwm1 = .2	self.spindlepwm2 = .8    def load(self, filename, app=None, force=False):	def str2bool(s):	    return s == 'True'        converters = {'string': str, 'float': float, 'int': int, 'bool': str2bool, 'eval': eval}        d = xml.dom.minidom.parse(open(filename, "r"))        for n in d.getElementsByTagName("property"):            name = n.getAttribute("name")            conv = converters[n.getAttribute('type')]            text = n.getAttribute('value')            setattr(self, name, conv(text))	warnings = []	for f, m in self.md5sums:	    m1 = md5sum(f)	    if m1 and m != m1:		warnings.append(_("File %r was modified since it was written by stepconf") % f)	if not warnings: return        warnings.append("")        warnings.append(_("Saving this configuration file will discard configuration changes made outside stepconf."))        if app:            dialog = gtk.MessageDialog(app.widgets.window1,                gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,                gtk.MESSAGE_WARNING, gtk.BUTTONS_OK,                     "\n".join(warnings))            dialog.show_all()            dialog.run()            dialog.destroy()        else:            for para in warnings:                for line in textwrap.wrap(para, 78): print line                print            print            if force: return            response = raw_input(_("Continue? "))            if response[0] not in _("yY"): raise SystemExit, 1    def add_md5sum(self, filename, mode="r"):	self.md5sums.append((filename, md5sum(filename)))    def write_inifile(self, base):	filename = os.path.join(base, self.machinename + ".ini")	file = open(filename, "w")	print >>file, _("# Generated by stepconf at %s") % time.asctime()	print >>file, _("# If you make changes to this file, they will be")	print >>file, _("# overwritten when you run stepconf again")	print >>file	print >>file, "[EMC]"	print >>file, "MACHINE = %s" % self.machinename	print >>file, "NML_FILE = emc.nml"	print >>file, "DEBUG = 0"	print >>file	print >>file, "[DISPLAY]"	print >>file, "DISPLAY = axis"	print >>file, "EDITOR = gedit"	print >>file, "POSITION_OFFSET = RELATIVE"	print >>file, "POSITION_FEEDBACK = ACTUAL"	print >>file, "MAX_FEED_OVERRIDE = 1.2"	print >>file, "INTRO_GRAPHIC = emc2.gif"	print >>file, "INTRO_TIME = 5"        print >>file, "PROGRAM_PREFIX = %s" % \                                    os.path.expanduser("~/emc2/nc_files")	if self.units:	    print >>file, "INCREMENTS = 5mm 1mm .5mm .1mm .05mm .01mm .005mm"	else:	    print >>file, "INCREMENTS = .1in .05in .01in .005in .001in .0005in .0001in"        if self.pyvcp:            print >>file, "PYVCP = panel.xml"        if self.axes == 2:            print >>file, "LATHE = 1"	print >>file	print >>file, "[TASK]"	print >>file, "TASK = milltask"	print >>file, "CYCLE_TIME = 0.010"	print >>file	print >>file, "[RS274NGC]"	print >>file, "PARAMETER_FILE = emc.var"        base_period = self.ideal_period()	print >>file	print >>file, "[EMCMOT]"	print >>file, "EMCMOT = motmod"	print >>file, "SHMEM_KEY = 111"	print >>file, "COMM_TIMEOUT = 1.0"	print >>file, "COMM_WAIT = 0.010"	print >>file, "BASE_PERIOD = %d" % base_period	print >>file, "SERVO_PERIOD = 1000000"	print >>file	print >>file, "[HAL]"	print >>file, "HALFILE = %s.hal" % self.machinename	if self.customhal:	    print >>file, "HALFILE = custom.hal"	    print >>file, "POSTGUI_HALFILE = custom_postgui.hal"	print >>file	print >>file, "[TRAJ]"	if self.axes == 1:

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?