Last active
April 24, 2022 19:26
-
-
Save robanonymous/b677a47aed504548440c8258f71724b1 to your computer and use it in GitHub Desktop.
This is a custom hal_manualtoolchange file that allows you to control linuxcnc during a tool change. You can find the file in the folder /usr/bin.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# -*- coding: utf-8 -*- | |
import sys, os, time | |
import gettext | |
BASE = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), "..")) | |
gettext.install("linuxcnc", localedir=os.path.join(BASE, "share", "locale"), unicode=True) | |
import linuxcnc, hal | |
linuxcncStat = linuxcnc.stat(); | |
linuxcncCmd = linuxcnc.command() | |
""" | |
_after = None | |
def hal_in_background(): | |
global _after | |
_after = None | |
if not h.change: | |
app.tk.call("set", "::tkPriv(button)", -1) | |
return | |
if (h.change_button): | |
h.changed = True | |
app.update() | |
app.tk.call("set", "::tkPriv(button)", -1) | |
stop_polling_hal_in_background() | |
return | |
_after = app.after(100, hal_in_background) | |
def poll_hal_in_background(): | |
global _after | |
_after = app.after(100, hal_in_background) | |
def stop_polling_hal_in_background(): | |
global _after | |
if _after: app.after_cancel(_after) | |
_after = None | |
""" | |
def do_change(n): | |
#Take the current line, remember, and install the program....... | |
linuxcncStat.poll() | |
# IMPORTANT - Before it was up 2.7 linuxcncStat.current_line | |
# But now it's value is somewhere in the strange lines, much more than the program stands now, towards the end of the file. | |
# It is even possible, if done "M6 T3" - something on the line where the actual call, and T3 is a change | |
# (such as he searches for the string in the code, and throws back ?! - that's the theory.) | |
curLine = linuxcncStat.motion_line | |
h.reported_current_line = curLine | |
# Previously, it had an abort() only if there is a current line. But why? Now we always abort(). :) | |
linuxcncCmd.abort() | |
if n: | |
message = _("Insert tool %d and click continue when ready") % n | |
else: | |
message = _("Remove the tool and click continue when ready") | |
# Close the dialog box (if the past is?) | |
app.wm_withdraw() | |
# Fulfill all the background tasks, is not made ?Tkinter? (see. below in the file, there is an explanation) | |
app.update() | |
# poll_hal_in_background () | |
# Fuck, is this necessary? I do not understand. In fact it turned out, and it is not necessary, and so works ... | |
# try: | |
r = app.tk.call("nf_dialog", ".tool_change", _("Tool change"), message, "info", 0, _("Continue")) # show dialogue seems modal | |
# finally: | |
# stop_polling_hal_in_background() | |
# If `r` is a string, then convert it into an int. Apparently, app.tk.call () returns 0 if the call is a success | |
if isinstance(r, str): | |
r = int(r) | |
if r == 0: | |
if curLine >0: | |
h.commanded_run_from_line = curLine + 1 | |
linuxcncCmd.mode(linuxcnc.MODE_AUTO) | |
linuxcncCmd.auto(linuxcnc.AUTO_RUN, curLine + 1) | |
app.update() | |
#=== CREATE PINS FOR LINUXCNC | |
h = hal.component("hal_manualtoolchange") | |
h.newpin("number", hal.HAL_S32, hal.HAL_IN) | |
h.newpin("commanded_run_from_line", hal.HAL_S32, hal.HAL_OUT) #This debug pin, we have created them - from hal-meter behind them can be seen :) | |
h.newpin("reported_current_line", hal.HAL_S32, hal.HAL_OUT) #This debug pin, we have created them - from hal-meter behind them can be seen :) | |
h.newpin("change", hal.HAL_BIT, hal.HAL_IN) | |
h.newpin("changed", hal.HAL_BIT, hal.HAL_OUT) | |
# See http://wiki.linuxcnc.org/cgi-bin/wiki.pl?Released_2.7.X | |
# Search strings hal_manualtool change.change button (version 2.7.0~pre3) | |
# h.newpin("change_button", hal.HAL_BIT, hal.HAL_IN) | |
# The component is ready. | |
# LinuxCNC when the component starts using "loadusr hal_manualtoolchange", apparently waiting for the UI. | |
h.ready() | |
#=== CREATE DIALOG WINDOW | |
import Tkinter, nf, rs274.options | |
app = Tkinter.Tk(className="AxisToolChanger") | |
app.wm_geometry("-60-60") | |
app.wm_title(_("AXIS Manual Toolchanger")) | |
rs274.options.install(app) | |
nf.start(app); nf.makecommand(app, "_", _) | |
""" | |
app.wm_protocol("WM_DELETE_WINDOW", app.wm_withdraw) | |
lab = Tkinter.Message(app, aspect=500, text = _("\ | |
This window is part of the AXIS manual toolchanger. It is safe to close \ | |
or iconify this window, or it will close automatically after a few seconds.")) | |
lab.pack() | |
""" | |
""" | |
#=== CLOSE DIALOG WINDOW AFTER LINUXCNC STARTS | |
# Communication events <Expose> (http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/event-types.html) = the window is visible, the challenge of closing the window. That is, as soon as the window was visible from under another window, it must be closed immediately. | |
# Why it's done ?! And then, that the withdraw () function is called only once - see next.. line of code - when LinuxCNC starts. | |
# Apparently, this is some clever way to hide the startup dialog. | |
def withdraw(): | |
app.wm_withdraw() # Removes the window from the screen (without destroying it) | |
app.bind("<Expose>", lambda event: app.wm_withdraw()) | |
# After 10 seconds, after the start of the program (ie, start linuxcnc), hide the window automatically. | |
# This location is called only once, at startup. | |
app.after(10 * 1000, withdraw) | |
""" | |
#=== MAIN LOOP | |
try: | |
while 1: | |
# change = h.change | |
if h.change and not h.changed: | |
do_change(h.number) | |
h.changed = True | |
h.change = False | |
# 0.2 sec - wait, let the pins will update their status. | |
time.sleep(0.5) | |
h.changed = False | |
# elif not change: | |
# h.changed = False | |
# Why is this? What happens 0.1 seconds? Just the type of sleep? | |
# Call after () function without index - which gives delay type? | |
# app.after(100) | |
# This call performs all tasks that have Tkinter left unfinished. | |
# Apparently, the meaning is: to fulfill all that relies Tkinteru, and go to the next step while | |
# app.update() | |
except KeyboardInterrupt: | |
pass |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Just one stupid question: How to add this to AXIS GUI to make it work? How to run or where to copy the hal_manualtoolchange.py