# Gscrib Quick Reference This reference shows how familiar G-code operations map to Gscrib's Python API. Gscrib is a **stateful G-code builder** that tracks your machine's state and generates appropriate G-code commands. Instead of writing raw G-code, you call Python methods that handle the details. ## Key Differences from Raw G-code - **State tracking:** Gscrib remembers position, feed rates, tool status, etc. - **Coordinate transforms:** Like CAM software, rotate, scale, translate before output. - **No G2/G3 arcs:** All curves become smooth G1 segments (controlled by `set_resolution()`). - **Safety:** Built-in validation and bounds checking. ## Essential Tips - **Set units early** before any movements. - **Set resolution** with `set_resolution()` for smooth curves. - **Use high-level methods** (`move`, `tool_on`) instead of `write` to maintain state. - **Use context managers** like `with absolute_mode()` for temporary changes. - **Add custom parameters** to any command (`move(x=10, custom_param="value")`). - **Add inline comments** to any command (`move(x=10, comment="Inline comment")`). - **Coordinates can be specified** as `x=10, y=5`, `Point(10, 5)` or `[10, 5]`. --- ## G-code to Gscrib Translation | G-code param | Meaning | Gscrib equivalent | |--------------|---------|-------------------| | X Y Z | Position | `move(x=…, y=…, z=…)` | | I J K | Arc center offsets | `center=(i, j, k)` in `trace.arc()` | | R | Arc radius | `radius=` in `trace.arc_radius()` | | F | Feed rate | `F=` in `move()` | | S | Laser power | `power_on(…, power)` | | S | Spindle speed | `tool_on(…, speed)` | | P | Dwell time | `sleep(duration)` | | T | Tool select | `tool_change(…, tool_number)` | --- ## 📏 Units & Coordinate Systems | G-code | Gscrib | Notes | |--------|--------|-------| | G92 | {meth}`set_axis(point) ` | Set position without moving. | | G17 / G18 / G19 | {meth}`set_plane(plane) ` | Ignored, use transforms instead | | G20 / G21 | {meth}`set_length_units(units) ` | Inches or millimeters | | — | {meth}`set_direction(direction) ` | For arc interpolation logic. | | — | {meth}`set_resolution(resolution) ` | Segmentation resolution. | | — | {meth}`set_temperature_units(units) ` | Controller specific. | | — | {meth}`set_time_units(units) ` | Controller specific. | **Tips** * Set units early in your program before any movements. * Lower resolution values create smoother curves but larger files. * The controller you use determines which temperature and time units apply. **Examples** ```python set_length_units("mm") # G21 set_axis(x=0, y=0, z=5) # G92 X0 Y0 Z5 ``` ## 🔀 Operation Modes | G-code | Gscrib | Notes | |--------|--------|-------| | G90 | {meth}`set_distance_mode("absolute") ` | Absolute positioning. | | G91 | {meth}`set_distance_mode("relative") ` | Relative positioning. | | G93 | {meth}`set_feed_mode("inverse_time") ` | Feed as 1/time | | G94 | {meth}`set_feed_mode("units_per_minute") ` | Standard feed mode | | G95 | {meth}`set_feed_mode("units_per_revolution") ` | Feed per spindle rev | | M82 | {meth}`set_extrusion_mode("absolute") ` | Absolute filament extrusion | | M83 | {meth}`set_extrusion_mode("relative") ` | Relative filament extrusion | **Tips** * Absolute mode is safer for precise positioning. * Relative mode is useful for incremental movements. * Use context managers for temporary mode changes. **Examples** ```python set_distance_mode("absolute") # G90 set_feed_mode("units_per_minute") # G94 ``` ## 📈 Feeds & Speeds | G-code | Gscrib | Notes | |--------|--------|-------| | F… | {meth}`set_feed_rate(speed) ` | Feed rate. | | S… | {meth}`set_tool_power(power) ` | Tool power/speed. | **Tips** * Feed rate and tool power persist until changed. * Use {meth}`set_bounds() ` to enforce safe speed limits. **Examples** ```python set_feed_rate(1500) # F1500 set_tool_power(8000) # S8000 (without M03) ``` ## 🔧 Tool Control | G-code | Gscrib | Notes | |--------|--------|-------| | S… M03 | {meth}`power_on("constant", power) ` | Constant-power mode. | | S… M03 | {meth}`tool_on("clockwise", speed) ` | CW spindle. | | S… M04 | {meth}`tool_on("counter", speed) ` | CCW spindle. | | T… M06 | {meth}`tool_change("automatic", tool_number) ` | Auto tool-change. | | T… M06 | {meth}`tool_change("manual", tool_number) ` | Manual tool-change. | | M05 | {meth}`tool_off() ` / {meth}`power_off() ` | Stop spindle / Power off tool. | **Tips** * Always turn off tool before tool changes. * Use {meth}`power_on() ` for lasers, {meth}`tool_on() ` for spindles. * Check `state.is_tool_active` before operations. **Examples** ```python tool_on("cw", 12000) # M03 S12000 power_on("constant", 80) # M03 S80 (laser) tool_change("manual", 2) # T2 M06 tool_off() # M05 ``` ## 💧 Coolant Control | M-code | Gscrib | |--------|--------| | M07 | {meth}`coolant_on("mist") ` | | M08 | {meth}`coolant_on("flood") ` | | M09 | {meth}`coolant_off() ` | **Tips** * Turn on coolant after tool start for proper flow. * Use flood coolant for heavy cutting, mist for light work. * Always turn off coolant before tool changes. **Examples** ```python coolant_on("flood") # M08 coolant_off() # M09 ``` ## 🔥 Temperature Control | M-code | Gscrib | Notes | |--------|--------|-------| | M106 | {meth}`set_fan_speed(speed, fan_number) ` | Range 0 to 255. | | M140 | {meth}`set_bed_temperature(temperature) ` | Non-blocking. | | M104 | {meth}`set_hotend_temperature(temperature) ` | Non-blocking. | | M141 | {meth}`set_chamber_temperature(temperature) ` | Non-blocking. | **Tips** * Temperature units controlled by {meth}`set_temperature_units() `. * Use `halt("wait-for-*")` methods to block until temperature reached. * Use {meth}`set_bounds() ` to prevent dangerous temperatures. **Examples** ```python set_bed_temperature(60) # M140 S60 set_hotend_temperature(200) # M104 S200 set_fan_speed(255) # M106 P0 S255 ``` ## 🎯 Motion Control | G-code | Gscrib | Notes | |--------|--------|-------| | G0 | {meth}`rapid(point) ` | Rapid move. | | G0 | {meth}`rapid_absolute(point) ` | Absolute rapid (ignore transforms). | | G1 | {meth}`move(point) ` | Linear move. | | G1 | {meth}`move_absolute(point) ` | Absolute linear (ignore transforms). | | G28 | {meth}`auto_home(point) ` | Homes axes. | **Tips** * Use {meth}`rapid() ` for positioning, {meth}`move() ` for cutting. * Bypass coordinate transforms with {meth}`rapid_absolute() `/{meth}`move_absolute() `. * Current position becomes unknown after {meth}`auto_home() ` if not specified. * The behaviour of {meth}`auto_home() ` may depend on the controller. **Examples** ```python rapid(z=5) # G0 Z5 rapid(x=10, y=5) # G0 X10 Y5 move(x=20, y=10, F=1500) # G1 X20 Y10 F1500 auto_home(x=0, y=0, z=0) # G28 X0 Y0 Z0 ``` ## 🌀 Path Interpolation | G-code | Gscrib | Notes | |--------|--------|-------| | G2/G3 (simulated) | {meth}`trace.arc(target, center) ` | Uses I/J/K-like geometry. | | G2/G3 (simulated) | {meth}`trace.arc_radius(target, radius) ` | Radius-mode arcs. | | — | {meth}`trace.circle(center) ` | Full circle. | | — | {meth}`trace.spline(points) ` | Cubic spline. | | — | {meth}`trace.helix(…) ` | Helical path. | | — | {meth}`trace.thread(…) ` | Thread-like helix. | | — | {meth}`trace.spiral(…) ` | Spiral pattern. | | — | {meth}`trace.polyline(points) ` | Linked G1 moves. | | — | {meth}`trace.parametric(fn, length) ` | Arbitrary parametric curve. | **Tips** * All arc/curve methods emit G1 segments; never G2/G3. * Interpolated paths ignore the active plane, use coordinate transforms instead. * Use {meth}`set_resolution() ` for smoother arcs/splines (smaller = smoother). * Use {meth}`set_direction() ` to control arc direction globally. **Examples** ```python set_resolution(0.1) # Fine resolution set_direction("cw") # Clockwise arcs trace.arc((10, 10), center=(5, 0)) # G2-like: X10 Y10 I5 J0 trace.arc_radius((20, 10), radius=30) # G2-like with R30 trace.circle(center=(0, 0), radius=5) # Full circle trace.spline([(0,0), (5,10), (10,0)]) # Smooth curve ``` ## 🧭 Coordinate Transforms | Gscrib | Notes | |--------|-------| | {meth}`transform.set_pivot(point) ` | Set rotation/scale center | | {meth}`transform.mirror(plane) ` | Mirror across plane | | {meth}`transform.reflect(normal) ` | Reflect across normal | | {meth}`transform.rotate(angle, axis) ` | Rotate in degrees | | {meth}`transform.scale(sx [,sy [,sz]]) ` | Scale factors | | {meth}`transform.translate(x, y, z) ` | Move origin | | {meth}`transform.save_state(name) ` | Save transform stack | | {meth}`transform.restore_state(name) ` | Restore saved state | | {meth}`transform.delete_state(name) ` | Delete saved state | **Tips** * Set pivot before rotating or scaling. * Use {meth}`current_transform() ` context manager for temporary changes. * Transforms stack like CAM operations, not G-code offsets. * Transforms affect all subsequent moves until changed. **Examples** ```python transform.save_state("original") # Save current state transform.translate(x=10, y=5) # Move coordinate system transform.set_pivot(point=(5, 5)) # Set rotation center transform.rotate(45, axis="z") # Rotate 45° move(x=10, y=0) # Move in rotated system transform.restore_state("original") # Back to start state ``` ## ⏱️ Timing & Synchronization | G/M-code | Gscrib | Notes | |----------|--------|-------| | G04 P… | {meth}`sleep(duration) ` | Dwell. | | M00 / M01 | {meth}`pause(optional) ` | Required/optional pause. | | M02 / M30 | {meth}`stop(reset) ` | End with/without reset. | | M400 | {meth}`wait() ` | Wait for motion to finish. | **Tips** * Time units controlled by {meth}`set_time_units() `. * Temperature units controlled by {meth}`set_temperature_units() `. **Examples** ```python wait() # M400 sleep(2) # G04 P2 ``` ## ⛔ Halt Operations | M-code | Gscrib | Notes | |--------|--------|-------| | M00 | {meth}`halt("pause") ` | Alias {meth}`pause() ` | | M01 | {meth}`halt("optional-pause") ` | Alias {meth}`pause(optional=True) ` | | M02 | {meth}`halt("end-without-reset") ` | Alias {meth}`stop() ` | | M30 | {meth}`halt("end-with-reset") ` | Alias {meth}`stop(reset=True) ` | | M60 | {meth}`halt("pallet-exchange") ` | Pallet exchange. | | M109 | {meth}`halt("wait-for-hotend") ` | Wait to reach temperature. | | M190 | {meth}`halt("wait-for-bed") ` | Wait to reach temperature. | | M191 | {meth}`halt("wait-for-chamber") ` | Wait to reach temperature. | **Tips** * Use the aliased methods unless you have a specific reason not to. * Use {meth}`emergency_halt() ` for a complete safety shutdown sequence. ## 📡 Probing | G-code | Gscrib | |--------|--------| | G38.2 | {meth}`probe("towards", point) ` | | G38.3 | {meth}`probe("towards-no-error", point) ` | | G38.4 | {meth}`probe("away", point) ` | | G38.5 | {meth}`probe("away-no-error", point) ` | **Tips** * Use slow feed rates for accurate probing. * Probe sets current position to unknown (actual stop depends on sensor). **Examples** ```python probe("towards", z=-10) # G38.2 Z-10 ``` ## 🔍 Queries & Status | M-code | Gscrib | |----------|--------| | M105 | {meth}`query("temperature") ` | | M114 | {meth}`query("position") ` | | ? | {meth}`write("?") ` | **Tips** * Only works in **direct write mode** with connected device. * Read sensor values with {meth}`writer.get_parameter() ` **Examples** ```python query("position") # M114 query("temperature") # M105 z = writer.get_parameter("Z") t = writer.get_parameter("B") ``` ## 📝 Comments & Annotations | G-code | Gscrib | Notes | |---|--------|-------| | ; comment | {meth}`comment("…") ` | Uses formatter syntax | | ; @set key=value | {meth}`annotate(key, value) ` | Structured annotation | **Tips** * Use {meth}`format.set_comment_symbols() ` to change comment style. * Annotations create machine-readable metadata. **Examples** ```python comment("Starting cut operation") # ; Starting cut operation comment(f"Feed rate: {feed_rate}") # ; Feed rate: 1500 annotate("tool", "1/4 inch endmill") # ; @set tool=1/4 inch endmill ``` ## ⚠️ Raw G-code | G-code | Gscrib | Notes | |--------|--------|-------| | Raw G-code | {meth}`write(statement) ` | Bypasses state tracking | **Tips** * Raw `write("G1 X…")` does not update internal position. * Prefer high-level methods to maintain state consistency. * Only use for unsupported commands or special cases.