LinuxCNC / linuxcnc

LinuxCNC controls CNC machines. It can drive milling machines, lathes, 3d printers, laser cutters, plasma cutters, robot arms, hexapods, and more.
http://linuxcnc.org/
GNU General Public License v2.0
1.8k stars 1.15k forks source link

axis raises exception when reloading file repeatedly #2490

Open rene-dev opened 1 year ago

rene-dev commented 1 year ago
  1. open sim/axix on master (have not checked 2.9)
  2. click reload a few times
  3. the following exception occurs:
Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib/python3.10/tkinter/__init__.py", line 1921, in __call__
    return self.func(*args)
  File "/home/rene/dev/linuxcnc/bin/axis", line 2292, in reload_file
    reload_file()
  File "/home/rene/dev/linuxcnc/bin/axis", line 1907, in reload_file
    shutil.copyfile(loaded_file, tempfile)
  File "/usr/lib/python3.10/shutil.py", line 234, in copyfile
    raise SameFileError("{!r} and {!r} are the same file".format(src, dst))
shutil.SameFileError: '/tmp/tmpps6fzowe/axis.ngc' and '/tmp/tmpps6fzowe/axis.ngc' are the same file
cakeslob commented 1 year ago

Hey Rene, it might have something to do with this one, as it was the most recent thing changed related to files. https://github.com/LinuxCNC/linuxcnc/pull/2419/commits/3db35073cab2d054724ea2d4f26f7cc440a3ef59

I am using an older 2.9 with a gcode editor tab which reloads the gcode file many times, and I not seen this issue before

rmu75 commented 12 months ago

I see this also. Strange thing is that i can usually start it with one single step (key T) and then continue (key S).

rmu75 commented 12 months ago

this https://github.com/LinuxCNC/linuxcnc/blob/master/src/emc/usr_intf/axis/scripts/axis.py#L1906

    if refilter or not get_filter(loaded_file):
        # we copy the file to a temporary file so that even if it subsequently
        # changes on disk, LinuxCNC is parsing the file contents from the time
        # the user opened the file
        tempfile = os.path.join(tempdir, os.path.basename(loaded_file))
        shutil.copyfile(loaded_file, tempfile)
        open_file_guts(tempfile, False, False)
    else:
        tempfile = os.path.join(tempdir, "filtered-" + os.path.basename(loaded_file))
        open_file_guts(tempfile, True, False)
    if line:
        o.set_highlight_line(line)

interacts badly with this https://github.com/LinuxCNC/linuxcnc/blob/master/src/emc/usr_intf/axis/scripts/axis.py#L1174 (notice the global variable)

loaded_file = None
def open_file_guts(f, filtered=False, addrecent=True):
    s.poll()
    save_task_mode = s.task_mode
    ensure_mode(linuxcnc.MODE_MANUAL)
    if addrecent:
        add_recent_file(f)
    if not filtered:
        global loaded_file
        loaded_file = f
...

also this code interferes https://github.com/LinuxCNC/linuxcnc/blob/master/src/emc/usr_intf/axis/scripts/axis.py#L2349

  def task_run(*event):
        res = 1
        while res == 1:
            res = run_warn()
            if res == 2: break
            if res == 3: return
            print("reload file")
            reload_file()

with this https://github.com/LinuxCNC/linuxcnc/blob/master/src/emc/usr_intf/axis/scripts/axis.py#L1876

def run_warn():
    warnings = []
    if o.canon:
        machine_limit_min, machine_limit_max = soft_limits()
        for i in range(3): # Does not enforce angle limits
            if not(s.axis_mask & (1<<i)): continue
            if o.canon.min_extents_notool[i] < machine_limit_min[i]:
                warnings.append(_("Program exceeds machine minimum on axis %s")
                    % "XYZABCUVW"[i])
            if o.canon.max_extents_notool[i] > machine_limit_max[i]:
                warnings.append(_("Program exceeds machine maximum on axis %s")
                    % "XYZABCUVW"[i])
    if warnings:
        text = "\n".join(warnings)
        return int(root_window.tk.call("nf_dialog", ".error",
            _("Program exceeds machine limits"),
            text,
            "warning",
            1, _("Re-Check"), _("Run Anyway"), _("Cancel"))) + 1
    return 0

notice how the non-warning-case returns 0, and 0 causes a reload, which will trigger the copying of the tmpfile onto the tmpfile.

Not sure how that ever worked.

andypugh commented 10 months ago

@rmu75 There seems to be a lot going on here, and lots of conflicting ideas in this and other PRs. You seem to have a handle on this, can you summarise which PRs should be merged, and which should be closed?

rmu75 commented 10 months ago

I'm a bit pressed for time at the moment -- I will try to summarize later today.

rmu75 commented 10 months ago

So testing currently a27fab362e0c3c5448842b80747ab6d3db23f40a, current tip of 2.9 branch. I tested modifying axis.ngc scale parameter with vim.

So I think that behaviour can't remain like it is now, esp. modifying, hitting "run" two times in a row and getting different results is clearly unacceptable.

IMO changing the file that is currently running via "remove or move to backup and create new file with same name" is a valid use-case and should be supported without any surprises happening. I like to tweak (in CAM) programs that are currently running to improve the next cycle, usually I write those programs via NFS directly to the machine. After this investigation I understand puzzling behaviour of the machine when doing that. I can imagine other scenarios, even with manual USB stick transfers, that could also lead to the GUI not noticing a changed file.

Cleanest solution is probably something like in qtpyvcp/probe_basic, i.e. watch the file for changes, and update preview if machine is idle. If machine is running the situation isn't that clear, but at least a warning should be displayed that the file has changed.

I will probably have to run that test again and check

andypugh commented 10 months ago

Personally I would expect "run" or "run from here" to run the file as-loaded. And I would expect to have to press the "reload" button for changes since the file was opened to be reflected in the preview and the motion.

This is how most things work, isn't it? (with the exception of some text editors, such as Geany, which display the file that you opened / edited, with a banner saying that it has changed on disc)

andypugh commented 2 months ago

Are we anywhere with a fix for this?