Python - yield INTERP_EXECUTE_FINISH

More
13 Apr 2023 08:20 #268961 by zz912
Hello,

I want:
1) Print "Hello"
2) move to x10 y10
3) Print "I moved"
4) move to x20 y20
5) Print "I moved to second place"
REMAP=M6 modalgroup=10 python=test_finish

This code:
def test_finish(self, **words):
    print("Hello")
    self.execute("G1 X10 Y10 f50")   
    print("I moved")
    self.execute("G1 X20 Y20 f50")   
    print("I moved to second place")
    yield INTERP_OK
I makes:
1) Print "Hello" "I moved" "I moved to second place"
2) move to x20 y20

This code:
def test_finish(self, **words):
    print("Hello")
    self.execute("G1 X10 Y10 f50")   
    yield INTERP_EXECUTE_FINISH
    print("I moved")
    self.execute("G1 X20 Y20 f50")   
    yield INTERP_EXECUTE_FINISH
    print("I moved to second place")
    yield INTERP_OK
I makes:
1) Print "Hello"
2) move to x10 y10
3) Print "I moved" "I moved to second place"

Can I ask for help?


 

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

More
13 Apr 2023 15:54 #268974 by Aciera
NOTE: after 'yield INTERP_EXECUTE_FINISH' we cannot use 'self.execute(..) anymore
The following user(s) said Thank You: zz912

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

More
13 Apr 2023 16:02 #268975 by Aciera
see the end of section 9.4. Calling conventions: NGC to Python here:

linuxcnc.org/docs/html/remap/remap.html

WarningThe yield feature is fragile. The following restrictions apply to the usage of yield INTERP_EXECUTE_FINISH:

  • Python code executing a yield INTERP_EXECUTE_FINISH must be part of a remap procedure. Yield does not work in a Python oword procedure.
  • A Python remap subroutine containing yield INTERP_EXECUTE_FINISH statement may not return a value, as with normal Python yield statements.
  • Code following a yield may not recursively call the interpreter, like with self.execute("<mdi command>"). This is an architectural restriction of the interpreter and is not fixable without a major redesign.
  

The following user(s) said Thank You: zz912

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

More
13 Apr 2023 16:08 - 13 Apr 2023 16:10 #268976 by Aciera
Here is an example using 'STRAIGHT_TRAVERSE' to move the machine after using 'yield INTERP_EXECUTE_FINISH':
Note that you need to give values for all axes XYZABCUVW (I forget what the '2' at the beginning is for)
# orient the tool to the current twp (No TCP)
def g531(self):
    if self.task == 0:
        yield INTERP_OK
    global saved_work_offset
    global twp_flag
    # reset the twp build 
    twp_flag = [0, 'empty']
    # switch to identity kins
    hal.set_p("motion.switchkins-type",str(0))
    yield INTERP_EXECUTE_FINISH

    # calculate the required rotary joint positions and 
    # pre_rotation for the requested tool-orientation 
    a_j, b_j, pre_rot = twp_calc_jnts_pos_and_pre_rot(self)
    gui_update_twp(self)
    kins_comp_set_pre_rot(self, pre_rot)
    yield INTERP_EXECUTE_FINISH

    print(" mdi moving joints A, B: ", a_j, b_j)
    # store current coordiantes because emccanon wants values for all nine axes
    x_pos = emccanon.GET_EXTERNAL_POSITION_X()
    y_pos = emccanon.GET_EXTERNAL_POSITION_Y()
    z_pos = emccanon.GET_EXTERNAL_POSITION_Z()
    c_pos = emccanon.GET_EXTERNAL_POSITION_C()
    emccanon.STRAIGHT_TRAVERSE(2, x_pos, y_pos, z_pos, a_j*(180/pi), b_j*(180/pi), c_pos, 0,0,0)
    yield INTERP_EXECUTE_FINISH

    # calculate the work offset in tool-coords
    P = matrix_to_point(kins_calc_tool_transformation(self, point_to_matrix(saved_work_offset)))
    print("Setting transformed work-offsets in tool-kins: ", P)
    emccanon.SET_G5X_OFFSET(0, P[0], P[1], P[2], 0,0,0,0,0,0)
    # same as above but for twp-offsets used for twp origin as set by g68.2 (x,y,z)-words
    # g69 will set the twp-offsets to zero.
    current_twp_offset = params_get_current_twp_offset(self)
    P = matrix_to_point(kins_calc_tool_transformation(self, point_to_matrix(current_twp_offset)))
    print("Setting transformed twp-offset in tool-kins: ", P)
    hal.set_p("xyzabc_trsrn_kins.twp-x",str(P[0]))
    hal.set_p("xyzabc_trsrn_kins.twp-y",str(P[1]))
    hal.set_p("xyzabc_trsrn_kins.twp-z",str(P[2]))
    yield INTERP_EXECUTE_FINISH

    # switch to tool kins
    hal.set_p("motion.switchkins-type",str(2))
    yield INTERP_EXECUTE_FINISH

    # we only want to update the offsets as those get rotated by rotary-joint positions
    # while the twp is rotated using the method chosen by the g68.2 p-word
    gui_update_offsets(self)

    yield INTERP_OK
Last edit: 13 Apr 2023 16:10 by Aciera. Reason: change example code
The following user(s) said Thank You: zz912

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

More
13 Apr 2023 16:10 #268977 by zz912
Is there another way to my goal?
1) Print "Hello"
2) move to x10 y10
3) Print "I moved"
4) move to x20 y20
5) Print "I moved to second place"

For example by stacking multiple functions? Or more Try: routines? Or something?

This example is stupid. It is only for understand principle.
In real world I will need:
1) move somewhere
2) check status sensor
3) move to other position
4) check status other sensor
5) do some G/M-code
.........

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

More
13 Apr 2023 16:13 - 13 Apr 2023 16:15 #268978 by Aciera
Maybe try:
def test_finish(self, **words):
    print("Hello")
    self.execute("G1 X10 Y10 f50")   
    yield INTERP_EXECUTE_FINISH
    print("I moved")
    emccanon.STRAIGHT_TRAVERSE(2, 20, 20, 0, 0, 0, 0, 0, 0, 0)
    yield INTERP_EXECUTE_FINISH
    print("I moved to second place")
    yield INTERP_OK

[edit]
You will need to

import emccanon
Last edit: 13 Apr 2023 16:15 by Aciera. Reason: typo
The following user(s) said Thank You: zz912

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

More
13 Apr 2023 16:23 #268979 by Aciera
Also note that there is probably more to the first parameter (which is set to '2' in my example above). In the examples I have found it is referred to as 'line' so setting it to the same value in consecutive commands may not be a good idea but I don't know. I just fumble my way along...
The following user(s) said Thank You: zz912

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

More
13 Apr 2023 16:59 #268980 by zz912
Thank you for the explanation. It's a shame that yield INTERP_EXECUTE_FINISH can only be used once, luckily linuxcnc offers a lot of other solutions. I am currently considering which way to go.

Is it possible to replace self.execute("G0 X10 Y20 Z30")  c.mdi("G0 X10 Y20 Z30") ?
    c.mode(linuxcnc.MODE_MDI)
    c.wait_complete() # wait until mode switch executed
    c.mdi("G0 X10 Y20 Z30")
Is it necessary to activate MODE_MDI? Or can I just use c.mdi?
Is it necessary to deactivate MODE_MDI after execute mdi command?
Is there an alternative to yield INTERP_EXECUTE_FINISH for MDI?
 

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

More
13 Apr 2023 17:12 #268981 by Aciera
As I understand it c.mdi can only be used in MDI mode. See section 5:
linuxcnc.org/docs/html/config/python-interface.html
The following user(s) said Thank You: zz912

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

More
13 Apr 2023 17:34 #268982 by zz912
I tried to solve it like this, but during time.sleep the execute command is not executed, so it just hangs in while.
def remap_m6_test(self, **words):
    print("Hello")
    self.execute("G1 X10 Y10 f50")
    
    s = linuxcnc.stat() # create a connection to the status channel
    s.poll() # get current values
    while (s.actual_position[0] != 10):
        print("HAFHAF1")
        time.sleep(0.1)
        print("HAFHAF2")
        s.poll() # get current values

    print("I moved")
    self.execute("G1 X20 Y20 f50")

    s.poll() # get current values
    while (s.actual_position[0] != 20):
        time.sleep(0.1)
        s.poll() # get current values
       
    print("I moved to second place")
    return INTERP_OK

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

Time to create page: 0.202 seconds
Powered by Kunena Forum