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 + -
显示快捷键?