vlachoudis / bCNC

GRBL CNC command sender, autoleveler and g-code editor
GNU General Public License v2.0
1.56k stars 532 forks source link

Prints Small #1209

Open KenwoodFox opened 5 years ago

KenwoodFox commented 5 years ago

All of my paths show up at one tenth the size, my board interperts mm, my gcode is in mm, my cam software is in mm, why does bCNC seem to move my pinter with the decimal point in the wrong spot?

Harvie commented 5 years ago

Go to bCNC settings and check if you have mm or inches... Also check GRBL settings: https://github.com/gnea/grbl/wiki/Grbl-v1.1-Configuration#13---report-inches-boolean

KenwoodFox commented 5 years ago

im reading 1/10 not 1/25 but ill check those settings, and yes bCNC has that dropdown selecting mm, are those the settings you're referring to?

Harvie commented 5 years ago

What input file do you use? Are you loading g-code to bCNC? If loading DXF, SVG, STL or PLY, you should make sure that it's in mm, not cm...

paulvdhoeven commented 5 years ago

I'm feeling a bit silly for mentioning it, but are you sure you've callibrated the number of steps /mm properly in Grbl? Maybe you accidentally entered calibration settings for cm, and are sending mm's to it.

Teddyz commented 4 years ago

I see a similar problem when saving as svg from Inkscape. Everything becomes small in bCNC. When I instead export as dxf from Inkscape it gets correct size.

See example: bild

elt.zip

But I am a rookie here. Any recommendation where I can post questions?

Harvie commented 4 years ago

@Teddyz what DPI you use for inkscape export? Do you have your bCNC and GRBL correctly set in metric?

Teddyz commented 4 years ago

@Harvie I do not know how to see the DPI setting you ask for. Can it be seen in the saved files? They are attached in my message above.

I think I have bCNC and GRBL set OK regarding metric settings. I have installed switches and Homing works. Movement and display of xyz-values are OK and I can use the router.

I posted because I have similar problem as OP, but my size-difference is not exactly 1:10. I use bCNC 0.9.14-dev.

Harvie commented 4 years ago

Have you read this? https://github.com/vlachoudis/bCNC/wiki/SVG-support You might need to apply transforms before exporting as SVG for use with bCNC There is issue open for this: https://github.com/regebro/svg.path/issues/36

KenwoodFox commented 4 years ago

I think my GRBL Settings were off, though, for some reason, the example gcode the machine shipped with seems to print perfectly, but my items all show up at 1/10 the size they should, so perhaps in china/Vietnam, it was configured in centimeters?

robughblah commented 4 years ago

Joe, This is a good CNC resources page. I copied the link from a subscription email so hoping it works in general.

https://cnccookbook.acemlnb.com/lt.php?s=7390b9be73e6c1d6c4d51865d5b54103&i=709A1010A1A102185

Rob

On Sep 25, 2019, at 6:36 PM, Joe S notifications@github.com wrote:

I think my GRBL Settings were off, though, for some reason, the example gcode the machine shipped with seems to print perfectly, but my items all show up at 1/10 the size they should, so perhaps in china/Vietnam, it was configured in centimeters?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.

KenwoodFox commented 4 years ago

Thanks so much, I'm good with traditional machining, but getting the interpreter I have to work is a hassle it seems. Thanks so much for the resources.

Harvie commented 4 years ago

@KenwoodFox I am sure you will catch up in no time. I came to CNC hobby from IT background, so i understood the workings of electronics, but had to learn everything about machining (tools, feeds and speeds, materials, ...). All you need is to find some workflow (combination of software tools) which works for you.

I was looking for free opensource that runs on Linux (which disqualified lots of well known software like fusion 360). bCNC seemed too complex in the begining, but later i regreted that i wasted my time with others, because i can do most of my workflow in the bCNC (both 2D CAM, autoleveling and streaming g-code to machine), which saves my time. Only the CAD work i have to do separately in LibreCAD.

Teddyz commented 4 years ago

Thanks for looking into this. I now believe that my problems are related to the command transform="translate(9.9350847,-19.807537)" in the elt.svg. This is a very simple file. I tried all the ungrouping, grouping, StrokeToPath and last ApplyTransform. Only the latter did any difference, as there were now many small movements made by bCNC: bild See the last three versus the first three blocks. The translate-thing is now gone, but the size is still "small". elt_4_ApplyTransform.svg.txt

Work-around is of course that I save as dxf in Inkscape, so this is not a life threatening problem to me. What I have yet not found, are examples on how to do common tasks, like "How to mill (correct word?) these letters (not only the outer path) 5mm into some piece of wood, 0.5mm at a time using a 4mm end mill". I think there are many ways to do this using non-commercial software, but I have no clue if I can do it in bCNC alone, or what programs I should try. Thanks!

Harvie commented 4 years ago

Thanks for looking into this. I now believe that my problems are related to the command transform="translate(9.9350847,-19.807537)" in the elt.svg.

Yes, that's exactly what i am talking about. You need to "apply" that transform somehow, because it's currently ignored by bCNC, until it gets implemented in svgpath library.

I know about this issue, so i will close this, unless you have solution for this problem. Feel free to continue discussion after closure.

tatarize commented 4 years ago

@Harvie I do work on an lasering application (https://github.com/meerk40t/meerk40t) and so I needed production working code. So I extended the path.py to perform a bunch of transformations etc. It's fairly compatible with svg.path. pip install svg.elements ( https://github.com/meerk40t/svg.elements ).

It's for a laser controller, so I needed all the SVG stuff scaled correctly. So it can easily apply that stuff.

path *= Matrix("translate(9.9350847,-19.807537)") would do the transform as needed. While transforms have been long planned for svg.path, it'll doesn't look great for the codebase. Also, it has the implementation of the viewport to matrix conversion for real sized objects. So when your svg says something is 33cm and you properly set the pixels_per_inch (inkscape uses 96, 1000 dpi things can use 1000), it'll end up being the correct size.

Harvie commented 4 years ago

@tatarize cool! would you be able to help us integrate your changes into the bCNC please?

tatarize commented 4 years ago

Sure.

I tried to lookup a good test case since the problem is the transformations it seemed like the SVG 1.1 Test Suite has a bunch of solid tests. ( https://www.w3.org/Graphics/SVG/Test/20110816/archives/W3C_SVG_11_TestSuite.tar.gz ) but, oddly most of the coords-trans--.svg files use <Line> and <Rect> shapes rather than paths and your code seems to only parse the paths.

My current code for svg.elements does that stuff a bit more robustly. And actually implements most of the spec at this point.

Method one:

The least disruptive method would be to expand the parsing a bit and leave everything else as is, you currently parse for id and path and adding in transform wouldn't be too hard. However, as part of the spec you'd need to know the groups that that path was a part of and the transforms applied to them. Basically nested transforms in <g> group objects need to be captured in the groups they are currently within. The current methodology wouldn't support that. However, if we just assumed any transform applied to all subsequent elements we could just extract the paths and since they'd be svg.elements Path just multiply them by the extracted transform. Just extract that stuff then if we's add a line: path *= "translate(9.9350847,-19.807537)"

You'd still have a lot of bugs and things that wouldn't be caught or dealt with properly. This might be far too weak.

Method two:

Just take the file, and get rid of the code you're currently using to regex through it and parse it. SVG.elements(filename) which uses the python builtin xml parser and it'll spit out some SVG objects like Rect, SimpleLine, Circle, Path, Image, etc. You then take any object that is a Shape and get the .d() parameter. Then feed that into your current conversion to gcode routine.

It would takes a block like:

        svg = SVG(pathname).elements(width=w, height=w, ppi=96.0)
        context = self.project.elements

        for element in svg:
            if isinstance(element, Path):
                convert_to_gcode(element)
            elif isinstance(element, Shape):
                convert_to_gcode(Path(element))
            elif isinstance(element, SVGImage):
                continue # Ignore images
            elif isinstance(element, SVGText):
                continue # Ignore text

Now it won't fix some things like the gcode arcs being circular arc only and svg arcs being potentially elliptical and thus somewhat problematic but it will do a much more in depth parsing according to the SVG spec. Sidenote: I daresay the best methodology there is to test whether the arc can be represented as a circular-arc less than semiperimeter arc, or could be broken up into Gcode compatible arcs and if not fallback into subdiv points.

The svg.elements project is pretty robust and I've tested it against much of the SVG 1.1 test suite. And the unneeded stuff can just be passed on.

I'm thinking method 2 would be strongly preferred generally because in my head I'm just seeing all the various elements things that would fail by the first method. Like exact unit scaling with regard to the viewbox. Or the lack of support for the other non-path shapes. I'll have to rewrite svgcode.py a bit, keeping the gcode conversion bit.

And I'll assume inserting the code directly into the project like the old svg.paths 3.0 code is your preferred method.

tatarize commented 4 years ago

Okay, PR is up at #1312

Added svg.elements code. Rewrite to some of svgcode.py:

A couple points I couldn't solve in a quick once over without any deep dive into the code. SVGs scale based on real world units such as PPI which gives, internally the physical differences between cm mm and in. So if you give it a conversion between real units and pixels it can use that. While I fed that to scale since it seemed to be converting svg default value of 96 pixels per inch into your units, it might actually be correct to just give it whatever your expected PPI is. For example my laser cutter is 1000 dpi since the stepper motors move 1/1000th of an inch per step, as such my PPI is 1000.

Secondly, SVGs scale often as part of a viewport. Basically we are told the width is 100cm and height is 100cm and the viewbox is say "0 0 100 100" which is to say each unit of 1 in the viewport is equal to 1cm. This value, however is scaled up based the actual physical height and width of the space you are putting that value in. The height and width you say an SVG is in, might be different if the actual physical space it can occupy is different. In my laser cutter my workspace is like 240cm by 180cm and so the bed settings are used to tell the SVG how big of a space it physically occupies. Often SVGs are said to occupy 100% width and 100% height and there's no way to determine what those actually mean if we don't know the actual size the SVG could be occupying. In webpages that's often the size of the svg element in the html for our uses is the size of the actual bed we're using. For some SVGs it won't matter. As they will say something like 30cm is the width and the viewport gives us user units and that can be scaled up so if your svg object is 30cm the viewport will give us a scaling to make that also be 30cm in our units too.

This is a pretty minor use of the code, and figured it was worth it just for real world usability, and testing integration.

I think the scale might be off, but elements can scale things as needed. Since it scales based on the viewport, in part. It now parses all the shapes SVG produces like rectangles etc. And does a bunch of stuff you don't need like interpret all the colors correctly and figure out where the images belong in the scene. But, a lot of things would otherwise render wrongly. Go ahead and try some svgs in the new code or audit the code as you need. And maybe you'll want to do color->speed color coding like some of the laser software.

Hit me up with any problems. It should have all SVG in it's wheelhouse so anything that doesn't work will have a reason it doesn't work and can be fixed. But, odds are good it'll be more functional than what you had before.

tatarize commented 4 years ago

While it's not really integration related I changed the gcode = '' and constant adding gcode_line, into gcode = [], append(gcode_line), return '\n'.join(gcode) as it'll be much faster with larger code segments.

Also a big cause for slowdown is from the line subdiv=max(1,round((segment.length())*subdivratio)) which is fine for most things but cubic bezier curves do a lot of linear interpolation to solve for the length. Arc would too but with scipy installed it opts to solving the hypergeometric function and solves the arc length exactly. I'll change that bit to increase the error there. Should end up significantly faster for larger paths.

Also, feel free to do something like: for element in self.svg.elements(ppi=scale, height=10, width=10): which would set the units for width and height to 10. Rather than their current default of 1. Which only should really matter if something is percent of width or the file doesn't otherwise specify an explicit width (which many won't).

Harvie commented 4 years ago

Now it won't fix some things like the gcode arcs being circular arc only and svg arcs being potentially elliptical and thus somewhat problematic

bCNC has "arcfit" plugin, which can take curves finely subdivided to large amounts of short lines and replace them with just few nicely fitting arcs. I've spent few weeks working on this and so far it seems to work reasonably well. Currently you have to run the plugin manualy, but once it's well tested, i have plans to run it automaticaly to handle imports of funny shaped curves from both DXF and SVG.

MARIOBASZ commented 4 years ago

I'm going to upload a problem: I have generated a silhouette with many very small lines, I do not know the reason, I suppose it is related to many lines, if I want to generate profile operation, bcnc simply does nothing, or sometimes "forgets" some sections (instead of starting at source, the resulting silhouette is left open by forgetting the first segments ....) arcfit has solved my problem: About the original, Houston we are in trouble. on the modified with arcfit, I can perform the operation .... I write because maybe that error happens when importing files with many very small lines (if that is the reason for my problem)

tatarize commented 4 years ago

I did notice when I opened a very large SVG it sort of stalled out. When I made it smaller with fewer points it seemed to work. So I judged that it was something to do with bCNC.

It seems like fixing a weird arc might be better to do at the source. Since the SVG has the information of how it should look. I could see approximating an elliptical arc with a series of small circular ones. For example ( https://www.researchgate.net/publication/241719740_Approximating_an_ellipse_with_four_circular_arcs )

Also, the library has a built in zingl/bresenham plotter for the path shapes. In theory it'll do pixel perfect shape plotting. I somewhat cheat with the Arc since I didn't yet bother to code in the Bernstein polynomial bezier curve plotter that could actually be used to plot the Arc and instead subdivided the arc into a series of quadratic curves and plotted those. The code is made for something more akin to what I have with the laser cutter. I'm working with where I need to give it explicit commands at the 1000 dpi level.

I tried hooking it up but didn't get the right resolution I'm not sure what the exact correct level of plotting would be. I'd assume with arc-digits at 4 it should be 1000 so 1 mil stepper motors or so. In theory if you wanted exact emulated shapes into direct move (G0) and cut (G1) commands that'd be pretty easy to achieve with the svg.elements code. Just scale the shapes up by a factor of 1000 then divide the coordinates by that. It would give 0.001 inch increments of pixel perfect coordinates to map the shapes. (See http://members.chello.at/easyfilter/bresenham.html ). Then batch them to coords where the path deviates from the line path. This sounds weird but I already do something pretty similar for meerk40t. And ideal svg to gcode renderer would likely do that, and simulate the arc ellipses into quadrarcs or whatever.


If you find anything specific to the svg.elements code I'll be happy to correct it. Mostly look around physically sized objects in SVG like you give them explicit dimensionality in Inkscape or whatever and then make sure that matches inside bCNC. It should just be a scale factor but that might be off, and if there's some design space that is knowable for the designs that would be nice. A lot of SVGs don't contain explicit width and height and the document might need to scale according to that. Like if they are width=100% height=100% that's meaningless unless it knows what space it's occupying.

paulvdhoeven commented 4 years ago

First: How much thought have you given this to attack the problem at thesource? Why are there so many line segments in the SVG in the first place?

This thread also reminded me of a PDF I have somewhere on my Harddrive, written by Hyungjun Park. You can easily find it with: https://duckduckgo.com/html?q=Optimal+Single+Biarc+Fitting+and+its+Applications

There are also many other papers written over biarc curve fitting, which I find interesting for CNC because of a few reasons. First, almost any CNC machine can handle arcs, while the bezier / nurbs / Splines/ more complex curves are often not directly implemented in the controller and must therefore be approximated. Also: A fitted bi-arc curve goes through the control points, while more commonly used curves do not.

Also: Bi-arc does not mean there are only 2 arc segments in a curve, but it means there are 2 arc segments between 2 control points of the curve. In CAD programs which have parametric drawing capabilities such as the sketcher in FreeCAD you can easily experiment a bit with bi-arcs by drawing a bunch of tangentially connected arc segments and then adding constraints.