diff --git a/_condaenv.yml b/_condaenv.yml index 41b1b4a..c0897c8 100644 --- a/_condaenv.yml +++ b/_condaenv.yml @@ -11,4 +11,6 @@ dependencies: - pandas - openpyxl - paramiko - - matplotlib \ No newline at end of file + - matplotlib + - trimesh + - manifold3d \ No newline at end of file diff --git a/cfg_parsets/wp.yml b/cfg_parsets/wp.yml new file mode 100644 index 0000000..323ddb4 --- /dev/null +++ b/cfg_parsets/wp.yml @@ -0,0 +1,9 @@ +wp1: + WPF_X: '20' + WPF_Y: '20' + WPF_Z: '20' + WPR_X: '20' + WPR_Y: '20' + WPR_Z: '33' + WP_CLP_OFFSET_X: '4' + WP_GRP_OFFSET_Z: '5' diff --git a/cfg_picture/img_clp.png b/cfg_picture/img_clp.png index ea3cd80..2882853 100644 Binary files a/cfg_picture/img_clp.png and b/cfg_picture/img_clp.png differ diff --git a/def.yml b/def.yml index 759f1ce..696a017 100644 --- a/def.yml +++ b/def.yml @@ -16,10 +16,11 @@ groups: WPR_X: double WPR_Y: double WPR_Z: double + WPF_X: double + WPF_Y: double + WPF_Z: double WP_CLP_OFFSET_X: double - WPR_GRP_OFFSET_Z: double - WPF_GRP_OFFSET_Y: double - WPF_GRP_OFFSET_Z: double + WP_GRP_OFFSET_Z: double cfg: picture_name: img_wp.png clp: diff --git a/funct_clp.py b/funct_clp.py index 966897c..5110cd9 100644 --- a/funct_clp.py +++ b/funct_clp.py @@ -6,7 +6,7 @@ import numpy as np def generate_picture_clp(all_group_vars, picture_path, DEBUG=False): try: # Get WPR_X, WPR_Y, and WPR_Z values - vars = all_group_vars['wp_raw'] + vars = all_group_vars['wp'] x_wpraw = float(vars['WPR_X']) y_wpraw = float(vars['WPR_Y']) z_wpraw = float(vars['WPR_Z']) diff --git a/funct_wp.py b/funct_wp.py index 59925d8..b93d8a0 100644 --- a/funct_wp.py +++ b/funct_wp.py @@ -1,32 +1,47 @@ import matplotlib.pyplot as plt from mpl_toolkits.mplot3d.art3d import Poly3DCollection import numpy as np +import trimesh def generate_picture_wp(all_group_vars, picture_path, DEBUG=False): # try: vars = all_group_vars['wp'] - WPR_X, WPR_Y, WPR_Z, WP_CLP_OFFSET_X, WPR_GRP_OFFSET_Z, WPF_GRP_OFFSET_Y, WPF_GRP_OFFSET_Z = (float(vars[k]) for k in - ['WPR_X', 'WPR_Y', 'WPR_Z', 'WP_CLP_OFFSET_X', 'WPR_GRP_OFFSET_Z', 'WPF_GRP_OFFSET_Y', 'WPF_GRP_OFFSET_Z']) - if min(WPR_X, WPR_Y, WPR_Z) <= 0: + 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']) + + if min(WPR_X, WPR_Y, WPR_Z, WPF_X, WPF_Y, WPF_Z) <= 0: raise ValueError("Dimensions must be positive.") - # -------------------- wpraw ------------------------- - fig, ax = plt.subplots(subplot_kw={'projection': '3d'}) - x_cube, y_cube = 2 * WPR_X, 2 * WPR_Y - vertices = 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 = [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]]] - # Polyeder hinzufügen - ax.add_collection3d(Poly3DCollection(faces, facecolors='k', linewidths=1, edgecolors='k', alpha=.15)) + fig, ax = plt.subplots(subplot_kw={'projection': '3d'}) + + # -------------------- wpraw ------------------------------------------------------------------------------------- + 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]]] # Achsen-Einstellungen zusammenfassen - ax.set_box_aspect([x_cube, y_cube, WPR_Z]) + ax.set_box_aspect([x_cube, y_cube, z_cube]) ax.set(xticks=[], yticks=[], zticks=[]) - # Kugel zeichnen + # KOS WP zeichnen + 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') + + + # WP + ax.add_collection3d(Poly3DCollection(faces_raw, facecolors='k', linewidths=1, edgecolors='k', alpha=.15)) + + # GRIFFPUNKT 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( @@ -36,30 +51,96 @@ def generate_picture_wp(all_group_vars, picture_path, DEBUG=False): color='r' ) - # Koordinatenachsen zeichnen - axis_len = max(x_cube, y_cube, WPR_Z) * 0.3 - colors = ['r', 'g', 'b'] - for i, vec in enumerate(np.eye(3)): - ax.quiver(0, 0, 0, *(axis_len * vec), color=colors[i], linewidth=5) - - gripper_thickness = max(x_cube, y_cube, WPR_Z) * 0.1 + # GREIFER + gripper_thickness = max(x_cube, y_cube, z_cube) * 0.1 gripper_wide = WPR_X * 0.4 - GRP_ALPHA = .25 + GRP_ALPHA = .40 bars = [ - ((x_cube - gripper_wide) * 0.5, -gripper_thickness, WPR_Z - WPR_GRP_OFFSET_Z), - ((x_cube - gripper_wide) * 0.5, y_cube, WPR_Z - WPR_GRP_OFFSET_Z), + ((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, 2 * WPR_Z + WPR_GRP_OFFSET_Z, + gripper_wide, gripper_thickness, 5 * WPR_Z + WP_GRP_OFFSET_Z, color='r', alpha=GRP_ALPHA, edgecolor='k', linewidth=0.5 ) + # -------------------- wpfin--------------------------------------------------------------------------------- + x_cube2, y_cube2, z_cube2 = 2 * WPF_X, 2 * WPF_Y, WPF_Z + + # GRIFFPUNKT + 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' + ) + + + # GREIFER + gripper_thickness2 = max(x_cube, y_cube, z_cube) * 0.05 + gripper_wide2 = WPR_X * 0.4 + GRP_ALPHA2 = .25 + # wpf_y_offs = (np.sign(WPF_Y-WPR_Y)/2+.5) * (WPF_Y-WPR_Y) + 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 + ) + + # -------------------- clp ------------------------------------------------------------------------------------- + + # KOS CLP zeichnen + 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') + + # Add two black blocks on the Y-faces in the middle of the cube height + + clp_height = z_cube * 0.2 + clp_width = 0.6 * x_cube + clp_deep = y_cube * 0.3 # Scale the arrows relative to the smallest dimension + clp_supportdeep = 3 # Scale the arrows relative to the smallest dimension + base_x = WPR_X - clp_width/2 + alpha = 0.35 + color = 'blue' + linewidth = 0 + + + # Replace the bar3d calls with plot_merged_cubes_trimesh + x = base_x - WP_CLP_OFFSET_X + dx = clp_width + y = 0 + dy1 = clp_deep + dy2 = clp_supportdeep + z = 0 + dz = clp_height + plot_clamping(ax, x, y, z, dx, dy1, dy2, dz, color=color, + alpha=alpha, linewidth=linewidth) + + y = y_cube + plot_clamping(ax, x, y, z, dx, dy1, dy2, dz, color=color, + alpha=alpha, linewidth=linewidth, inverty=True) + # -------------------- view ------------------------------------------------------------------------------------- ax.view_init(elev=18, azim=-130) + # ax.view_init(elev=45, azim=-160) ax.set_xlim([0, x_cube]); ax.set_ylim([0, y_cube]); ax.set_zlim([0, WPR_Z]) ax.set_aspect('auto') @@ -75,142 +156,38 @@ def generate_picture_wp(all_group_vars, picture_path, DEBUG=False): +def plot_clamping(ax, x, y, z, dx, dy1, dy2, dz, color='blue', alpha=0.5, + linewidth=1, inverty=False): + """Plots merged cubes using trimesh, hiding mesh edges and drawing specific edges manually.""" + dyy1 = y - dy1 / 2 if not inverty else y + dy1 / 2 + dyy2 = y - (dy1-dy2) / 2 if not inverty else y + (dy1-dy2)/2 -# --------------- OLD ------------------------ -def generate_picture_wpraw(all_group_vars, picture_path, DEBUG=False): + # Create and translate Cube 1 + cube1 = trimesh.creation.box(extents=[dx, dy1, dz]) + cube1.apply_translation([x + dx / 2, dyy1, z + dz / 2]) + + # Create and translate Cube 2 + cube2 = trimesh.creation.box(extents=[dx, dy2+dy1, dz]) + cube2.apply_translation([x + dx / 2, dyy2, z - dz / 2]) + try: - # --- wpraw - vars = all_group_vars['wp_raw'] - x, y, z = float(vars['WPR_X']), float(vars['WPR_Y']), float(vars['WPR_Z']) - if min(x, y, z) <= 0: - raise ValueError("Dimensions must be positive.") - - 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]]] - - 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) - - 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) - - 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) - - - - 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') - - if not DEBUG: - fig.savefig(picture_path, bbox_inches='tight', dpi=300, transparent=True) - else: - plt.show() - plt.close() + # Perform boolean union + merged = trimesh.boolean.union([cube1, cube2]) + # Create Poly3DCollection with NO edges + ax.add_collection3d(Poly3DCollection( + merged.vertices[merged.faces], + facecolors=color, alpha=alpha, edgecolors=color, linewidth=linewidth + )) except Exception as e: - print(f"An error occurred: {e}") + print(f"Trimesh union failed: {e}") -def generate_picture_wpfin(all_group_vars, picture_path, DEBUG=False): - try: - # --- wpraw - vars = all_group_vars['wp_raw'] - x, y, z = float(vars['WPR_X']), float(vars['WPR_Y']), float(vars['WPR_Z']) - if min(x, y, z) <= 0: - raise ValueError("Dimensions must be positive.") - - 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]]] - - 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) - - - # --- 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.") - - 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}") if __name__ == "__main__": - vars = {'WPR_X': 20, 'WPR_Y': 15, 'WPR_Z': 20, 'WP_CLP_OFFSET_X': 20, 'WPR_GRP_OFFSET_Z': 15, 'WPF_GRP_OFFSET_Y': 20, 'WPF_GRP_OFFSET_Z': 20} + vars = {'WPR_X': 20, 'WPR_Y': 15, 'WPR_Z': 20, 'WPF_X': 10, 'WPF_Y': 18, 'WPF_Z': 10, 'WP_CLP_OFFSET_X': 3, 'WP_GRP_OFFSET_Z': 5} generate_picture_wp({'wp': vars}, "cfg_picture/TEST_wpraw.jpg", DEBUG=True) # vars = {'x_wpfin': 10, 'y_wpfin': 20, 'z_wpfin': 20, 'l_wpfin': 10}