Porting Fanuc macro to LinuxCNC

More
01 May 2018 17:23 #109923 by vicstransam
Forgive me if this has been covered but I have been searching for a solution with little success.
I have written many Fanuc macros that I would like to port to LinuxCNC syntax if possible. I have called up a macro sub from the main program and set global named variables prior to the call, similar to issuing a G65 with arguments.That seems to work well. The snag is that I cannot seem to find a alternative way to check if all global variables were set and it they are within a set range. In Fanuc macros I do it like this:
IF[#100EQ#0]THEN#3000=1(NO VARIABLE IS SET)
Variable #0 is always null in Fanuc but doesn't exist in LinuxCNC. Also I want the alarm to display if it catches an error. I can't seem to find a way around this by using MSG. I have tried this:

o100 if [#100 EQ #0] (#0 doesn't exist apparently. NULL isn't recognized either and zero isn't always appropriate)
(msg, Variable is zero!)
M30(stop if error else do the next check)
0100 endif

Maybe I'll try using the "EXIST" function.

I understand that NGCGUI can do something similar but I want to experiment since I have lots of Fanuc Macros.
I'm also looking for ways to emulate the GOTO statement in Fanuc for LinuxCNC. I think a conditional/unconditional "call" statement would almost work except it would return from where it was called after execution and I may need to jump over lots of code depending on the conditions. Is it possible to run a Python script in the sub to emulate some of this?

I'm using the latest stable release of LinuxCNC 2.7.012 I believe.
The main program I use will set the global variables before the sub call and then resets whichever variables needed like positions and depth and whatever and calls macro sub again,etc.
The sub macro will translate the named global variables over to Fanuc syntax and check if all variables are accounted for and set their default values as + or - and do all necessary rounding up or down and possibly display any error message and stop execution.

Here is the macro sub that I'm playing with currently:
Note: Somehow the sub wouldn't run without the % signs.

Thank you all for your help and knowledge.

%
o<scroll> sub
(Vic Moore 4/29/2018)
(LinuxCNC scroll macro)
(CONSTANT PITCH SCROLL RH OR LH MACRO)
(FEED RATE IS G94 FEED PER MINUTE)
(CALL IS o<scroll> call )
(SET GLOBAL VARIABLES IN MAIN BEFORE SUB CALL!)
(PITCH IS MORE ACCURATE IF R IS SMALLER THAN 5)
(ported from FANUC MACRO B to LinuxCNC)

(*********** global variables set from main program *********)

( #<_abs_x> )
( #<_abs_y> )
( #<_start_rad> )
( #<_degrees> )
( #<_depth> )
( #<_rotations> )
( #<_feed> )
( #<_direction> )
( #<_height> )
( #<_pitch> )

(************* transfer variables to FANUC syntax *************)

(U IS ABS X LOCATION) #21=#<_abs_x>
(V IS ABS Y LOCATION) #22=#<_abs_y>
(A=STARTING RADIUS AT CENTER) #1=#<_start_rad>
(R=RESOLUTION IN DEGREES, R5 = 5 DEGREE SEGMENTS) #18=#<_degrees>
(Z=-DEPTH, EXAMPLE: -.1) #26=#<_depth>
(E=NUMBER OF TOTAL ROTATIONS FROM CENTER TO END) #8=#<_rotations>
(F=FEED IN IPM BASED ON TOOL CENTERLINE PATH) #9=#<_feed>
(D=DIRECTION OF CUT, 1=CW, 2=CCW, FROM INSIDE OUT) #7=#<_direction>
(H=HEIGHT ABOVE PART TO RAPID TO) #11=#<_height>
(T= PITCH) #20=#<_pitch>

(********************* VALUE SIGN PRESETS *********************)

#1=ABS[#1] (A IS SET POSITIVE ONLY)
#7=ABS[#7] (D IS SET POSITIVE ONLY)
#7=FUP[#7] (D IS ROUNDED UP TO WHOLE #)
#8=ABS[#8] (E IS SET POSITIVE ONLY)
#9=ABS[#9] (F IS SET POSITIVE ONLY)
#18=ABS[#18] (R IS SET POSITIVE ONLY)
#20=ABS[#20] (T IS SET POSITIVE ONLY)

(********************** ERROR CHECKING ***********************)

(** NOT FULLY FUCTIONAL YET! **)
(** CAN'T CHECK FOR NULL VARIABLE #0 YET! **)
(** NEED A #3000=1 ALTERNATIVE **)
(COMMENTED OUT UNTIL SOLVED!)
(MAYBE USE "EXIST" FUNCTION?)
(SOME OF THESE DO WORK)

(o5 if#7 LT 1] OR [GT 2)
(msg,DIR EITHER 1 OR 2)
(M00)
(o5 endif)

(o10 if[#21 EQ #0])
(msg,NO X POSITION)
(M00)
(o10 endif)

(o15 if[#22 EQ #0])
(msg,NO Y POSITION)
(M00)
(o15 endif)

(o20 if[#1 EQ #0])
(msg,NO START RADIUS)
(M00)
(o20 endif)

(o25 if[#18 EQ #0])
(msg,NO ANGLE/SEG )
(M00)
(o25 endif)

(o30 if[#26 EQ #0])
(msg,NO Z DEPTH)
(M00)
(o30 endif)

(o35 if[#8 EQ #0])
(msg,NO ROTATIONS)
(M00)
(o35 endif)

(o40 if[#8 EQ 0])
(msg,ROTATIONS MUST BE GT 0)
(M00)
(o40 endif)

(o45 if[#9 EQ #0])
(msg,NO FEED RATE)
(M00)
(o45 endif)

(o50 if[#18 GT 20])
(msg,ANGLE/SEG TOO BIG)
(M00)
(050 endif)

(o55 if[#18 LT .1])
(msg,ANGLE/SEG TOO LOW)
(M00)
(055 endif)

(o60 if[#11 EQ #0])
(msg,NO RAPID HEIGHT)
(M00)
(o60 endif)

(o65 if[#20 EQ #0])
(msg,NO PITCH SET)
(M00)
(o65 endif)

(********************** PRESETS **************************)

G94(IPM)
#10=[360/#18] (CALCULATE NUMBER OF SEGMENTS)
#109=#10 (COPY RESULT TO #109 AS DISPOSABLE)
#3=#18 (COPY R TO #3 AS DYNAMIC)

(*********************** DO WORK **************************)
(RH/LH SCROLL)
G90G00 X#21 Y#22 (GO TO CENTER OF SCROLL)
G0Z#11 (GO TO RAPID HEIGHT ABOVE)
#19=[#1 + #21] (CALCULATE X + RADIUS OF CENTER)
G0 X#19 Y#22 (FEED OVER FOR START CUT)
G01 Z#26 F[#9/4] (1/4 OF NORMAL FEED FOR PLUNGE)

(** LOOP START **)
o101 while [ #3 LE 360 * #8 ]
#24=[COS[ #3 ] * #1] (CALCULATE X)(DEGREES * RADIUS )

o102 if[#7 EQ 1]
#25=[SIN[-#3] * #1] (RH CALCULATE Y)(DEGREES * RADIUS)
o102 endif

o103 if[#7 EQ 2]
#25=[SIN[#3] * #1] (LH CALCULATE Y)(DEGREES * RADIUS)
o103 endif

#24=[#24 + #21] (ADD RESULT X TO ABS POSITION X)
#25=[#25 + #22] (ADD RESULT Y TO ABS POSITION Y)
G01 X#24 Y#25 F#9 (MAKE CUT)
#3=[#3 + #18] (INCREMENT THE ANGLE)
#1=[#1 + [#20/#109]] (INCREMENT THE NEW RADIUS)
o101 endwhile (LOOP END)

G90 G00 Z#11 (RAPID BACK TO INITIAL Z)
o<scroll> endsub
M2
%

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

More
02 May 2018 02:07 #109989 by vicstransam
Here is a fully working version of the main program that calls the ported Fanuc macro along with the ported macro.
I still haven't got alarm messages to work as I would like and I suppose all local and global variables can never be null but I'm not sure yet.


(BI-DIRECTIONAL SCROLL DEMO.ngc)
(MAKES 8 SCROLLS OR SPIRALS)
G91G28Z0
G28X0Y0
G90G0G54X0Y0
G43Z.1H1

(GLOBAL VARIABLE DEFINITIONS)
#<_abs_x>=0
#<_abs_y>=0
#<_start_rad>=.25
#<_degrees>=3.
#<_depth>=-.05
#<_rotations>=3.
#<_feedrate>=15.
#<_direction>=1
#<_height>=.1
#<_pitch>=.5

(CALL 1ST SCROLL SUB WITH ABOVE PARAMS)
o<scroll> call
(FINISHED 1ST ONE)

#<_abs_x>=0
#<_abs_y>=5.
#<_direction>=1
(CALL NEW SCROLL SUB WITH SOME UPDATED PARAMS)
o<scroll> call
(FINISHED 2ND ONE)

#<_abs_x>=0
#<_abs_y>=10.
#<_direction>=1
(CALL NEW SCROLL SUB WITH SOME UPDATED PARAMS)
o<scroll> call
(FINISHED 3RD ONE)

#<_abs_x>=0
#<_abs_y>=15.
#<_direction>=1
(CALL NEW SCROLL SUB WITH SOME UPDATED PARAMS)
o<scroll> call
(FINISHED 4TH ONE)

(*************** NEXT ROW ***********************)

#<_abs_x>=5.
#<_abs_y>=15.
#<_direction>=2
#<_rotations>=6.
#<_pitch>=.25
(CALL NEW SCROLL SUB WITH SOME UPDATED PARAMS)
o<scroll> call
(FINISHED 5TH ONE)

#<_abs_x>=5.
#<_abs_y>=10.
#<_direction>=2
#<_rotations>=6.
#<_pitch>=.25
(CALL NEW SCROLL SUB WITH SOME UPDATED PARAMS)
o<scroll> call
(FINISHED 6TH ONE)

#<_abs_x>=5.
#<_abs_y>=5.
#<_direction>=2
#<_rotations>=6.
#<_pitch>=.25
(CALL NEW SCROLL SUB WITH SOME UPDATED PARAMS)
o<scroll> call
(FINISHED 7TH ONE)

#<_abs_x>=5.
#<_abs_y>=0
#<_direction>=2
#<_rotations>=6.
#<_pitch>=.25
(CALL NEW SCROLL SUB WITH SOME UPDATED PARAMS)
o<scroll> call
(FINISHED 8TH ONE)
G91G28Z0
G28X0Y0
M2

And here is the fully working ported sub:

o<scroll> sub
(scroll.ngc)
(LinuxCNC scroll macro)
(CONSTANT PITCH SCROLL RH OR LH MACRO)
(FEED RATE IS G94 FEED PER MINUTE)
(CALL IS o<scroll> call )
(SET GLOBAL VARIABLES IN MAIN BEFORE SUB CALL!)
(PITCH IS MORE ACCURATE if R IS SMALLER THAN 5)
(ported from FANUC MACRO B to LinuxCNC)
(** global variables used from main program **)
(global variables start with a underscore)
(copy these to main program and assign value)
(#<_abs_x>=1.)
(#<_abs_y>=1.)
(#<_start_rad>=.25)
(#<_degrees>=3.)
(#<_depth>=-.05)
(#<_rotations>=3.)
(#<_feedrate>=15.)
(#<_direction>=1.)
(#<_height>=.1)
(#<_pitch>=.5)

(** transfer variables to FANUC syntax **)

(U IS ABS X LOCATION) #21=#<_abs_x>
(W IS ABS Y LOCATION) #23=#<_abs_y>
(A=STARTING RADIUS AT CENTER) #1=#<_start_rad>
(R=RESOLUTION IN DEGREES, EXAMPLE: R5 = 5 DEGREE SEGMENTS) #18=#<_degrees>
(Z=-DEPTH, EXAMPLE: -.1) #26=#<_depth>
(E=NUMBER OF TOTAL ROTATIONS FROM CENTER TO END) #8=#<_rotations>
(F=FEED IN IPM BASED ON TOOL CENTERLINE PATH) #9=#<_feedrate>
(D=DIRECTION OF CUT, 1=CW, 2=CCW, FROM INSIDE OUT) #7=#<_direction>
(H=HEIGHT ABOVE PART TO RAPID TO) #11=#<_height>
(T= PITCH) #20=#<_pitch>

(****************** VALUE SIGN PRESETS ****************)
#1=ABS[#1] (A IS SET POSITIVE ONLY)
#7=ABS[#7] (D IS SET POSITIVE ONLY)
#7=FUP[#7] (D IS ROUNDED UP TO WHOLE #)
#8=ABS[#8] (E IS SET POSITIVE ONLY)
#9=ABS[#9] (F IS SET POSITIVE ONLY)
#18=ABS[#18] (R IS SET POSITIVE ONLY)
#20=ABS[#20] (T IS SET POSITIVE ONLY)

(************** ERROR CHECKING ************************)

o05 if#7 LT 1] OR [#7 GT 2
(msg, DIR EITHER 1 OR 2)
o05 endif

o35 if[#8 LT .5]
(msg,NO ROTATIONS)
o35 endif

o45 if[#9 EQ 0]
(msg,NO FEED RATE)
o45 endif

o50 if[#18 GT 20]
(msg,ANGLE/SEG TOO BIG)
o50 endif

o55 if[#18 LT .1]
(msg,ANGLE/SEG TOO LOW)
o55 endif

o65 if[#20 EQ 0]
(msg,NO PITCH SET)
o65 endif

(***************** PRESETS *********************************)
G94 (INCHES/MIN)
#10=[360/#18] (CALCULATE NUMBER OF SEGMENTS)
#109=#10 (SET #109 TO SEGMENTS PER ROTATION)
#3=#18 (SET #3 TO RADIUS AT BOTTOM START)

(*********************** DO WORK ***************************)
(RH/LH SCROLL)
G90G00 X#21 Y#23
G0Z#11
#19=[#1 + #21] (CALCULATE X + RADIUS OF CENTER)
G0 X#19 Y#23 (FEED OVER FOR START CUT)
G01 Z#26 F[#9/4] (1/4 OF NORMAL FEED FOR PLUNGE)

(LOOP START)
o101 while [ #3 LE 360 * #8 ]
#24=[COS[ #3 ] * #1] (CALCULATE X)(DEGREES * RADIUS )

o102 if[#7 EQ 1]
#25=[SIN[-#3] * #1] (RH CALCULATE Y)(DEGREES * RADIUS)
o102 endif

o103 if[#7 EQ 2]
#25=[SIN[ #3 ] * #1] (LH CALCULATE Y)(DEGREES * RADIUS)
o103 endif

#24=[#24 + #21] (ADD RESULT X TO ABS POSITION X)
#25=[#25 + #23] (ADD RESULT Y TO ABS POSITION Y)
G01 X#24 Y#25 F#9 (MAKE CUT)
#3=[#3 + #18] (INCREMENT THE ANGLE)
#1=[#1 + [#20/#109]] (INCREMENT THE NEW RADIUS)
o101 endwhile (LOOP END)

G00 Z#11 (RETURN Z TO RAPID HEIGHT)
o<scroll> endsub
m30

I would like to see an example of the EXIST function that's mentioned in the manual. The manual curiously mentions it but does not elaborate. Can it be used to check if a variable has been declared and then post a message if one is missing? I guess I'll wing it and see how it works.

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

More
02 May 2018 02:25 #109991 by vicstransam
I found a bug in the this forum post XML. Seem it strips out the outer set of [ ] brackets at o05 under error checking section above. If I edit the post to fix it, it is shown correctly while in edit mode but then strips it out when done editing. The line o05 should have a outer most brackets that encapsulates two other sets of brackets. Interesting.
The code runs fine on my machine.

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

More
02 May 2018 23:55 #110074 by andypugh
linuxcnc.org/docs/2.7/html/gcode/o-code.html#ocode:subroutines

Is the LinuxCNC equivalent. But I think that there are errors on that page. Section 1 says that subs have no return values, but section 7 says that they do.

I don't know if ordinary subs support missing parameters. But it can be done in G-code remaps:
linuxcnc.org/docs/2.7/html/remap/remap.h...apped_code_execution
Is a very long page, and incomplete in places. And possibly not relevant to your question.

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

More
07 May 2018 14:51 #110328 by vicstransam
Ok, so I have been playing around with porting a few of my Fanuc macro programs to LinuxCNC and here are a few things I have learned.
1. It is possible to emulate a GOTO statement with a "IF, ELSE, ENDIF" sequence but it's not as tidy or as easy.
2. The local variables are reset to a value of zero at boot, not a value of NULL so that is a dead end. I just avoid local variables if possible.
3. Error checking of passed variables takes way more lines of code and can't emulate a #3000=1(ERROR).

I was able to port a few programs over but ultimately was left with a total re-write of the code that acted somewhat as a FANUC macro.
I do like using named variables in LinuxCNC. It is very handy not having to use SETVN to name them.

Anyways, thanks for the reply and here are some very handy macros that you may find interesting.

They are: Jeweling macro (makes engine turned spots like the instrument panel of a 78' TransAm)
Scroll macro ( bi-directional scroll /spiral with lots of options)
Shapes macro (cut stars/polygons with multi cuts if needed and bi-directional cuts options and angular rotation options)
I tried to heavily comment these with all pertinent info on usage, etc....
I'm sure there are typos and clutter that I forgot to remove but they all run correctly.
Attachments:

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

More
07 May 2018 18:11 #110334 by Todd Zuercher
For #3 could you not just use a Message followed by an end program (M2). to do essentially the same thing as the Fanuc #3000 error.

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

More
07 May 2018 18:14 #110336 by eneias_eringer
I made a conversion from renishaw fanuc macros to linux cnc, the worst problem was "goto", I had to write the same command several times because there is no "goto" ...
but the problem with the null variable I solved,i set always with a large value #<null>=9999 , renishaw macros for siemens uses that !

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

More
07 May 2018 18:30 #110337 by Todd Zuercher
Working arround the lack of a GOTO, can be difficult. It usually requires a little different way of looking at your sub program.

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

More
07 May 2018 18:34 #110338 by andypugh

vicstransam wrote: 2. The local variables are reset to a value of zero at boot, not a value of NULL so that is a dead end. I just avoid local variables if .


This G-code works (only with named parameters, I just tested it)
O100 if [exists[#<test>]
  (debug, exists with value #<test>)
O100 else
  (debug, does not exist)
O100 endif
M2

Documented here:
linuxcnc.org/docs/html/gcode/overview.html#gcode:functions

(Possibly it should also appear in the parameters section?)

There is no "GOTO" in LinuxCNC G-code because it was written by programmers who have been trained to believe that GOTO is evil :-)

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

Time to create page: 0.101 seconds
Powered by Kunena Forum