Remapped M code in python mdi command
- AndrewL
 - Offline
 - Junior Member
 - 
				
			 
		Less
		More
		
			
	
		- Posts: 27
 - Thank you received: 2
 
			
	
						21 Jul 2022 13:53				#247941
		by AndrewL
	
	
		
			
	
			
			 		
													
	
				Remapped M code in python mdi command was created 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:
(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.)
 			
					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.
- andypugh
 - 
				
											 - Offline
 - Moderator
 - 
				
			 
		Less
		More
		
			
	
		- Posts: 19678
 - Thank you received: 4559
 
			
	
						21 Jul 2022 19:41				#247983
		by andypugh
	
	
		
			
	
			
			 		
													
	
				Replied by andypugh on topic Remapped M code in python mdi command			
			
				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
					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.
- AndrewL
 - Offline
 - Junior Member
 - 
				
			 
		Less
		More
		
			
	
		- Posts: 27
 - Thank you received: 2
 
			
	
						26 Jul 2022 17:28				#248353
		by AndrewL
	
	
		
			
	
			
			 		
													
	
				Replied by AndrewL on topic Remapped M code in python mdi command			
			
				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
... 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
 			
					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.
- andypugh
 - 
				
											 - Offline
 - Moderator
 - 
				
			 
		Less
		More
		
			
	
		- Posts: 19678
 - Thank you received: 4559
 
			
	
						31 Jul 2022 10:01				#248711
		by andypugh
	
	
		
			
	
			
			 		
													
	
				Replied by andypugh on topic Remapped M code in python mdi command			
			
				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.
- AndrewL
 - Offline
 - Junior Member
 - 
				
			 
		Less
		More
		
			
	
		- Posts: 27
 - Thank you received: 2
 
			
	
						17 Aug 2022 15:39				#249952
		by AndrewL
	
	
		
			
	
			
			 		
													
	
				Replied by AndrewL on topic Remapped M code in python mdi command			
			
				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:
M150 can be called from another M code:
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
 			
					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.068 seconds