Checking in the pattern printing gcode

Also started cleaning up the video recording code so that it can work off the same parameters as the pa printing code.
This commit is contained in:
Mike Abbott 2023-03-29 22:19:52 -06:00
parent 2b44662261
commit 1658d54006
4 changed files with 79 additions and 37 deletions

View File

@ -56,11 +56,11 @@ def has_homed():
return result["status"]["toolhead"]["homed_axes"] == "xyz"
def do_initialization_routine():
# if not has_homed():
# print("Homing")
# home()
# print("Quad Gantry Level")
# send_gcode("QUAD_GANTRY_LEVEL")
if not has_homed():
print("Homing")
home()
print("Quad Gantry Level")
send_gcode("QUAD_GANTRY_LEVEL")
print("Rehoming Z")
send_gcode("G28 Z")

42
pa.py
View File

@ -1,17 +1,10 @@
import numpy as np
from pattern_info import PatternInfo
import klipper.gcode as g
# TODO: Populate all of these and place them in an appropriate file
CAMERA_OFFSET_X = 0
CAMERA_OFFSET_Y = 0
CAMERA_FOV_X = 0
CAMERA_FOV_Y = 0
BUILD_PLATE_TEMPERATURE = 110
HOTEND_TEMPERATURE = 255
def generate_pa_tune_gcode(start_value, stop_value, start_x, start_y, num_lines, line_length, spacing):
def generate_pa_tune_gcode(info: PatternInfo):
Z_HOP_HEIGHT = 0.75
LAYER_HEIGHT = 0.25
RETRACTION_DISTANCE = 0.5
@ -25,27 +18,31 @@ def generate_pa_tune_gcode(start_value, stop_value, start_x, start_y, num_lines,
G92 E0 ;
M106 S0 ; set fan speed to 0
G1 X{start_x} Y{start_y} F30000 ; move to start position
G1 X{info.start_x + info.line_length} Y{info.start_y} F30000 ; move to start position
G1 Z{LAYER_HEIGHT} F300 ; move to layer height
G91 ; switch to relative movements
; Print a bounding box to aid with removal and prime the extruder.
G1 Y{(num_lines + 1) * spacing} E{((num_lines + 1) * spacing) * EXTRUSION_DISTANCE_PER_MM} F3000;
G1 X{line_length} E{line_length * EXTRUSION_DISTANCE_PER_MM};
G1 Y{-(num_lines + 1) * spacing} E{((num_lines + 1) * spacing) * EXTRUSION_DISTANCE_PER_MM};
G1 Z{Z_HOP_HEIGHT} Y{-spacing} E{-RETRACTION_DISTANCE} F300; retract and prepare to hop to first line location.
G1 Y{info.num_lines * info.spacing} E{info.num_lines * info.spacing * EXTRUSION_DISTANCE_PER_MM} F3000;
G1 X{-info.line_length} E{info.line_length * EXTRUSION_DISTANCE_PER_MM};
G1 Y{-info.num_lines * info.spacing} E{info.num_lines * info.spacing * EXTRUSION_DISTANCE_PER_MM};
G1 X{info.line_length} E{info.line_length * EXTRUSION_DISTANCE_PER_MM};
G1 Z{Z_HOP_HEIGHT} Y{-info.spacing} E{-RETRACTION_DISTANCE} F300; retract and prepare to hop to first line location.
"""
for pa_value in np.linspace(start_value, stop_value, num_lines):
for pa_value in info.pa_values:
# TODO: parameterize the extrusion values based on the layer height
#
# TODO: the lines could be printed in alternating directions to
# eliminate the need for retractions and also decrease print time.
gcode += f"""
SET_PRESSURE_ADVANCE ADVANCE={pa_value} ; set Pressure Advance
M117 Testing Pressure Advance at: {pa_value}
G1 X-{line_length} Y{spacing} F30000 ; move to start position
G1 X-{info.line_length} Y{info.spacing} F30000 ; move to start position
G1 Z{-Z_HOP_HEIGHT} F300 ; move to layer height
G1 E{RETRACTION_DISTANCE} F1800 ; un-retract
G1 X{line_length / 4} E{(line_length / 4) * EXTRUSION_DISTANCE_PER_MM} F300 ; print line part one
G1 X{line_length / 2} E{(line_length / 2) * EXTRUSION_DISTANCE_PER_MM} F9000 ; print line part two
G1 X{line_length / 4} E{(line_length / 4) * EXTRUSION_DISTANCE_PER_MM} F300 ; print line part three
G1 X{info.line_length / 4} E{(info.line_length / 4) * EXTRUSION_DISTANCE_PER_MM} F300 ; print line part one
G1 X{info.line_length / 2} E{(info.line_length / 2) * EXTRUSION_DISTANCE_PER_MM} F9000 ; print line part two
G1 X{info.line_length / 4} E{(info.line_length / 4) * EXTRUSION_DISTANCE_PER_MM} F300 ; print line part three
G1 E{-RETRACTION_DISTANCE} F1800 ; retract
G1 Z{Z_HOP_HEIGHT} F300 ; Move above layer height
"""
@ -55,6 +52,9 @@ def generate_pa_tune_gcode(start_value, stop_value, start_x, start_y, num_lines,
return gcode
if __name__=="__main__":
# FIXME: this stuff times out when it takes too long for the printer to respond... not sure
# how to properly send commands and block until they're finished. Can I poll for the printer
# status?
g.do_initialization_routine()
g.send_gcode(f"""
M104 S180; preheat nozzle while waiting for build plate to get to temp
@ -66,8 +66,8 @@ if __name__=="__main__":
generate_pa_tune_gcode(
0, 0.1,
30, 30,
20,
40, 4
10,
30, 4
)
)

15
pattern_info.py Normal file
View File

@ -0,0 +1,15 @@
import numpy as np
class PatternInfo:
def __init__(self, start_value, stop_value, start_x, start_y, num_lines, line_length, spacing) -> None:
# TODO: honestly might be better to just have people pass in
# the values they want to test. It's more flexible that way.
self.pa_values = np.linspace(start_value, stop_value, num_lines)
self.start_x = start_x
self.start_y = start_y
self.line_length = line_length
self.spacing = spacing
def lines_start_y(self):
return [(x * self.spacing) + self.start_y for x in range(1, len(self.pa_values) + 1)]

View File

@ -1,7 +1,18 @@
from klipper.gcode import *
from pattern_info import PatternInfo
import numpy as np
import subprocess
import time
# TODO: Populate all of these.
CAMERA_OFFSET_X = 0
CAMERA_OFFSET_Y = 0
CAMERA_FOV_X = 0
CAMERA_FOV_Y = 0
LASER_FOCUS_HEIGHT = 17.86
ffmpeg_cmd = [
"ffmpeg",
"-f",
@ -16,26 +27,42 @@ ffmpeg_cmd = [
"/dev/video0",
]
# start at x=45, y=250, end at x=73 (leaving 8mm off the start and end for now)
def main():
send_gcode("STATUS_OFF")
send_gcode("LASER_ON")
move_absolute(40, 250, 17.86, 18000)
# TODO: make this return a list of files that are saved
# TODO: make this save to a unique folder each run (maybe this should be passed in?)
def record_pattern(info: PatternInfo, buffer_distance: float) -> list:
send_gcode("STATUS_OFF") # Turn off LEDs
send_gcode("LASER_ON") # Turn on line laser
y_values = np.ndarray(info.lines_start_y) + CAMERA_OFFSET_Y
scan_start_x = info.start_x + buffer_distance + CAMERA_OFFSET_X
scan_length = info.line_length - buffer_distance
time.sleep(2)
for i in range(20):
for index, y_value in enumerate(y_values):
move_absolute(scan_start_x, y_value, LASER_FOCUS_HEIGHT, 30000)
# start recording
# with open('') as f:
with subprocess.Popen(ffmpeg_cmd + [f"sample_data2/line{i}.mp4"]) as ffmpeg:
with subprocess.Popen(ffmpeg_cmd + [f"sample_data2/line{index}.mp4"]) as ffmpeg:
# move_relative(64, f=600)
time.sleep(0.5)
print(move_relative(34, f=600))
print(move_relative(scan_length, f=600))
# Total hack here... I need to not hardcode this.
# We should be able to compute this programatically relatively easily.
time.sleep(5)
ffmpeg.terminate()
time.sleep(0.5)
# stop recording
print(move_relative(-34, 4, f=18000))
# print(move_relative(-34, 4, f=18000))
time.sleep(1)
# start at x=45, y=250, end at x=73 (leaving 8mm off the start and end for now)
def main():
# record_pattern()
pass
if __name__=="__main__":
main()