Skip to content

Go Host: SET_SERVO timing alignment differs from Python #7

@AndySze

Description

@AndySze

SET_SERVO Timing Alignment Issue

Current State

Basic SET_SERVO command support has been added in commit 3040230, but there are timing differences compared to Python Klippy.

Problem Description

The Go implementation sends servo PWM commands immediately using toolhead.getLastMoveTime(), while Python uses a more sophisticated approach:

  1. GCodeRequestQueue pattern: Python's servo uses queue_gcode_request() which registers a lookahead callback to queue commands at the correct time in the motion pipeline.

  2. PWM cycle alignment: Python calls next_aligned_print_time() to align servo commands to PWM signal period boundaries (20ms cycle).

  3. Command coalescing: Python's GCodeRequestQueue coalesces/discards commands that are overridden before flush, sending only the final value at each time point.

Observed Differences in dual_carriage Test

Expected (Python):
queue_digital_out oid=14 clock=1386933333 on_ticks=20444
queue_digital_out oid=14 clock=1389173333 on_ticks=24889
queue_digital_out oid=14 clock=1396853333 on_ticks=27556

Actual (Go):
queue_digital_out oid=14 clock=1386568000 on_ticks=20444
queue_digital_out oid=14 clock=1388733333 on_ticks=24888
queue_digital_out oid=14 clock=1399432000 on_ticks=30222  # Extra command (not coalesced)
queue_digital_out oid=14 clock=1399432000 on_ticks=27555

Issues

  1. Clock times differ by ~365,333 ticks (~23ms at 16MHz)
  2. on_ticks values differ by 1 due to rounding (fixed with +0.5 rounding)
  3. Go outputs extra commands that Python coalesces away
  4. Servo OID is hardcoded to 14 (only works for dual_carriage config)

Proposed Fix

  1. Implement next_aligned_print_time() for PWM cycle alignment
  2. Implement GCodeRequestQueue pattern or equivalent for command coalescing
  3. Use proper lookahead callback integration for timing
  4. Make servo OID dynamic based on config parsing

Impact

  • Functional: Servo commands work, but timing may differ slightly
  • Golden tests: dual_carriage test has ~156 line differences (mostly related to servo timing)

Files Affected

  • go/pkg/hosth4/runtime.go: servoController implementation

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions