Compare commits
7 Commits
f145b5c878
...
75689925d0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
75689925d0 | ||
|
|
f0cf8c40d9 | ||
|
|
10a0e86caf | ||
|
|
261e3b4929 | ||
|
|
b607afcd86 | ||
|
|
377fb1422f | ||
|
|
635d8e29e9 |
3
.gitignore
vendored
@ -1,5 +1,6 @@
|
||||
/.idea
|
||||
/__pycache__/
|
||||
*ARCHIV*
|
||||
*BAK*
|
||||
*BACKUP*
|
||||
out
|
||||
cfg_inlay_PUTx.xlsx
|
||||
|
||||
47
BAK/241031_def.yml
Normal 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
|
||||
@ -7,7 +7,7 @@ $scriptPath = "./MAIN.py"
|
||||
$username = [System.Environment]::UserName
|
||||
|
||||
# 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
|
||||
& $pythonExe $scriptPath
|
||||
|
||||
21
MAIN.py
@ -1,5 +1,4 @@
|
||||
# main.py
|
||||
|
||||
from functions import *
|
||||
from funct_inlay 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_dropdown = ttk.Combobox(frame, textvariable=param_var, values=param_values)
|
||||
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
|
||||
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
|
||||
if grpnm == "inlay":
|
||||
generate_picture_inlay(all_group_vars, picture_to_use)
|
||||
elif grpnm == "wp_raw":
|
||||
generate_picture_wpraw(all_group_vars, picture_to_use)
|
||||
elif grpnm == "wp_fin":
|
||||
generate_picture_wpfin(all_group_vars, picture_to_use)
|
||||
elif grpnm == "wp":
|
||||
generate_picture_wp(all_group_vars, picture_to_use)
|
||||
elif grpnm == "grp":
|
||||
generate_picture_grp(all_group_vars, picture_to_use)
|
||||
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")
|
||||
|
||||
# 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
|
||||
image_label = ttk.Label(frame, image=group_image_tk)
|
||||
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
|
||||
def btn_gen():
|
||||
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
|
||||
button_frame = ttk.Frame(frame)
|
||||
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)
|
||||
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)
|
||||
|
||||
|
||||
30
README.md
@ -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
|
||||
|
||||
|
||||
|
||||
@ -8,3 +8,9 @@ dependencies:
|
||||
- jsonschema
|
||||
- tk
|
||||
- pillow
|
||||
- pandas
|
||||
- openpyxl
|
||||
- paramiko
|
||||
- matplotlib
|
||||
- trimesh
|
||||
- manifold3d
|
||||
@ -1,4 +1,9 @@
|
||||
clp1:
|
||||
clp_offset: '0'
|
||||
clp2:
|
||||
clp_offset: '0'
|
||||
CLP_AUFLAGETIEFE: '3'
|
||||
CLP_BACKENHOHE: '30'
|
||||
CLP_BACKENWEITE: '30'
|
||||
CLP_SPANNHOHE: '5'
|
||||
MESSPOS_TOL: '0'
|
||||
MESSPOS_X: '0'
|
||||
MESSPOS_Y: '0'
|
||||
MESSPOS_Z: '0'
|
||||
|
||||
@ -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'
|
||||
@ -1,12 +1,10 @@
|
||||
inlay7:
|
||||
kos: '4'
|
||||
x_num: '4'
|
||||
x_offset: '30'
|
||||
y_num: '3'
|
||||
y_offset: '30'
|
||||
inlay_kleinteil:
|
||||
kos: '4'
|
||||
x_num: '7'
|
||||
x_offset: '5'
|
||||
y_num: '4'
|
||||
y_offset: '4'
|
||||
<<new par set>>:
|
||||
INL_X_NUM: '10'
|
||||
INL_X_OFFSET: '50'
|
||||
INL_Y_NUM: '10'
|
||||
INL_Y_OFFSET: '50'
|
||||
inlay1:
|
||||
INL_X_NUM: '10'
|
||||
INL_X_OFFSET: '10'
|
||||
INL_Y_NUM: '10'
|
||||
INL_Y_OFFSET: '10'
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
job1:
|
||||
clp: clp1
|
||||
grp: grp1
|
||||
inlay: inlay7
|
||||
inlay: inlay1
|
||||
wp_fin: wpfin1
|
||||
wp_raw: wpraw1
|
||||
job3:
|
||||
|
||||
9
cfg_parsets/wp.yml
Normal 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'
|
||||
@ -1,5 +0,0 @@
|
||||
wpfin1:
|
||||
l_wpfin: '8'
|
||||
x_wpfin: '20'
|
||||
y_wpfin: '10'
|
||||
z_wpfin: '13'
|
||||
@ -1,8 +0,0 @@
|
||||
test:
|
||||
x_wpraw: '20'
|
||||
y_wpraw: '10'
|
||||
z_wpraw: '20'
|
||||
wpraw1:
|
||||
x_wpraw: '10'
|
||||
y_wpraw: '10'
|
||||
z_wpraw: '20'
|
||||
BIN
cfg_picture/cat_wondering.png
Normal file
|
After Width: | Height: | Size: 1.0 MiB |
BIN
cfg_picture/dog_progr.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
|
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 148 KiB |
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 93 KiB |
BIN
cfg_picture/img_wp.png
Normal file
|
After Width: | Height: | Size: 197 KiB |
|
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 89 KiB |
|
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 155 KiB |
|
Before Width: | Height: | Size: 155 KiB |
54
def.yml
@ -1,44 +1,38 @@
|
||||
general:
|
||||
yolovar: int
|
||||
initpic_name: puppy.png
|
||||
notavailablepic_name: cat_wondering.png
|
||||
generatorpic_name: dog_progr.png
|
||||
|
||||
groups:
|
||||
inlay:
|
||||
parameter:
|
||||
x_num: int
|
||||
x_offset: double
|
||||
y_num: int
|
||||
y_offset: double
|
||||
kos: str
|
||||
INL_X_NUM: int
|
||||
INL_X_OFFSET: double
|
||||
INL_Y_NUM: int
|
||||
INL_Y_OFFSET: double
|
||||
cfg:
|
||||
picture_name: img_inlay.png
|
||||
wp_raw:
|
||||
wp:
|
||||
parameter:
|
||||
x_wpraw: double
|
||||
y_wpraw: double
|
||||
z_wpraw: double
|
||||
WPR_X: double
|
||||
WPR_Y: double
|
||||
WPR_Z: double
|
||||
WPF_X: double
|
||||
WPF_Y: double
|
||||
WPF_Z: double
|
||||
WP_CLP_OFFSET_X: double
|
||||
WP_GRP_OFFSET_Z: double
|
||||
cfg:
|
||||
picture_name: img_wpraw.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
|
||||
picture_name: img_wp.png
|
||||
clp:
|
||||
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:
|
||||
picture_name: img_clp.png
|
||||
|
||||
200
funct_clp.py
@ -1,130 +1,116 @@
|
||||
import matplotlib.pyplot as plt
|
||||
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
|
||||
import numpy as np
|
||||
from functions import *
|
||||
|
||||
|
||||
def generate_picture_clp(all_group_vars, picture_path, DEBUG=False):
|
||||
try:
|
||||
# Get x_wpraw, y_wpraw, and z_wpraw values
|
||||
vars = all_group_vars['wp_raw']
|
||||
x_wpraw = float(vars['x_wpraw'])
|
||||
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'])
|
||||
vars = all_group_vars['clp']
|
||||
CLP_BACKENWEITE, CLP_BACKENHOHE, CLP_SPANNHOHE, CLP_AUFLAGETIEFE = (float(vars[k]) for k in
|
||||
['CLP_BACKENWEITE', 'CLP_BACKENHOHE',
|
||||
'CLP_SPANNHOHE', 'CLP_AUFLAGETIEFE'])
|
||||
|
||||
# ERROR HANDLING
|
||||
if x_cube <= 0 or y_cube <= 0 or z_cube <= 0:
|
||||
raise ValueError("x_wpraw, y_wpraw, and z_wpraw must be positive values.")
|
||||
WPR_X = CLP_BACKENWEITE/2
|
||||
WPR_Y = CLP_BACKENWEITE/2
|
||||
WPR_Z = CLP_SPANNHOHE * 5
|
||||
|
||||
# Define the vertices of the cube based on wpraw dimensions
|
||||
vertices = (np.array([[0, 0, 0], [x_cube, 0, 0], [x_cube, y_cube, 0], [0, y_cube, 0],
|
||||
[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]))
|
||||
if min(WPR_X, WPR_Y, WPR_Z) <= 0:
|
||||
raise ValueError("Dimensions must be positive.")
|
||||
|
||||
# Define the 6 faces of the cube
|
||||
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
|
||||
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
|
||||
|
||||
# Plot the cube in 3D
|
||||
fig = plt.figure()
|
||||
ax = fig.add_subplot(111, projection='3d')
|
||||
# Define raw workpiece dimensions
|
||||
x_cube, y_cube, z_cube = 2 * WPR_X, 2 * WPR_Y, WPR_Z
|
||||
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
|
||||
ax.add_collection3d(Poly3DCollection(faces, facecolors='k', linewidths=1, edgecolors='k', alpha=.15))
|
||||
# Set axis properties
|
||||
ax.set_box_aspect([x_cube, y_cube, z_cube])
|
||||
ax.set(xticks=[], yticks=[], zticks=[])
|
||||
|
||||
# Set the aspect ratio for each axis
|
||||
ax.set_box_aspect([x_cube, y_cube, z_cube])
|
||||
# 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')
|
||||
|
||||
# Hide the axis ticks and labels
|
||||
ax.set_xticks([]) # Hide X axis ticks
|
||||
ax.set_yticks([]) # Hide Y axis ticks
|
||||
ax.set_zticks([]) # Hide Z axis ticks
|
||||
# Draw WP
|
||||
ax.add_collection3d(Poly3DCollection(faces_raw, facecolors='k', linewidths=1, edgecolors='k', alpha=.15))
|
||||
|
||||
# Add a ball (sphere) at the center of the cube
|
||||
ball_radius = min(x_wpraw, y_wpraw, z_wpraw) * 0.1 # Size relative to cube dimensions
|
||||
# Draw CLP coordinate system
|
||||
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)
|
||||
v = np.linspace(0, np.pi, 20)
|
||||
x_sphere = x_wpraw + ball_radius * np.outer(np.cos(u), np.sin(v))
|
||||
y_sphere = y_wpraw - clp_offset + ball_radius * np.outer(np.sin(u), np.sin(v))
|
||||
z_sphere = z_wpraw + ball_radius * np.outer(np.ones(np.size(u)), np.cos(v))
|
||||
ax.plot_surface(x_sphere, y_sphere, z_sphere, color='red', alpha=1)
|
||||
# Define clamping block dimensions
|
||||
clp_deep = y_cube * 0.3
|
||||
base_x = WPR_X - CLP_BACKENWEITE / 2
|
||||
alpha = 0.35
|
||||
color = 'blue'
|
||||
linewidth = 1
|
||||
|
||||
# Add the origin sparrow (a small 3D marker at the origin)
|
||||
max_size = max(x_cube, y_cube, z_cube) * 0.2 # Scale the arrows relative to the smallest dimension
|
||||
ax.quiver(0, -clp_offset, 0, max_size, 0, 0, color='red', linewidth=2, label='X-axis') # Red arrow for X-axis
|
||||
ax.quiver(0, -clp_offset, 0, 0, max_size, 0, color='green', linewidth=2, label='Y-axis') # Green arrow for Y-axis
|
||||
ax.quiver(0, -clp_offset, 0, 0, 0, max_size, color='blue', linewidth=2, label='Z-axis') # Blue arrow for Z-axis
|
||||
# Draw clamping blocks
|
||||
x = base_x
|
||||
dx = CLP_BACKENWEITE
|
||||
y = 0
|
||||
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
|
||||
max_size2 = max(x_cube, y_cube, z_cube) * 0.4 # Scale the arrows relative to the smallest dimension
|
||||
ax.bar3d(-max_size2, -(2.0-1)/2 * y_cube, -z_wpraw * 0.0,
|
||||
max_size2, 2.0 * y_cube, z_wpraw * 0.2,
|
||||
color='black', alpha=.10)
|
||||
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)
|
||||
# Draw text for geometry values
|
||||
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.text(0, 2*WPR_Y+clp_deep, -CLP_BACKENHOHE/2, f'{CLP_BACKENHOHE}mm', color='blue', fontsize=9, weight='bold', ha='right', va='center')
|
||||
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')
|
||||
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(x_cube, -(2-1)/2 * y_cube, -z_wpraw * 0.0,
|
||||
max_size2, 2.0 * y_cube, z_wpraw * 0.2,
|
||||
color='black', alpha=.10)
|
||||
ax.bar3d(x_cube-3, -(2-1)/2 * y_cube, -z_wpraw * 0.0,
|
||||
max_size2+3, 2.0 * y_cube, -z_wpraw * 0.2,
|
||||
color='black', alpha=.10)
|
||||
# Set view properties
|
||||
z_trans = WPR_Z
|
||||
zoom_factor = 1.5 # Adjust this factor to zoom out more or less
|
||||
ax.view_init(elev=30, azim=-160)
|
||||
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
|
||||
|
||||
# Add the origin sparrow (a small 3D marker at the origin)
|
||||
max_size3 = max(x_cube, y_cube, z_cube) * 0.3 # Scale the arrows relative to the smallest dimension
|
||||
ax.quiver(x_wpraw, y_wpraw, 0, max_size3, 0, 0, color='red', linewidth=3, label='X-axis') # Red arrow for X-axis
|
||||
ax.quiver(x_wpraw, y_wpraw, 0, 0, max_size3, 0, color='green', linewidth=3, label='Y-axis') # Green arrow for Y-axis
|
||||
ax.quiver(x_wpraw, y_wpraw, 0, 0, 0, max_size3, color='blue', linewidth=3, label='Z-axis') # Blue arrow for Z-axis
|
||||
|
||||
# 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}")
|
||||
# Save or display the plot
|
||||
if not DEBUG:
|
||||
fig.savefig(picture_path, bbox_inches='tight', dpi=300, transparent=True)
|
||||
else:
|
||||
plt.show()
|
||||
plt.close()
|
||||
|
||||
|
||||
# Example use-case
|
||||
if __name__ == "__main__":
|
||||
all_group_vars = {
|
||||
'wp_raw': {
|
||||
'x_wpraw': '10', # Example values for testing
|
||||
'y_wpraw': '15',
|
||||
'z_wpraw': '20'
|
||||
},
|
||||
'clp': {
|
||||
'clp_offset': '4'
|
||||
}
|
||||
'CLP_BACKENWEITE': 25,
|
||||
'CLP_BACKENHOHE': 20,
|
||||
'CLP_SPANNHOHE': 3,
|
||||
'CLP_AUFLAGETIEFE': 3
|
||||
}
|
||||
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)
|
||||
|
||||
94
funct_gen.py
@ -2,9 +2,13 @@
|
||||
|
||||
import os
|
||||
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):
|
||||
# Get the current timestamp for folder name (format: YYMMDD_HHmmSS)
|
||||
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)
|
||||
|
||||
# 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
|
||||
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}")
|
||||
|
||||
# def generate_config_spf():
|
||||
# tbd
|
||||
os.startfile(folder_path)
|
||||
|
||||
|
||||
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)
|
||||
|
||||
@ -4,47 +4,56 @@ import numpy as np
|
||||
def generate_picture_inlay(all_group_vars, picture_path, DEBUG=False):
|
||||
try:
|
||||
vars = all_group_vars['inlay']
|
||||
x_num, y_num = int(vars['x_num']), int(vars['y_num'])
|
||||
x_offset_mm, y_offset_mm = float(vars['x_offset']), float(vars['y_offset'])
|
||||
canvas_width_mm, canvas_height_mm = 800, 1200
|
||||
x_num, y_num = int(vars['INL_X_NUM']), int(vars['INL_Y_NUM'])
|
||||
x_offset_mm, y_offset_mm = float(vars['INL_X_OFFSET']), float(vars['INL_Y_OFFSET'])
|
||||
|
||||
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
|
||||
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))
|
||||
ax.set_facecolor('black')
|
||||
|
||||
total_x_offset = x_offset * (y_num + 1)
|
||||
total_y_offset = y_offset * (x_num + 1)
|
||||
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):
|
||||
for xxx in range(x_num):
|
||||
for yyy in range(y_num):
|
||||
# Mirroring horizontally
|
||||
x_start = 1 - (y_offset + i * (rect_height + y_offset) + rect_height)
|
||||
y_start = x_offset + j * (rect_width + x_offset)
|
||||
x_start = xxx * 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)
|
||||
|
||||
triangle_sizefactor = 0.2
|
||||
triangle = plt.Polygon([
|
||||
(x_start + rect_height, y_start), # Bottom right of the rectangle
|
||||
(x_start + rect_height - 0.05 * rect_height, y_start), # Left along the bottom
|
||||
(x_start + rect_height, y_start + 0.05 * rect_width) # Up from the bottom right
|
||||
(y_start+y_wide, x_start), # Bottom right of the rectangle
|
||||
(y_start+y_wide, x_start + triangle_sizefactor * y_wide), # Left along the bottom
|
||||
(y_start+y_wide - triangle_sizefactor * y_wide, x_start ) # Up from the bottom right
|
||||
], color='black')
|
||||
ax.add_patch(triangle)
|
||||
|
||||
# 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(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.3, 0, head_width=0.03, head_length=0.02, fc='green', ec='green', 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)
|
||||
ax.set_ylim(0, 1)
|
||||
margin = 0.03
|
||||
ax.set_xlim(0-margin, 1+margin)
|
||||
ax.set_ylim(0-margin, 1+margin)
|
||||
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:
|
||||
plt.show()
|
||||
@ -58,6 +67,6 @@ def generate_picture_inlay(all_group_vars, picture_path, DEBUG=False):
|
||||
print(f"Error generating matrix: {e}")
|
||||
|
||||
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"
|
||||
generate_picture_inlay({'inlay': vars}, picture_path, DEBUG=True)
|
||||
|
||||
263
funct_wp.py
@ -1,142 +1,165 @@
|
||||
import matplotlib.pyplot as plt
|
||||
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
|
||||
import numpy as np
|
||||
from functions import *
|
||||
|
||||
|
||||
def generate_picture_wpraw(all_group_vars, picture_path, DEBUG=False):
|
||||
try:
|
||||
# --- wpraw
|
||||
vars = all_group_vars['wp_raw']
|
||||
x, y, z = float(vars['x_wpraw']), float(vars['y_wpraw']), float(vars['z_wpraw'])
|
||||
if min(x, y, z) <= 0:
|
||||
raise ValueError("Dimensions must be positive.")
|
||||
def generate_picture_wp(all_group_vars, picture_path, DEBUG=False):
|
||||
vars = all_group_vars['wp']
|
||||
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
|
||||
['WPR_X', 'WPR_Y', 'WPR_Z', 'WPF_X',
|
||||
'WPF_Y', 'WPF_Z', 'WP_CLP_OFFSET_X',
|
||||
'WP_GRP_OFFSET_Z'])
|
||||
|
||||
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
|
||||
x_cube, y_cube = 2 * x, 2 * y
|
||||
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]]]
|
||||
if min(WPR_X, WPR_Y, WPR_Z, WPF_X, WPF_Y, WPF_Z) <= 0:
|
||||
raise ValueError("Dimensions must be positive.")
|
||||
|
||||
ax.add_collection3d(Poly3DCollection(faces, facecolors='k', linewidths=1, edgecolors='k', alpha=.15))
|
||||
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)
|
||||
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
|
||||
|
||||
max_size = max(x_cube, y_cube, z) * 0.3
|
||||
ax.quiver(0, 0, 0, max_size, 0, 0, color='r', linewidth=5)
|
||||
ax.quiver(0, 0, 0, 0, max_size, 0, color='g', linewidth=5)
|
||||
ax.quiver(0, 0, 0, 0, 0, max_size, color='b', linewidth=5)
|
||||
# Define raw workpiece dimensions
|
||||
x_cube, y_cube, z_cube = 2 * WPR_X, 2 * WPR_Y, WPR_Z
|
||||
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]]]
|
||||
|
||||
block_depth = y * 0.4
|
||||
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.bar3d(x_cube, (y_cube - block_depth) * 0.5, z * 0.8, max_size, block_depth, z * 0.8, color='k', alpha=.25)
|
||||
# Set axis properties
|
||||
ax.set_box_aspect([x_cube, y_cube, z_cube])
|
||||
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)
|
||||
ax.set_xlim([0, x_cube]); ax.set_ylim([0, y_cube]); ax.set_zlim([0, z])
|
||||
ax.set_aspect('auto')
|
||||
# Draw gripping point
|
||||
u, v = np.mgrid[0:2 * np.pi:20j, 0:np.pi:20j]
|
||||
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:
|
||||
fig.savefig(picture_path, bbox_inches='tight', dpi=300, transparent=True)
|
||||
else:
|
||||
plt.show()
|
||||
plt.close()
|
||||
# Draw gripper
|
||||
gripper_thickness = max(x_cube, y_cube, z_cube) * 0.1
|
||||
gripper_wide = WPR_X * 0.4
|
||||
GRP_ALPHA = .40
|
||||
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:
|
||||
print(f"An error occurred: {e}")
|
||||
# Define finished workpiece dimensions
|
||||
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):
|
||||
try:
|
||||
# --- wpraw
|
||||
vars = all_group_vars['wp_raw']
|
||||
x, y, z = float(vars['x_wpraw']), float(vars['y_wpraw']), float(vars['z_wpraw'])
|
||||
if min(x, y, z) <= 0:
|
||||
raise ValueError("Dimensions must be positive.")
|
||||
# Draw gripper for finished workpiece
|
||||
gripper_thickness2 = max(x_cube, y_cube, z_cube) * 0.05
|
||||
gripper_wide2 = WPR_X * 0.4
|
||||
GRP_ALPHA2 = .25
|
||||
yyy2 = [-gripper_thickness2, y_cube2] if WPF_Y < WPR_Y else [-gripper_thickness2 + (WPF_Y - WPR_Y) * 2, y_cube]
|
||||
bars = [
|
||||
((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'})
|
||||
x_cube, y_cube = 2 * x, 2 * y
|
||||
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]]]
|
||||
# Draw CLP coordinate system
|
||||
axis_len = max(x_cube, y_cube, z_cube) * 0.15
|
||||
colors = ['r', 'g', 'b']
|
||||
origin_x = WPR_X - WP_CLP_OFFSET_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')
|
||||
|
||||
ax.add_collection3d(Poly3DCollection(faces, facecolors='k', linewidths=1, edgecolors='k', alpha=.15))
|
||||
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)
|
||||
# Define clamping block dimensions
|
||||
clp_height = z_cube * 0.2
|
||||
clp_width = 0.6 * x_cube
|
||||
clp_deep = y_cube * 0.3
|
||||
clp_supportdeep = 3
|
||||
base_x = WPR_X - clp_width / 2
|
||||
alpha = 0.35
|
||||
color = 'blue'
|
||||
linewidth = 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
|
||||
vars = all_group_vars['wp_fin']
|
||||
x, y, z, l = float(vars['x_wpfin']), float(vars['y_wpfin']), float(vars['z_wpfin']), float(vars['l_wpfin'])
|
||||
if min(x, y, z, l) <= 0:
|
||||
raise ValueError("Dimensions must be positive.")
|
||||
# Set view properties
|
||||
z_trans = WPR_Z*0.2
|
||||
zoom_factor = 1.1 # Adjust this factor to zoom out more or less
|
||||
ax.view_init(elev=30, azim=-160)
|
||||
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'})
|
||||
x_offset = x - l / 2
|
||||
vertices = np.array([[0, 0, 0], [l, 0, 0], [l, 2 * y, 0], [0, 2 * y, 0],
|
||||
[0, 0, z], [l, 0, z], [l, 2 * y, z], [0, 2 * y, z]]) + np.array([x_offset, 0, 0])
|
||||
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))
|
||||
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}")
|
||||
# Save or display the plot
|
||||
if not DEBUG:
|
||||
fig.savefig(picture_path, bbox_inches='tight', dpi=300, transparent=True)
|
||||
else:
|
||||
plt.show()
|
||||
plt.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
vars = {'x_wpraw': 10, 'y_wpraw': 15, 'z_wpraw': 20}
|
||||
generate_picture_wpraw({'wp_raw': vars}, "cfg_picture/TEST_wpraw.jpg", DEBUG=True)
|
||||
|
||||
vars = {'x_wpfin': 10, 'y_wpfin': 20, 'z_wpfin': 20, 'l_wpfin': 10}
|
||||
generate_picture_wpfin({'wp_fin': vars}, "cfg_picture/TEST_wpfin.jpg", DEBUG=True)
|
||||
vars = {'WPR_X': 20,
|
||||
'WPR_Y': 15,
|
||||
'WPR_Z': 20,
|
||||
'WPF_X': 10,
|
||||
'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)
|
||||
|
||||
40
functions.py
@ -5,6 +5,9 @@ from PIL import Image, ImageTk
|
||||
from tkinter import ttk, filedialog, messagebox
|
||||
import tkinter as tk
|
||||
import os
|
||||
import trimesh
|
||||
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
|
||||
import numpy as np
|
||||
|
||||
# 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()
|
||||
|
||||
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}")
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
; ---------------------------------------------------
|
||||
@ -1,5 +0,0 @@
|
||||
Selected Parameter Sets:
|
||||
inlay: inlay7
|
||||
wp_raw: wpraw1
|
||||
wp_fin: <<new par set>>
|
||||
grp: grp1
|
||||
@ -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
|
||||
|
||||
; ---------------------------------------------------
|
||||
@ -1,5 +0,0 @@
|
||||
Selected Parameter Sets:
|
||||
inlay: inlay4
|
||||
wp_raw: wpraw1
|
||||
wp_fin: wpfin1
|
||||
grp: grp1
|
||||
@ -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
|
||||
|
||||
; ---------------------------------------------------
|
||||
@ -1,5 +0,0 @@
|
||||
Selected Parameter Sets:
|
||||
inlay: inlay_kleinteil
|
||||
wp_raw: wpraw2
|
||||
wp_fin: wpfin1
|
||||
grp: grp1
|
||||
@ -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 =
|
||||
|
||||
; ---------------------------------------------------
|
||||
@ -1,6 +0,0 @@
|
||||
Selected Parameter Sets:
|
||||
inlay: inlay7
|
||||
wp_raw: wpraw1
|
||||
wp_fin: wpfin1
|
||||
grp: grp1
|
||||
clp: <<new par set>>
|
||||
@ -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
|
||||
|
||||
; ---------------------------------------------------
|
||||
@ -1,6 +0,0 @@
|
||||
Selected Parameter Sets:
|
||||
inlay: inlay7
|
||||
wp_raw: wpraw2
|
||||
wp_fin: wpfin1
|
||||
grp: grp1
|
||||
clp: clp2
|
||||
@ -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
|
||||
|
||||
; ---------------------------------------------------
|
||||
@ -1,6 +0,0 @@
|
||||
Selected Parameter Sets:
|
||||
inlay: <<new par set>>
|
||||
wp_raw: wpraw1
|
||||
wp_fin: wpfin1
|
||||
grp: grp3
|
||||
clp: clp1
|
||||