Remapped M code in python mdi command

More
21 Jul 2022 13:53 #247941 by AndrewL
I have a remapped M code written in python. I'm having trouble with the parts of the code using linuxcnc.command() - the M-Code will work when run from the mdi, but not when it is inside another .ngc program.

Example error messages:
can't do that (EMC_TOOL_LOAD_TOOL_TABLE) in auto mode with interpreter waiting
can't do that (EMC_TASK_PLAN_EXECUTE) in auto mode with interpreter reading
Must be in MDI mode to issue MDI command

The main question I have is:
Is there a workaround for executing a motion command (eg.  G0 Z0) from #!/usr/bin/python code?



Here is a simplified remapped M-Code that is condensed down to the problematic sections:
#!/usr/bin/python

import linuxcnc
s = linuxcnc.stat()
c = linuxcnc.command()



#Problem Command (solved):
# c.set_digital_output(16,1)
#Error Message: can't do that (EMC_MOTION_SET_DOUT) in auto mode with the interpreter waiting
#Solution: use shell command

#Problem Command:
linuxcnc.command().load_tool_table()
# can't do that (EMC_TOOL_LOAD_TOOL_TABLE) in auto mode with interpreter waiting

#Problem Command:
# c.mdi("M127")
carouselZ = -1.3192
c.mdi('G53 G90 G0 Z{}'.format(carouselZ))
# Must be in MDI mode to issue MDI command

exit(0)


(Note: On other code, I tried omitting #!/usr/bin/python and let python do: print(G0 Z0) to linuxcnc but then there is a tkinter import problem:
import-im6.q16: attempt to perform an operation that is not allowed by the security policy 'PS' @ error/constitute.c/IsCoderAuthorized/408.)
 

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

More
21 Jul 2022 19:41 #247983 by andypugh
If you are in a _remap_ and want to move an axis then use canonical commands.

import emccanon

There is an example in the testsuite:

github.com/LinuxCNC/linuxcnc/blob/2e75b0...terp/pymove/oword.py

I think you would need to look through emccanon.cc to find the list of canonical commands

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

More
26 Jul 2022 17:28 #248353 by AndrewL
Thank you for your reply.

I can get this code to work inside test.ngc. But how do you execute it from python?

for example:

m159
#!/usr/bin/python


print('m159 test')

import sys
sys.path.append('./python/oword.py')

import imp

oword = imp.load_source('oword', './python/oword.py')
oword.canonmove(X1, Y3, Z0)


exit(0)



... fails with:
Traceback (most recent call last):
  File "./nc_files//M159", line 11, in <module>
    oword = imp.load_source('oword', './python/oword.py')
  File "./python/oword.py", line 21, in <module>
    from util import call_pydevd
ImportError: No module named util
is_callable(oword.on_abort) = FALSE

 

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

More
31 Jul 2022 10:01 #248711 by andypugh
You probably can’t run it outside of a remap routine. It needs to run in the context of an active interpreter.

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

More
17 Aug 2022 15:39 #249952 by AndrewL
I have solutions for most of these problems
Error Messages:
can't do that (EMC_MOTION_SET_DOUT) in auto mode with the interpreter waiting
Must be in MDI mode to issue MDI command
My solution:
create M-code M150:
#!/usr/bin/python

# call shell script from the python script


print('___________________start M150___________________')



import os

import subprocess
import time
import math




def write_hal_signal(hal_signal , value):

    command = ['halcmd','sets',hal_signal,str(value)]

    process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None)
    output = process.communicate()        #Launch the shell command

    # print 'output:',output[0]
    # print 'outputF:', output
    # print 'poll', process.poll()
    if process.poll() == 0:
        # print(command, 'success')
        return 'success'
    else:
        print(command, 'failure')
        return 'failure'


def write_hal_pin(hal_pin , value):

    command = ['halcmd','setp',hal_pin,str(value)]

    process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None)
    output = process.communicate()        #Launch the shell command

    # print 'output:',output[0]
    # print 'outputF:', output
    # print 'poll', process.poll()
    if process.poll() == 0:
        # print(command, 'success')
        return 'success'
    else:
        print(command, 'failure')
        return 'failure'


def read_hal_signal(hal_signal):


    command = ['halcmd','gets',hal_signal]

    process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None)
    (command_output, error) = process.communicate()        #Launch the shell command
    value_str = str.strip(command_output)

    # print 'poll', process.poll()

    if process.poll() == 0:
        # print(command, 'success')
        if value_str == 'FALSE':
            value = 0
        elif value_str == 'TRUE':
            value = 1
        else:
            try:
                value = float(value_str)
            except:
                value = None
                # print 'Vaue Error!'
        # print 'value: ', value
    else:
        print(command, 'failure')
        value = None

    return value


def read_hal_pin(hal_pin):


    command = ['halcmd','getp',hal_pin]

    process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None)
    (command_output, error) = process.communicate()        #Launch the shell command
    value_str = str.strip(command_output)

    # print 'poll', process.poll()

    if process.poll() == 0:
        # print(command, 'success')
        if value_str == 'FALSE':
            value = 0
        elif value_str == 'TRUE':
            value = 1
        else:
            try:
                value = float(value_str)
            except:
                value = None
                # print 'Vaue Error!'
        # print 'value: ', value
    else:
        print(command, 'failure')
        value = None

    return value




def wait_hal_signal(hal_signal, value):
    # import time
    if read_hal_signal(hal_signal) is None:
        wait_success = 0
    else:
        while read_hal_signal(hal_signal) != value:
            wait_success = 0
            time.sleep(0.1)
            print 'Waiting for {}: {} == {}'.format(hal_signal, read_hal_signal(hal_signal),value)
        print 'wait_success'
        wait_success = 1
    return wait_success



def machine_command(*command_string):         #executes G-code / M-code machine commands        # can't take debug commands
    start_time = time.time()
    print('>>>>>>>>>>>>>>> execute g-code: ', command_string)

    '''Edit the subroutine .ngc file used by the halui.mdi-command'''
    writeMode = "w"
    a_file = open("./nc_subroutines/m502.ngc", writeMode)    #write mode
    writeMode = "a"


    remap_header = '''
; this file is auto-generated by python code in M150
; argspec Values are set by shell script via python (eg. M150)

; include these in the .ini file:
; [RS274NGC]
; REMAP=M502  modalgroup=10 argspec=(none) ngc=m502

; [HALUI]
; MDI_COMMAND = M502        (halui.mdi-command-02: machine_command_trigger)

o<m502> sub
'''


    # print remap_header.splitlines()
    remap_header_list = remap_header.splitlines()
    for line in remap_header_list:
        a_file.writelines(line)
        a_file.writelines('\n')

    for command in command_string:
        a_file.writelines('\n')
        a_file.writelines(command)
        # a_file.writelines('\n')
        # a_file.writelines('(DEBUG, exectued m502: {})'.format(command))
        a_file.writelines('\n')


    remap_footer = '''
o<m502> endsub
M2
'''

    remap_footer_list = remap_footer.splitlines()
    for line in remap_footer_list:
        a_file.writelines(line)
        a_file.writelines('\n')

    a_file.close()
    
    
    ''' execute the halui.mdi-command '''
    write_hal_signal('machine_command_trigger',1)
    time.sleep(0.1)        #pulse signal time
    write_hal_signal('machine_command_trigger',0)
    
    

    print("--- %s seconds ---" % (time.time() - start_time))


def delayed_machine_command(*command_string):         #executes G-code / M-code machine commands        
    start_time = time.time()
    print('>>>>>>>>>>>>>>> execute g-code: ', command_string)

    '''Edit the subroutine .ngc file used by the halui.mdi-command'''
    writeMode = "w"
    a_file = open("./nc_subroutines/m504.ngc", writeMode)    #write mode
    writeMode = "a"


    remap_header = '''
; this file is auto-generated by python code in M140
; argspec Values are set by shell script via python (eg. M140)

; include these in the .ini file:
; [RS274NGC]
; REMAP=M504  modalgroup=10 argspec=(none) ngc=m504

; [HALUI]
; MDI_COMMAND = M504        (halui.mdi-command-04: execute_delayed_command)

o<m504> sub
'''


    # print remap_header.splitlines()
    remap_header_list = remap_header.splitlines()
    for line in remap_header_list:
        a_file.writelines(line)
        a_file.writelines('\n')

    for command in command_string:
        a_file.writelines('\n')
        a_file.writelines(command)
        a_file.writelines('\n')
        # a_file.writelines('(DEBUG, exectued m504: {})'.format(command))
        # a_file.writelines('\n')


    remap_footer = '''
o<m504> endsub
M2
'''

    remap_footer_list = remap_footer.splitlines()
    for line in remap_footer_list:
        a_file.writelines(line)
        a_file.writelines('\n')

    a_file.close()
    
    
    # ''' execute the halui.mdi-command '''
    # write_hal_signal('machine_command_trigger',1)
    # time.sleep(0.1)        #pulse signal time
    # write_hal_signal('machine_command_trigger',0)
    
    

    print("--- %s seconds ---" % (time.time() - start_time))



def testprint(*strings):
    for string in strings:
        print string


def viewPockets():

    command = ['/home/weeke1/linuxcnc/configs/Weeke1/nc_files/M118']

    process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None)
    output = process.communicate()        #Launch the shell command

    # print 'output:',output[0]
    # print 'outputF:', output
    # print 'poll', process.poll()
    if process.poll() == 0:
        # print(command, 'success')
        return 'openPocketView success'
    else:
        print(command, 'openPocketView failure')
        return 'failure'
        
def showRotation():

    command = ['/home/weeke1/linuxcnc/configs/Weeke1/nc_files/M117']

    process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None)
    output = process.communicate()        #Launch the shell command

    # print 'output:',output[0]
    # print 'outputF:', output
    # print 'poll', process.poll()
    if process.poll() == 0:
        # print(command, 'success')
        return 'showRotation success'
    else:
        print(command, 'showRotation failure')
        return 'failure'
# import threading

# def printit():
    # threading.Timer(5.0, printit).start()
    # #print "Hello, World!"
    # print 'Weeke1Logic.0.loadA4State', read_hal_pin('Weeke1Logic.0.loadA4State')
    # return read_hal_pin('Weeke1Logic.0.loadA4State')





# from threading import *
# import time
 
# def thread_1():
    # #for i in range(8):
    # while True:
        # print 'Weeke1Logic.0.loadA4State', read_hal_pin('Weeke1Logic.0.loadA4State')
        # return read_hal_pin('Weeke1Logic.0.loadA4State')
        # time.sleep(0.1)
 
# T = Thread(target = thread_1)        # creating a thread
# T.setDaemon(True)            # change T to daemon
# T.start()        # starting of Thread T
# time.sleep(5)
# print('this is Main Thread')

# ''' expand functionality with examples here:
# https://stackoverflow.com/questions/3393612/run-certain-code-every-n-seconds
# '''






if __name__ == "__main__":
    
    """ Run test commands here """
    
    # print 'WRITE', write_hal_signal('areaLeftUnlock',1)
    # print 'WRITE', write_hal_signal('changeCommand',1)

    # print 'READ',read_hal_signal('areaLeftUnlock')


    # print 'WAIT', wait_hal_signal('223_Foot_Switch_A4',1)


    ##### signal's pin to be read by M502
    # write_hal_signal('pyPosValueX',23.123)


    ##### move to enabled axis values via pyPosMoveCmd => halui.mdi-command-02 => M502
    # write_hal_signal('pyPosMoveCmd',1)
    # time.sleep(1)
    # write_hal_signal('pyPosMoveCmd',0)



    # g_code_string_cmd('G53 g90 G0 X4 Z-0.125')
    # g_code_string_cmd('G53 G1 X20  F100')
    # g_code_string_cmd('X4 Z-0.125')

    # machine_command('G53 G0 X10 Y-5')
    # machine_command('G53 G0 X10 Y-5','G53 G0 X20 Y-10')


    #can't do this# machine_command('(DEBUG, M150 machine_command)')

    # machine_command('M127')

    # write_hal_signal('testMoveCmd',1)
    # time.sleep(1)
    # write_hal_signal('testMoveCmd',0)

    # write_hal_signal('m140active',0)
    # write_hal_signal('router1CylPosMuxIn1',0)
    
    # printit()
    
    # machine_command("G58 G91 G2 X0 Y0 I0.0001 P1 F150","G90")
    # machine_command("M550 P1 Q2")
    # openPocketView()


    
    
    
    
    
    
    print ("M150 is being run directly")
    print ("M150 __name__ = %s" %__name__)
    print('___________________end M150___________________')

    exit(0)            # If a M1nn command exits with nonzero status, the gcode program exits.  Exit 0 for success
else:
    print ("M150 is being imported")
    print('___________________end M150___________________')

M150 can be called from another M code:
""" M150 import """
# import sys
sys.path.append('/path_to_file/nc_files/M151')
import imp
M150 = imp.load_source('M150', '/home/weeke1/linuxcnc/configs/Weeke1/nc_files/M150')
from M150 import *

If the execution order gets problematic, I use
delayed_machine_command inside python a M code
M504 in a .ngc to make sure it gets executed at the right time
 

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

Time to create page: 0.207 seconds
Powered by Kunena Forum