GladeVCP + Python: error handling during G38.2

More
14 Sep 2020 12:06 - 14 Sep 2020 12:08 #182071 by aekhv
Hi everyone,

I trying to catch errors during executing G38.2 and sometime it works fine, but sometimes not... Please point me what I'm doing wrong.

I have a simple GladeVCP panel with a button and textview component, python code is below.
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import linuxcnc
from datetime import datetime

class HandlerClass:

    # Prints message in following format: current time + text + LF code
    def msg(self, text):
        end_iter = self.buffer.get_end_iter()
        self.buffer.insert(end_iter, "%s %s\n" % (datetime.now().strftime('%H:%M:%S'), text))
        self.textview.scroll_to_mark(self.buffer.get_insert(), 0)

    # Returns -1 if LinuxCNC error detected
    def error_poll(self):
        error = self.e.poll()
        if error:
            kind, text = error
            if kind in (linuxcnc.NML_ERROR, linuxcnc.OPERATOR_ERROR):
                return -1
        return 0

    # Switching to MDI mode
    def set_mdi_mode(self):
        self.command.mode( linuxcnc.MODE_MDI )
        self.command.wait_complete()

    # Switching to manual mode
    def set_manual_mode(self):
        self.command.mode( linuxcnc.MODE_MANUAL )
        self.command.wait_complete()

    # Line by line G-Code execution
    def gcode(self, s):
        for s in s.split("\n"):
            self.command.mdi(s)
            self.command.wait_complete()
            if self.error_poll() == -1:
                return -1
        return 0

    # On button click
    def on_button_clicked(self, widget, data = None):
        self.msg("Button pressed...");

        # Set MDI mode
        self.set_mdi_mode()

        # A simple G-Code
        cmd = """G91
        G38.2 X-20 F300
        G90"""

        # Executing G-Code
        if self.gcode(cmd) == -1:
            self.msg("ERROR!")
        else:
            self.msg("OK!")

        # Set manual mode
        self.set_manual_mode()

# INIT FUNCTION
    def __init__(self, halcomp, builder, useropts):
        self.builder = builder
        self.stat = linuxcnc.stat()
        self.command = linuxcnc.command()
        self.e = linuxcnc.error_channel()
        self.textview = builder.get_object("textview")
        self.buffer = self.textview.get_property('buffer')
        # Welcome message
        end_iter = self.buffer.get_end_iter()
        self.buffer.insert(end_iter, "Welcome!\n\n")

# HANDLERS
def get_handlers(halcomp, builder, useropts):
    return [HandlerClass(halcomp, builder, useropts)]

Few times my code works fine, errors during G38.2 catching correctly:


But sometime it finished with OK, but it should not:


I think the problem is in error_poll() function, but I have no idea what I have missed. Hope for your help, guys.

Sources:

File Attachment:

File Name: glade-test...9-14.zip
File Size:2 KB
Attachments:
Last edit: 14 Sep 2020 12:08 by aekhv. Reason: Attachments lost

Please Log in or Create an account to join the conversation.

More
14 Sep 2020 15:23 #182094 by cmorley
Error handling like this will not be reliable.
Linuxcnc can only send error messages to one reader.
it's a race condition on who gets it.
In qtvcp we worked around this by having qtvcp read the error then send that to all other registered listeners (using STATUS messages)

You would need to tap into AXIS's error handling some how and send a message to gladevcp (like maybe x11 client messages as AXIS slready has this capability) to do this.
it's not impossible but I'm not an AXIS expert.

Chris
The following user(s) said Thank You: aekhv

Please Log in or Create an account to join the conversation.

More
15 Sep 2020 03:32 #182174 by aekhv
Hi Chris,

Thanks a lot for your reply, I have to think about it. Also I found another way (probably), I will try to get global parameter #5070 (G38 probe result) from my python code, maybe this will be best solution for me.

Please Log in or Create an account to join the conversation.

More
15 Sep 2020 03:56 #182178 by cmorley
That's a great idea to try!

Please Log in or Create an account to join the conversation.

More
17 Sep 2020 13:30 #182543 by aekhv
It looks like I found pretty simple and worked solution, the modified part of my source code is below:
...
    # Line by line G-Code execution
    def gcode(self, s):
        for l in s.split("\n"):
            self.command.mdi(l)
            # Default wait_complete() timeout is 5 seconds,
            # so 30 seconds should be enough for slow G38 operations
            self.command.wait_complete(30)
            #if self.error_poll() == -1:
            #    return -1
        return 0

    # On button click
    def on_button_clicked(self, widget, data = None):
        self.msg("Button pressed...");

        # Set MDI mode
        self.set_mdi_mode()

        # A simple G-Code
        cmd = """G91
        G38.2 X-20 F300
        G90"""

        # Executing G-Code
        self.gcode(cmd)

        # Check probe status
        self.stat.poll()
        if self.stat.probe_tripped == False:
            self.msg("ERROR!")
        else:
            self.msg("OK!")

        # Set manual mode
        self.set_manual_mode()
...

Please Log in or Create an account to join the conversation.

More
17 Sep 2020 15:24 #182549 by cmorley
Nice thinking. I'll remember that.

Please Log in or Create an account to join the conversation.

Moderators: HansU
Time to create page: 0.279 seconds
Powered by Kunena Forum