3dSynth

Tutorials / Custom G-code

Open in the interactive tutorials reader

---
title: Tutorial 42 Machine Physics Awareness
description: Treating the printer as a dynamic system.
---

Tutorial 42 Machine Physics Awareness

1. Lesson Header

2. Concept Introduction

The Printer is a Spring-Mass System.
The print head has mass (M). The belts are springs (K).
When you accelerate, the head lags behind. When you stop, it overshoots and oscillates (Ringing).
Solution: Input Shaping.
Instead of Move(A, B), we send Move(A, B) + Cancel_Signal.
We intentionally create a counter-vibration to cancel the natural resonance.

3. Machine State Explanation

Resonance Frequency.
Every printer has a natural frequency (e.g., 40Hz).
If you excite this frequency, ringing is maximized.
Input Shaping (ZV Shaper):
Send the move. Wait half a period (1/80 sec). Send a second, smaller move.
The two waves cancel out.

4. Command Breakdown

5. Minimal Working Example

The Manual Shaper.
Instead of one sharp corner:
G1 X100 F3000 (Stop abruptly).
We send two smaller moves:
G1 X99 F3000
G1 X100 F3000 (Tiny delay).
This spreads the energy over time.

6. Visual Representation

Interactive preview is available in the interactive reader.

7. Build Exercise

Task: Write a Python script to apply ZV Shaping to a G-code file.
1. Read G1 moves.
2. Calculate the time of each move.
3. Split each move into two components separated by dt = 1 / (2 * Frequency).
4. This is hard in pure G-code because timing is controlled by the firmware planner.
5. Alternative: Simulate the effect by changing acceleration dynamically.

Wait, we can't do true Input Shaping in G-code easily.
Firmware handles steps at microsecond precision. G-code is too coarse.
Better Exercise: Pressure Advance Simulation.
Modify G-code to add E pulses at corners to compensate for bowden elasticity.
E_current = E_target + K * Acceleration.
If accelerating, push extra E.
If decelerating, retract E.

8. Deep Insight Section

Klipper's Approach.
Klipper does this in software before sending step pulses.
It uses an accelerometer (ADXL345) to measure the resonance.
Then it convolves the entire motion plan with the shaper.

9. Common Failure Modes

  1. Over-smoothing: Shaping reduces acceleration. Corners get rounded if the shaper is too aggressive.
  2. Frequency Mismatch: If you tune for 40Hz but belt tension changes to 35Hz, the shaper makes ringing worse (constructive interference).

10. Real-World Application

High Speed Machining.
CNC mills use "Jerk Control" and "Lookahead" to smooth motion.
The same math applies to 3D printers running at 500mm/s.

11. Final Clean Version

The Pressure Advance Script:
This script adds manual PA to a file.

import math

filename = "pa_test.gcode"
K = 0.5 # PA Factor
last_f = 0
last_e = 0

with open(filename, 'r') as f:
    lines = f.readlines()

output = []
for line in lines:
    if "G1" in line and "E" in line:
        # Parse F and E
        # Calculate Acceleration (Assume constant from M204)
        accel = 1000 # mm/s^2
        
        # Calculate required pressure offset
        # P = K * (v_target - v_current)
        # This is hard without full lookahead.
        
        # Simple heuristic:
        # If F increases, add E push.
        # If F decreases, add E retract.
        
        parts = line.split()
        current_f = last_f
        current_e_move = 0
        
        for p in parts:
            if p.startswith("F"): current_f = float(p[1:])
            if p.startswith("E"): current_e_move = float(p[1:]) - last_e
            
        # Delta V (approx)
        dv = (current_f - last_f) / 60.0 # mm/s
        
        extra_e = K * dv * 0.01 # Scaling factor
        
        # We can't just add E to the move. We need a separate move?
        # M900 does this internally.
        # Manual G-code:
        # G1 E{extra_e} (Advance)
        # G1 ... (Move)
        # G1 E{-extra_e} (Retract)
        
        if abs(extra_e) > 0.01:
            output.append(f"G1 E{extra_e:.4f} F3000 ; PA Push\n")
            
        output.append(line)
        
        last_f = current_f
        last_e += current_e_move

# Save output

12. Stretch Challenge

Challenge: Write a script to calculate Belt Tension from a frequency audio file.
Record the sound of plucking the belt (like a guitar string).
Frequency = (1/2L) * sqrt(Tension / Mass_Density).
User inputs L (length) and Mass. Script outputs Tension (Newtons).
Hint: Use scipy.fft (Fast Fourier Transform) to find the peak frequency.