On question for remap in pure python

More
17 Dec 2021 12:18 - 17 Dec 2021 13:35 #229285 by bazhenov4job
A remapping of existing procedures is wide spreaded practice.
There are two ways to perfrom the remap (see docs sec. 8.7).
Using o-procedures, which is described in documentation.
And using pure python, which is poorly described in documentation and, perhaps of that, is rarely used.

This post describes my experience in remapping using pure python subroutine.

You need no prolog and epilog for pure python. Put all your code in one subroutine.

1. Configuring ini file.

Comprehensively described in documentation. Use modalgroup 10 if you are in doubt.

2. Modules to use in pure python.

from interpreter import *
import emccanon

About emccanon you can read in docs page 463. This module contains most of functions used for remap.

3. Function definition.

def M6_remap(self, **words):
    <put your code here>

- self here - is implicit call of interpreter object. So you can take some properties from it.
For example self.current_tool contains current tool in spindle; self.execute("<your g-code here>") allows you to call interpreter recursively to perform g-code.

- **words is a classic python kwargs statement and allows subroutine to accept implicit amount of named parameters.

I didn't used **words explicitly.

More of this you can find in docs as described above and also in stdglue.py (see docs sec. 8.7.4).

4. Remap function return mechanism.

- for simple "ignore" function (see ignore_M6 in stdglue.py) it is enough to use python return operator
- for complex functions with queuebusters (will be explained further) use python yield operator to return either INTERP_OK, INTERP_ERROR or INTERP_EXECUTE_FINISH statements.

5. Queuebusters.
First met on docs page 460 understanding a bit confusing. It is revealed in section 8.7.17.
The idea is to stop interpreter subroutine readahead and therefore to avoid incorrect reading of coordiates, pin state and etc.
It is strongly recommended to read section 8.7.17 in docs for further understanding of post.

6. How to perform queuebuster.

Working example of queuebuster is described on page 460 docs. On page 461 described restrictions on using this construction.
On my experience using kind of this algorithm is enough to make queuebuster.


# wait 5secs for digital-input 00 to go high
# 1st argument - pin number
# 2nd argument - pin state to wait
# 3d argument - wait mode
#   3- high
#   4- low
# 4th argument - time to wait secs
# use either pin number you want
# better if you have a free pin not involved in your programm execution logic to use
emccanon.WAIT(0,1,3,5.0)
# stop the interpreter
yield INTERP_EXECUTE_FINISH
# run the interpreter again with calling it through emccanon module
emccanon.GET_EXTERNAL_DIGITAL_INPUT(0,0)

unfortunately this algorithm cannot be performed in separate function due to former restrictions

7. Restriction on using self.execute() construction after post section 6 statement.

You want to move, but cannot use self.execute()
Use functions from emccanon module.

7.1. STRAIGHT_TRAVERSE(*args) - moves as fast as allowed to point specified in args
    example:
    emccanon.STRAIGHT_TRAVERSE(2, self.x_init, self.y_init, self.z_init, self.a_init, self.b_init, 0, 0, 0, 0)
7.2 STRAIGHT_FEED(*args) - moves to cords according to speed set in SET_FEED_RATE() function for joint specified in SET_FEED_MODE()
    example:
    emccanon.SET_FEED_MODE(0, 0)
    emccanon.SET_FEED_RATE(100)
    emccanon.STRAIGHT_FEED(2, self.x_init, self.y_init, self.z_init, self.a_init, self.b_init, 0, 0, 0, 0)
7.3 STRAIGHT_PROBE(*args) - works similarly to former, but abort movement when probe is reached. If probe is not reached rises error. To configure probe read docs section 4.2.6.2
See source code for more (Github).

8. Usage example.
Let's write an example. We try to remap a M6 procedure.
The simplest procedure is as follows:
1) stop spindle (if it rotates);
2) leave working area;
3) go to tool shop
4) put tool to its pocket
5) go to new tool
6) take new tool
7) measure its offset (related to essential wear, spindle construction features and etc.)
8) turn on spindle (if it had been rotated) and return to working area

following code will omit steps related to extraction tool parameters from interpreter and applying new tool configuration. They can be easily found in stdglue prolog and epilog procedures or in user bevins related topic " M6 remap in pure python... "

def M6_remap(self, **words):
    
    if self.task == 0:
        yield INTERP_OK
    
    # stop readhead to ensure correct data
    emccanon.WAIT(10, 1, 3, 0.01)
    yield INTERP_EXECUTE_FINISH
    emccanon.GET_EXTERNAL_DIGITAL_INPUT(10, 1)
    
    # read and remember coordiantes in the begining of the operation
    # you may have more or less coords - syntax and logic are the same
    self.x_init = round(emccanon.GET_EXTERNAL_POSITION_X(), 3)
    self.y_init = round(emccanon.GET_EXTERNAL_POSITION_Y(), 3)
    self.z_init = round(emccanon.GET_EXTERNAL_POSITION_Z(), 3)

    
    # check the spindle state and stop it if needed; we ude spindle by default - 0
    self.spindle_speed = emccanon.GET_EXTERNAL_SPEED(0)
    if self.spindle_speed:
        emccanon.SET_SPINDLE_SPEED(0, 0)
        
    # now when spindle stopped lets move away from working area slowly
    emccanon.SET_FEED_MODE(0, 0)
    emccanon.SET_FEED_RATE(200)
    emccanon.STRAIGHT_FEED(2, self.x_init - 5, self.y_init - 5, self.z_init - 5, 0, 0, 0, 0, 0, 0)
    
    # here take parameters from tool table; we made external tool table as file in json with all required parameters
    # maybe it is possible to do with standart tool table - we did not even try
    # let's suppose user's function get_tool_parameter(tool_number) will do this for you in dictionary data structure
    # where the keys - are the coordinates names x, y and etc.
    
    self.tool_params = get_tool_parameter(self.current_tool)
    
    # let's move to old tool pocket now
    # in real production you probably have to perform a variety of operations to move to tool pocket safely - and that is by you
    
    emccanon.STRAIGHT_TRAVERSE(2, self.tool_params["x"], self.tool_params["y"], self.tool_params["z"], 0, 0, 0, 0, 0, 0)
    
    # now we have to command to collet to release tool
    # if we do it without queuebuster collet will probably release tool much earlier because of readahead
    # so we need to stop interpreter anf only then command collet to open
    # let's suppose collet control is on pin 2
    
    # stop readhead to ensure correct data
    emccanon.WAIT(10, 1, 3, 0.01)
    yield INTERP_EXECUTE_FINISH
    emccanon.GET_EXTERNAL_DIGITAL_INPUT(10, 1)
    # open collet
    emccanon.SET_AUX_OUTPUT_BIT(2)
    
    # and so on
    #
    # hope you catched the idea and queuebuster principle
    # try this approach and you will find out how to build subroutine for your specific task
    
    # end your subroutine with
    yield INTERP_OK

9. Used software.
linuxcnc 2.8.2
       
Last edit: 17 Dec 2021 13:35 by bazhenov4job.
The following user(s) said Thank You: andypugh, tommylight

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

More
17 Dec 2021 13:09 #229289 by andypugh
Can we persuade you to submit a pull request to add these details to the actual documentation?

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

More
17 Dec 2021 13:31 #229290 by bazhenov4job
Why not?
This might be useful for future users.

I want community to discuss content of topic. Maybe something is evident, maybe needed to add more explanation and examples.

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

Time to create page: 0.121 seconds
Powered by Kunena Forum