Remapping: Was: Stand Alone Interpe r ter
- bevins
- 
				  
- Offline
- Platinum Member
- 
				  
		Less
		More
		
			
	
		- Posts: 1940
- Thank you received: 338
			
	
						29 May 2019 17:02				#135300
		by bevins
	
	
		
			
				
Oh, it is long and complicated but the short story is, after four or five running of the same file and cutting, the interpreter just stops executing commands. IT just stops, the spindle still running, and no more commands are executed. The queue is empty, there are no errors, just stops.
Its been a long haul;, but, it is a known issue if you dig back into the threads and mailing list. IT is a pure python remap, and I cant get help on it because no one really understands the inner workings I guess I can say, except one person that just doesn't respond to questions. They do say you are on your own when you go this route.
but I would like to play with the stand alone interpreter, and I may get some kind of direction.
This is my config. Sorry, didnt mean to hijack this thread.
					
	
			
			 		
													
	
				Replied by bevins on topic Stand Alone Interpe r ter			
			@Bevins,
I am curious wich command's are ignored and what the bug's in remap are in your vision?
Maybe i can tell you some tip's after your info, maybe not
Oh, it is long and complicated but the short story is, after four or five running of the same file and cutting, the interpreter just stops executing commands. IT just stops, the spindle still running, and no more commands are executed. The queue is empty, there are no errors, just stops.
Its been a long haul;, but, it is a known issue if you dig back into the threads and mailing list. IT is a pure python remap, and I cant get help on it because no one really understands the inner workings I guess I can say, except one person that just doesn't respond to questions. They do say you are on your own when you go this route.
but I would like to play with the stand alone interpreter, and I may get some kind of direction.
This is my config. Sorry, didnt mean to hijack this thread.
Please Log in or Create an account to join the conversation.
- Grotius
- 
				  
- Offline
- Platinum Member
- 
				  
		Less
		More
		
			
	
		- Posts: 2419
- Thank you received: 2343
			
	
						29 May 2019 18:16		 -  29 May 2019 18:22		#135311
		by Grotius
	
	
		
			
	
	
			 		
													
	
				Replied by Grotius on topic Stand Alone Interpe r ter			
			
				@Bevins,
Oh, it is long and complicated but the short story is, after four or five running of the same file and cutting, the interpreter just stops executing commands. IT just stops, the spindle still running, and no more commands are executed. The queue is empty, there are no errors, just stops.
I never had this issue. Linux is stable as hell in my case. Is your machine pc at internet? In worst case you are hacked.
They do say you are on your own when you go this route.
Hmm. Why that? It can be monitored on several way's.
If you need some hijacked contact adresses. Please visit : darknetleaks.ru/archive/leaked/Dumps/FBI.txt
					Oh, it is long and complicated but the short story is, after four or five running of the same file and cutting, the interpreter just stops executing commands. IT just stops, the spindle still running, and no more commands are executed. The queue is empty, there are no errors, just stops.
I never had this issue. Linux is stable as hell in my case. Is your machine pc at internet? In worst case you are hacked.
They do say you are on your own when you go this route.
Hmm. Why that? It can be monitored on several way's.
If you need some hijacked contact adresses. Please visit : darknetleaks.ru/archive/leaked/Dumps/FBI.txt
		Last edit: 29 May 2019 18:22  by Grotius.			
			Please Log in or Create an account to join the conversation.
- bevins
- 
				  
- Offline
- Platinum Member
- 
				  
		Less
		More
		
			
	
		- Posts: 1940
- Thank you received: 338
			
	
						29 May 2019 19:05				#135315
		by bevins
	
	
		
			
				
I am not quite understanding your comments but....
I know Linuxcnc is stable. I have done many machine retrofits and building from scratch.
Pure Python remaps are very tedious and unpredictable. That is coming from the fellow that wrote the remap part of Linuxcnc.
This issue is documented in mailing lists. My machine is not hacked, it cannot be cause it is not connected to the internet.
					
	
			
			 		
													
	
				Replied by bevins on topic Stand Alone Interpe r ter			
			@Bevins,
Oh, it is long and complicated but the short story is, after four or five running of the same file and cutting, the interpreter just stops executing commands. IT just stops, the spindle still running, and no more commands are executed. The queue is empty, there are no errors, just stops.
I never had this issue. Linux is stable as hell in my case. Is your machine pc at internet? In worst case you are hacked.
They do say you are on your own when you go this route.
Hmm. Why that? It can be monitored on several way's.
If you need some hijacked contact adresses. Please visit : darknetleaks.ru/archive/leaked/Dumps/FBI.txt
I am not quite understanding your comments but....
I know Linuxcnc is stable. I have done many machine retrofits and building from scratch.
Pure Python remaps are very tedious and unpredictable. That is coming from the fellow that wrote the remap part of Linuxcnc.
This issue is documented in mailing lists. My machine is not hacked, it cannot be cause it is not connected to the internet.
Please Log in or Create an account to join the conversation.
- Todd Zuercher
- 
				  
- Away
- Platinum Member
- 
				  
		Less
		More
		
			
	
		- Posts: 4686
- Thank you received: 1433
			
	
						29 May 2019 19:47				#135318
		by Todd Zuercher
	
	
		
			
	
			
			 		
													
	
				Replied by Todd Zuercher on topic Stand Alone Interpe r ter			
			
				Maybe the problem isn't the interpreter, but the way the python remaps interact with it.  (from the sound of it, the developer who created it is suspicious of that.)
Can you make your remaps work without using python?
					Can you make your remaps work without using python?
Please Log in or Create an account to join the conversation.
- bevins
- 
				  
- Offline
- Platinum Member
- 
				  
		Less
		More
		
			
	
		- Posts: 1940
- Thank you received: 338
			
	
						30 May 2019 01:58		 -  30 May 2019 01:59		#135341
		by bevins
	
	
		
			
				
That's pretty much it. From what I understand the interpreter is not the master of its domain so it needs input from task before it can process commands. Or it's dependent on other processes or a combination , it just cannot execute by itself. Plus there is an issue of python not being able to process a sequence of functions, that's why you cannot use Standard glue with a remap in pure python. You have to put the functions standard glue has in the remap function, which is what I did and it works.
I am pretty sure it would work with oword ngc, but I know nothing about that and I guess it is not documented in one place where I can read and understand. I know of a guy that did the same type of machine with remapping M codes to fire all the relays but he didnt need to move the axis as he had no tool changer just 30 some odd number of gang drills.
I got everything working tool changes drill gangs but after a certain number of times processing the program, it just stops dead in it's tracks.
					
	
	
			 		
													
	
				Replied by bevins on topic Stand Alone Interpe r ter			
			Maybe the problem isn't the interpreter, but the way the python remaps interact with it. (from the sound of it, the developer who created it is suspicious of that.)
Can you make your remaps work without using python?
That's pretty much it. From what I understand the interpreter is not the master of its domain so it needs input from task before it can process commands. Or it's dependent on other processes or a combination , it just cannot execute by itself. Plus there is an issue of python not being able to process a sequence of functions, that's why you cannot use Standard glue with a remap in pure python. You have to put the functions standard glue has in the remap function, which is what I did and it works.
I am pretty sure it would work with oword ngc, but I know nothing about that and I guess it is not documented in one place where I can read and understand. I know of a guy that did the same type of machine with remapping M codes to fire all the relays but he didnt need to move the axis as he had no tool changer just 30 some odd number of gang drills.
I got everything working tool changes drill gangs but after a certain number of times processing the program, it just stops dead in it's tracks.
		Last edit: 30 May 2019 01:59  by bevins.			
			Please Log in or Create an account to join the conversation.
- andypugh
- 
				  
- Away
- Moderator
- 
				  
		Less
		More
		
			
	
		- Posts: 19677
- Thank you received: 4554
			
	
						30 May 2019 09:48				#135372
		by andypugh
	
	
		
			
				
I would say that if you need to move axes then it is a much better idea to use an O-word sub than to use pure Python. (I imagine that your Python uses MDI commands to move axes? Though you can do it with canonical movement commands too.)
You don't need M-codes to operate relays, G-code can toggle HAL pins directly, and has built-in codes to wait for HAL pin inputs to change.
Look at this G-code tool change sub, it sets HAL pins using M64 / M65 and uses M66 to wait for inputs confirming that the mechanisms are in position.
github.com/LinuxCNC/linuxcnc/blob/master...hange/toolchange.ngc
					
	
			
			 		
													
	
				Replied by andypugh on topic Remapping: Was: Stand Alone Interpe r ter			
			I am pretty sure it would work with oword ngc, but I know nothing about that and I guess it is not documented in one place where I can read and understand. I know of a guy that did the same type of machine with remapping M codes to fire all the relays but he didnt need to move the axis as he had no tool changer just 30 some odd number of gang drills.
I would say that if you need to move axes then it is a much better idea to use an O-word sub than to use pure Python. (I imagine that your Python uses MDI commands to move axes? Though you can do it with canonical movement commands too.)
You don't need M-codes to operate relays, G-code can toggle HAL pins directly, and has built-in codes to wait for HAL pin inputs to change.
Look at this G-code tool change sub, it sets HAL pins using M64 / M65 and uses M66 to wait for inputs confirming that the mechanisms are in position.
github.com/LinuxCNC/linuxcnc/blob/master...hange/toolchange.ngc
Please Log in or Create an account to join the conversation.
- bevins
- 
				  
- Offline
- Platinum Member
- 
				  
		Less
		More
		
			
	
		- Posts: 1940
- Thank you received: 338
			
	
						30 May 2019 11:04		 -  30 May 2019 11:05		#135374
		by bevins
	
	
		
			
				
Here is my main remap file. You think ngc oword could do this?
There is alot of code I am not using in there.
	
		
			
		
		
			
							
		
	
			
					
	
	
			 		
													
	
				Replied by bevins on topic Remapping: Was: Stand Alone Interpe r ter			
			
I am pretty sure it would work with oword ngc, but I know nothing about that and I guess it is not documented in one place where I can read and understand. I know of a guy that did the same type of machine with remapping M codes to fire all the relays but he didnt need to move the axis as he had no tool changer just 30 some odd number of gang drills.
I would say that if you need to move axes then it is a much better idea to use an O-word sub than to use pure Python. (I imagine that your Python uses MDI commands to move axes? Though you can do it with canonical movement commands too.)
You don't need M-codes to operate relays, G-code can toggle HAL pins directly, and has built-in codes to wait for HAL pin inputs to change.
Look at this G-code tool change sub, it sets HAL pins using M64 / M65 and uses M66 to wait for inputs confirming that the mechanisms are in position.
github.com/LinuxCNC/linuxcnc/blob/master...hange/toolchange.ngc
Here is my main remap file. You think ngc oword could do this?
There is alot of code I am not using in there.
			Warning: Spoiler!		
		#!/usr/bin/env python
# Mar 2017 Code by Michel Trahan, Bob Bevins and Sylvain Deschene
# Remap of M6 in Pure Python, remap.py includes change_epilog
# Machine is Biesse 346 1995, with 3 position rack toolchanger
#-----------------------------------------------------------------------------------
import linuxcnc
from interpreter import *
import emccanon
from util import lineno
#-----------------------------------------------------------------------------------
throw_exceptions = 1 # raises InterpreterException if execute() or read() fail
#-----------------------------------------------------------------------------------
import xmlBiesse
import sys
#------------------------------------------------------------------------------------------------------
# MAIN FUNCTION : change_remap 
#
#      REMAP=M6 modalgroup=6  python=M6_Remap_BiesseRover346  
#       - Do not use stdglue.py, in pure python remap
#------------------------------------------------------------------------------------------------------
def queuebuster(self, **words):
    yield INTERP_EXECUTE_FINISH
    
def M6_Remap_BiesseRover346(self, **words):
    #--------------------------------------------------
    # if in preview mode exit without doing anything and all ok
    #----------------------------------------------------------
    if self.task==0:
        return INTERP_OK
    #else:
    #    DoYield()
    change_prolog1(self, **words)
	
    try:
        #--------------------------------------------------------------------
        #   Get the xmlfile path from the ini file ... or hardcode here
        #--------------------------------------------------------------------
        # [XML]
        # FILE=/home/bob/linuxcnc/configs/python/BiesseRover346.xml
        #--------------------------------------------------------------------
		
		
        
		
        xmlfile = "/home/bob/linuxcnc/configs/python/BiesseRover346.xml"
        #---------------------------------------------------------------------
        #   XML - Objects to fetch needed infos ...
        #---------------------------------------------------------------------
        
        self.x = xmlBiesse.xmlBiesse(xmlfile) # the xml interface
        # set some self values 
        self.feedSpeed  = self.x.getFeedSpeed()
        self.pulseDelay = self.x.getDelay("pulseDelay")
        self.stat = linuxcnc.stat()
        self.HIGH = 1
		
        StopSpindleNow(self)
        
        # -------------------------------------
        # test if spindle has really stopped
        #--------------------------------------
        self.stat.poll()
        index = self.x.getSignalInfos("spindleHasStopped")
        isSpindleStopped = int(self.stat.din[index])
        if isSpindleStopped != 1:
            msg = "Spindle has not stopped even after M66"
            self.set_errormsg(msg)
            return ReturnERROR()
        
        #------------------------------------------------------------------
        # we are good to go
        #------------------------------------------------------------------
        print("Spindle Stopped")
        #-----------------------
        # raise the Z
        #-----------------------
        MoveZtoZero(self)
        #----------------------------------------------
        
        #-----------------------
        # raise all spindles
        #-----------------------
        print("Lets just try raising A,B and C for now")
        raisespindlesABC(self)
        #raiseALLspindles(self)
        print("ALL Spindle Raised")
        #--------------------------
        # De Energise all spindles
        #--------------------------
        DeEnergiseALLSpindle(self)
        print("ALL Spindles DeEnergised")
        #---------------------------------------------------------------------------------
        # now go according to selected_tool given by linuxcnc for the Txxx M6 ngc command
        #---------------------------------------------------------------------------------
        selectedtool = int(self.params["selected_tool"])
        self.selected_tool = int(self.params["selected_tool"])
        print("Selected Tool : %d" % selectedtool)
        if selectedtool > 700:                                  # 701 to ... any combinations of drills and side drills
            DropTools(self, selectedtool)
            self.current_tool = selectedtool
            self.current_pocket = selectedtool
            self.execute("G43 H%d" % selectedtool)
        elif (selectedtool > 500 and selectedtool < 510):       # 5 pairs of side drills (1,3,5,7,9)
            DropSideDrill(self, selectedtool - 500)
            self.current_tool = selectedtool
            self.current_pocket = selectedtool
            self.execute("G43 H%d" % selectedtool)
        elif (selectedtool > 400 and selectedtool < 434):       # 33 drills (1-33)
            DropDrill(self, selectedtool - 400)
            self.current_tool = selectedtool
            self.current_pocket = selectedtool
            self.execute("G43 H%d" % selectedtool)
        else:
            if selectedtool == 21:
                if SpindleHasTool(self, "C"):
                    DropSpindleC(self)
                    EnergiseSpindle(self, "C")
                    #This is if you have three ISO spindles. This is spindle#3 or C
                    return INTERP_OK
                else:
                    msg = "Spindle C has no tool"
                    self.set_errormsg(msg)
                    return ReturnERROR()
            elif selectedtool == 20:
                if SpindleHasTool(self, "B"):
                    DropSpindleB(self)
                    EnergiseSpindle(self, "B")
                    SetG43Tool20(self)
                    #This is if you have three ISO spindles. This is spindle#2 or B
                    return INTERP_OK
                else:
                    msg = "Spindle B has no tool"
                    self.set_errormsg(msg)
                    return ReturnERROR()
            elif selectedtool > 0 and selectedtool < 4: #only 3 tools for A (1, 2, 3)
                EnergiseSpindle(self, "A")
                # now time to see if already in spindle
                freePocket = FindFreePocket(self)
                self.current_pocket = freePocket
                print("freePocket = %s" % freePocket)
                currenttool = int(self.params["tool_in_spindle"])
                print("tool in spindle = %s" % currenttool)
                if freePocket == -1:
                    # what is in spindle 1 ? check if spindle has tool
                    if SpindleHasTool(self, "A"): # we have a problem
                        msg = "No Free Pockets and Spindle A has a tool"
                        self.set_errormsg(msg)
                        return ReturnERROR()
                    else: # if not, go get the one needed
                        #------------------------------------------
                        # PICKUP selected tool in according pocket
                        #------------------------------------------
                        print("Spindle A has no tool, going to PickUpNewTool %d" % selectedtool)
                        OpenCasket(self)
                        if selectedtool == 1:       #Pickup Tool 1
                            PickUpTool1(self)                            
                            CloseCasket(self)
#                            self.current_tool = 1
                        elif selectedtool == 2:     #Pickup Tool 2
                            PickUpTool2(self)
                            #SetG43Tool2(self)
                            CloseCasket(self)
#                            self.current_tool = 2
                        elif selectedtool == 3:     #Pickup Tool 3
                            PickUpTool3(self)
                            CloseCasket(self)
#                            self.current_tool = 3
							
                        self.current_tool = selectedtool
                        self.current_pocket = selectedtool
                        self.execute("G43 H%d" % selectedtool)
						
                        return INTERP_OK    
                else:
                    print("There is a free pocket")
                    #-------------------------------------------------------
                    # check if spindle has tool
                    #-------------------------------------------------------
                    if not SpindleHasTool(self, "A"):
                        msg = "Error while droping a tool, Spindle A has no tool to drop"
                        self.set_errormsg(msg) # replace builtin error message
                        return ReturnERROR()
                    print("Spindle A has tool, do drop it")
                    #-------------------------------------------------------
                    # check if tool already in spindle
                    #-------------------------------------------------------
                    if freePocket == selectedtool:
                        DropSpindleA(self)
                        print("Spindle A already has the right tool")
                        self.current_tool = selectedtool
                        self.current_pocket = selectedtool
                        return INTERP_OK
                    #------------------------------------
                    # DROP current tool in free pocket
                    #------------------------------------
                    OpenCasket(self)
                    if freePocket == 1:
                         
                        DropTool1(self)
                        if selectedtool == 2:
                            PickUpTool2(self)
                        elif selectedtool ==3:
                            PickUpTool3(self)
                        CloseCasket(self)
                        DropSpindleA(self)
                        self.current_tool = selectedtool
                        self.current_pocket = selectedtool
                        self.execute("G43 H%d" % selectedtool)
                        return INTERP_OK
                        
                    elif freePocket == 2:
                        
                        DropTool2(self)
                        if selectedtool == 1:
                            PickUpTool1(self)
                        elif selectedtool ==3:
                            PickUpTool3(self)
                        CloseCasket(self)
                        DropSpindleA(self)
                        self.current_tool = selectedtool
                        self.current_pocket = selectedtool
                        self.execute("G43 H%d" % selectedtool)
                        return INTERP_OK
                        
                    elif freePocket == 3:
                        DropTool3(self)
                        if selectedtool == 2:
                            PickUpTool2(self)
                        elif selectedtool ==1:
                            PickUpTool1(self)
                        CloseCasket(self)
                        DropSpindleA(self)
                        self.current_tool = selectedtool
                        self.current_pocket = selectedtool
                        self.execute("G43 H%d" % selectedtool)
                        return INTERP_OK
                   
            
                        
            else: # not > 700, not between 400 and 434 (exclusive), not between 500 and 510 (exclusive), nor 0,1,2,3,10,11
                msg  = "Wrong tool number either 0 to remove it from spindle or 1,2,3,20,21\n"
                msg += "Or 401 to 433 for drills, 501, 503, 505, 507, 509 for side drills,\n"
                msg += "701 to whatever is defined in the tool table AND the xml file\n"
                msg += "Tool given was: %d" %  selectedtool
                self.set_errormsg(msg) # replace builtin error message
                return ReturnERROR()
                
    #-----------------------------------------
    # We have errors ! catch and return error
    #-----------------------------------------
    except InterpreterException,e:
        msg = "BOB look at this error : %d: '%s' - %s" % (e.line_number,e.line_text, e.error_message)
        self.set_errormsg(msg) # replace builtin error message
        print("%s" % msg)
        return ReturnERROR()
    except IOError as e:
        print "I/O error({0}): {1}".format(e.errno, e.strerror)
        return ReturnERROR()
    except ValueError:
        print "Could not convert data to an integer."
        return ReturnERROR()
    except ZeroDivisionError as detail:
        print 'Handling run-time error:', detail
        return ReturnERROR()
    except:
        print "Unexpected error:", sys.exc_info()[0]
        raise
   
    finally:
        
 
    
        print 'Hold on, off to epilog coming up!'
        print("Current pocket = %s" % self.current_pocket)
        print("Selected pocket = %s" % self.selected_pocket)
        print("Param.Selected pocket = %s" % int(self.params["selected_pocket"]))
        print("Current tool in spindle = %s" % self.current_tool)
        print("Selected tool = %s" % self.selected_tool)
        
        self.return_value = self.selected_tool
    #-----------------------
    # all fine, return ok !
    #-----------------------
        # This is the change_epilog within remap body     
        print 'Final!'
        print("Self return value = %s" % self.return_value)
        print 'calling epilog'
        print 'Returned form epilog journey'
        print("Current pocket = %s" % self.current_pocket)
        print("Selected pocket = %s" % self.selected_pocket)
        print("Param.Selected pocket = %s" % int(self.params["selected_pocket"]))
        print("Current tool in spindle = %s" % self.current_tool)
        print("Selected tool = %s" % self.selected_tool)
        self.selected_pocket =  int(self.params["selected_pocket"])
        print("before emccannon CHANGE TOOL")
        emccanon.CHANGE_TOOL(self.selected_pocket)
        print("emccannon CHANGE TOOL sent")
        self.current_pocket = self.selected_pocket
        #self.selected_pocket = -1
        #self.selected_tool = -1
        # cause a sync()
        print("Lets Sync this Bitch, NOW")
        self.set_tool_parameters()
        self.toolchange_flag = True
        
        
    return INTERP_OK
    
#----------------------------------------------------------
#----------------------------------------------------------
def change_prolog1(self, **words):
    try:
        if self.selected_pocket < 0:
            return "M6: no tool prepared"
        if self.cutter_comp_side:
            return "Cannot change tools with cutter radius compensation on"
        self.params["tool_in_spindle"] = self.current_tool
        self.params["selected_tool"] = self.selected_tool
        self.params["current_pocket"] = self.current_pocket
        self.params["selected_pocket"] = self.selected_pocket
        
        return INTERP_OK
    except Exception, e:
        return "M6/change_prolog: %s" % (e)
def change_epilog(self, **words):
    try:
            #print("Change epilog executing....")
            if self.return_value > 0.0:
                print("pass return value")
                self.selected_pocket =  int(self.params["selected_pocket"])
                print("before emccannon CHANGE TOOL")
                emccanon.CHANGE_TOOL(self.selected_pocket)
                print("emccannon CHANGE TOOL sent")
                self.current_pocket = self.selected_pocket
                self.selected_pocket = -1
                self.selected_tool = -1
                # cause a sync()
                print("Lets Sync this Bitch, NOW")
                self.set_tool_parameters()
                self.toolchange_flag = True
                yield INTERP_EXECUTE_FINISH
            else:
                self.set_errormsg("M6 aborted (return code %.1f)" % (self.return_value))
                return
    except Exception, e:
        self.set_errormsg("M6/change_epilog: %s" % (e))
        return 
#----------------------------------------------------------
#-----Set me some tool offsets here!!!---------------------
#----------------------------------------------------------
def SetG43Tool20(self):
    self.execute("G43 H20")
    
def SetG43Tool2(self):
    self.execute("G43 H2")    
#----------------------------------------------------------
def DropSpindleA(self):
    self.execute("M64 P2")                      #Drop Spindle
    self.execute("G4 P1")                       #wait to release pulse on lock spindle
    self.execute("M65 P2")                      #Release drop SP relay, only needs pulse
    self.execute("G4 P1")
    self.execute("M66 P9 L3 Q5")  
    print("drop Spindle A Done")              #Wait for Spindle to drop
    
def DropSpindleB(self):
    index = self.x.getSignalInfos("spindleBdrop")
    self.execute("M64 P%d" % index)
    self.execute("G4 P0.5")
    self.execute("M65 P%d" % index)
    index = self.x.getSignalInfos("spindleBdown")
    self.execute("M66 P%d L4 Q1" % index)
    #self.execute("M64 P3")
    #self.execute("G4 P0.5")
    #self.execute("M65 P3")
    #self.execute("M66 P10 L4 Q1")
    print("DropSpindle(B) done")
def DropSpindleC(self):
    self.execute("M64 P4")
    self.execute("G4 P0.5")
    self.execute("M65 P4")
    self.execute("M66 P11 L4 Q1")
    print("DropSpindle(C) done")    
    
def DropTool1(self):
    #id = 1
    #posX, posY, posZ = self.x.getPocketPos(id, "Front")
    self.execute("G53 G0 X15.375 Y-25.57 Z0")   #Move to front of pocket 1
    #self.execute("G53 G0 F%d X%f Y%f Z0.0" % (self.feedSpeed, posX, posY), lineno())
    self.execute("M64 P2")                      #Drop Spindle A
    self.execute("M66 P9 L3 Q5")                #Wait for Spindle to drop
    self.execute("M65 P2")                      #Release drop SP relay, only needs pulse
    self.execute("M64 P10")                     #raise Pocket 1
    self.execute("M66 P17 L3 Q5")               #wait for Pocket to raise
    self.execute("G53 G0 Z-1.788")              #Drop the Z into position
    #self.execute("G53 G0 F%d Z%f" % (self.feedSpeed, posZ), lineno())
    self.execute("G53 G1 F200 X11.825")         #Move into pocket to release tool
    #posX2, posY2, posZ2 = self.x.getPocketPos(id, "Top")
    #self.execute("G53 G1 F%d X%f " % (self.feedSpeed, posX2),lineno())
    self.execute("M66 P4 L3 Q5")                #Wait for pocket 1 has tool
    self.execute("M64 P8")                      #Release Spindle
    self.execute("M66 P13 L3 Q5")               #Wait for Spindle to release
    self.execute("M64 P5")                      #Raise Spindle
    self.execute("M66 P7 L3 Q5")                #Wait for Spindle to raise
    self.execute("G53 G0 Z0")                   #Move to Z0
    self.execute("M65 P8")                      #Release Sp A pulse relay, only needs pulse
    self.execute("M64 P9")                      #Lock Spindle A
    self.execute("G4 P1.0")                     #wait to release pulse on lock spindle
    self.execute("M65 P9")                      #release Lock Spindle A, only needs pulse    
    self.execute("M65 P10")                     #Lower Pocket 1
    self.execute("G53 G0 X15.375 Y-25.57 Z0")   #Move to front of pocket 1   
    #self.execute("G53 G0 F%d X%f Y%f Z0.0" % (self.feedSpeed, posX, posY), lineno())
    #self.execute("G1 G53 F%d Z%f" % (self.feedSpeed, posZ), lineno())
    #INTERP_EXECUTE_FINISH
#---------------------------------------------------------------------
def DropTool2(self):
    self.execute("G53 G0 X15.375 Y-33.527 Z0")  #Move to front of pocket 2
    self.execute("M64 P2")                      #Drop Spindle
    self.execute("M66 P9 L3 Q5")                #Wait for Spindle to drop
    self.execute("M65 P2")                      #Release drop SP relay, only needs pulse
    self.execute("M64 P11")                     #raise Pocket 2
    self.execute("M66 P18 L3 Q5")              #wait for Pocket to raise
    self.execute("G53 G0 Z-1.840")              #Drop the Z into position
    self.execute("G53 G1 F200 X11.900")         #Move into pocket to release tool
    #self.execute("M66 P5 L3 Q5")                #Wait for pocket 2 has tool
    self.execute("M64 P8")                      #Release Spindle
    self.execute("M66 P13 L3 Q5")               #Wait for Spindle to release
    self.execute("M64 P5")                      #Raise Spindle
    self.execute("M66 P7 L3 Q5")                #Wait for Spindle to raise
    self.execute("G53 G0 Z0")                   #Move to Z0
    self.execute("M65 P8")                      #Release Sp B pulse relay, only needs pulse
    self.execute("M64 P9")                      #Lock Spindle A
    self.execute("G4 P1.0")                     #wait to release pulse on lock spindle
    self.execute("M65 P9")                      #release Lock Spindle A, only needs pulse
    self.execute("M65 P11")                     #Lower Pocket 2
    self.execute("G53 G0 X15.375 Y-33.527 Z0")   #Move to front of pocket 2
    #INTERP_EXECUTE_FINISH
#---------------------------------------------------------------------
def DropTool3(self):
    self.execute("G53 G0 X15.375 Y-41.545 Z0")  #Move to front of pocket 3
    self.execute("M64 P2")                      #Drop Spindle
    self.execute("M66 P9 L3 Q5")                #Wait for Spindle to drop
    self.execute("M65 P2")                      #Release drop SP relay, only needs pulse
    self.execute("M64 P12")                     #raise Pocket 3
    self.execute("M66 P19 L3 Q5")               #wait for Pocket to raise
    self.execute("G53 G0 Z-1.790")              #Drop the Z into position
    self.execute("G53 G1 F200 X11.825")         #Move into pocket to release tool
    #self.execute("M66 P6 L3 Q5")                #Wait for pocket 3 has tool
    self.execute("M64 P8")                      #Release Spindle 
    self.execute("M66 P13 L3 Q5")               #Wait for Spindle to release
    self.execute("M64 P5")                      #Raise Spindle
    self.execute("M66 P7 L3 Q5")                #Wait for Spindle to raise
    self.execute("G53 G0 Z0")                   #Move to Z0
    self.execute("M65 P8")                      #Release Sp B pulse relay, only needs pulse
    self.execute("M64 P9")                      #Lock Spindle A
    self.execute("G4 P1.0")                     #wait to release pulse on lock spindle
    self.execute("M65 P9")                      #release Lock Spindle A, only needs pulse    
    self.execute("M65 P12")                     #Lower Pocket 3
    self.execute("G53 G0 X15.375 Y-41.545 Z0")  #Move to front of pocket 3  
    #INTERP_EXECUTE_FINISH
#---------------------------------------------------------------------
def PickUpTool1(self):
	self.execute("G53 G0 Z0")          			#Move to Z0
	self.execute("G53 G0 X11.825 Y-25.57 Z0")   #Move to top of pocket 1
	self.execute("G53 G0 Z-1.788")              #Drop the Z into position
	self.execute("M64 P10")                     #raise Pocket 1
	self.execute("M66 P17 L3 Q5")               #wait for Pocket to raise
	self.execute("M64 P8")                      #Release Spindle
	#self.execute("M66 P13 L3 Q5")               #Wait for Spindle to release
	self.execute("G4 P1")
	self.execute("M64 P2")                      #Drop Spindle
	self.execute("M66 P9 L3 Q5")                #Wait for Spindle to drop
	self.execute("G4 P0.5")
	self.execute("M65 P8")                      #Release Rel Spindle. only needs a pulse 
	self.execute("M64 P9")                      #Lock Spindle A
	self.execute("G4 P0.5")                     #wait to release pulse on lock spindle
	self.execute("M65 P9")                      #release Lock Spindle A, only needs pulse
	#self.execute("M66 P12 L3 Q5")               #Wait for spindle Has Tool 1
	self.execute("M65 P2")                      #Release drop SP relay, only needs pulse
	self.execute("G4 P0.5")   
	self.execute("G53 G0 X15.375")   			#Move out to front of pocket 1
	self.execute("G4 P1.0")   
	self.execute("M64 P5")                      #Raise Spindle
	self.execute("M66 P7 L3 Q2")                #Wait for Spindle to raise
	self.execute("G53 G0 Z0")   				#Move to Z0
	self.execute("M65 P5")                      #RAise spindle release only pulse needed   
	self.execute("M65 P10")                     #Lower Pocket 1
	self.execute("G53 G0 Z0")                   #Move to Z0
	#INTERP_EXECUTE_FINISH
	
    
    
def PickUpTool2(self):
	self.execute("G53 G0 Z0")   				#Move to Z0
	self.execute("G53 G0 X11.900 Y-33.537 Z0")   #Move to top of pocket 2
	self.execute("G53 G0 Z-1.840")              #Drop the Z into position
	self.execute("M64 P11")                     #raise Pocket 2
	self.execute("M66 P18 L3 Q5")               #wait for Pocket to raise
	self.execute("M64 P8")                      #Release Spindle
	#self.execute("M66 P13 L3 Q5")               #Wait for Spindle to release
	self.execute("G4 P1")
	self.execute("M64 P2")                      #Drop Spindle
	self.execute("M66 P9 L3 Q5")                #Wait for Spindle to drop
	self.execute("G4 P0.5")
	self.execute("M65 P8")                      #Release Rel Spindle. only needs a pulse 
	self.execute("M64 P9")                      #Lock Spindle A
	self.execute("G4 P0.5")                     #wait to release pulse on lock spindle
	self.execute("M65 P9")                      #release Lock Spindle A, only needs pulse
	#self.execute("M66 P12 L3 Q5")               #Wait for spindle Has Tool 1
	self.execute("M65 P2")                      #Release drop SP relay, only needs pulse
	self.execute("G4 P0.5")   
	self.execute("G53 G0 X15.375")   			#Move out to front of pocket 2
	self.execute("G4 P1.0")   
	self.execute("M64 P5")                      #Raise Spindle
	self.execute("M66 P7 L3 Q2")                #Wait for Spindle to raise
	self.execute("G53 G0 Z0")   				#Move to Z0
	self.execute("M65 P5")                      #RAise spindle release only pulse needed   
	self.execute("M65 P11")                     #Lower Pocket 2
	self.execute("G53 G0 Z0")                   #Move to Z0
	#INTERP_EXECUTE_FINISH
	
def PickUpTool3(self):
	self.execute("G53 G0 Z0")   				#Move to Z0
	self.execute("G53 G0 X11.825 Y-41.545 Z0")   #Move to top of pocket 3
	self.execute("G53 G0 Z-1.790")              #Drop the Z into position
	self.execute("M64 P12")                     #raise Pocket 3
	self.execute("M66 P19 L3 Q5")               #wait for Pocket to raise
	self.execute("M64 P8")                      #Release Spindle
	#self.execute("M66 P13 L3 Q5")               #Wait for Spindle to release
	self.execute("G4 P1")
	self.execute("M64 P2")                      #Drop Spindle
	self.execute("M66 P9 L3 Q5")                #Wait for Spindle to drop
	self.execute("G4 P0.5")
	self.execute("M65 P8")                      #Release Rel Spindle. only needs a pulse 
	self.execute("M64 P9")                      #Lock Spindle A
	self.execute("G4 P0.5")                     #wait to release pulse on lock spindle
	self.execute("M65 P9")                      #release Lock Spindle A, only needs pulse
	#self.execute("M66 P12 L3 Q5")               #Wait for spindle Has Tool 3
	self.execute("M65 P2")                      #Release drop SP relay, only needs pulse
	self.execute("G4 P0.5")   
	self.execute("G53 G0 X15.375")   			#Move out to front of pocket 3
	self.execute("G4 P1.0")   
	self.execute("M64 P5")                      #Raise Spindle
	self.execute("M66 P7 L3 Q2")                #Wait for Spindle to raise
	self.execute("G53 G0 Z0")   				#Move to Z0
	self.execute("M65 P5")                      #RAise spindle release only pulse needed   
	self.execute("M65 P12")                     #Lower Pocket 3
	self.execute("G53 G0 Z0")                   #Move to Z0
	#INTERP_EXECUTE_FINISH
#---------------------------------------------------------------------
def raisespindlesABC(self):
    #Raising Spindle A, B, C
    self.execute("M64 P5")
    self.execute("M64 P6")
    self.execute("M64 P7")
    self.execute("G4 P1.0")
    self.execute("M65 P5") 
    self.execute("M65 P6")
    self.execute("M65 P7")
    #------------------------------
    # loop through all drills
    #------------------------------
    for i in range(1, 34, 1):
        self.execute("M65 P%d" % (int(i) + 15))
    #------------------------------
    # loop through all side drills
    #------------------------------
    for i in range(1, 6, 1):
        self.execute("M65 P%d" % (int(i) + 48))
       
    
    
def CloseCasket(self):
    #----------------------------------------------------------------
    self.execute("M64 P1", lineno())
    self.execute("G4 P0.5", lineno())
    self.execute("M65 P1", lineno())
    
#----------------------------------------------------------
#----------------------------------------------------------
def OpenCasket(self):
    #----------------------------------------------------------------
    self.execute("M64 P0", lineno())
    self.execute("G4 P0.5", lineno())
    self.execute("M65 P0", lineno())
    self.execute("M66 P2 L3 Q5", lineno())
   
#----------------------------------------------------------
#------------------------------------------------------------------------------------------        
#----------------------------------------------------------
def CheckDIN(self, sWhich, doPoll):
    index = self.x.getSignalInfos(sWhich)
    if doPoll:
        self.stat.poll()
    return(int(self.stat.din[index]))
    
#----------------------------------------------------------
#----------------------------------------------------------
def CheckDOUT(self, sWhich, doPoll):
    index = self.x.getSignalInfos(sWhich)
    if doPoll:
        self.stat.poll()
    #print("signal:%s index= %d" %(sWhich, index))
    return(int(self.stat.dout[index]))
    
#----------------------------------------------------------
#----------------------------------------------------------
def SendDOUT(self, sWhich, val):
    index = self.x.getSignalInfos(sWhich)
    # only call M6x if not already at desired value
    if CheckDOUT(self, sWhich, True) != val:
        self.execute("M6%d P%d" % (4 if val == 1 else 5, index),lineno())
#----------------------------------------------------------
#----------------------------------------------------------
def WaitOnSignalToBecome(self, sWhich, val, sSec): # val = 0 (L2) val = 1 (L1)
    index = self.x.getSignalInfos(sWhich)
    self.execute("M66 P%d L%d Q%f" % (index, 4 if val == 0 else 3, sSec), lineno())
                       
#----------------------------------------------------------
#----------------------------------------------------------
def WaitAFewSeconds(self, sSec):
    self.execute("G4 P%f" % sSec, lineno())
                    
#-------------------------------------------------------------------
# M5 command to stop the spindle, here to clean up Spindle class, 
# not in moves so we don't give moves to spindle class ...
#-------------------------------------------------------------------
def StopSpindleNow(self):
    self.execute("M5", lineno())
    # Now lets stop the drill spindle if running
    self.execute("M65 P54")
    # Wait for signal spindleHasStopped to go high
    index = self.x.getSignalInfos("spindleHasStopped")
    delay = self.x.getDelay("spindlehasstopped")
    #self.execute("M66 P%d  L3 Q%f"" % (index, delay), lineno())
    self.execute("M66 P8 L3 Q15")
    print("Stop Spindle command sent")
    
	
        
        
#-------------------------------------------------------------------------------------------
#-------------------------------------------------------------------------------------------
#   
#-------------------------------------------------------------------------------------------
#-------------------------------------------------------------------------------------------
#----------------------------------------------------------
#----------------------------------------------------------
def MoveZtoZero(self):
    self.execute("G53 G0 Z0.0",lineno())
    print("Moved to Z = 0.0")
    
#----------------------------------------------------------
def SetToolOffsets(self):
    self.execute("G43")
#----------------------------------------------------------
#----------------------------------------------------------
#----------------------------------------------------------
def isSpindleReallyStopped(self):
    isSpindleStopped = CheckDIN(self, "spindleHasStopped", True)
    print("isSpindleStopped = %s" % isSpindleStopped)
    if isSpindleStopped == 1:
        return True
    else:
        return False
#----------------------------------------------------------
# raising all spindles ... to make sure they are all raised
#----------------------------------------------------------
def raiseALLspindles(self):
    #------------------------------
    # loop through all spindles
    #------------------------------
    #------------------------------------------------
    # check first if all spindle are already up
    #------------------------------------------------
    print("raiseALLspindles")
    isSpindleALLup = CheckDIN(self, "spindleALLup", True)
    if isSpindleALLup == 0:
        # nope some are down, so put them all up
        validSpindle = ("A", "B", "C")
        for i in validSpindle:
            RaiseSpindleNoCheck(self, i)
    WaitOnSignalToBecome(self, "spindleALLup", self.HIGH, self.x.getDelay("spindleALLup"))
    isSpindleALLup = CheckDIN(self, "spindleALLup", True)
    if isSpindleALLup == 0:
        print("ERROR: SpindleAllup not true") #we have an error
    #------------------------------
    # loop through all drills
    #------------------------------
    for i in range(1, 34, 1):
        RaiseDrill(self, i)
    #------------------------------
    # loop through all side drills
    #------------------------------
    for i in range(1, 11, 2):
        RaiseSideDrill(self, i)
    print("All spindles, drills, and side drills are raised")
    
#----------------------------------------------------------
#----------------------------------------------------------
def DropSpindleB(self):
    index = self.x.getSignalInfos("spindleBdrop")
    self.execute("M64 P%d" % index)
    self.execute("G4 P0.5")
    self.execute("M65 P%d" % index)
    index = self.x.getSignalInfos("spindleBdown")
    self.execute("M66 P%d L4 Q1" % index)
    #self.execute("M64 P3")
    #self.execute("G4 P0.5")
    #self.execute("M65 P3")
    #self.execute("M66 P10 L4 Q1")
    print("DropSpindle(B) done")
    
def DropSpindleC(self):
    self.execute("M64 P4")
    self.execute("G4 P0.5")
    self.execute("M65 P4")
    self.execute("M66 P11 L4 Q1")
    print("DropSpindle(C) done")
    
#----------------------------------------------------------
#----------------------------------------------------------
def EnergiseSpindle(self, sWhich):
    #------------------------------
    # Deenergise if not selected
    #------------------------------
    if sWhich != "A":
        self.execute("M65 P13")
    if sWhich != "B":
        self.execute("M65 P14")
    if sWhich != "C":
        self.execute("M65 P15")
        
    #------------------------------
    # Energise if selected
    #------------------------------
    if sWhich == "A":
        self.execute("M64 P13")
    elif sWhich == "B":
        self.execute("M64 P14")
    elif sWhich == "C":
        self.execute("M64 P15")
    #------------------------------
    # wait a second
    #------------------------------
    self.execute("G4 P1.0")
    print("EnergiseSpindle(%s) done" % sWhich)
    
    #self.execute("M64 P13")
    #self.execute("M65 P14")
    #self.execute("M65 P15")
    #self.execute("G4 P1.0")
    
#----------------------------------------------------------
#----------------------------------------------------------
def DeEnergiseALLSpindle(self):
    self.execute("M65 P13") 
    self.execute("M65 P14")
    self.execute("M65 P15")
    self.execute("G4 P1.0")
    print("DeEnergiseALLSpindle done")
    
    
#----------------------------------------------------------
#----------------------------------------------------------
#----------------------------------------------------------
#----------------------------------------------------------
def SpindleHasTool(self, sWhich):
    doesSpindleHasTool = CheckDIN(self, "spindle%shastool" % sWhich, True)
    if doesSpindleHasTool == 0:
        print("Spindle has no tool")
        return False
    else:
        print("Spindle has tool")
        return True
            
#-------------------------------------------------------------------------------------------
#----------------------------------------------------------
def DropDrill(self, sWhich):
    
    index = self.x.getSignalInfos("spindle%ddrop" % sWhich)
    self.execute("M64 P%d" % (index))
    self.execute("M64 P54")
    print("DropDrill(%s) done" % sWhich)
    
#----------------------------------------------------------
#----------------------------------------------------------
def RaiseDrill(self, sWhich):
    index = self.x.getSignalInfos("spindle%ddrop" % sWhich)
    self.execute("M65 P%d" % (index)) 
    print("RaiseDrill(%s) done" % sWhich)
    
#-------------------------------------------------------------------------------------------
##----------------------------------------------------------
def DropSideDrill(self, sWhich):
    index = self.x.getSignalInfos("spindle%dand%ddrop" % (int(sWhich), int(sWhich) + 1))
    self.execute("M64 P%d" % (index)) 
    print("DropSideDrill(%s) done" % sWhich)
    
    
#----------------------------------------------------------
#----------------------------------------------------------
def RaiseSideDrill(self, sWhich):
    index = self.x.getSignalInfos("spindle%dand%ddrop" % (int(sWhich), int(sWhich) + 1))
    self.execute("M65 P%d" % (index)) 
    print("RaiseSideDrill(%s) done" % sWhich)
    
    
#-------------------------------------------------------------------------------------------
#----------------------------------------------------------
def DropTools(self, sWhich):
    drillList, sidedrillList = self.x.getMultiToolsLists(sWhich)
    # drop the drills found
    for d in drillList:
        DropDrill(self, d)
    # drop the side drills found
    for d in sidedrillList:
        DropSideDrill(self, d)
    print("DropTools(%s) done" % sWhich)
    
#----------------------------------------------------------
#----------------------------------------------------------
def FindFreePocket(self):
    #----------------------------------------------------------------
    # for each pocket defined, check if it has a tool
    #   if pocket does not have a tool, return that pocket number
    #----------------------------------------------------------------
    #---------------------------------
    # Query stat digital input status 
    #---------------------------------
    pocket1hastool = CheckDIN(self, "pocket1hastool", True)
    pocket2hastool = CheckDIN(self, "pocket2hastool", True)
    pocket3hastool = CheckDIN(self, "pocket3hastool", True)
    print("%s - %s - %s" % (pocket1hastool, pocket2hastool, pocket3hastool))
    if pocket1hastool == 1:
        if pocket2hastool == 1:
            if pocket3hastool == 1:
                return -1 # all pockets have something
            else:
                return 3    # pocket 3 has no tool
        else:
            return 2        # pocket 2 has no tool
    else:
        return 1            # pocket 1 has no tool
         
#----------------------------------------------------------
#---------------------------------------------------------------------------------------
#---------------------------------------------------------------------------------------
def DoYield():
    print("In DoYield()")
    
#---------------------------------------------------------------------------------------
# ReturnOK()
#---------------------------------------------------------------------------------------
def ReturnOK():
    print("Calling DoYield()")
    DoYield()
    print("After DoYield(), before return INTERP_OK")
    return INTERP_OK
#---------------------------------------------------------------------------------------
# ReturnERROR()
#---------------------------------------------------------------------------------------
def ReturnERROR():
    # if DoYield() is needed but I think not
    #DoYield()
    print("Before return INTERP_ERROR")
    return INTERP_ERROR
        
#---------------------------------------------------------------------------------------
#---------------------------------------------------------------------------------------
# emc_status(actualtask)
#---------------------------------------------------------------------------------------
#---------------------------------------------------------------------------------------
# return tuple (task mode, task state, exec state, interp state) as strings
#self.stat.poll()
#task_mode = ['invalid', 'MANUAL', 'AUTO', 'MDI'][self.s.task_mode]
#task_state = ['invalid', 'ESTOP', 'ESTOP_RESET', 'OFF', 'ON'][self.s.task_state]
#exec_state = ['invalid', 'ERROR', 'DONE',
#       'WAITING_FOR_MOTION',
#       'WAITING_FOR_MOTION_QUEUE',
#       'WAITING_FOR_IO',
#       'WAITING_FOR_PAUSE',
#       'WAITING_FOR_MOTION_AND_IO',
#       'WAITING_FOR_DELAY',
#       'WAITING_FOR_SYSTEM_CMD' ][self.s.exec_state]
#interp_state = ['invalid', 'IDLE', 'READING', 'PAUSED', 'WAITING'][self.s.interp_state]
#---------------------------------------------------------------------------------------
def emc_status(actualtask):
    s = linuxcnc.stat()
    s.poll()
    task_mode = s.task_mode
    task_state = s.task_state
    exec_state = s.exec_state
    interp_state = s.interp_state
    #actualtask = self.task
    
    sReturn = "---------------------------------------------------------\n"
    sReturn += "task_mode values are :\n"
    sReturn += "MODE_MANUAL : %d \n" % (linuxcnc.MODE_MANUAL)
    sReturn += "MODE_AUTO : %d \n" % (linuxcnc.MODE_AUTO)
    sReturn += "MODE_MDI : %d \n" % (linuxcnc.MODE_MDI)
    sReturn += "task_mode = %d \n" % (task_mode)
    sReturn += "\n"
    sReturn += "task_state values are :\n"
    sReturn += "STATE_ESTOP : %d \n" % (linuxcnc.STATE_ESTOP)
    sReturn += "STATE_ESTOP_RESET : %d \n" % (linuxcnc.STATE_ESTOP_RESET)
    sReturn += "STATE_OFF : %d \n" % (linuxcnc.STATE_OFF)
    sReturn += "STATE_ON : %d \n" % (linuxcnc.STATE_ON)
    sReturn += "task_state = %d \n" % (task_state)
    sReturn += "\n"
    sReturn += "exec_state values are :\n"
    sReturn += "EXEC_ERROR : %d \n" % (linuxcnc.EXEC_ERROR)
    sReturn += "EXEC_DONE : %d \n" % (linuxcnc.EXEC_DONE)
    sReturn += "EXEC_WAITING_FOR_MOTION : %d \n" % (linuxcnc.EXEC_WAITING_FOR_MOTION)
    sReturn += "EXEC_WAITING_FOR_MOTION_QUEUE : %d \n" % (linuxcnc.EXEC_WAITING_FOR_MOTION_QUEUE)
    sReturn += "EXEC_WAITING_FOR_IO : %d \n" % (linuxcnc.EXEC_WAITING_FOR_IO)
    #sReturn += "EXEC_WAITING_FOR_PAUSE : %d \n" % (linuxcnc.EXEC_WAITING_FOR_PAUSE) This does not exist
    sReturn += "EXEC_WAITING_FOR_MOTION_AND_IO : %d \n" % (linuxcnc.EXEC_WAITING_FOR_MOTION_AND_IO)
    sReturn += "EXEC_WAITING_FOR_DELAY : %d \n" % (linuxcnc.EXEC_WAITING_FOR_DELAY)
    sReturn += "EXEC_WAITING_FOR_SYSTEM_CMD : %d \n" % (linuxcnc.EXEC_WAITING_FOR_SYSTEM_CMD)
    sReturn += "exec_state = %d \n" % (exec_state)
    sReturn += "\n"
    sReturn += "interp_state values are :\n"
    sReturn += "INTERP_IDLE : %d \n" % (linuxcnc.INTERP_IDLE)
    sReturn += "INTERP_READING : %d \n" % (linuxcnc.INTERP_READING)
    sReturn += "INTERP_PAUSED : %d \n" % (linuxcnc.INTERP_PAUSED)
    sReturn += "INTERP_WAITING : %d \n" % (linuxcnc.INTERP_WAITING)
    sReturn += "interp_state = %d \n" % (interp_state)
    sReturn += "\n"
    sReturn += "self.task = %d\n" % (actualtask)
    sReturn += "---------------------------------------------------------\n"
    return sReturn #(task_mode, task_state, exec_state, interp_state)
		Last edit: 30 May 2019 11:05  by bevins.			
			Please Log in or Create an account to join the conversation.
- andypugh
- 
				  
- Away
- Moderator
- 
				  
		Less
		More
		
			
	
		- Posts: 19677
- Thank you received: 4554
			
	
						30 May 2019 11:23				#135375
		by andypugh
	
	
		
			
				
Well, in theory, yes, as any Turing-complete language can do anything that any other one can do.
I grant it might be difficult.
One thing that I am curious about is whether self.execute("G code here") is the best approach.
(Those bits would probably be _better_ done from a g-code sub).
The Python interface offers the command.mdi() way to run G-code. I wonder if that works better, worse or the same? It would be a simple search-and-replace job to try it.
Another option is the canonical command interface. That does not seem to be particularly well documented, but it is what I used in my G71 Python remaps:
github.com/LinuxCNC/linuxcnc/blob/andypu...python/remap.py#L443
Though I think it only uses emccanon.STRAIGHT_TRAVERSE and STRAIGHT_FEED
The canon commands are defined (and quite well described) in this file:
github.com/LinuxCNC/linuxcnc/blob/master...mc/nml_intf/canon.hh
					
	
			
			 		
													
	
				Replied by andypugh on topic Remapping: Was: Stand Alone Interpe r ter			
			Here is my main remap file. You think ngc oword could do this?
Well, in theory, yes, as any Turing-complete language can do anything that any other one can do.
I grant it might be difficult.
One thing that I am curious about is whether self.execute("G code here") is the best approach.
(Those bits would probably be _better_ done from a g-code sub).
The Python interface offers the command.mdi() way to run G-code. I wonder if that works better, worse or the same? It would be a simple search-and-replace job to try it.
Another option is the canonical command interface. That does not seem to be particularly well documented, but it is what I used in my G71 Python remaps:
github.com/LinuxCNC/linuxcnc/blob/andypu...python/remap.py#L443
Though I think it only uses emccanon.STRAIGHT_TRAVERSE and STRAIGHT_FEED
The canon commands are defined (and quite well described) in this file:
github.com/LinuxCNC/linuxcnc/blob/master...mc/nml_intf/canon.hh
Please Log in or Create an account to join the conversation.
- bevins
- 
				  
- Offline
- Platinum Member
- 
				  
		Less
		More
		
			
	
		- Posts: 1940
- Thank you received: 338
			
	
						30 May 2019 11:50		 -  30 May 2019 11:56		#135376
		by bevins
	
	
		
			
				
I used those commands because it was the only way I could get it to work in python. The problem was when I got into a few functions deep, I couldn't get it to respond to canon commands.
/EDIT Granted, I may not have done it correctly.... whether that was causing it to ignore commands or not, I am not sure.
					
	
	
			 		
													
	
				Replied by bevins on topic Remapping: Was: Stand Alone Interpe r ter			
			
Here is my main remap file. You think ngc oword could do this?
Well, in theory, yes, as any Turing-complete language can do anything that any other one can do.
I grant it might be difficult.
One thing that I am curious about is whether self.execute("G code here") is the best approach.
(Those bits would probably be _better_ done from a g-code sub).
The Python interface offers the command.mdi() way to run G-code. I wonder if that works better, worse or the same? It would be a simple search-and-replace job to try it.
Another option is the canonical command interface. That does not seem to be particularly well documented, but it is what I used in my G71 Python remaps:
github.com/LinuxCNC/linuxcnc/blob/andypu...python/remap.py#L443
Though I think it only uses emccanon.STRAIGHT_TRAVERSE and STRAIGHT_FEED
The canon commands are defined (and quite well described) in this file:
github.com/LinuxCNC/linuxcnc/blob/master...mc/nml_intf/canon.hh
I used those commands because it was the only way I could get it to work in python. The problem was when I got into a few functions deep, I couldn't get it to respond to canon commands.
/EDIT Granted, I may not have done it correctly.... whether that was causing it to ignore commands or not, I am not sure.
		Last edit: 30 May 2019 11:56  by bevins.			
			Please Log in or Create an account to join the conversation.
- andypugh
- 
				  
- Away
- Moderator
- 
				  
		Less
		More
		
			
	
		- Posts: 19677
- Thank you received: 4554
			
	
						30 May 2019 11:52				#135377
		by andypugh
	
	
		
			
				
Did you try the canonical commands?
					
	
			
			 		
													
	
				Replied by andypugh on topic Remapping: Was: Stand Alone Interpe r ter			
			I used those commands because it was the only way I could get it to work in python. The problem was when I got into a few functions deep, it wouldn't respond to commands.
Did you try the canonical commands?
Please Log in or Create an account to join the conversation.
		Moderators: HansU	
		Time to create page: 0.108 seconds	
 
													