mirror of
https://github.com/furrysalamander/rubedo.git
synced 2025-09-26 23:29:12 +08:00
Started work on generating report data
This commit is contained in:
parent
bc22aaa597
commit
9f60da8950
@ -3,3 +3,4 @@ FROM debian:bullseye-slim
|
|||||||
RUN apt-get update && apt-get install -y python3 python3-pip git ffmpeg
|
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 opencv-python-headless matplotlib aiohttp requests
|
||||||
RUN pip3 install websocket-client
|
RUN pip3 install websocket-client
|
||||||
|
RUN pip3 install scipy
|
||||||
|
@ -1,13 +1,19 @@
|
|||||||
{
|
{
|
||||||
"name": "rubedo",
|
"name": "rubedo",
|
||||||
"build": {
|
"build": {
|
||||||
"dockerfile":"Dockerfile",
|
"dockerfile": "Dockerfile",
|
||||||
"args": {
|
"args": {
|
||||||
"USERNAME": "vscode",
|
"USERNAME": "vscode",
|
||||||
"BUILDKIT_INLINE_CACHE": "0"
|
"BUILDKIT_INLINE_CACHE": "0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"runArgs": ["--device=/dev/video2"],
|
"runArgs": [
|
||||||
"extensions": ["ms-python.python", "076923.python-image-preview"]
|
"--device=/dev/video2"
|
||||||
|
],
|
||||||
|
"customizations": {
|
||||||
|
"extensions": [
|
||||||
|
"ms-python.python",
|
||||||
|
"076923.python-image-preview"
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,6 @@ OUTPUT_FRAMES = False
|
|||||||
OUTPUT_HEIGHT_MAPS = False
|
OUTPUT_HEIGHT_MAPS = False
|
||||||
|
|
||||||
CROP_X_OFFSET = 200
|
CROP_X_OFFSET = 200
|
||||||
CROP_Y_OFFSET = 20
|
CROP_Y_OFFSET = 0
|
||||||
CROP_FRAME_SIZE_X = 200
|
CROP_FRAME_SIZE_X = 200
|
||||||
CROP_FRAME_SIZE_Y = 60
|
CROP_FRAME_SIZE_Y = 60
|
||||||
|
58
generate_bulk_scans.py
Normal file
58
generate_bulk_scans.py
Normal 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
57
generate_report_data.py
Normal 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()
|
2
main.py
2
main.py
@ -50,7 +50,7 @@ def main():
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# g.send_gcode(PRINT_START)
|
g.send_gcode(PRINT_START)
|
||||||
g.send_gcode("CLEAN_NOZZLE")
|
g.send_gcode("CLEAN_NOZZLE")
|
||||||
g.send_gcode(generate_pa_tune_gcode(calibration_pattern))
|
g.send_gcode(generate_pa_tune_gcode(calibration_pattern))
|
||||||
g.wait_until_printer_at_location(FINISHED_X, FINISHED_Y)
|
g.wait_until_printer_at_location(FINISHED_X, FINISHED_Y)
|
||||||
|
4
pa.py
4
pa.py
@ -73,13 +73,13 @@ def generate_pa_tune_gcode(info: PatternInfo, finished_printing=True):
|
|||||||
G1 Z{Z_HOP_HEIGHT} F300 ; Move above layer height
|
G1 Z{Z_HOP_HEIGHT} F300 ; Move above layer height
|
||||||
"""
|
"""
|
||||||
gcode += """
|
gcode += """
|
||||||
G1 Z20; move up 20mm
|
G1 Z5; move up 1mm
|
||||||
M117
|
M117
|
||||||
"""
|
"""
|
||||||
if finished_printing:
|
if finished_printing:
|
||||||
gcode += f"""
|
gcode += f"""
|
||||||
G90; switch back to absolute coordinates
|
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)
|
# print(gcode)
|
||||||
return gcode
|
return gcode
|
||||||
|
@ -5,3 +5,6 @@ class PaResult:
|
|||||||
self.video_file = video_file
|
self.video_file = video_file
|
||||||
self.height_data = height_data
|
self.height_data = height_data
|
||||||
self.score = score
|
self.score = score
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.score}"
|
||||||
|
@ -35,6 +35,7 @@ ffmpeg_cmd = [
|
|||||||
def record_pattern(info: PatternInfo, buffer_distance: float, output_directory: str) -> list:
|
def record_pattern(info: PatternInfo, buffer_distance: float, output_directory: str) -> list:
|
||||||
send_gcode("STATUS_OFF") # Turn off LEDs
|
send_gcode("STATUS_OFF") # Turn off LEDs
|
||||||
send_gcode("LASER_ON") # Turn on line laser
|
send_gcode("LASER_ON") # Turn on line laser
|
||||||
|
send_gcode("SET_LED LED=chamber_lights WHITE=0.01")
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
|
|
||||||
lines_start_y = info.lines_start_y()
|
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)
|
time.sleep(0.6)
|
||||||
|
|
||||||
send_gcode("LASER_OFF")
|
send_gcode("LASER_OFF")
|
||||||
|
send_gcode("SET_LED LED=chamber_lights WHITE=1")
|
||||||
return video_files
|
return video_files
|
||||||
|
|
||||||
|
29
results.py
Normal file
29
results.py
Normal 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))
|
@ -1,4 +1,4 @@
|
|||||||
import cv2
|
# import cv2
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
from pa_result import PaResult
|
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):
|
def graph_frame(pixel_values: np.ndarray, output_file: str):
|
||||||
# fig.
|
# fig.
|
||||||
return
|
return
|
||||||
@ -30,7 +60,6 @@ def graph_frame(pixel_values: np.ndarray, output_file: str):
|
|||||||
return
|
return
|
||||||
|
|
||||||
def graph_height_map(z_data: np.ndarray, output_file: str):
|
def graph_height_map(z_data: np.ndarray, output_file: str):
|
||||||
# fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
|
|
||||||
fig, ax = plt.subplots()
|
fig, ax = plt.subplots()
|
||||||
|
|
||||||
# points = []
|
# 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)
|
cv2.imwrite(f"frame_data/{Path(video_file).stem}-{frame_index}.png", frame)
|
||||||
|
|
||||||
|
|
||||||
fig = plt.figure()
|
# fig = plt.figure()
|
||||||
from matplotlib.animation import FFMpegWriter
|
# from matplotlib.animation import FFMpegWriter
|
||||||
writer = FFMpegWriter(fps=30)
|
# writer = FFMpegWriter(fps=30)
|
||||||
plt.ylim([0, 200])
|
# plt.ylim([0, 200])
|
||||||
l = None
|
# l = None
|
||||||
|
Loading…
Reference in New Issue
Block a user