Python interface: Wrong program line

More
02 Jan 2016 08:47 #67694 by yaqwsx
I am trying to read and modify LinuxCNC's (2.7.3) state using Python interface. One of the state properties I am interested in is current line of the running program. According to the documentation (linuxcnc.org/docs/2.6/html/common/python-interface.html) I should read "current_line". However I am getting nonsences. When I run the program, first two or three lines are OK, I get correct line numbers. However after them I always read value 198 and nothing else no matter what line is beeing executed.

I created this minimal example:
import sys, os, time
import gettext
BASE = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), ".."))
gettext.install("emc2", localedir=os.path.join(BASE, "share", "locale"), unicode=True)

import linuxcnc

emcStat = linuxcnc.stat()
emcCmd = linuxcnc.command()

try:
    while 1:
        emcStat.poll()
        print("Line: " + str(emcStat.current_line))
        time.sleep(0.5)
except KeyboardInterrupt:
    pass

What am I doing wrong?
What value should I read when no program is beeing executed?

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

More
02 Jan 2016 11:49 #67698 by ArcEye
The line numbers returned vary according to what value you access.
I have not done it through python before, but the same problems exist using the C interface directly

Try using this program and you will see what the 3 possible values return

current_line typically returns a value close to the length of the file without line spaces
read_line typically returns end of file with line spacing
motion_line is the one which returns the actual line currently being executed
# !/usr/bin/python

import sys, os, time
import gettext
BASE = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), ".."))
gettext.install("emc2", localedir=os.path.join(BASE, "share", "locale"), unicode=True)

import linuxcnc

emcStat = linuxcnc.stat()
emcCmd = linuxcnc.command()

try:
    while 1:
        emcStat.poll()
        print("CurrentLine: " + str(emcStat.current_line))
        print("ReadLine: " + str(emcStat.read_line))
        print("MotionLine: " + str(emcStat.motion_line))
        time.sleep(1)
except KeyboardInterrupt:
    pass

Do some experiments and you will see that read_line and motion_line return 0 when the program is not running, but current_line will keep the same value, even if you load another file, until that new file is started.
Then it will show a value equating to the new files length without line spaces.

Try running a program with an interpreter 'queue-buster' command in it, such as waiting for a digital input, and you will see a different pattern emerge. I won't go into why that is, but you can look it up.

regards
The following user(s) said Thank You: yaqwsx

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

More
02 Jan 2016 12:01 #67701 by yaqwsx
Thank you for the clarification! Is there a better documentation for the meaning of the values other than the page I mentioned in my question?

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

More
02 Jan 2016 12:33 - 02 Jan 2016 17:27 #67702 by ArcEye
The documentation you linked to is all there is AFAIK.

You will see even from that however, that the explanation for current_line, is plain wrong most of the time.

read_line is the line the interpreter is reading, which often is the end of the file, since it read it all in already

motion_line is the only one which returns close to what the GUI has highlighted in the code panel.

Poke around in the Axis code and search for motion_line.

You will see that it is motion_line that Axis function
def update()
uses to set the current line number in the the GUI
(note also the status.id field which the docs says is unknown relationship to motion_line.
Put this value in your printout and see if you can figure out the relationship B) )

EDIT:
AFAICT it mirrors motion_line, but I have not tried it with a subroutine or wait for digital input in the code eg. queue-buster
which would cause the interpreter to behave differently.

regards
Last edit: 02 Jan 2016 17:27 by ArcEye. Reason: Clarify

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

More
03 Jan 2016 13:13 #67749 by newbynobi
If you use a GladeVCP Panel, you can ad a hal status and connect a handler to on_line_changed signal.

The signal is generated in linuxcnc-dev/lib/python/hal_glib.py

I use that signal to update my gmoccapy program progress information, see gmoccapy.py line 1535 to 1543

Norbert

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

More
14 Mar 2018 16:34 #107352 by tivoi
make file log for motion_line code

# !/usr/bin/python

import sys, os, time
import gettext
BASE = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), ".."))
gettext.install("emc2", localedir=os.path.join(BASE, "share", "locale"), unicode=True)

import linuxcnc

emcStat = linuxcnc.stat()
emcCmd = linuxcnc.command()


try:
while 1:
emcStat.poll()
print("MotionLine: " + str(emcStat.motion_line))
f=open("gcode_line.txt","w+")
f.write("MotionLine: " + str(emcStat.motion_line))
f.close()
time.sleep(5)
except KeyboardInterrupt:
pass

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

Time to create page: 0.403 seconds
Powered by Kunena Forum