Coder Social home page Coder Social logo

pygcode's People

Contributors

fragmuffin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pygcode's Issues

Test Dialects

With #13 & #14 closed, create tests:

  • use as much of the new dialects as possible (find example files)
  • switch dialects mid script (test that interpreter is not confused, or mixing dialects)

decimal points

In general it is important to include a decimal point on many numbers in gcode (particularly those following A, B, C, F, I, J, K, Q, R, U, V, W, X, Y, Z). On many machines (e.g. haas see https://www.haascnc.com/content/dam/haascnc/en/service/manual/operator/english---mill-ngc---operator's-manual---2017.pdf Section 6.14.5), an integer is interpreted as either 1 thousandth or ten thousandth of the default unit.. so Z50 moves the Z axis to 0.05 mm above the WCS zero instead of 50 mm above the zero, potentially crashing the spindle (not fun!).

the code print(Line('G0 Z50.').block) results in G0 Z50, massively changing the meaning of a move to the 50 mm clearance plane!

How hard is this going to be to fix? I need to parse some G code and using a tool like this could really help - but I cannot use if it does the equivalent of dividing my positions and feed rates by 1000!!

param_letters with no numbers after parameter do not work

Hey,

i've got gcode lines like:

  • T1 R
  • M1013 R

and if there is no number after the "R", i get the exception GCodeWordStrError : word 'R' value invalid

I have added the classes:

class GCodeParkReturn(GCode):
    """M1013: park/return"""
    word_key = Word('M', 1013)
    word_letter = 'M'
    param_letters = set('R')

class GCodeSwitchExtruder(GCode):
    """T1: switch extruder"""
    word_key = Word('T', 1)
    word_letter = 'T'
    param_letters = set('R')

E.g. T1 R123 does work without an issue with the added "123" after the "R"
Is there an option to allow zero parameter values? Maybe I have just missed it.

I'm testing it using text2gcodes('T1 R')

Thanks.

Language Variants

Allow multiple GCode languages to be supported
(that's the only way this library is going to be practical)

  • Split conflicting GCodes by language in a sub-module pygcode.lang
  • Allow "switching" between language variants with pygcode.set_lang("reprap")

To make this possible, I'll first have to:
Change discovery mapping method to registration as opposed to on-demand class search

root problem identified by @revarbat in #8

Workaround

It's likely you're coming across this problem:

>>> from pygcode import text2gcodes
>>> text2gcodes('M80')
GCodeWordStrError: gcode text not fully formed, unassigned parameters: [<Word: M80>]

What the interpreter does is finds all valid G or M codes, then loops though all other Words from right to left, assigning them to their nearest valid G or M code as a parameter.
This error is saying that it could not attach 'M80' as a parameter to any valid gcode (because it was not identified as a valid gcode itself)

Upon closure of this issue, the M80 code will be defined in 1 or more gcode dialects, then it will just be a matter of switching to the correct dialect.

In the meantime this workaround may get you out of trouble in some cases.

You can create your own G or M codes to be interpreted.

>>> import pygcode
>>> class PirateGCode(pygcode.GCode):
...     word_key = pygcode.Word('M', 80)  # yarrr matey!!
>>> from pygcode import text2gcodes
>>> text2gcodes('M80')
[<PirateGCode: M80>]

Tasklist

  • separate linuxcnc as a selectable "dialect"
  • create empty dialect stub (to use as template)
  • add new dialects
  • expand tests (#15)

E motion letter support for 3D printers

This is a beautiful library for parsing CNC subtractive process GCode. However, 3D printing, an additive process, uses a slight variant on GCode.

Almost all cheap 3D printers use the E letter to denote extruder motion, such that X, Y, Z and E are motion axes. Yes, it would have been smarter to use the A, B, C, U, V, or W codes instead. Unfortunately E became the standard, and it's too late to do much about that.

In addition:

  • M82 sets E axis (and only E axis) motion to absolute mode.
  • M82 sets E axis (and only E axis) motion to relative mode.
  • G29 does a homing similar to G28, with the addition of multiple Z height tests at various XY positions to test how level the bed is.
  • There are also various other G and M codes it would be nice to get info from in parsing, that don't affect motion. You can find more info at http://reprap.org/wiki/G-code though it includes info on obsolete and obscure codes for older or unusual printers as well. Info specific for the Marlin firmware, which I am most interested in, is at http://marlinfw.org/meta/gcode/

If there is a way you could at least enable the E motion axis in this library, that'd let me use this library to write a program to visually preview GCode files with PyOpenGL.

Useful M codes

Hi Peter,

I like the pygcode very much. I am using your library to simulate GCode and create laser path optimization for my hobby machine. It works perfectly.

The simulation usability could be improved by adding some non LinuxCNC standard codes:

M18 (disable steppers, GCodeMovement will automatically reenable stepper)
M80 (ATX power on)
M81 (ATX power off)

If the ATX power is off, the GCode consumed will not cause any physical movement. A parameter in the Machine object reflecting the ATX power state would be useful.

The M18 is implementation specific, nevertheless a NoOP calss would be useful in the pygcode distribution eliminate ERROR on parsing.

Thanks for your time and great work done!
Attila

M117 string parameter

Hi there,

i just discovered pygcode and this seems to be a really useful project.

But i have some problems using it with marlin. It doesn't this seem to be easily possible to add a command with arbitrary string parameters. This is needed for commands like M117 which is used to display text on an LCD display.
I tried the workaround from #9 but it only takes "Words"/ one letter Arguments.

Did i miss something?

This line fails Line

This line is used in 3D printing:
M84 X Y E ;Disable all steppers but Z

error: word 'X' value invalid

Calculate machining time

Hi! I am trying to figure out a way to calculate machining time. The use case is a CNC Milling Machine, cant seem to figure out how to calculate the time

Migrate wiki --> sphinx

The github wiki was a good place to start, but I think this project would benefit from automatic code documentation.

sphinx autodoc hosted on github pages is probably the simplest option.

Especially since now I have experience in this while setting it up for cqparts.

Exported GCode contains OctoPrint API Key

I manually inspected some GCode file and by accident discovered the following line:

; printhost_apikey = XXXXXXXXXXXXX

I would not classify this as a severe vulnerability, but I don't think users are aware that their gcode files now contain the access credentials to control their OctoPrint Host. Sharing GCode is rare, but it happens.

Line number in program

Hello,

I'm trying to process a program that contains N codes at the begining of each line

while trying to process the block in the machine
an error is raised

self.machine.process_block(line.block)
/usr/bin/python2.7 /home/turboss/Sources/hazzy/hazzy/modules/kremlin/kremlin.py
Traceback (most recent call last):
  File "/home/turboss/Sources/hazzy/hazzy/modules/kremlin/kremlin.py", line 395, in <module>
    main()
  File "/home/turboss/Sources/hazzy/hazzy/modules/kremlin/kremlin.py", line 386, in main
    kremlin.draw_path()
  File "/home/turboss/Sources/hazzy/hazzy/modules/kremlin/kremlin.py", line 332, in draw_path
    self.add_points(line, points)
  File "/home/turboss/Sources/hazzy/hazzy/modules/kremlin/kremlin.py", line 370, in add_points
    self.machine.process_block(line.block)
  File "/home/turboss/Sources/hazzy/hazzy/modules/pygcode/machine.py", line 471, in process_block
    self.process_gcodes(*block.gcodes, modal_params=block.modal_params)
  File "/home/turboss/Sources/hazzy/hazzy/modules/pygcode/machine.py", line 452, in process_gcodes
    modal_gcode = self.modal_gcode(modal_params)
  File "/home/turboss/Sources/hazzy/hazzy/modules/pygcode/machine.py", line 422, in modal_gcode
    ' '.join(str(x) for x in unasigned_words), self.mode
hazzy.modules.pygcode.exceptions.MachineInvalidState: modal parameters 'N10' cannot be assigned when in mode: <Mode: G00 G17 G90 G91.1 G94 G21 G40 G49 G54 G61 G97 M05 M09 F0 S0 T0>
N10 (HAZZY SPLASH G-CODE)

I was trying to figure what is wrong but failed

Thanks this project is great

G80 returns from canned cycle

G80 is a return from a can cycle.. there is nothing wrong with the following (from the perspective of a machine)

strs = ['G0 G90 X0 Y0', 'S100 M3', 'G81 Z0 F100', 'G80', 'X1 Y1']
m = Machine()
for s in strs: m.process_str(s)

but running the above causes the error:

MachineInvalidState: modal parameters 'X1 Y1' cannot be assigned when in mode: <Mode: G17 G90 G91.1 G94 G21 G40 G49 G54 G61 G97 M3 M9 F100 S100 T0>

The mode when this comes out of the can cycle (with G80) should be G0 -- so the X1 Y1 command should cause the machine to rapid to X1 Y1

Estimate time for path

Add functionality to pygcode.Machine to estimate time needed to follow a CNC path.

For example:

>>> m = pygcode.Machine()

# Initial state
>>> m.pos
<Position: X0 Y0 Z0>
>>> m.time
0.0

# After movement
>>> rapid_move = pygcode.GCodeRapidMove(X=10, Y=20)
>>> m.process_gcodes(rapid_move)
>>> m.pos
<Position: X10 Y20 Z0>
>>> m.time
1.23

Scope: (estimate only)
In scope:

  • Delays from acceleration / deceleration to varied speeds
  • Configured jogging speed (of pygcode.GCodeRapidMove)
  • Feed-rate of pygcode.GCodeMotion.__subclasses__()

Out of scope:

  • micro-arcs injected during instant direction-changes
    eg G01 X0 Y10 -> G01 X10 Y10, tool can't instantly change direction at full speed
    For the purposes of this estimate the above example would take the same time as G01 X0 Y20

project dead?

this repo (but the project itself) is obviously dead : pull requests from years ago ave never bee merged, and no reaction from the repo owner. I have merged all pull requests on my own fork https://github.com/petaflot/pygcode and will be making active use of the code base.

in general, how does it happen when the individual(s) who maintain a project become unavailable for a long term? can this project be removed from the pip repos?

Dialects and floating-point precision

Thanks for this useful project!

I am working with GCode files which specify measurements in inches to 6 decimal places (and yes, this level of precision can matter on professional tools). The default linuxcnc dialect in pygcode appears to be parsing my files without difficulty. However, I noticed that all numbers were being rounded to 3 decimal places. The rounding is performed on line 33 of https://github.com/fragmuffin/pygcode/blob/master/src/pygcode/dialects/linuxcnc.py:

CLEAN_FLOAT = lambda v: "{0:g}".format(round(v, 3))

To proceed with my current project, I will simply modify my local copy of pygcode to round to 6 decimal places. However, I wonder whether I should register another dialect instead, perhaps I could call it "precise". The dialects section of pygcode appears to be incomplete. I'd like to start a discussion about what the author's intentions are for pygcode dialects, and how best to use them.

arc movement example

Hi, in the document, we can learn how to use linear move,
but no example for arc movement is provided,
for example, I have a arc ( start, end, radius, cw/ccw ) etc. ,
how to i pass the parameters to the pygcode?

missing parameter letter in G43

hey, it would be great if you could add the parameter Z to the GCodeToolLengthOffset (G43). Im using your parser for a project at the university and it's really helpful!

PrusaSlicer gcode file compatibility

The following code chunk worked well for a gcode file sliced in CURA but not in PrusaSlicer. Now I get error: word 'P' value invalid. Is there a way to go about this to parse this file with pygcode, perhaps if it's not a compatibility issue? There is a PyGcode extension for Prusa but it's for adding gcode into the file via python.

from pygcode import Line
    gcode_lines = []
    gcode_block = []
    gcode_params = []
    
    with open(test_file2, 'r') as test:
      for line_text in test.readlines():
          line = Line(line_text) # decode gcode line
          line.block.gcodes  # list of gcodes
          line.block.modal_params  # motion modal parameters
          
          gcode_lines.append(line)
          gcode_block.append(line.block.gcodes)
          gcode_params.append(line.block.modal_params)
    
    print(gcode_block, sep='\n') 

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.