I need help with an AutoLISP program I am editing/re-writing. I have tried searching the internet for how to address my issue without much success. I believe that my problem is that I don’t know how to properly handle, account for, and set null values, particularly when it comes to having a list with some null values as part of that list.
I have a LISP program that will read a text file and convert that text file into data points (X Y points) that the LISP routine then used to draw a polyline. The LISP program uses the read-line command to read in one line at a time the text string of that line, and then parses out that text letter by letter to obtain the X and Y coordinates and convert those text characters into real numbers that can be entered in as coordinates for a polyline.
The existing program uses a list variable containing the first list item of the X coordinate and the second list item of the Y coordinate, as well as other list variables. There are instances where a coordinate may not exist and I need to be able to properly handle that null instance and not pass a zero (0), or not pass a nil to a function that cannot handle a nil, etc. I am also not sure how the LISP routine is declaring variables and properly setting the variable type, or keeping variable types straight so that the wrong type of variable is not passed to a function expecting a different variable type. The LISP routine reads in G-code and converts the G-code XY coordinates into a graphical polyline representation of the tool path(s). The original LISP routine uses 0.0 as the default “no value” X and Y coordinate values, and 999 as the set value for the non-coordinate comparison check to know when to stop. This is problematic should the G-code contain 0.0 or 999 coordinate values.
if OP doesn't show us (not telling) all variations of real data files coming from his CNC machine, all we can do is play 'guessing games' 😀 as you notice there are odd characters in file like ';' and it could be (or not) part of a number.
i think what i did could be a good skeleton for the OP to continue - agree?
Moshe
@john.uhden wrote:You've got a problem there, @Moshe-A .
At least one of the examples @mmazanec provided had no spaces, as in
X3Y4
So each line has to be dissected differently, perhaps by one character at a time, or by testing to see if there are any spaces in the line using (vl-string-search " " line)
If there are no spaces then you could pretreat the line via (vl-string-subst " Y" "Y" line) and then convert it into a list.
for you to play 😀, this now supports X3Y4
The alpha character essentially tells a given CNC machine what the "command" is. I assume that this is what you mean when you are saying "OP". At present, the LISP routine I provided only recognizes a few alpha characters and of those characters the routine only handles/processes the numeric characters after the TX&Y characters. My routine would fault with more complex G-code programs, which right now would entail any actual G-code program that had other alpha characters after an XYorZ character. This would be easy to "fix" though by just adding those letters to the list of conditions and allowing them to pass through in a similar way to the way the NG&M are allowed to pass through. There are different flavors of G-code and there can be differences from CNC machine to machine. Right now, I am just trying to handle the basics. I think you are trying to handle everything without understanding the rules of G-code, and this is probably what is making this challenging.
If you really want to learn about G-code, the attached to references might help. Note that one of the references is from Autodesk.
As the LISP routine does presently, I would ignore the G-code command and just process the Z coordinate as part of the 3D point for the 3D polyline. G29 is not a common command and from my brief search on the internet seems to be more related to 3D printing. Handling the G02 and G03 commands would be more relevant for creating/cutting/drawing arcs. See the files I attached to my previous post.
@mmazanec wrote:The alpha character essentially tells a given CNC machine what the "command" is. I assume that this is what you mean when you are saying "OP".
i know what CNC means. OP means the person who ask for help here, in this case you 😀
At present, the LISP routine I provided only recognizes a few alpha characters and of those characters the routine only handles/processes the numeric characters after the TX&Y characters.
i understand that, you said it number times.
My routine would fault with more complex G-code programs, which right now would entail any actual G-code program that had other alpha characters after an XYorZ character. This would be easy to "fix" though by just adding those letters to the list of conditions and allowing them to pass through in a similar way to the way the NG&M are allowed to pass through. There are different flavors of G-code and there can be differences from CNC machine to machine. Right now, I am just trying to handle the basics. I think you are
trying to handle everything without understanding the rules of G-code, and this is probably what is making this challenging.
not at all, my lisp version only handle exactly the same g-codes you handle (T, X, Y)
If you really want to learn about G-code, the attached to references might help. Note that one of the references is from Autodesk.
i am not interested in g-code my goal here is to help you 🙏
tell you what? this thread now is on it's page 3 and to me it looks like it is riding in space and your goal is to bring it to an end with some positive result - agree?
We need to advance step by step, so let's look at what we have up till now, we have your working version which i said i can not integrate with so i gave my version which for me is more lisp structured. i want you to take your data file from message #3 (without any changes) and take the last version of my lisp rdf.lsp from message #44 and run the lisp and tell me - if it's working for you so we know we have a good basis to continue - do we have a deal? 😀
Moshe
Here'a little playing of my own to read lines without spaces...
(defun @readXYZ (line / pos)
(foreach char (setq xyz '("X" "Y" "Z"))
(set (read char) nil)
(and
(setq pos (vl-string-search char line))
(set (read char)(atof (substr line (+ pos 2))))
;; If you don't want to print the results,
;; then either delete or rem out the following line:
(princ (strcat "\n" char "="))(princ (eval (read char)))
;; The values of X, Y, and Z will be created for that line
;; except for those that do not exist.
)
)
(princ)
;; You could also return a 3D list...
(mapcar '(lambda (a)(eval (read a))) xyz)
)
;; Examples:
(@readXYZ "X1.1 Y2.2 Z3.3")
(1.1 2.2 3.3)
(@readXYZ "X0.1Y0.2Z0.3")
(0.1 0.2 0.3)
(@readXYZ "X1.1")
(1.1 nil nil)
John F. Uhden
brilliant! brilliant! brilliant!
Never done that [the use of [ (set (read "X") (atof (substr "X5.78Y3.90Z6.90" 2))) ]
it's amazing what these functions does and return .
Gee, thanks @Moshe-A . 😊
I look back ay my old work (90s) before VLisp and what a kludge. Yeah, I made things work somehow, but the tools we have these days have a lot more horsepower. Just gotta sprinkle in some imagination, frequent trips to F1 and Google, and lots of trial and error. Of course the gang here is quite a resource.
John F. Uhden
Your LISP routine did not process the file correctly. One thing it did incorrectly is that it was not separating the start and end of the pline data points correctly. When a new Tool number is introduced, the XY values on that same line are for that tool, not the previous tool.
Attached is the drawing generated from your routine processing the new data point set that is attached, and how the drawing is supposed to look.
@mmazanec wrote, "When a new Tool number is introduced, the XY values on that same line are for that tool, not the previous tool."
I take it then that N## X__ Y__ would represent the starting point of the new tool. So there would be a temporary tool-up to get the new tool and then the head would go back to the new XY, and then tool-down, and then continue? But the new XY could be the same as the previous XY, right? But in that case, the new XY isn't required at all, is it? Or does changing tools create a memory loss and the head forgets where it was and needs to be reminded?
John F. Uhden
N## is just the numbered line, and the numbering of lines may or may not be used. T## is the starting point of the new tool. So, for a line like T## X__ Y__, or for a line like X__ Y__ T## the X__ Y__ on that line would be for that tool. Without an X__ Y__ on a line with a T## line, the machine would only change the tool because only having a T## command is only telling the machine to change the tool. So, in those cases, it would be the next X__ Y__ that would tell the machine where to go. For many machines, particularly older machines, it only knows what is on the line it reads and forgets the previous line and doesn't know the upcoming line.
There are machines that require an M06 (which is equivalent to M6 on many machines) to actually start the tool change. In those cases, a T## command only stages the tool. The machine continues to use the previous tool until an M6 command is read. For the machines I am dealing with, a T## command signifies both the tool number and the request for a tool change.
I probably should also point out with the new sample I provided, the original LISP that I posted would not be able to properly handle the BIG square because of the 999 coordinate points. One will have to zoom in (near the 0,0 origin) to see the much smaller triangle and square and diamond of the "DATA POINTS for TESTING purposes6.dwg" that I sent. Also, neither my original post routine nor my revised routine (the one that can process the 999 coordinates) are presently able to draw a 3D polyline to capture the Z coordinate, but they do capture the XY of the rest of the coordinates with a Z value.
I'm not sure how your program works, but it captures and handles most of the two sample G-code programs correctly, including the Z values. I will look to figure out what is going on within the program as I have time to do so, as I suspect there are some cool/powerful/optimized steps you are taking in your routine.
I'm not sure what is happening for the initial triangle. The routine seems to be missing the datapoints on lines N30 and N40, which is perhaps because of the G70 code that is in the sample file? G70 is essentially a positioning command on the Amada Turret press. Perhaps you have the routine intentionally skipping those points because of the G70 command. The Amada Turret press is the machine that the LISP routine was originally developed for by my retired colleague. For my purposes, I would still like that (G70) datapoint captured and incorporated into the polyline/3D-polyline. In this case using all of the datapoints to correctly form the initial triangle would tell the LISP routine user that there was a "move" command (a motion) to that coordinate. If we really wanted to get fancy, we (and by we I mean you at this point because it would take me some time to figure it out if I ever was able to figure it out) could have the width of the pline change to signify that it was a move command only. Right now, I'm not sure what command tells the Amada it can start punching again and I will have to look into that further.
If any of you checked, you may have noticed that the routine I posted actually does more than just inputting and graphically representing G-code. It also outputs G-code, although very rudimentarily. I appreciate the time and effort everyone has put into helping me and hopefully I will make some sense of how to incorporate everything.
@mmazanec wrote:Right now, I'm not sure what command tells the Amada it can start punching again and I will have to look into that further.
it seems g70 is one time punch off code. after repositioning the punching is resumed.
@mmazanec wrote:Perhaps you have the routine intentionally skipping those points because of the G70 command.
most surely
hey there,
width cannot be set to segments in 3dpoly, so if a g70 happens to be within a 3dpoly, 3dpoly needs to be somehow broken and the g70 segment to be replaced with, say, a line with thickness. what do you think?
Thanks for your efforts on this. I did some more research on the internet to see what the G70 command did/does on other machines. It appears that for (some) CNC mills, unlike the Amada turret punch, a G70 command generates a bolt hole circle.
https://www.haascnc.com/service/codes-settings.type=gcode.machine=mill.value=G70.html
https://www.helmancnc.com/cnc-milling-g70-bolt-hole-circle-program-example/
For my purposes at this point, I think it makes more sense if the LISP routine just processes the G70 point as part of the 3D polyline. Perhaps adding a point (with pdmode set to 35) at those locations (3D polyline nodes) in addition to the 3D polyline.
I tried figuring out how your routine is generating points and 3D polylines. It appears to be using a/the “vla-addline” command, and I found the “AddLine Method” documented on the Autodesk website but I did not understand the explanation given or the examples given. I am not familiar with programing with Visual Lisp (vl) or ActiveX and do not have a good understanding of how to modify the program to do things. I believe the routine I posted was all “Vanilla LISP”.
I tried testing your routine’s ability to handle tools with a single point usage and noticed that it was not drawing the single point locations properly. The routine also seems to fault with fractional (decimal) values that do not have a leading zero (like X-.5 as opposed to X-0.5). I’ve attached another G-code sample program.
Can't find what you're looking for? Ask the community or share your knowledge.