Compare commits

..

7 Commits

Author SHA1 Message Date
Eduard Gerlitz
75689925d0 . 2025-03-12 14:52:26 +01:00
Eduard Gerlitz
f0cf8c40d9 . 2025-03-12 14:44:01 +01:00
Eduard Gerlitz
10a0e86caf v2 - Finalizing and short testing 2025-03-12 14:37:23 +01:00
Eduard Gerlitz
261e3b4929 adapt funct_wp.py 2025-03-12 11:58:48 +01:00
Eduard Gerlitz
b607afcd86 . 2025-03-11 16:00:41 +01:00
Eduard Gerlitz
377fb1422f . 2025-03-11 15:06:20 +01:00
Eduard Gerlitz
635d8e29e9 devl_v3 2025-03-11 14:02:57 +01:00
42 changed files with 551 additions and 572 deletions

5
.gitignore vendored
View File

@ -1,5 +1,6 @@
/.idea /.idea
/__pycache__/ /__pycache__/
*ARCHIV* *ARCHIV*
*BAK* *BACKUP*
*BACKUP* out
cfg_inlay_PUTx.xlsx

47
BAK/241031_def.yml Normal file
View File

@ -0,0 +1,47 @@
general:
yolovar: int
initpic_name: puppy.png
groups:
inlay:
parameter:
x_num: int
x_offset: double
y_num: int
y_offset: double
kos: str
cfg:
picture_name: img_inlay.png
wp_raw:
parameter:
x_wpraw: double
y_wpraw: double
z_wpraw: double
h_grp_wpraw: double
cfg:
picture_name: img_wpraw.png
wp_fin:
parameter:
x_wpfin: double
y_wpfin: double
z_wpfin: double
l_wpfin: double
h_grp_wpfin: double
cfg:
picture_name: img_wpfin.png
clp:
parameter:
clp_offset: double
y_prb_floor1: double
z_prb_floor1: double
y_prb_floor2: double
z_prb_floor2: double
x_prb_backen: double
z_prb_backen: double
l_prb_backen: double
y_prb_seite: double
z_prb_seite: double
cfg:
picture_name: img_clp.png

View File

@ -7,7 +7,7 @@ $scriptPath = "./MAIN.py"
$username = [System.Environment]::UserName $username = [System.Environment]::UserName
# Construct the path to the Python executable # Construct the path to the Python executable
$pythonExe = "C:\Users\$username\AppData\Local\miniconda3\envs\$venvName\python.exe" $pythonExe = "C:\Users\user58\.conda\envs\$venvName\python.exe"
# Execute the Python script # Execute the Python script
& $pythonExe $scriptPath & $pythonExe $scriptPath

21
MAIN.py
View File

@ -1,5 +1,4 @@
# main.py # main.py
from functions import * from functions import *
from funct_inlay import * from funct_inlay import *
from funct_wp import * from funct_wp import *
@ -34,7 +33,7 @@ def setup_group(frame, group_name, data, input_vars, selected_params, group_widg
param_var = selected_params[group_name] # Bind the dropdown to the corresponding selected_param entry param_var = selected_params[group_name] # Bind the dropdown to the corresponding selected_param entry
param_dropdown = ttk.Combobox(frame, textvariable=param_var, values=param_values) param_dropdown = ttk.Combobox(frame, textvariable=param_var, values=param_values)
group_widgets[group_name] = {"param_dropdown": param_dropdown} # Save for later reference group_widgets[group_name] = {"param_dropdown": param_dropdown} # Save for later reference
source_path = f"{folder_pictures}/{data['general']['initpic_name']}" source_path = f"{folder_pictures}/{data['general']['notavailablepic_name']}"
# Handle missing picture case # Handle missing picture case
if not os.path.exists(picture_path): if not os.path.exists(picture_path):
@ -55,10 +54,8 @@ def setup_group(frame, group_name, data, input_vars, selected_params, group_widg
picture_to_use = picture_path picture_to_use = picture_path
if grpnm == "inlay": if grpnm == "inlay":
generate_picture_inlay(all_group_vars, picture_to_use) generate_picture_inlay(all_group_vars, picture_to_use)
elif grpnm == "wp_raw": elif grpnm == "wp":
generate_picture_wpraw(all_group_vars, picture_to_use) generate_picture_wp(all_group_vars, picture_to_use)
elif grpnm == "wp_fin":
generate_picture_wpfin(all_group_vars, picture_to_use)
elif grpnm == "grp": elif grpnm == "grp":
generate_picture_grp(all_group_vars, picture_to_use) generate_picture_grp(all_group_vars, picture_to_use)
elif grpnm == "clp": elif grpnm == "clp":
@ -275,7 +272,7 @@ def setup_evaluation(root, folder_pictures, data, folder_output, input_vars, sel
frame.grid(row=2, column=0, columnspan=5, padx=10, pady=10, sticky="nsew") frame.grid(row=2, column=0, columnspan=5, padx=10, pady=10, sticky="nsew")
# Load and display the specific initial picture # Load and display the specific initial picture
picture_path = f"{folder_pictures}/{data['general']['initpic_name']}" picture_path = f"{folder_pictures}/{data['general']['generatorpic_name']}"
group_image_tk = load_image(picture_path, 200) # Assuming a function load_image exists and works as expected group_image_tk = load_image(picture_path, 200) # Assuming a function load_image exists and works as expected
image_label = ttk.Label(frame, image=group_image_tk) image_label = ttk.Label(frame, image=group_image_tk)
image_label.image = group_image_tk # Keep a reference to avoid garbage collection image_label.image = group_image_tk # Keep a reference to avoid garbage collection
@ -284,12 +281,20 @@ def setup_evaluation(root, folder_pictures, data, folder_output, input_vars, sel
# Function to generate configuration file based on current parameters # Function to generate configuration file based on current parameters
def btn_gen(): def btn_gen():
generate_config_spf(folder_output, input_vars, selected_params) generate_config_spf(folder_output, input_vars, selected_params)
def btn_gen_custom1():
generate_config_spf_custom1(folder_output, input_vars, selected_params)
def btn_gen_custom2():
generate_config_spf_custom1(folder_output, input_vars, selected_params, filetransfer=True)
# Place buttons in the vertical frame for operations # Place buttons in the vertical frame for operations
button_frame = ttk.Frame(frame) button_frame = ttk.Frame(frame)
button_frame.grid(row=0, column=1, padx=10, pady=10, sticky="n") button_frame.grid(row=0, column=1, padx=10, pady=10, sticky="n")
button1 = ttk.Button(button_frame, text="GENERATE DMUAUT_CFG.SPF FILE", width=45, command=btn_gen) button1 = ttk.Button(button_frame, text="GEN CFG_DMUAUT.SPF FILE", width=45, command=btn_gen)
button1.grid(row=0, column=0, padx=10, pady=5) button1.grid(row=0, column=0, padx=10, pady=5)
button2 = ttk.Button(button_frame, text="GEN CFG_INLAY.SPF FILE", width=45, command=btn_gen_custom1)
button2.grid(row=1, column=0, padx=5, pady=5)
button3 = ttk.Button(button_frame, text="GEN+TRANSFER CFG_INLAY.SPF FILE", width=45, command=btn_gen_custom2)
button3.grid(row=1, column=1, padx=5, pady=5)
root.grid_columnconfigure(0, weight=1) root.grid_columnconfigure(0, weight=1)

View File

@ -1 +1,29 @@
v1.3 # README
## Beschreibung
Diese GUI dient zur Erfassung verschiedener Parameter für die Maschinenautomatisierung mittels Roboterbestückung.
## Funktionen
- Erfassung von Parametern für:
- **Inlay**
- **Werkstück Roh- und Fertigmaße (WP Raw & Finish)**
- **Schraubstock**
- Verwaltung von Parameter-Sets und Jobs
- Erstellung einer ausführbaren G-Code-Datei mit allen erfassten Parametern
- Möglichkeit zur direkten Übertragung der G-Code-Datei auf die Steuerung
## Verwendung
1. Parameter eingeben oder bestehende Sets laden
2. Parameter-Sets speichern oder löschen
3. Job auswählen oder erstellen
4. G-Code-Datei generieren und optional auf die Steuerung übertragen
---
# CHANGELOG
v2
- Beschränkung nur auf Inlay, Werkstück, Schraubstock
- neue Parameter definiert und Abhängigkeit implementiert
- Generator für die Visualisierung komplett überarbeitet
- neue Platzhalter-Bilder

View File

@ -7,4 +7,10 @@ dependencies:
- pyyaml - pyyaml
- jsonschema - jsonschema
- tk - tk
- pillow - pillow
- pandas
- openpyxl
- paramiko
- matplotlib
- trimesh
- manifold3d

View File

@ -1,4 +1,9 @@
clp1: clp1:
clp_offset: '0' CLP_AUFLAGETIEFE: '3'
clp2: CLP_BACKENHOHE: '30'
clp_offset: '0' CLP_BACKENWEITE: '30'
CLP_SPANNHOHE: '5'
MESSPOS_TOL: '0'
MESSPOS_X: '0'
MESSPOS_Y: '0'
MESSPOS_Z: '0'

View File

@ -1,28 +0,0 @@
grp1:
h_offset: '30'
h_step: '10'
hub: '50'
steps_num: '5'
w_offset: '40'
w_step: '45'
grp2:
h_offset: '30'
h_step: '5'
hub: '10'
steps_num: '6'
w_offset: '20'
w_step: '10'
grp3:
h_offset: '10'
h_step: '25'
hub: '10'
steps_num: '5'
w_offset: '25'
w_step: '45'
newset:
h_offset: '10'
h_step: '25'
hub: '10'
steps_num: '5'
w_offset: '25'
w_step: '45'

View File

@ -1,12 +1,10 @@
inlay7: <<new par set>>:
kos: '4' INL_X_NUM: '10'
x_num: '4' INL_X_OFFSET: '50'
x_offset: '30' INL_Y_NUM: '10'
y_num: '3' INL_Y_OFFSET: '50'
y_offset: '30' inlay1:
inlay_kleinteil: INL_X_NUM: '10'
kos: '4' INL_X_OFFSET: '10'
x_num: '7' INL_Y_NUM: '10'
x_offset: '5' INL_Y_OFFSET: '10'
y_num: '4'
y_offset: '4'

View File

@ -1,7 +1,6 @@
job1: job1:
clp: clp1 clp: clp1
grp: grp1 inlay: inlay1
inlay: inlay7
wp_fin: wpfin1 wp_fin: wpfin1
wp_raw: wpraw1 wp_raw: wpraw1
job3: job3:

9
cfg_parsets/wp.yml Normal file
View File

@ -0,0 +1,9 @@
wp1:
WPF_X: '15'
WPF_Y: '20'
WPF_Z: '15'
WPR_X: '20'
WPR_Y: '20'
WPR_Z: '20'
WP_CLP_OFFSET_X: '5'
WP_GRP_OFFSET_Z: '5'

View File

@ -1,5 +0,0 @@
wpfin1:
l_wpfin: '8'
x_wpfin: '20'
y_wpfin: '10'
z_wpfin: '13'

View File

@ -1,8 +0,0 @@
test:
x_wpraw: '20'
y_wpraw: '10'
z_wpraw: '20'
wpraw1:
x_wpraw: '10'
y_wpraw: '10'
z_wpraw: '20'

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

BIN
cfg_picture/dog_progr.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 93 KiB

BIN
cfg_picture/img_wp.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 155 KiB

54
def.yml
View File

@ -1,44 +1,38 @@
general: general:
yolovar: int yolovar: int
initpic_name: puppy.png notavailablepic_name: cat_wondering.png
generatorpic_name: dog_progr.png
groups: groups:
inlay: inlay:
parameter: parameter:
x_num: int INL_X_NUM: int
x_offset: double INL_X_OFFSET: double
y_num: int INL_Y_NUM: int
y_offset: double INL_Y_OFFSET: double
kos: str
cfg: cfg:
picture_name: img_inlay.png picture_name: img_inlay.png
wp_raw: wp:
parameter: parameter:
x_wpraw: double WPR_X: double
y_wpraw: double WPR_Y: double
z_wpraw: double WPR_Z: double
WPF_X: double
WPF_Y: double
WPF_Z: double
WP_CLP_OFFSET_X: double
WP_GRP_OFFSET_Z: double
cfg: cfg:
picture_name: img_wpraw.png picture_name: img_wp.png
wp_fin:
parameter:
x_wpfin: double
y_wpfin: double
z_wpfin: double
l_wpfin: double
cfg:
picture_name: img_wpfin.png
grp:
parameter:
hub: double
h_offset: double
h_step: double
w_offset: double
w_step: double
steps_num: int
cfg:
picture_name: img_grp.png
clp: clp:
parameter: parameter:
clp_offset: double CLP_BACKENWEITE: double
CLP_BACKENHOHE: double
CLP_SPANNHOHE: double
CLP_AUFLAGETIEFE: double
MESSPOS_X: double
MESSPOS_Y: double
MESSPOS_Z: double
MESSPOS_TOL: double
cfg: cfg:
picture_name: img_clp.png picture_name: img_clp.png

View File

@ -1,130 +1,116 @@
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.art3d import Poly3DCollection from functions import *
import numpy as np
def generate_picture_clp(all_group_vars, picture_path, DEBUG=False): def generate_picture_clp(all_group_vars, picture_path, DEBUG=False):
try: vars = all_group_vars['clp']
# Get x_wpraw, y_wpraw, and z_wpraw values CLP_BACKENWEITE, CLP_BACKENHOHE, CLP_SPANNHOHE, CLP_AUFLAGETIEFE = (float(vars[k]) for k in
vars = all_group_vars['wp_raw'] ['CLP_BACKENWEITE', 'CLP_BACKENHOHE',
x_wpraw = float(vars['x_wpraw']) 'CLP_SPANNHOHE', 'CLP_AUFLAGETIEFE'])
y_wpraw = float(vars['y_wpraw'])
z_wpraw = float(vars['z_wpraw'])
x_cube = x_wpraw*2
y_cube = y_wpraw*2
z_cube = z_wpraw
clp_offset = float(all_group_vars['clp']['clp_offset'])
# ERROR HANDLING WPR_X = CLP_BACKENWEITE/2
if x_cube <= 0 or y_cube <= 0 or z_cube <= 0: WPR_Y = CLP_BACKENWEITE/2
raise ValueError("x_wpraw, y_wpraw, and z_wpraw must be positive values.") WPR_Z = CLP_SPANNHOHE * 5
# Define the vertices of the cube based on wpraw dimensions if min(WPR_X, WPR_Y, WPR_Z) <= 0:
vertices = (np.array([[0, 0, 0], [x_cube, 0, 0], [x_cube, y_cube, 0], [0, y_cube, 0], raise ValueError("Dimensions must be positive.")
[0, 0, z_cube], [x_cube, 0, z_cube], [x_cube, y_cube, z_cube], [0, y_cube, z_cube]])
+ np.array([0, -clp_offset, 0]))
# Define the 6 faces of the cube fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
faces = [[vertices[j] for j in [0, 1, 2, 3]], # Bottom face
[vertices[j] for j in [4, 5, 6, 7]], # Top face
[vertices[j] for j in [0, 3, 7, 4]], # Left face
[vertices[j] for j in [1, 2, 6, 5]], # Right face
[vertices[j] for j in [0, 1, 5, 4]], # Front face
[vertices[j] for j in [2, 3, 7, 6]]] # Back face
# Plot the cube in 3D # Define raw workpiece dimensions
fig = plt.figure() x_cube, y_cube, z_cube = 2 * WPR_X, 2 * WPR_Y, WPR_Z
ax = fig.add_subplot(111, projection='3d') vertices_raw = np.array([[0, 0, 0], [x_cube, 0, 0], [x_cube, y_cube, 0], [0, y_cube, 0],
[0, 0, WPR_Z], [x_cube, 0, WPR_Z], [x_cube, y_cube, WPR_Z], [0, y_cube, WPR_Z]])
faces_raw = [vertices_raw[[0, 1, 2, 3]], vertices_raw[[4, 5, 6, 7]], vertices_raw[[0, 3, 7, 4]],
vertices_raw[[1, 2, 6, 5]], vertices_raw[[0, 1, 5, 4]], vertices_raw[[2, 3, 7, 6]]]
# Plot the cube with the specified faces # Set axis properties
ax.add_collection3d(Poly3DCollection(faces, facecolors='k', linewidths=1, edgecolors='k', alpha=.15)) ax.set_box_aspect([x_cube, y_cube, z_cube])
ax.set(xticks=[], yticks=[], zticks=[])
# Set the aspect ratio for each axis # Draw WP coordinate system
ax.set_box_aspect([x_cube, y_cube, z_cube]) axis_len = max(x_cube, y_cube, z_cube) * 0.2
colors = ['r', 'g', 'b']
origin_x = 0
origin_y = 0
origin_z = 0
for i, vec in enumerate(np.eye(3)):
ax.quiver(origin_x, origin_y, origin_z, *(axis_len * vec), color=colors[i], linewidth=3)
ax.text(origin_x, origin_y, origin_z - axis_len * 0.3, 'WP', color='black', fontsize=9, weight='bold', ha='center',
va='top')
# Hide the axis ticks and labels # Draw WP
ax.set_xticks([]) # Hide X axis ticks ax.add_collection3d(Poly3DCollection(faces_raw, facecolors='k', linewidths=1, edgecolors='k', alpha=.15))
ax.set_yticks([]) # Hide Y axis ticks
ax.set_zticks([]) # Hide Z axis ticks
# Add a ball (sphere) at the center of the cube # Draw CLP coordinate system
ball_radius = min(x_wpraw, y_wpraw, z_wpraw) * 0.1 # Size relative to cube dimensions axis_len = max(x_cube, y_cube, z_cube) * 0.15
colors = ['r', 'g', 'b']
origin_x = WPR_X
origin_y = WPR_Y
origin_z = 0
for i, vec in enumerate(np.eye(3)):
ax.quiver(origin_x, origin_y, origin_z, *(axis_len * vec), color=colors[i], linewidth=3)
ax.text(origin_x, origin_y, origin_z - axis_len * 0.3, 'CLP', color='blue', fontsize=9, weight='bold', ha='center',
va='top')
u = np.linspace(0, 2 * np.pi, 20) # Define clamping block dimensions
v = np.linspace(0, np.pi, 20) clp_deep = y_cube * 0.3
x_sphere = x_wpraw + ball_radius * np.outer(np.cos(u), np.sin(v)) base_x = WPR_X - CLP_BACKENWEITE / 2
y_sphere = y_wpraw - clp_offset + ball_radius * np.outer(np.sin(u), np.sin(v)) alpha = 0.35
z_sphere = z_wpraw + ball_radius * np.outer(np.ones(np.size(u)), np.cos(v)) color = 'blue'
ax.plot_surface(x_sphere, y_sphere, z_sphere, color='red', alpha=1) linewidth = 1
# Add the origin sparrow (a small 3D marker at the origin) # Draw clamping blocks
max_size = max(x_cube, y_cube, z_cube) * 0.2 # Scale the arrows relative to the smallest dimension x = base_x
ax.quiver(0, -clp_offset, 0, max_size, 0, 0, color='red', linewidth=2, label='X-axis') # Red arrow for X-axis dx = CLP_BACKENWEITE
ax.quiver(0, -clp_offset, 0, 0, max_size, 0, color='green', linewidth=2, label='Y-axis') # Green arrow for Y-axis y = 0
ax.quiver(0, -clp_offset, 0, 0, 0, max_size, color='blue', linewidth=2, label='Z-axis') # Blue arrow for Z-axis dy1 = clp_deep
dy2 = CLP_AUFLAGETIEFE
z = 0
dz1 = CLP_SPANNHOHE
dz2 = CLP_BACKENHOHE
plot_clamping(ax, x, y, z, dx, dy1, dy2, dz1, dz2, color=color,
alpha=alpha, linewidth=linewidth)
y = y_cube
plot_clamping(ax, x, y, z, dx, dy1, dy2, dz1, dz2, color=color,
alpha=alpha, linewidth=linewidth, inverty=True)
# Add two black blocks (greifer fingers) on the Y-faces in the middle of the cube height # Draw text for geometry values
max_size2 = max(x_cube, y_cube, z_cube) * 0.4 # Scale the arrows relative to the smallest dimension ax.text(0, 2*WPR_Y+clp_deep, CLP_SPANNHOHE/2, f'{CLP_SPANNHOHE}mm', color='blue', fontsize=9, weight='bold', ha='right', va='center')
ax.bar3d(-max_size2, -(2.0-1)/2 * y_cube, -z_wpraw * 0.0, ax.text(0, 2*WPR_Y+clp_deep, -CLP_BACKENHOHE/2, f'{CLP_BACKENHOHE}mm', color='blue', fontsize=9, weight='bold', ha='right', va='center')
max_size2, 2.0 * y_cube, z_wpraw * 0.2, ax.text(WPR_X, 2*WPR_Y+clp_deep, CLP_SPANNHOHE, f'{CLP_BACKENWEITE}mm', color='blue', fontsize=9, weight='bold', ha='right', va='center')
color='black', alpha=.10) ax.text(WPR_X*2, 2*WPR_Y-CLP_AUFLAGETIEFE/2, 0, f'{CLP_AUFLAGETIEFE}mm', color='blue', fontsize=9, weight='bold', ha='left', va='bottom')
ax.bar3d(-max_size2, -(2.0-1)/2 * y_cube, -z_wpraw * 0.0,
max_size2+3, 2.0 * y_cube, -z_wpraw * 0.2,
color='black', alpha=.10)
ax.bar3d(x_cube, -(2-1)/2 * y_cube, -z_wpraw * 0.0, # Set view properties
max_size2, 2.0 * y_cube, z_wpraw * 0.2, z_trans = WPR_Z
color='black', alpha=.10) zoom_factor = 1.5 # Adjust this factor to zoom out more or less
ax.bar3d(x_cube-3, -(2-1)/2 * y_cube, -z_wpraw * 0.0, ax.view_init(elev=30, azim=-160)
max_size2+3, 2.0 * y_cube, -z_wpraw * 0.2, ax.set_xlim([-x_cube * zoom_factor * 0.1, x_cube * zoom_factor])
color='black', alpha=.10) ax.set_ylim([-y_cube * zoom_factor * 0.1, y_cube * zoom_factor])
ax.set_zlim([-WPR_Z * zoom_factor * 0.1 - z_trans, WPR_Z * zoom_factor - z_trans])
ax.set_aspect('auto')
ax.grid(False) # Remove grid lines
ax.set_xticks([])
ax.set_yticks([])
ax.set_zticks([])
for axis in [ax.xaxis, ax.yaxis, ax.zaxis]:
axis.set_pane_color((1, 1, 1, 0)) # Hide background panes
axis.line.set_color((1, 1, 1, 0)) # Hide axis lines
# Add the origin sparrow (a small 3D marker at the origin) # Save or display the plot
max_size3 = max(x_cube, y_cube, z_cube) * 0.3 # Scale the arrows relative to the smallest dimension if not DEBUG:
ax.quiver(x_wpraw, y_wpraw, 0, max_size3, 0, 0, color='red', linewidth=3, label='X-axis') # Red arrow for X-axis fig.savefig(picture_path, bbox_inches='tight', dpi=300, transparent=True)
ax.quiver(x_wpraw, y_wpraw, 0, 0, max_size3, 0, color='green', linewidth=3, label='Y-axis') # Green arrow for Y-axis else:
ax.quiver(x_wpraw, y_wpraw, 0, 0, 0, max_size3, color='blue', linewidth=3, label='Z-axis') # Blue arrow for Z-axis plt.show()
plt.close()
# Set viewing angle
ax.view_init(elev=30, azim=-150) # Set elevation to 24° and azimuth to -151°
# ax.view_init(elev=90, azim=180) # Set elevation to 24° and azimuth to -151°
# Set limits for the axes
# ax.set_xlim([0, x_cube])
# ax.set_ylim([0, y_cube])
# ax.set_zlim([0, z_cube])
# Set equal aspect ratio to make grid cells look square
ax.set_aspect('equal')
if not DEBUG:
# Save the figure to the specified picture path
fig.savefig(picture_path, bbox_inches='tight', pad_inches=0.1, dpi=300, transparent=True)
else:
plt.show()
# Close the figure to free memory
plt.close()
except ValueError as ve:
# Handle value error (e.g., invalid input)
print(f"Invalid Input: Error: {ve}")
except Exception as e:
# Catch any other exceptions and show a generic error message
print(f"An error occurred while generating the 3D cube: {e}")
# Example use-case # Example use-case
if __name__ == "__main__": if __name__ == "__main__":
all_group_vars = { all_group_vars = {
'wp_raw': { 'CLP_BACKENWEITE': 25,
'x_wpraw': '10', # Example values for testing 'CLP_BACKENHOHE': 20,
'y_wpraw': '15', 'CLP_SPANNHOHE': 3,
'z_wpraw': '20' 'CLP_AUFLAGETIEFE': 3
},
'clp': {
'clp_offset': '4'
}
} }
generate_picture_clp(all_group_vars, 'output_image.png', DEBUG=True) generate_picture_clp({'clp': all_group_vars}, "cfg_picture/TEST_wpraw.jpg", DEBUG=True)

View File

@ -2,9 +2,13 @@
import os import os
import time import time
import pandas as pd
import paramiko
import yaml
import shutil
# Function to generate the DMUAUT_CFG.SPF configuration file and save selected parameter sets # Function to generate the CFG_DMUAUT.SPF configuration file and save selected parameter sets
def generate_config_spf(folder_output, input_vars, selected_params): def generate_config_spf(folder_output, input_vars, selected_params):
# Get the current timestamp for folder name (format: YYMMDD_HHmmSS) # Get the current timestamp for folder name (format: YYMMDD_HHmmSS)
timestamp = time.strftime("%y%m%d_%H%M%S") timestamp = time.strftime("%y%m%d_%H%M%S")
@ -15,7 +19,7 @@ def generate_config_spf(folder_output, input_vars, selected_params):
os.makedirs(folder_path) os.makedirs(folder_path)
# Define the file path for the SPF configuration file # Define the file path for the SPF configuration file
spf_file_path = os.path.join(folder_path, "DMUAUT_CFG.SPF") spf_file_path = os.path.join(folder_path, "CFG_DMUAUT.SPF")
# Generate the SPF file content # Generate the SPF file content
with open(spf_file_path, "w") as spf_file: with open(spf_file_path, "w") as spf_file:
@ -42,5 +46,87 @@ def generate_config_spf(folder_output, input_vars, selected_params):
print(f"Configuration files saved in {folder_path}") print(f"Configuration files saved in {folder_path}")
# def generate_config_spf(): os.startfile(folder_path)
# tbd
def generate_config_spf_custom1(folder_output, input_vars, selected_params, filetransfer=False):
filename = "CFG_INL.SPF"
filename2 = "_N_CFG_INL_SPF"
# Get the current timestamp for folder name (format: YYMMDD_HHmmSS)
timestamp = time.strftime("%y%m%d_%H%M%S")
folder_path = os.path.join(folder_output, f"{timestamp}")
# Create the folder with the timestamp
if not os.path.exists(folder_path):
os.makedirs(folder_path)
# Define the file path for the SPF configuration file
spf_file_path = os.path.join(folder_path, filename)
xlsx_path = "cfg_inlay_PUTx.xlsx"
# Extract grid parameters
x_num = int(input_vars['inlay']['INL_X_NUM'].get()) # Number of columns
y_num = int(input_vars['inlay']['INL_Y_NUM'].get()) # Number of rows
x_offset = float(input_vars['inlay']['INL_X_OFFSET'].get()) # X offset
y_offset = float(input_vars['inlay']['INL_Y_OFFSET'].get()) # Y offset
# Check if Excel file exists, if not create it with 'x' values
if not os.path.exists(xlsx_path):
df = pd.DataFrame("x", index=range(x_num), columns=range(y_num))
df.to_excel(xlsx_path, index=False, header=False)
# Load Excel file
df = pd.read_excel(xlsx_path, header=None, dtype=str).fillna("")
df = df.reindex(range(x_num), fill_value=0).reindex(columns=range(y_num), fill_value=0)
df = df.map(lambda x: 1 if str(x).strip().lower() == "x" else 0)
# Generate the SPF file content
with open(spf_file_path, "w") as spf_file:
spf_file.write(f"; CFG FILE FOR DMU50 AUTOMATION\n")
spf_file.write(f"; GENERATED: {timestamp}\n")
spf_file.write("; ---------------------------------------------------\n")
# Write WP_X[i] and WP_Y[i] values
cnt = 0
for j in range(y_num): # Rows
for i in range(x_num): # Columns
if df.iloc[i, j] == 1: # Consider only marked positions
spf_file.write(f"WP_X[{cnt}]={x_offset * i}\n")
spf_file.write(f"WP_Y[{cnt}]={y_offset * j}\n")
cnt += 1
spf_file.write(f"WP_NUM={cnt}\n")
spf_file.write(f"M17\n")
spf_file.write("\n; ---------------------------------------------------\n")
print(f"Configuration file saved at: {spf_file_path}")
if filetransfer:
spf_file_path2 = os.path.join(folder_path, filename2)
shutil.copyfile(spf_file_path, spf_file_path2)
# try:
# Transfer to Sinumerik
url2 = "192.168.214.1"
ssh_username = "manufact"
ssh_password = "SUNRISE"
upload_folder_nc = "/nckfs/_N_MPF_DIR/_N_AUTO_ROB_DIR"
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(url2, username=ssh_username, password=ssh_password)
sftp = ssh.open_sftp()
sftp.chdir(upload_folder_nc)
if filename2 in sftp.listdir():
sftp.remove(filename2)
sftp.put(spf_file_path2, filename2)
sftp.close()
ssh.close()
os.remove(spf_file_path2)
print(f"------->>>> FILE TRANSFERED TO SINUMERIK ------->>>> ")
# except Exception as e:
# print(f"ERROR IN FILETRANSFER {e}")
else:
os.startfile(folder_path)

View File

@ -4,47 +4,56 @@ import numpy as np
def generate_picture_inlay(all_group_vars, picture_path, DEBUG=False): def generate_picture_inlay(all_group_vars, picture_path, DEBUG=False):
try: try:
vars = all_group_vars['inlay'] vars = all_group_vars['inlay']
x_num, y_num = int(vars['x_num']), int(vars['y_num']) x_num, y_num = int(vars['INL_X_NUM']), int(vars['INL_Y_NUM'])
x_offset_mm, y_offset_mm = float(vars['x_offset']), float(vars['y_offset']) x_offset_mm, y_offset_mm = float(vars['INL_X_OFFSET']), float(vars['INL_Y_OFFSET'])
canvas_width_mm, canvas_height_mm = 800, 1200
if x_num <= 0 or y_num <= 0:
raise ValueError("INL_X_NUM and INL_Y_NUM must be positive integers.")
rect_realsize_factor = 0.90
canvas_height_mm = x_num * x_offset_mm - x_offset_mm * (1-rect_realsize_factor)
canvas_width_mm = y_num * y_offset_mm - y_offset_mm * (1-rect_realsize_factor)
x_offset = x_offset_mm / canvas_height_mm # Swapping due to axis swap x_offset = x_offset_mm / canvas_height_mm # Swapping due to axis swap
y_offset = y_offset_mm / canvas_width_mm # Swapping due to axis swap y_offset = y_offset_mm / canvas_width_mm # Swapping due to axis swap
if x_num <= 0 or y_num <= 0:
raise ValueError("x_num and y_num must be positive integers.") x_wide = x_offset * rect_realsize_factor
y_wide = y_offset * rect_realsize_factor
fig, ax = plt.subplots(figsize=(12, 8)) fig, ax = plt.subplots(figsize=(12, 8))
ax.set_facecolor('black') ax.set_facecolor('black')
total_x_offset = x_offset * (y_num + 1) for xxx in range(x_num):
total_y_offset = y_offset * (x_num + 1) for yyy in range(y_num):
rect_width = (1 - total_y_offset) / x_num
rect_height = (1 - total_x_offset) / y_num
for j in range(x_num):
for i in range(y_num):
# Mirroring horizontally # Mirroring horizontally
x_start = 1 - (y_offset + i * (rect_height + y_offset) + rect_height) x_start = xxx * x_offset
y_start = x_offset + j * (rect_width + x_offset) y_start = ((yyy) * y_offset) # Corrected vertical mirroring
rect = plt.Rectangle((x_start, y_start), rect_height, rect_width, color='white') rect = plt.Rectangle((y_start, x_start), y_wide, x_wide, color='white')
ax.add_patch(rect) ax.add_patch(rect)
triangle_sizefactor = 0.2
triangle = plt.Polygon([ triangle = plt.Polygon([
(x_start + rect_height, y_start), # Bottom right of the rectangle (y_start+y_wide, x_start), # Bottom right of the rectangle
(x_start + rect_height - 0.05 * rect_height, y_start), # Left along the bottom (y_start+y_wide, x_start + triangle_sizefactor * y_wide), # Left along the bottom
(x_start + rect_height, y_start + 0.05 * rect_width) # Up from the bottom right (y_start+y_wide - triangle_sizefactor * y_wide, x_start ) # Up from the bottom right
], color='black') ], color='black')
ax.add_patch(triangle) ax.add_patch(triangle)
# Arrows with adjusted margins # Arrows with adjusted margins
ax.arrow(0.98, 0.02, -0.9, 0, head_width=0.03, head_length=0.02, fc='green', ec='green', linewidth=2, edgecolor='white') ax.arrow(1.0, 0.0, -0.3, 0, head_width=0.03, head_length=0.02, fc='green', ec='green', linewidth=2, edgecolor='white')
ax.arrow(0.98, 0.02, 0, 0.9, head_width=0.02, head_length=0.03, fc='red', ec='red', linewidth=2, edgecolor='white') ax.arrow(1.0, 0.0, 0, 0.3, head_width=0.02, head_length=0.03, fc='red', ec='red', linewidth=2, edgecolor='white')
ax.set_xlim(0, 1) margin = 0.03
ax.set_ylim(0, 1) ax.set_xlim(0-margin, 1+margin)
ax.set_ylim(0-margin, 1+margin)
ax.set_xticks([]), ax.set_yticks([]) ax.set_xticks([]), ax.set_yticks([])
plt.subplots_adjust(left=0.1, right=0.9, top=0.9, bottom=0.1) # Adjusting the margins # plt.subplots_adjust(left=0.01, right=0.99, top=0.99, bottom=0.01) # Adjusting the margins
# ax.set_xlim(1, 0) # Flipping the x-axis
# ax.set_ylim(1, 0) # Flipping the y-axis
if DEBUG: if DEBUG:
plt.show() plt.show()
@ -58,6 +67,6 @@ def generate_picture_inlay(all_group_vars, picture_path, DEBUG=False):
print(f"Error generating matrix: {e}") print(f"Error generating matrix: {e}")
if __name__ == "__main__": if __name__ == "__main__":
vars = {'x_num': 5, 'y_num': 3, 'x_offset': 20, 'y_offset': 20} vars = {'INL_X_NUM': 8, 'INL_Y_NUM': 12, 'INL_X_OFFSET': 100, 'INL_Y_OFFSET': 125}
picture_path = "cfg_picture/TEST_inlay.jpg" picture_path = "cfg_picture/TEST_inlay.jpg"
generate_picture_inlay({'inlay': vars}, picture_path, DEBUG=True) generate_picture_inlay({'inlay': vars}, picture_path, DEBUG=True)

View File

@ -1,142 +1,165 @@
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.art3d import Poly3DCollection from functions import *
import numpy as np
def generate_picture_wpraw(all_group_vars, picture_path, DEBUG=False): def generate_picture_wp(all_group_vars, picture_path, DEBUG=False):
try: vars = all_group_vars['wp']
# --- wpraw WPR_X, WPR_Y, WPR_Z, WPF_X, WPF_Y, WPF_Z, WP_CLP_OFFSET_X, WP_GRP_OFFSET_Z = (float(vars[k]) for k in
vars = all_group_vars['wp_raw'] ['WPR_X', 'WPR_Y', 'WPR_Z', 'WPF_X',
x, y, z = float(vars['x_wpraw']), float(vars['y_wpraw']), float(vars['z_wpraw']) 'WPF_Y', 'WPF_Z', 'WP_CLP_OFFSET_X',
if min(x, y, z) <= 0: 'WP_GRP_OFFSET_Z'])
raise ValueError("Dimensions must be positive.")
fig, ax = plt.subplots(subplot_kw={'projection': '3d'}) if min(WPR_X, WPR_Y, WPR_Z, WPF_X, WPF_Y, WPF_Z) <= 0:
x_cube, y_cube = 2 * x, 2 * y raise ValueError("Dimensions must be positive.")
vertices = np.array([[0, 0, 0], [x_cube, 0, 0], [x_cube, y_cube, 0], [0, y_cube, 0],
[0, 0, z], [x_cube, 0, z], [x_cube, y_cube, z], [0, y_cube, z]])
faces = [vertices[[0, 1, 2, 3]], vertices[[4, 5, 6, 7]], vertices[[0, 3, 7, 4]],
vertices[[1, 2, 6, 5]], vertices[[0, 1, 5, 4]], vertices[[2, 3, 7, 6]]]
ax.add_collection3d(Poly3DCollection(faces, facecolors='k', linewidths=1, edgecolors='k', alpha=.15)) fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
ax.set_box_aspect([x_cube, y_cube, z])
ax.set_xticks([]);
ax.set_yticks([]);
ax.set_zticks([])
ball_radius = min(x, y, z) * 0.1
u, v = np.linspace(0, 2 * np.pi, 20), np.linspace(0, np.pi, 20)
x_sphere = x + ball_radius * np.outer(np.cos(u), np.sin(v))
y_sphere = y + ball_radius * np.outer(np.sin(u), np.sin(v))
z_sphere = z + ball_radius * np.outer(np.ones_like(u), np.cos(v))
ax.plot_surface(x_sphere, y_sphere, z_sphere, color='r', alpha=1)
max_size = max(x_cube, y_cube, z) * 0.3 # Define raw workpiece dimensions
ax.quiver(0, 0, 0, max_size, 0, 0, color='r', linewidth=5) x_cube, y_cube, z_cube = 2 * WPR_X, 2 * WPR_Y, WPR_Z
ax.quiver(0, 0, 0, 0, max_size, 0, color='g', linewidth=5) vertices_raw = np.array([[0, 0, 0], [x_cube, 0, 0], [x_cube, y_cube, 0], [0, y_cube, 0],
ax.quiver(0, 0, 0, 0, 0, max_size, color='b', linewidth=5) [0, 0, WPR_Z], [x_cube, 0, WPR_Z], [x_cube, y_cube, WPR_Z], [0, y_cube, WPR_Z]])
faces_raw = [vertices_raw[[0, 1, 2, 3]], vertices_raw[[4, 5, 6, 7]], vertices_raw[[0, 3, 7, 4]],
vertices_raw[[1, 2, 6, 5]], vertices_raw[[0, 1, 5, 4]], vertices_raw[[2, 3, 7, 6]]]
block_depth = y * 0.4 # Set axis properties
ax.bar3d(-max_size, (y_cube - block_depth) * 0.5, z * 0.8, max_size, block_depth, z * 0.8, color='k', alpha=.25) ax.set_box_aspect([x_cube, y_cube, z_cube])
ax.bar3d(x_cube, (y_cube - block_depth) * 0.5, z * 0.8, max_size, block_depth, z * 0.8, color='k', alpha=.25) ax.set(xticks=[], yticks=[], zticks=[])
# Draw WP coordinate system
axis_len = max(x_cube, y_cube, z_cube) * 0.2
colors = ['r', 'g', 'b']
origin_x = 0
origin_y = 0
origin_z = 0
for i, vec in enumerate(np.eye(3)):
ax.quiver(origin_x, origin_y, origin_z, *(axis_len * vec), color=colors[i], linewidth=3)
ax.text(origin_x, origin_y, origin_z - axis_len * 0.3, 'WP', color='black', fontsize=9, weight='bold', ha='center',
va='top')
# Draw WP
ax.add_collection3d(Poly3DCollection(faces_raw, facecolors='k', linewidths=1, edgecolors='k', alpha=.15))
ax.view_init(elev=18, azim=-130) # Draw gripping point
ax.set_xlim([0, x_cube]); ax.set_ylim([0, y_cube]); ax.set_zlim([0, z]) u, v = np.mgrid[0:2 * np.pi:20j, 0:np.pi:20j]
ax.set_aspect('auto') ball_radius = min(WPR_X, WPR_Y, WPR_Z) * 0.1
ax.plot_surface(
WPR_X + ball_radius * np.cos(u) * np.sin(v),
WPR_Y + ball_radius * np.sin(u) * np.sin(v),
WPR_Z + ball_radius * np.cos(v),
color='r'
)
if not DEBUG: # Draw gripper
fig.savefig(picture_path, bbox_inches='tight', dpi=300, transparent=True) gripper_thickness = max(x_cube, y_cube, z_cube) * 0.1
else: gripper_wide = WPR_X * 0.4
plt.show() GRP_ALPHA = .40
plt.close() bars = [
((x_cube - gripper_wide) * 0.5, -gripper_thickness, WPR_Z - WP_GRP_OFFSET_Z),
((x_cube - gripper_wide) * 0.5, y_cube, WPR_Z - WP_GRP_OFFSET_Z),
]
for (x, y, z) in bars:
ax.bar3d(
x, y, z,
gripper_wide, gripper_thickness, 5 * WPR_Z + WP_GRP_OFFSET_Z,
color='r', alpha=GRP_ALPHA, edgecolor='k', linewidth=0.5
)
except Exception as e: # Define finished workpiece dimensions
print(f"An error occurred: {e}") x_cube2, y_cube2, z_cube2 = 2 * WPF_X, 2 * WPF_Y, WPF_Z
# Draw gripping point for finished workpiece
u, v = np.mgrid[0:2 * np.pi:20j, 0:np.pi:20j]
ball_radius = min(WPF_X, WPF_Y, WPF_Z) * 0.08
ax.plot_surface(
WPF_X + ball_radius * np.cos(u) * np.sin(v),
WPF_Y + ball_radius * np.sin(u) * np.sin(v),
WPF_Z + ball_radius * np.cos(v),
color='g'
)
def generate_picture_wpfin(all_group_vars, picture_path, DEBUG=False): # Draw gripper for finished workpiece
try: gripper_thickness2 = max(x_cube, y_cube, z_cube) * 0.05
# --- wpraw gripper_wide2 = WPR_X * 0.4
vars = all_group_vars['wp_raw'] GRP_ALPHA2 = .25
x, y, z = float(vars['x_wpraw']), float(vars['y_wpraw']), float(vars['z_wpraw']) yyy2 = [-gripper_thickness2, y_cube2] if WPF_Y < WPR_Y else [-gripper_thickness2 + (WPF_Y - WPR_Y) * 2, y_cube]
if min(x, y, z) <= 0: bars = [
raise ValueError("Dimensions must be positive.") ((x_cube2 - gripper_wide2) * 0.5, yyy2[0], WPF_Z - WP_GRP_OFFSET_Z),
((x_cube2 - gripper_wide2) * 0.5, yyy2[1], WPF_Z - WP_GRP_OFFSET_Z),
]
for (x, y, z) in bars:
ax.bar3d(
x, y, z,
gripper_wide2, gripper_thickness2, 5 * WPF_Z + WP_GRP_OFFSET_Z,
color='g', alpha=GRP_ALPHA2, edgecolor='k', linewidth=0.5
)
fig, ax = plt.subplots(subplot_kw={'projection': '3d'}) # Draw CLP coordinate system
x_cube, y_cube = 2 * x, 2 * y axis_len = max(x_cube, y_cube, z_cube) * 0.15
vertices = np.array([[0, 0, 0], [x_cube, 0, 0], [x_cube, y_cube, 0], [0, y_cube, 0], colors = ['r', 'g', 'b']
[0, 0, z], [x_cube, 0, z], [x_cube, y_cube, z], [0, y_cube, z]]) origin_x = WPR_X - WP_CLP_OFFSET_X
faces = [vertices[[0, 1, 2, 3]], vertices[[4, 5, 6, 7]], vertices[[0, 3, 7, 4]], origin_y = WPR_Y
vertices[[1, 2, 6, 5]], vertices[[0, 1, 5, 4]], vertices[[2, 3, 7, 6]]] origin_z = 0
for i, vec in enumerate(np.eye(3)):
ax.quiver(origin_x, origin_y, origin_z, *(axis_len * vec), color=colors[i], linewidth=3)
ax.text(origin_x, origin_y, origin_z - axis_len * 0.3, 'CLP', color='blue', fontsize=9, weight='bold', ha='center',
va='top')
ax.add_collection3d(Poly3DCollection(faces, facecolors='k', linewidths=1, edgecolors='k', alpha=.15)) # Define clamping block dimensions
ax.set_box_aspect([x_cube, y_cube, z]) clp_height = z_cube * 0.2
ax.set_xticks([]); clp_width = 0.6 * x_cube
ax.set_yticks([]); clp_deep = y_cube * 0.3
ax.set_zticks([]) clp_supportdeep = 3
ball_radius = min(x, y, z) * 0.1 base_x = WPR_X - clp_width / 2
u, v = np.linspace(0, 2 * np.pi, 20), np.linspace(0, np.pi, 20) alpha = 0.35
x_sphere = x + ball_radius * np.outer(np.cos(u), np.sin(v)) color = 'blue'
y_sphere = y + ball_radius * np.outer(np.sin(u), np.sin(v)) linewidth = 1
z_sphere = z + ball_radius * np.outer(np.ones_like(u), np.cos(v))
ax.plot_surface(x_sphere, y_sphere, z_sphere, color='r', alpha=1)
# Draw clamping blocks
x = base_x - WP_CLP_OFFSET_X
dx = clp_width
y = 0
dy1 = clp_deep
dy2 = clp_supportdeep
z = 0
dz1 = z_cube * 0.2
dz2 = z_cube * 0.6
plot_clamping(ax, x, y, z, dx, dy1, dy2, dz1, dz2, color=color,
alpha=alpha, linewidth=linewidth)
y = y_cube
plot_clamping(ax, x, y, z, dx, dy1, dy2, dz1, dz2, color=color,
alpha=alpha, linewidth=linewidth, inverty=True)
# --- wprfin # Set view properties
vars = all_group_vars['wp_fin'] z_trans = WPR_Z*0.2
x, y, z, l = float(vars['x_wpfin']), float(vars['y_wpfin']), float(vars['z_wpfin']), float(vars['l_wpfin']) zoom_factor = 1.1 # Adjust this factor to zoom out more or less
if min(x, y, z, l) <= 0: ax.view_init(elev=30, azim=-160)
raise ValueError("Dimensions must be positive.") ax.set_xlim([-x_cube * zoom_factor * 0.1, x_cube * zoom_factor])
ax.set_ylim([-y_cube * zoom_factor * 0.1, y_cube * zoom_factor])
ax.set_zlim([-WPR_Z * zoom_factor * 0.1 - z_trans, WPR_Z * zoom_factor - z_trans])
ax.set_aspect('auto')
ax.grid(False) # Remove grid lines
ax.set_xticks([])
ax.set_yticks([])
ax.set_zticks([])
for axis in [ax.xaxis, ax.yaxis, ax.zaxis]:
axis.set_pane_color((1, 1, 1, 0)) # Hide background panes
axis.line.set_color((1, 1, 1, 0)) # Hide axis lines
fig, ax = plt.subplots(subplot_kw={'projection': '3d'}) # Save or display the plot
x_offset = x - l / 2 if not DEBUG:
vertices = np.array([[0, 0, 0], [l, 0, 0], [l, 2 * y, 0], [0, 2 * y, 0], fig.savefig(picture_path, bbox_inches='tight', dpi=300, transparent=True)
[0, 0, z], [l, 0, z], [l, 2 * y, z], [0, 2 * y, z]]) + np.array([x_offset, 0, 0]) else:
faces = [vertices[[0, 1, 2, 3]], vertices[[4, 5, 6, 7]], vertices[[0, 3, 7, 4]], plt.show()
vertices[[1, 2, 6, 5]], vertices[[0, 1, 5, 4]], vertices[[2, 3, 7, 6]]] plt.close()
ax.add_collection3d(Poly3DCollection(faces, facecolors='k', linewidths=1, edgecolors='k', alpha=.15))
ball_radius = min(x, y, z) * 0.1
u, v = np.linspace(0, 2 * np.pi, 20), np.linspace(0, np.pi, 20)
x_sphere = x + ball_radius * np.outer(np.cos(u), np.sin(v))
y_sphere = y + ball_radius * np.outer(np.sin(u), np.sin(v))
z_sphere = z + ball_radius * np.outer(np.ones_like(u), np.cos(v))
ax.plot_surface(x_sphere, y_sphere, z_sphere, color='blue', alpha=1)
max_size = max(l, 2 * y, z) * 0.3
ax.quiver(0, 0, 0, max_size, 0, 0, color='red', linewidth=5)
ax.quiver(0, 0, 0, 0, max_size, 0, color='green', linewidth=5)
ax.quiver(0, 0, 0, 0, 0, max_size, color='blue', linewidth=5)
block_depth = y * 0.4
ax.bar3d(-max_size + x_offset, (2 * y - block_depth) * 0.5, z * 0.8, max_size, block_depth, z * 0.8,
color='black', alpha=.25)
ax.bar3d(l + x_offset, (2 * y - block_depth) * 0.5, z * 0.8, max_size, block_depth, z * 0.8, color='black',
alpha=.25)
ax.view_init(elev=18, azim=-130)
ax.set_xticks([]);
ax.set_yticks([]);
ax.set_zticks([])
ax.set_xlim([0, l + x_offset]);
ax.set_ylim([0, 2 * y]);
ax.set_zlim([0, z])
ax.set_aspect('equal')
if not DEBUG:
fig.savefig(picture_path, bbox_inches='tight', dpi=300, transparent=True)
else:
plt.show()
plt.close()
except Exception as e:
print(f"An error occurred: {e}")
if __name__ == "__main__": if __name__ == "__main__":
vars = {'x_wpraw': 10, 'y_wpraw': 15, 'z_wpraw': 20} vars = {'WPR_X': 20,
generate_picture_wpraw({'wp_raw': vars}, "cfg_picture/TEST_wpraw.jpg", DEBUG=True) 'WPR_Y': 15,
'WPR_Z': 20,
vars = {'x_wpfin': 10, 'y_wpfin': 20, 'z_wpfin': 20, 'l_wpfin': 10} 'WPF_X': 10,
generate_picture_wpfin({'wp_fin': vars}, "cfg_picture/TEST_wpfin.jpg", DEBUG=True) 'WPF_Y': 18,
'WPF_Z': 15,
'WP_CLP_OFFSET_X': 3,
'WP_GRP_OFFSET_Z': 5}
generate_picture_wp({'wp': vars}, "cfg_picture/TEST_wpraw.jpg", DEBUG=True)

View File

@ -5,6 +5,9 @@ from PIL import Image, ImageTk
from tkinter import ttk, filedialog, messagebox from tkinter import ttk, filedialog, messagebox
import tkinter as tk import tkinter as tk
import os import os
import trimesh
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
import numpy as np
# Function to load object definitions from YAML # Function to load object definitions from YAML
@ -87,3 +90,40 @@ def create_new_param_popup(root, group_name, input_vars, param_values, param_dro
new_window.destroy() new_window.destroy()
tk.Button(new_window, text="Create", command=create_param_set).pack(pady=10) tk.Button(new_window, text="Create", command=create_param_set).pack(pady=10)
# -------------------------------------------------------------------------------------------------------
def plot_clamping(ax, x, y, z, dx, dy1, dy2, dz1, dz2, color='blue', alpha=0.5, linewidth=1, inverty=False):
"""Efficiently plots an L-shaped merged cube structure and draws only axis-aligned edges."""
# Compute Y offsets
dyy1, dyy2 = (y - dy1 / 2, y - (dy1 - dy2) / 2) if not inverty else (y + dy1 / 2, y + (dy1 - dy2) / 2)
# Create and position both cubes
cubes = [
trimesh.creation.box(extents=[dx, dy1, dz1]).apply_translation([x + dx / 2, dyy1, z + dz1 / 2]),
trimesh.creation.box(extents=[dx, dy1 + dy2, dz2]).apply_translation([x + dx / 2, dyy2, z - dz2 / 2])
]
try:
# Perform boolean union on merged cubes
merged = trimesh.boolean.union(cubes)
# Extract vertices and edges
vertices = np.array(merged.vertices)
edges = merged.edges_unique
# Add merged faces without visible edges
ax.add_collection3d(Poly3DCollection(
vertices[merged.faces], facecolors=color, alpha=alpha, edgecolors=None, linewidth=0
))
# Draw only axis-aligned edges
for edge in edges:
v1, v2 = vertices[edge]
if np.isclose(v1, v2, atol=1e-6).sum() == 2: # Only one coordinate changes
ax.plot(*zip(*[v1, v2]), color='black', linewidth=linewidth)
except Exception as e:
print(f"Trimesh union failed: {e}")

View File

@ -1,29 +0,0 @@
; CFG FILE FOR DMU50 AUTOMATION
; GENERATED: 241016_164629
; ---------------------------------------------------
X_NUM = 8
X_OFFSET = 5
Y_NUM = 7
Y_OFFSET = 4
KOS = 4
; ---------------------------------------------------
X_WPRAW = 10
Y_WPRAW = 1
Z_WPRAW = 1
; ---------------------------------------------------
X_WPFIN =
Y_WPFIN =
Z_WPFIN =
L_WPFIN =
; ---------------------------------------------------
HUB = 10
H_OFFSET = 20
H_STEP = 5
W_OFFSET = 20
W_STEP = 10
STEPS_NUM = 6
; ---------------------------------------------------

View File

@ -1,5 +0,0 @@
Selected Parameter Sets:
inlay: inlay7
wp_raw: wpraw1
wp_fin: <<new par set>>
grp: grp1

View File

@ -1,29 +0,0 @@
; CFG FILE FOR DMU50 AUTOMATION
; GENERATED: 241017_101415
; ---------------------------------------------------
X_NUM = 11
X_OFFSET = 5
Y_NUM = 4
Y_OFFSET = 4
KOS = 4
; ---------------------------------------------------
X_WPRAW = 10
Y_WPRAW = 10
Z_WPRAW = 20
; ---------------------------------------------------
X_WPFIN = 10
Y_WPFIN = 10
Z_WPFIN = 20
L_WPFIN = 10
; ---------------------------------------------------
HUB = 10
H_OFFSET = 20
H_STEP = 5
W_OFFSET = 20
W_STEP = 10
STEPS_NUM = 6
; ---------------------------------------------------

View File

@ -1,5 +0,0 @@
Selected Parameter Sets:
inlay: inlay4
wp_raw: wpraw1
wp_fin: wpfin1
grp: grp1

View File

@ -1,29 +0,0 @@
; CFG FILE FOR DMU50 AUTOMATION
; GENERATED: 241017_103326
; ---------------------------------------------------
X_NUM = 7
X_OFFSET = 5
Y_NUM = 4
Y_OFFSET = 4
KOS = g54
; ---------------------------------------------------
X_WPRAW = 5
Y_WPRAW = 5
Z_WPRAW = 15
; ---------------------------------------------------
X_WPFIN = 10
Y_WPFIN = 10
Z_WPFIN = 13
L_WPFIN = 8
; ---------------------------------------------------
HUB = 10
H_OFFSET = 10
H_STEP = 5
W_OFFSET = 25
W_STEP = 4
STEPS_NUM = 6
; ---------------------------------------------------

View File

@ -1,5 +0,0 @@
Selected Parameter Sets:
inlay: inlay_kleinteil
wp_raw: wpraw2
wp_fin: wpfin1
grp: grp1

View File

@ -1,32 +0,0 @@
; CFG FILE FOR DMU50 AUTOMATION
; GENERATED: 241017_180108
; ---------------------------------------------------
X_NUM = 8
X_OFFSET = 5
Y_NUM = 7
Y_OFFSET = 4
KOS = 4
; ---------------------------------------------------
X_WPRAW = 10
Y_WPRAW = 10
Z_WPRAW = 20
; ---------------------------------------------------
X_WPFIN = 10
Y_WPFIN = 10
Z_WPFIN = 13
L_WPFIN = 8
; ---------------------------------------------------
HUB = 50
H_OFFSET = 30
H_STEP = 10
W_OFFSET = 40
W_STEP = 45
STEPS_NUM = 5
; ---------------------------------------------------
CLP_OFFSET =
; ---------------------------------------------------

View File

@ -1,6 +0,0 @@
Selected Parameter Sets:
inlay: inlay7
wp_raw: wpraw1
wp_fin: wpfin1
grp: grp1
clp: <<new par set>>

View File

@ -1,32 +0,0 @@
; CFG FILE FOR DMU50 AUTOMATION
; GENERATED: 241017_181437
; ---------------------------------------------------
X_NUM = 8
X_OFFSET = 5
Y_NUM = 7
Y_OFFSET = 4
KOS = 4
; ---------------------------------------------------
X_WPRAW = 5
Y_WPRAW = 5
Z_WPRAW = 15
; ---------------------------------------------------
X_WPFIN = 10
Y_WPFIN = 10
Z_WPFIN = 13
L_WPFIN = 8
; ---------------------------------------------------
HUB = 50
H_OFFSET = 30
H_STEP = 10
W_OFFSET = 40
W_STEP = 45
STEPS_NUM = 5
; ---------------------------------------------------
CLP_OFFSET = 0
; ---------------------------------------------------

View File

@ -1,6 +0,0 @@
Selected Parameter Sets:
inlay: inlay7
wp_raw: wpraw2
wp_fin: wpfin1
grp: grp1
clp: clp2

View File

@ -1,32 +0,0 @@
; CFG FILE FOR DMU50 AUTOMATION
; GENERATED: 241017_184239
; ---------------------------------------------------
X_NUM =
X_OFFSET =
Y_NUM =
Y_OFFSET =
KOS =
; ---------------------------------------------------
X_WPRAW = 10
Y_WPRAW = 10
Z_WPRAW = 20
; ---------------------------------------------------
X_WPFIN = 10
Y_WPFIN = 10
Z_WPFIN = 13
L_WPFIN = 8
; ---------------------------------------------------
HUB = 10
H_OFFSET = 10
H_STEP = 5
W_OFFSET = 25
W_STEP = 45
STEPS_NUM = 2
; ---------------------------------------------------
CLP_OFFSET = 4
; ---------------------------------------------------

View File

@ -1,6 +0,0 @@
Selected Parameter Sets:
inlay: <<new par set>>
wp_raw: wpraw1
wp_fin: wpfin1
grp: grp3
clp: clp1