Started work on generating report data

This commit is contained in:
Mike Abbott 2023-04-13 20:31:13 -06:00
parent bc22aaa597
commit 9f60da8950
11 changed files with 201 additions and 16 deletions

View File

@ -3,3 +3,4 @@ FROM debian:bullseye-slim
RUN apt-get update && apt-get install -y python3 python3-pip git ffmpeg
RUN pip3 install opencv-python-headless matplotlib aiohttp requests
RUN pip3 install websocket-client
RUN pip3 install scipy

View File

@ -1,13 +1,19 @@
{
"name": "rubedo",
"build": {
"dockerfile":"Dockerfile",
"dockerfile": "Dockerfile",
"args": {
"USERNAME": "vscode",
"BUILDKIT_INLINE_CACHE": "0"
}
},
"runArgs": ["--device=/dev/video2"],
"extensions": ["ms-python.python", "076923.python-image-preview"]
"runArgs": [
"--device=/dev/video2"
],
"customizations": {
"extensions": [
"ms-python.python",
"076923.python-image-preview"
]
}
}

View File

@ -3,6 +3,6 @@ OUTPUT_FRAMES = False
OUTPUT_HEIGHT_MAPS = False
CROP_X_OFFSET = 200
CROP_Y_OFFSET = 20
CROP_Y_OFFSET = 0
CROP_FRAME_SIZE_X = 200
CROP_FRAME_SIZE_Y = 60

58
generate_bulk_scans.py Normal file
View File

@ -0,0 +1,58 @@
from pprint import pprint
import klipper.gcode as g
from main import generate_pa_results_for_pattern, PRINT_START
from pa import *
from pa_result import PaResult
import pickle
def main():
patterns: list[PatternInfo] = []
for x in range(20, 286, 31):
for y in range(20, 130, 45):
patterns.append(
PatternInfo(
0, 0.06,
x, y,
10,
30, 4
))
# g.send_gcode(PRINT_START)
# g.send_gcode("M109 S255")
# g.send_gcode("CLEAN_NOZZLE")
# for pattern in patterns:
# g.send_gcode(generate_pa_tune_gcode(pattern, False))
# g.send_gcode("G90;")
# g.send_gcode(f"G1 X{FINISHED_X} Y{FINISHED_Y} F30000")
# g.wait_until_printer_at_location(FINISHED_X, FINISHED_Y)
# g.send_gcode("M104 S0; let the hotend cool")
pa_scans: list[PaResult] = []
for pattern in patterns:
pa_scans.extend(
zip(pattern.pa_values,
generate_pa_results_for_pattern(
pattern
))
)
break
with open("testing_adjustments.pkl", "wb") as f:
pickle.dump(pa_scans, f)
# results = generate_pa_results_for_pattern(calibration_pattern)
# sorted_results = list(sorted(zip(results, calibration_pattern.pa_values), key=lambda x: x[0].score))
# sorted_results = list([(x.score, y) for x, y in sorted_results])
# best_pa_value = sorted_results[0][1]
# print()
# pprint(sorted_results)
# print()
# print(f"Recommended PA Value: {best_pa_value}, with a score of {sorted_results[0][0]}")
# print()
# g.send_gcode(f"SET_PRESSURE_ADVANCE ADVANCE={best_pa_value}")
if __name__=="__main__":
main()

57
generate_report_data.py Normal file
View File

@ -0,0 +1,57 @@
import pickle
import matplotlib.pyplot as plt
from pprint import pprint
import numpy as np
from pa_result import PaResult
with open("testing_adjustments.pkl", "rb") as f:
data: list[PaResult] = pickle.load(f)
pa_values = list([x[0] for x in data[:10]])
data_clean = list([(x, y.score) for x, y in data])
pprint(list(sorted(data_clean, key=lambda x: x[1])))
x, y = list(zip(*data_clean))
p = np.polyfit(x, y, 3)
plt.plot(pa_values, np.poly1d(p)(pa_values))
plt.scatter(x, y)
plt.plot(pa_values, np.poly1d(p)(pa_values))
from matplotlib.colors import LinearSegmentedColormap
from scipy.stats import gaussian_kde
from collections import Counter
# Calculate the point density
# xy = np.vstack([x,y])
# z = gaussian_kde(xy)(xy)
# fig, ax = plt.subplots()
# ax.set_xlabel("PA Value")
# ax.set_ylabel("Score")
# ax.scatter(x, y, c=z, s=100)
# ax.plot(pa_values, np.poly1d(p)(pa_values))
winning_results = []
for i in range(0, len(data_clean), 10):
x = i
individual_scan = list(sorted(data_clean[x:x+10], key=lambda x: x[1]))
pprint(individual_scan[0])
winning_results.append(individual_scan[0][0])
# pprint(data_clean[x:x+10])
counter = Counter(winning_results)
print(counter)
fig, ax = plt.subplots()
ax.set_ylabel("Winning Frequency")
ax.set_xlabel("PA Value")
ax.bar(counter.keys(), counter.values(), width=0.06/10)
from visualization import generate_color_map, generate_3d_height_map
generate_color_map(data[3][1])
generate_3d_height_map(data[3][1])
plt.show()

View File

@ -50,7 +50,7 @@ def main():
)
# g.send_gcode(PRINT_START)
g.send_gcode(PRINT_START)
g.send_gcode("CLEAN_NOZZLE")
g.send_gcode(generate_pa_tune_gcode(calibration_pattern))
g.wait_until_printer_at_location(FINISHED_X, FINISHED_Y)

4
pa.py
View File

@ -73,13 +73,13 @@ def generate_pa_tune_gcode(info: PatternInfo, finished_printing=True):
G1 Z{Z_HOP_HEIGHT} F300 ; Move above layer height
"""
gcode += """
G1 Z20; move up 20mm
G1 Z5; move up 1mm
M117
"""
if finished_printing:
gcode += f"""
G90; switch back to absolute coordinates
G1 X{FINISHED_X} Y{FINISHED_Y} F30000;
G1 X{FINISHED_X} Y{FINISHED_Y} Z20 F30000;
"""
# print(gcode)
return gcode

View File

@ -5,3 +5,6 @@ class PaResult:
self.video_file = video_file
self.height_data = height_data
self.score = score
def __str__(self):
return f"{self.score}"

View File

@ -35,6 +35,7 @@ ffmpeg_cmd = [
def record_pattern(info: PatternInfo, buffer_distance: float, output_directory: str) -> list:
send_gcode("STATUS_OFF") # Turn off LEDs
send_gcode("LASER_ON") # Turn on line laser
send_gcode("SET_LED LED=chamber_lights WHITE=0.01")
time.sleep(0.5)
lines_start_y = info.lines_start_y()
@ -64,5 +65,6 @@ def record_pattern(info: PatternInfo, buffer_distance: float, output_directory:
time.sleep(0.6)
send_gcode("LASER_OFF")
send_gcode("SET_LED LED=chamber_lights WHITE=1")
return video_files

29
results.py Normal file
View File

@ -0,0 +1,29 @@
import numpy as np
control = \
[186.56256372513926,
236.4280909963605,
194.8965990884127,
186.02849956667927,
201.05698347607975,
201.70169943918023,
195.83328724309604,
236.14796974386718,
224.61775628475698,
443.5180396174067
]
print("Average deviation of lines in control pattern")
print(np.average(control))
calibrated = \
[
35.745380947164946,
42.096965823872175,
45.43428879223724,
41.415640249952666,
52.08084270611824,
50.53732451711894,
44.22630732805901,
42.33189729658413,
52.967477038659496
]
print("Average deviation of lines in calibrated pattern")
print(np.average(calibrated))

View File

@ -1,4 +1,4 @@
import cv2
# import cv2
import numpy as np
import matplotlib.pyplot as plt
from pa_result import PaResult
@ -14,6 +14,36 @@ from constants import *
#
#
def generate_color_map(pa_result: PaResult):
fig, ax = plt.subplots()
y = np.arange(len(pa_result.height_data))
x = np.arange(len(pa_result.height_data[0]))
(x ,y) = np.meshgrid(x,y)
# ax.plot_surface(x, y, z_data,cmap=cm.coolwarm,linewidth=0, antialiased=False)
ax.pcolormesh(x, y, pa_result.height_data, cmap='RdBu')
# ax.scatter(x, y, z)
return fig
def generate_cross_section_video():
pass
def generate_cross_sections():
pass
def generate_3d_height_map(pa_result: PaResult):
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
y = np.arange(len(pa_result.height_data))
x = np.arange(len(pa_result.height_data[0]))
(x ,y) = np.meshgrid(x,y)
ax.plot_surface(x, y, pa_result.height_data, cmap="RdBu")
ax.set_zlim3d(60, 100)
return fig
def graph_frame(pixel_values: np.ndarray, output_file: str):
# fig.
return
@ -30,7 +60,6 @@ def graph_frame(pixel_values: np.ndarray, output_file: str):
return
def graph_height_map(z_data: np.ndarray, output_file: str):
# fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
fig, ax = plt.subplots()
# points = []
@ -59,8 +88,8 @@ def generate_frames_from_heightmap(pa_data: PaResult):
cv2.imwrite(f"frame_data/{Path(video_file).stem}-{frame_index}.png", frame)
fig = plt.figure()
from matplotlib.animation import FFMpegWriter
writer = FFMpegWriter(fps=30)
plt.ylim([0, 200])
l = None
# fig = plt.figure()
# from matplotlib.animation import FFMpegWriter
# writer = FFMpegWriter(fps=30)
# plt.ylim([0, 200])
# l = None