REMAP M0
05 Jan 2014 23:13 #42371
by f1oat
I have a NGC code with multiple stock fixtures that require some manual operation such as rotating the stock by 180° and update the G54 offsets.
There is a M0 for this manual operation. But I need to jog and call touchoff functions before restarting the machine.
That is not possible with standard M0 implementation.
This solution seems not too far from what I need: wiki.linuxcnc.org/cgi-bin/wiki.pl?ManualToolChangeMacro
Any clue to do that with M0 remapping ?
Thanks.
Frederic.
There is a M0 for this manual operation. But I need to jog and call touchoff functions before restarting the machine.
That is not possible with standard M0 implementation.
This solution seems not too far from what I need: wiki.linuxcnc.org/cgi-bin/wiki.pl?ManualToolChangeMacro
Any clue to do that with M0 remapping ?
Thanks.
Frederic.
Please Log in or Create an account to join the conversation.
07 Jan 2014 19:54 #42432
by ArcEye
Hi
Have a search on 'jog while paused'
Michael H had a branch which allowed this sort of thing
It is actually easier to achieve this in a pause situation than a tool change
www.linuxcnc.org/index.php/english/forum...set-a-variable#28642
was a demo program which allowed the execution of a MDI command and then restarted
However the problems start when there is a spindle to turn back on etc, Linuxcnc does not do this automatically like some other controllers.
For something like this, sometimes the easiest way is just to break the gcode into seperate programs or just end it when the adjustment is required and restart it (if it is always the same code)
regards
Have a search on 'jog while paused'
Michael H had a branch which allowed this sort of thing
It is actually easier to achieve this in a pause situation than a tool change
www.linuxcnc.org/index.php/english/forum...set-a-variable#28642
was a demo program which allowed the execution of a MDI command and then restarted
However the problems start when there is a spindle to turn back on etc, Linuxcnc does not do this automatically like some other controllers.
For something like this, sometimes the easiest way is just to break the gcode into seperate programs or just end it when the adjustment is required and restart it (if it is always the same code)
regards
The following user(s) said Thank You: f1oat
Please Log in or Create an account to join the conversation.
08 Jan 2014 04:38 #42457
by f1oat
Thank you for the clue. I will look at this solution.
For now, I have a first solution running inside Gmoccapy, but it makes some assumption on G-CODE content around the M0 :
- It needs to have a G0 statement on the M0 line so that self.emc.emcstat.current_line var actually points to the proper line- restore spindle, mist and other things after M0
It is ok for me because I can add these statements in my G-CODE post-processor. But that is not a universal solution.
I am now playing with REMAP for M60 command (M60 official definition is not far from my "change fixture" need).
emctask.emcstat.task.readLine var is promising because it seems to point to the proper ngc line. But the Python code is called immediately after ngc file is started, and not when it is actually synchronized with motion. So, I am trying "yield INTERP_EXECUTE_FINISH".
But I experience problem when it is included in stdglue.py: Gmoccapy is becoming very slow. Looks like some hidden exceptions are slowing down everything.
I useHere is my stdglue.py contentAnd my ngc test fileBest regards.
Frederic.
For now, I have a first solution running inside Gmoccapy, but it makes some assumption on G-CODE content around the M0 :
- It needs to have a G0 statement on the M0 line so that self.emc.emcstat.current_line var actually points to the proper line
G53 G0 Z #<_ini[change_position]z> M0
It is ok for me because I can add these statements in my G-CODE post-processor. But that is not a universal solution.
I am now playing with REMAP for M60 command (M60 official definition is not far from my "change fixture" need).
emctask.emcstat.task.readLine var is promising because it seems to point to the proper ngc line. But the Python code is called immediately after ngc file is started, and not when it is actually synchronized with motion. So, I am trying "yield INTERP_EXECUTE_FINISH".
But I experience problem when it is included in stdglue.py: Gmoccapy is becoming very slow. Looks like some hidden exceptions are slowing down everything.
I use
REMAP=M60 modalgroup=6 python=m60
def m60(self, **words):
yield INTERP_EXECUTE_FINISH
print "***** M60 ***", emctask.emcstat.task.currentLine, emctask.emcstat.task.motionLine, emctask.emcstat.task.readLine
return INTERP_OK
G21 G90 G64 P0.01 G40
G0 X0 Y0 Z0
G1 Y10 F1000
(msg, calling M60)
M60
(msg, back from M60)
G1 X10 F1000
M30
Frederic.
Please Log in or Create an account to join the conversation.
08 Jan 2014 06:24 #42466
by newbynobi
Hallo Frederik,
I found the same problem with the yield command, also with other Gui. I tried to sort that out with Michael, but the real problem is very deep in the very old way of line handling of linuxcnc. I do hope i did get Michael right.
I don't see an easy solution from here.
Norbert
I found the same problem with the yield command, also with other Gui. I tried to sort that out with Michael, but the real problem is very deep in the very old way of line handling of linuxcnc. I do hope i did get Michael right.
I don't see an easy solution from here.
Norbert
The following user(s) said Thank You: f1oat
Please Log in or Create an account to join the conversation.
08 Jan 2014 06:40 #42467
by f1oat
Hello Norbert,
OK, thanks. I am working on another solution.
I can save easily the M60 line number in a named global variable inside the remap python code.
Then, by returning INTERP_ENDFILE, the interpreter stops and jog is possible.
To restart ngc at the proper line, I have two options:
option#1: read this variable in Gmoccapy and re-use my already existing handler restart code
=> how to read named global variable for Gmoccapy Python code ?
option#2: define a new Mxx command to be included at beginning of file. It will act as a GOTO statement to jump to the saved ngc line depending on dialog box result
=> how to implement a GOTO #ngc_line in Python code called by REMAP ?
For your information, here is my Gscreen handler used in GmoccapyFrederic.
OK, thanks. I am working on another solution.
I can save easily the M60 line number in a named global variable inside the remap python code.
Then, by returning INTERP_ENDFILE, the interpreter stops and jog is possible.
def m60(self, **words):
#yield INTERP_EXECUTE_FINISH
print "***** M60 ***", emctask.emcstat.task.currentLine, emctask.emcstat.task.motionLine, emctask.emcstat.task.readLine
try:
print "_m60-saved-line=%d" % self.params["_m60-saved-line"]
except:
self.params["_m60-saved-line"] = 0
self.params["_m60-saved-line"] = emctask.emcstat.task.readLine
#self.execute("o<m60-save-state>call")
return INTERP_ENDFILE
To restart ngc at the proper line, I have two options:
option#1: read this variable in Gmoccapy and re-use my already existing handler restart code
=> how to read named global variable for Gmoccapy Python code ?
option#2: define a new Mxx command to be included at beginning of file. It will act as a GOTO statement to jump to the saved ngc line depending on dialog box result
=> how to implement a GOTO #ngc_line in Python code called by REMAP ?
For your information, here is my Gscreen handler used in Gmoccapy
self.gscreen.widgets["hal_status"].connect("interp-paused", self.on_hal_status_interp_paused)
def dialog_return(self, widget, result, gscreen, dialogtype, pinname):
if pinname == "RESUME":
if result == gtk.RESPONSE_YES: ok = True
else: ok = False
self.resume(ok)
widget.destroy()
else:
self.gscreen.dialog_return(widget, result, dialogtype, pinname)
def on_hal_status_interp_paused(self, widget):
self.emc.emcstat.poll()
self.curLine = self.emc.emcstat.current_line
if self.curLine >=0:
self.emc.emccommand.abort()
self.gscreen.widgets.rbt_manual.set_active(True)
self.gscreen.widgets.rbt_manual.pressed()
def resume(self, ok):
if self.curLine != None and ok:
self.emc.emccommand.auto(self.emc.emc.AUTO_RUN, self.curLine + 1)
self.curLine = None
def on_rbt_auto_pressed(self, widget, data=None):
HandlerClass.on_rbt_auto_pressed(self, widget, data)
if self.curLine != None:
self.gscreen.warning_dialog("Resume at line %d ?" % (self.curLine + 1), False, pinname="RESUME")
Please Log in or Create an account to join the conversation.
08 Jan 2014 16:44 #42481
by newbynobi
Hallo Frederic,
you may have a epilog in your remap function:
And then:
gscreen / gmoccapy use a hal_toggleaction_run widget
so the following code starts the program from the line you wish:
(you must include the code in gmoccapy_handler.py)
If you now push start the program will run from self.current_line
It is untested!!
Norbert
P.S. Because of internal problems, I will get away from gscreens self.emc.emcstat and introduce my own self.stat, so be aware to future changes, you might need to rename the stat calls after the next release!
you may have a epilog in your remap function:
def epilog(self, **words):
self.current_line = int(self.params["current_line"])
And then:
gscreen / gmoccapy use a hal_toggleaction_run widget
so the following code starts the program from the line you wish:
(you must include the code in gmoccapy_handler.py)
# do not call it "update_restart_line", as that would override a gscreen handler
def restart_from_given_line(self, line)
# set the line in the sourceview widget
# this is not needed, but will show you the line in sourceview
# so you will see if the start point is correct.
self.widgets.gcode_view.set_line_number(line)
# set the restart line
self.widgets.hal_toggleaction_run.set_start_line(line)
If you now push start the program will run from self.current_line
It is untested!!
Norbert
P.S. Because of internal problems, I will get away from gscreens self.emc.emcstat and introduce my own self.stat, so be aware to future changes, you might need to rename the stat calls after the next release!
The following user(s) said Thank You: f1oat
Please Log in or Create an account to join the conversation.
18 Jan 2014 05:56 #42942
by f1oat
Norbert, thank you.
I have designed a sharedvar class to exchange data between Gmoccapy and the Python code called by REMAP.
Now, my jog-while-paused for M60 runs in simulation. The native pause buttons is fully handled.
Everything looks like a standard M0 behavior, except you have access to all functions as for manual mode during pause.
There is an automatic machine state save/restore included in my modified M60.
I need to validate on a real machine before publishing !
Frederic
I have designed a sharedvar class to exchange data between Gmoccapy and the Python code called by REMAP.
Now, my jog-while-paused for M60 runs in simulation. The native pause buttons is fully handled.
Everything looks like a standard M0 behavior, except you have access to all functions as for manual mode during pause.
There is an automatic machine state save/restore included in my modified M60.
I need to validate on a real machine before publishing !
Frederic
Please Log in or Create an account to join the conversation.
18 Jan 2014 06:04 #42944
by f1oat
Here is how the m60.ngc called by REMAP looks like.
It is called two times:And the M60 prolog
In Gmoccapy, the interpreter pause state is hijacked to implement jog-while-paused.
Stay tuned.
Frederic.
It is called two times:
- First call goes to first part of IF statement which invokes the pause state.
- Second call is done when clicking pause button, and goes to ELSE statement to restore machine state and restart G-CODE.
o<m60> sub
O<xresult> if [#<_m60_do_pause>]
(save current machine state)
#<_saved_metric> = #<_metric>
#<_saved_absolute> = #<_absolute>
#<_saved_feed> = #<_feed>
#<_saved_rpm> = #<_rpm>
#<_saved_mist> = #<_mist>
#<_saved_flood> = #<_flood>
#<_saved_spindle_on> = #<_spindle_on>
#<_saved_spindle_cw> = #<_spindle_cw>
(put axis Z on safe position and switch off spindle/coolant)
M5
M9
G21 (TLO and toolchange position is in mm as per ini)
G90 (absolute)
g53 g0 Z #<_ini[change_position]z>
(calling native M60 to pause program)
M60
O<xresult> else
(here we restart from previous pause state)
(restore previous machine state)
O100 if [#<_saved_metric>]
G21
O100 else
G20
O100 endif
O200 if [#<_saved_absolute>]
G90
O200 else
G91
O200 endif
O300 if [#<_saved_mist>]
M7
O300 endif
O500 if [#<_saved_flood>]
M8
O500 endif
O400 if [#<_saved_spindle_on>]
O410 if [#<_saved_spindle_cw>]
M3
O410 else
M4
O410 endif
O400 endif
F#<_saved_feed>
S#<_saved_rpm>
(go back to normal program execution)
O<xresult> endif
o<m60> endsub
m2
def m60_prolog(self, **words):
global sharedvar
import emctask # Sporadic startup issue if done at beginning of file
if sharedvar["RESUME-at-line"] == None: # We were not in pause state
sharedvar["RESUME-at-line"] = emctask.emcstat.task.readLine
self.params["_m60_do_pause"] = 1
else: # We were in pause state
sharedvar["RESUME-at-line"] = None
self.params["_m60_do_pause"] = 0
return INTERP_OK
In Gmoccapy, the interpreter pause state is hijacked to implement jog-while-paused.
Stay tuned.
Frederic.
Please Log in or Create an account to join the conversation.
24 Jan 2014 05:08 #43114
by f1oat
My full configuration is now available from here: blog.f1oat.org/linuxcnc/
It includes the JOG-WHILE-PAUSED feature.
Frederic.
It includes the JOG-WHILE-PAUSED feature.
Frederic.
Please Log in or Create an account to join the conversation.
Time to create page: 0.076 seconds