-
Notifications
You must be signed in to change notification settings - Fork 101
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
218 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
218 changes: 218 additions & 0 deletions
218
examples/worm_cutting_tool/cutting_tool_worm_assembly.ipynb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,218 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"id": "5e24589a-461d-46b5-8141-37f948dcf4dc", | ||
"metadata": {}, | ||
"source": [ | ||
"# cutting tool for a worm gear\n", | ||
"\n", | ||
"1. idea 1: \n", | ||
"\n", | ||
"<img src=\"../../docs/computing a profile_from_a_given_rack.jpg\">" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 35, | ||
"id": "7eacf041-aa83-49e2-9cbe-066f177197f6", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"import sympy as sp\n", | ||
"import numpy as np" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 119, | ||
"id": "980417d0-c79d-4501-a7cc-9725b3bbea83", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"def symbolic_transformation(angle, axis, translation):\n", | ||
" \"\"\"\n", | ||
" see http://en.wikipedia.org/wiki/SO%284%29#The_Euler.E2.80.93Rodrigues_formula_for_3D_rotations\n", | ||
" sympy enabled transformation\n", | ||
" angle: angle of rotation\n", | ||
" axis: the axis of the rotation\n", | ||
" translation: translation of transformation\n", | ||
" \"\"\"\n", | ||
" assert len(axis) == 3\n", | ||
" a = sp.cos(angle / 2)\n", | ||
" axis_normalized = axis / sp.sqrt(axis.dot(axis))\n", | ||
" (b, c, d) = -axis_normalized * sp.sin(angle / 2)\n", | ||
" mat = sp.Matrix(\n", | ||
" [\n", | ||
" [\n", | ||
" a**2 + b**2 - c**2 - d**2,\n", | ||
" 2 * (b * c - a * d),\n", | ||
" 2 * (b * d + a * c),\n", | ||
" translation[0],\n", | ||
" ],\n", | ||
" [\n", | ||
" 2 * (b * c + a * d),\n", | ||
" a**2 + c**2 - b**2 - d**2,\n", | ||
" 2 * (c * d - a * b),\n", | ||
" translation[1],\n", | ||
" ],\n", | ||
" [\n", | ||
" 2 * (b * d - a * c),\n", | ||
" 2 * (c * d + a * b),\n", | ||
" a**2 + d**2 - b**2 - c**2,\n", | ||
" translation[2],\n", | ||
" ],\n", | ||
" [0.0, 0.0, 0.0, 1.0],\n", | ||
" ]\n", | ||
" )\n", | ||
" return sp.nsimplify(mat,tolerance=1e-10,rational=True)\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 219, | ||
"id": "5852aa56-e66b-4f3c-a50d-0cb4cb21abd2", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"T1 = symbolic_transformation(np.pi / 2.,\n", | ||
" np.array([1., 0., 0.]),\n", | ||
" np.array([12.5,0., 1.15]))\n", | ||
"T2 = symbolic_transformation(-t / 7.5,\n", | ||
" np.array([0., 0., 1.]),\n", | ||
" np.array([0., 0., 0.]))\n", | ||
"T3 = symbolic_transformation(0.,\n", | ||
" np.array([1., 0., 0.]),\n", | ||
" np.array([0., 0., t]))\n", | ||
"\n", | ||
"T = T2.inverse() @ T1.inverse() @ T3" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 220, | ||
"id": "7c9837b8-caf7-4447-bf0d-eba9085197a5", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"data": { | ||
"text/plain": [ | ||
"array([[ 0. , 0. , -0.13333333, 0.15333333],\n", | ||
" [-0.13333333, 0. , 0. , 0.66666667],\n", | ||
" [ 0. , 0. , 0. , 0. ],\n", | ||
" [ 0. , 0. , 0. , 0. ]])" | ||
] | ||
}, | ||
"execution_count": 220, | ||
"metadata": {}, | ||
"output_type": "execute_result" | ||
} | ||
], | ||
"source": [ | ||
"T_fn = sp.lambdify(t, T)\n", | ||
"dT_fn = sp.lambdify(t, T.diff(t))\n", | ||
"dT_fn(0.)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "e4354a36-409a-40a6-8f4f-bb5a6c84f3b7", | ||
"metadata": {}, | ||
"source": [ | ||
"Diese Methode funktioniert nicht, weil die Bedingung zur Bestimmung des Kontaktpunktes falsch ist.\n", | ||
"Eine Bedingung für die generierung einer konstanten Übersetzung ist, dass die Normale auf die Kontaktfläche (Zahnstange) immer durch den Punkt p (Eingriffspunkt für Ersatzzahnrad (Zylinder) und Ersatzzahnstange (Quader) gehen muss.\n", | ||
"Gesucht sind also Punkte auf der Fläche S welche verbunden mit P normal auf die Fläche stehen. Dies kann auch als minimaler Abstand von P zur Fläche gesehen werden.\n", | ||
"\n", | ||
"für jedes u: min(norm(S(u,v)-P)) -> d(norm(S(u,v)-P)/dv = 0\n", | ||
"die Änderung des Abstands ist 0 -> die Gerade steht normal auf die Fläche\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "43f00b65-c05c-4734-8c5a-e7845a6f4dff", | ||
"metadata": {}, | ||
"source": [ | ||
"## Vorgehensweise\n", | ||
"\n", | ||
"1. approximate the surface by a BSplineSurface\n", | ||
"\n", | ||
"- Erstellen eines \"Cross-Sektion\" objekts aus dem \"Werkzeug\"\n", | ||
"\n", | ||
"<img src=\"cross_section.png\"> \n", | ||
"\n", | ||
"- Draft downgrade um Kanten zu bekommen\n", | ||
"das Cross-section Objekt beinhaltet nicht die anfangs und end Kanten. Diese müssen zusätzlich vom Werkzeug extrahiert werden\n", | ||
"\n", | ||
"- Part Loft zum erstellen einer schönen BSplinefläche\n", | ||
"\n", | ||
"<img src=\"loft_bspline_flaechen.png\"> \n", | ||
"\n", | ||
"3. Loft -> Surface\n", | ||
"\n", | ||
"```python\n", | ||
"# select the cutting faces\n", | ||
"face_1 = App.ActiveDocument.Loft.Shape.Faces[0].copy()\n", | ||
"face_2 = App.ActiveDocument.Loft001.Shape.Faces[0].copy()\n", | ||
"\n", | ||
"# compute the contact curve:\n", | ||
"bsp_1 = face_1.Surface\n", | ||
"bsp_2 = face_2.Surface\n", | ||
"\n", | ||
"```\n", | ||
"\n", | ||
"4. Minimierung des Abstands zum \"Pitch-Punkt\"\n", | ||
"\n", | ||
"```python\n", | ||
"import scipy as scp\n", | ||
"point = App.Vector(5., 0., 1.15 - time) \n", | ||
"xyz_1 = []\n", | ||
"for v in np.linspace(0, 1, 5):\n", | ||
" def dist_1(u):\n", | ||
" distance = bsp_1.value(u, v) - point\n", | ||
" return distance.x ** 2 + distance.z ** 2\n", | ||
" u_1 = scp.optimize.minimize(dist_1, 0.5, tol=1e-6).x[0]\n", | ||
" xyz_1.append(bsp_1.value(u_1, v))\n", | ||
"```\n", | ||
"\n", | ||
"5. erstellen einer B-Spline Kurve welche durch die Kinematik T transformiert wird\n", | ||
"\n", | ||
"```python\n", | ||
"c_1 = Part.BSplineCurve()\n", | ||
"c_1.interpolate(Points=xyz_1)\n", | ||
"c_1 = c_1.toShape()\n", | ||
"\n", | ||
"Part.show(c_1.transformShape(T))\n", | ||
"```\n", | ||
"\n", | ||
"6. Loft anwenden auf die erstellten BSpline Kurven\n", | ||
"\n", | ||
"<img src=\"loft_of_generated_bsplines.png\">\n", | ||
"\n", | ||
"7. Array für das Zahnrad\n", | ||
"\n", | ||
"<img src=\"gear_assembly.png\">" | ||
] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "Python 3 (ipykernel)", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3", | ||
"version": "3.11.7" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 5 | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.