403 lines
49 KiB
Plaintext
403 lines
49 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Inverse Kinematics Simulation"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 81,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"from scipy.optimize import fsolve\n",
|
|
"import matplotlib.pyplot as plt\n",
|
|
"import math\n",
|
|
"import numpy as np"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Polar coordinate functions"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 82,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def cartesian_to_polar(x, y):\n",
|
|
" r = np.sqrt(x**2 + y**2)\n",
|
|
" theta = np.arctan2(y, x)\n",
|
|
" return r, theta\n",
|
|
"\n",
|
|
"def polar_to_cartesian(r, theta):\n",
|
|
" x = r * np.cos(theta)\n",
|
|
" y = r * np.sin(theta)\n",
|
|
" return x, y"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Calculate end-joint values from xyz position"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 83,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"[-243.619306486927,\n",
|
|
" -123.2097721836616,\n",
|
|
" 140.34764917140853,\n",
|
|
" -107.13787698774695,\n",
|
|
" -90.0,\n",
|
|
" 90.0]"
|
|
]
|
|
},
|
|
"execution_count": 83,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"def normalize_degree(theta):\n",
|
|
" # Normalizes degree theta from -1.5pi to 1.5pi\n",
|
|
" multiplier = 1.5\n",
|
|
" normalized_theta = theta % (math.pi * multiplier)\n",
|
|
" \n",
|
|
" # Maintain the negative sign if the original angle is negative\n",
|
|
" if theta < 0:\n",
|
|
" normalized_theta -= math.pi * multiplier\n",
|
|
"\n",
|
|
" # Return angle\n",
|
|
" return normalized_theta\n",
|
|
"\n",
|
|
"def get_joints_from_xyz_rel(x, y, z, rx=0, ry=-math.pi/2, rz=0, initial_guess = (math.pi/2, math.pi/2, 0)):\n",
|
|
" # Get limbs and offsets\n",
|
|
" offset_x, offset_y, offset_z = (0, 0, 0.14) # Tool offset\n",
|
|
" l_bs, l1, l2, l3, l_wt = (0.1333, .425, .39225, .1267, .0997) # Limb lengths\n",
|
|
" \n",
|
|
" # Calculate base angle and r relative to shoulder joint\n",
|
|
" def calculate_theta(x, y, a):\n",
|
|
" # Calculate if we need the + or - in our equations\n",
|
|
" if (x>a and y>=0) or (x>-a and y<0):\n",
|
|
" flip = 1\n",
|
|
" elif (x<a and y>=0) or (x<-a and y<0):\n",
|
|
" flip = -1\n",
|
|
" else: \n",
|
|
" # Critical section (x=a, or x=-a). Infinite slope\n",
|
|
" # Return 0 or 180 depending on sign\n",
|
|
" return math.atan2(y, 0) - math.pi/2\n",
|
|
" \n",
|
|
" # Calculate tangent line y = mx + b\n",
|
|
" if abs(a) != abs(x): # If there is no division by 0\n",
|
|
" m = (x*y + math.sqrt(x*x*y*y-(x*x-a*a)*(y*y-a*a)))/(x*x-a*a)\n",
|
|
" else: # Deal with edge case when x^2=a^2\n",
|
|
" m = flip*(-a*a+y*y)/(a*y-flip*abs(a*y))\n",
|
|
" b = flip * a * math.sqrt(1+m*m)\n",
|
|
"\n",
|
|
" # Calculate equivalent tangent point on circle\n",
|
|
" cx = (-flip*m*b)/(1+m*m)\n",
|
|
" cy = m*cx + flip*b\n",
|
|
"\n",
|
|
" # Calculate base angle, make angle negative if flip=1\n",
|
|
" theta = math.atan2(cy, cx) + (-math.pi if flip==1 else 0)\n",
|
|
"\n",
|
|
" return theta \n",
|
|
" \n",
|
|
" base_theta = calculate_theta(x, y, l_bs)\n",
|
|
" cx, cy = l_bs*math.cos(base_theta), l_bs*math.sin(base_theta)\n",
|
|
" r = math.sqrt((x-cx)**2 + (y-cy)**2) \n",
|
|
"\n",
|
|
"\n",
|
|
" # Formulas to find out joint positions for (r, z)\n",
|
|
" def inv_kin_r_z(p):\n",
|
|
" a, b, c = p \n",
|
|
"\n",
|
|
" return (l1*math.cos(a) + l2*math.cos(a-b) + l3*math.cos(a-b-c) - r, # r\n",
|
|
" l1*math.sin(a) + l2*math.sin(a-b) - l3*math.sin(a-b-c) - (l3*math.sin(a-b-c)) - (z + offset_z), # z\n",
|
|
" a-b-c) # wrist angle\n",
|
|
"\n",
|
|
"\n",
|
|
" # Normalize angles\n",
|
|
" base, shoulder, elbow, wrist1 = [normalize_degree(deg) for deg in [base_theta, *fsolve(inv_kin_r_z, initial_guess)]]\n",
|
|
"\n",
|
|
" # Return result\n",
|
|
" return base, shoulder, elbow, wrist1, ry, rz\n",
|
|
"\n",
|
|
"def get_joints_from_xyz_abs(x, y, z, rx=0, ry=-math.pi/2, rz=math.pi/2):\n",
|
|
" joints = get_joints_from_xyz_rel(x, y, z, rx, ry, rz)\n",
|
|
"\n",
|
|
" # Joint offsets\n",
|
|
" # Base, Shoulder, Elbow, Wrist\n",
|
|
" inverse = [1, -1, 1, 1, 1, 1]\n",
|
|
" offsets = [-math.pi/2, 0, 0, -math.pi/2, 0, 0]\n",
|
|
"\n",
|
|
" # Return adjusted joint positions\n",
|
|
" return [o+j*i for j, o, i in zip(joints, offsets, inverse)]\n",
|
|
"\n",
|
|
"# Print degree rotation for each joint (robot angles)\n",
|
|
"[math.degrees(deg) for deg in get_joints_from_xyz_abs(0, -0.3, 0.1)]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Simulate Arm and Joint Angles"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 84,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def draw_arm_side_view(x, y, z, details=False):\n",
|
|
"\n",
|
|
" # Get joint angles\n",
|
|
" l1, l2, l3 = .425, .39225, .1267\n",
|
|
" offset_x, offset_y, offset_z = (0, 0, 0.14)\n",
|
|
" r, theta = cartesian_to_polar(x, y)\n",
|
|
" base, shoulder, elbow, wrist, _, _ = get_joints_from_xyz_rel(x, y, z)\n",
|
|
"\n",
|
|
" # Print angles\n",
|
|
" if details:\n",
|
|
" print('Target position (x,y,z):', x, y, z)\n",
|
|
" print('R: ', round(math.sqrt(x**2+y**2),4))\n",
|
|
" print('Angles (base, shoulder, elbow, wrist):', [round(math.degrees(i), 4) for i in [base, shoulder, elbow, wrist]])\n",
|
|
" print('Robot Angles:', [round(math.degrees(i), 4) for i in get_joints_from_xyz_abs(x, y, z)])\n",
|
|
"\n",
|
|
" # Calculate each joint's endpoint position\n",
|
|
" x1, y1 = polar_to_cartesian(l1, shoulder)\n",
|
|
" x2, y2 = polar_to_cartesian(l2, shoulder-elbow)\n",
|
|
" x2 += x1\n",
|
|
" y2 += y1\n",
|
|
" x3, y3 = polar_to_cartesian(l3, shoulder-elbow-wrist)\n",
|
|
" x3 += x2\n",
|
|
" y3 += y2 \n",
|
|
" \n",
|
|
" tx = x3\n",
|
|
" ty = y3 - offset_z\n",
|
|
"\n",
|
|
" # Print each joint's endpoint position\n",
|
|
" if details:\n",
|
|
" print('elbow (x,y):', round(x1,3), round(y1,3))\n",
|
|
" print('wrist (x,y):', round(x2,3), round(y2,3))\n",
|
|
" print('tool (x,y):', round(x3,3), round(y3,3))\n",
|
|
"\n",
|
|
" # Draw limbs\n",
|
|
" plt.plot([0, x1], [0, y1], color='cyan', linewidth=7)\n",
|
|
" plt.plot([x1, x2], [y1, y2], color='orange', linewidth=7)\n",
|
|
" plt.plot([x2, x2+l3], [y2, y2], color='red', linewidth=7)\n",
|
|
" plt.plot()\n",
|
|
"\n",
|
|
" # Draw toolpoint\n",
|
|
" plt.plot([x3, tx], [y3, ty], color='black', linewidth=7)\n",
|
|
"\n",
|
|
" # Display angles\n",
|
|
" plt.text(0, 0.02, f'{round(math.degrees(shoulder), 2)}°')\n",
|
|
" plt.text(x1, y1+0.02, f'{round(math.degrees(elbow), 2)}°')\n",
|
|
" plt.text(x2, y2+0.02, f'{round(math.degrees(wrist), 2)}°')\n",
|
|
"\n",
|
|
" # Display r arrow\n",
|
|
" plt.annotate(f'', xy=(0, 0), xycoords='data', xytext=(x3, 0), textcoords='data', arrowprops={'arrowstyle': '<->'})\n",
|
|
" plt.annotate(f'r={round(r,4)}', xy=(x2/2, 0.01), xycoords='data', xytext=(x2/2, 0), textcoords='offset points')\n",
|
|
"\n",
|
|
" # Display z arrow\n",
|
|
" plt.annotate(f'', xy=(x3, 0), xycoords='data', xytext=(tx, ty), textcoords='data', arrowprops={'arrowstyle': '<->'})\n",
|
|
" plt.annotate(f'z={round(ty,4)}', xy=(tx+0.01, ty/2), xycoords='data', xytext=(x3/2, 0), textcoords='offset points')\n",
|
|
" \n",
|
|
" # Display plot\n",
|
|
" ax = plt.subplot(111)\n",
|
|
" ax.spines[['right', 'top']].set_visible(False)\n",
|
|
" plt.axis('equal')\n",
|
|
" plt.show()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def draw_arm_top_view(x, y, z, details=False):\n",
|
|
" # Get joint and position information\n",
|
|
" angles = get_joints_from_xyz_rel(x, y, z)\n",
|
|
" offset_x, offset_y, offset_z = (0, 0, 0.14) # Tool offset\n",
|
|
" l_bs, l1, l2, l3, l_wt = (0.1333, .425, .39225, .1267, .0997) # Limb lengths\n",
|
|
" cx, cy = l_bs*math.cos(angles[0]), l_bs*math.sin(angles[0]) # Base tangent point\n",
|
|
" line_angle = math.pi/2+angles[0]\n",
|
|
"\n",
|
|
" if details:\n",
|
|
" print('Angles:', [round(math.degrees(angle),3) for angle in angles])\n",
|
|
" print(f'Circle position (cx, cy): ({round(cx, 3)}, {round(cy, 3)})')\n",
|
|
"\n",
|
|
"\n",
|
|
" # Plot coordinate system\n",
|
|
" fig = plt.figure()\n",
|
|
" ax = fig.add_subplot(1, 1, 1)\n",
|
|
" ax.spines['left'].set_position('center')\n",
|
|
" ax.spines['bottom'].set_position('center')\n",
|
|
" ax.spines['right'].set_color('none')\n",
|
|
" ax.spines['top'].set_color('none')\n",
|
|
" ax.set_yticklabels([])\n",
|
|
" ax.set_xticklabels([])\n",
|
|
" ax.set_xticks([])\n",
|
|
" ax.set_yticks([])\n",
|
|
"\n",
|
|
" # Target point\n",
|
|
" # plt.plot(x, y, 'go')\n",
|
|
"\n",
|
|
" # Circle\n",
|
|
" circle = plt.Circle((0, 0), l_bs, color='b', fill=False, linewidth=1)\n",
|
|
" plt.plot([0, cx], [0, cy], color='b', linewidth=1)\n",
|
|
" ax.add_patch(circle)\n",
|
|
"\n",
|
|
" # Draw limbs\n",
|
|
" # Shoulder\n",
|
|
" x1, y1 = polar_to_cartesian(l1*math.cos(angles[1]), line_angle)\n",
|
|
" x1, y1 = cx+x1, cy+y1\n",
|
|
" z1 = l1*math.sin(angles[1])\n",
|
|
" plt.plot([cx, x1], [cy, y1], color='cyan', linewidth=3)\n",
|
|
"\n",
|
|
" # Elbow\n",
|
|
" x2, y2 = polar_to_cartesian(l2*math.cos(angles[1]-angles[2]), line_angle)\n",
|
|
" x2 += x1\n",
|
|
" y2 += y1\n",
|
|
" z2 = z1 + l2*math.sin(angles[1]-angles[2])\n",
|
|
" plt.plot([x1, x2], [y1, y2], color='orange', linewidth=2)\n",
|
|
"\n",
|
|
" # Wrist\n",
|
|
" x3, y3 = polar_to_cartesian(l3*math.cos(angles[1]-angles[2]-angles[3]), line_angle)\n",
|
|
" x3 += x2\n",
|
|
" y3 += y2\n",
|
|
" z3 = z2 + l3*math.sin(angles[1]-angles[2]-angles[3]) \n",
|
|
" plt.plot([x2, x3], [y2, y3], color='red', linewidth=2)\n",
|
|
"\n",
|
|
" # Print joint positions\n",
|
|
" if details:\n",
|
|
" print(f'Shoulder (x, y, z): ({round(x1,3)}, {round(y1,3)}, {round(z1,3)})')\n",
|
|
" print(f'Elbow (x, y, z): ({round(x2,3)}, {round(y2,3)}, {round(z2,3)})')\n",
|
|
" print(f'Wrist (x, y, z): ({round(x3,3)}, {round(y3,3)}, {round(z3,3)})')\n",
|
|
"\n",
|
|
" # Display angle\n",
|
|
" plt.text(0.01, -0.01-cy/abs(cy+0.00001)*0.02, f'{round(math.degrees(angles[0]), 2)}°', fontsize=7)\n",
|
|
"\n",
|
|
" # Display x arrow\n",
|
|
" sign = x3/abs(x3)\n",
|
|
" plt.annotate(f'', xy=(0, y3), xycoords='data', xytext=(x3, y3), textcoords='data', arrowprops={'arrowstyle': '<->'})\n",
|
|
" plt.annotate(f'x={round(x3,3)}', xy=(-0.1-sign*0.13, y3-0.015), xycoords='data', xytext=(x2/2, 0), textcoords='offset points')\n",
|
|
"\n",
|
|
" # Display y arrow\n",
|
|
" sign = y3/abs(y3)\n",
|
|
" plt.annotate(f'', xy=(x3, 0), xycoords='data', xytext=(x3, y3), textcoords='data', arrowprops={'arrowstyle': '<->'})\n",
|
|
" plt.annotate(f'y={round(y3,3)}', xy=((x3-0.1), -0.015-sign*0.03), xycoords='data', xytext=(x3/2, 0), textcoords='offset points')\n",
|
|
"\n",
|
|
"\n",
|
|
" # Set axis limits and labels\n",
|
|
" axis_limit = math.hypot(x, y)+.1\n",
|
|
" plt.axis('square')\n",
|
|
" plt.xlim(-axis_limit, axis_limit)\n",
|
|
" plt.ylim(-axis_limit, axis_limit)\n",
|
|
"\n",
|
|
" # Adjust the position of axis labels\n",
|
|
" plt.xlabel('+x', horizontalalignment='right', x=1.05)\n",
|
|
" plt.ylabel('+y', verticalalignment='top', rotation=0, y=1.05)\n",
|
|
" plt.show()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 89,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Target position (x,y,z): 0.5 0.5 0.3\n",
|
|
"R: 0.7071\n",
|
|
"Angles (base, shoulder, elbow, wrist): [-34.1339, 65.0453, 57.0325, 8.0128]\n",
|
|
"Robot Angles: [-124.1339, -65.0453, 57.0325, -81.9872, -90.0, 90.0]\n",
|
|
"elbow (x,y): 0.179 0.385\n",
|
|
"wrist (x,y): 0.568 0.44\n",
|
|
"tool (x,y): 0.694 0.44\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAj0AAAGfCAYAAAC0rWN5AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAA9hAAAPYQGoP6dpAABCx0lEQVR4nO3de1xUdf7H8RcMAiIXNZKLoSiYlqmUJGGm9osi10p3t12r3TAq223VX8WvvJRKFwtvmbvqapqXLutq7c+t3S5Ysflr3ShbL128bZiGmqBWgoCBMuf3BzVGgJyBOTPMzPv5eJxHcOZzznzmRPDunO/5ngDDMAxEREREfFygpxsQERERcQeFHhEREfELCj0iIiLiFxR6RERExC8o9IiIiIhfUOgRERERv6DQIyIiIn5BoUdERET8gkKPiIiI+AWFHhEREfELLQo9ixcvJjExkdDQUNLS0ti8eXOTtatXryYgIKDeEhoa6tT7GYZBeXk5emKGiIiItJTToWfdunXk5OSQm5vL1q1bGTBgAJmZmRw5cqTJbSIjIzl8+LBj+eKLL5x6zxMnThAVFcWJEyecbVdEREQEaEHomT9/PuPGjSM7O5sLL7yQpUuXEhYWxsqVK5vcJiAggNjYWMcSExPTqqZFREREnOVU6KmpqWHLli1kZGSc2UFgIBkZGRQWFja5XUVFBd27dychIYFRo0axY8eOs75PdXU15eXl9RYRERGR1nAq9Bw7doza2toGZ2piYmIoKSlpdJvevXuzcuVKXnnlFV544QXsdjuDBw/m4MGDTb5PXl4eUVFRjiUhIcGZNkVEREQasPzurfT0dLKyskhJSWHYsGGsX7+ec889l6effrrJbaZOnUpZWZljOXDggNVtioiIiI8LcqY4Ojoam81GaWlpvfWlpaXExsaa2ke7du24+OKLKSoqarImJCSEkJAQZ1oTEREROSunzvQEBwczcOBACgoKHOvsdjsFBQWkp6eb2kdtbS2ffPIJcXFxznUqIiIi0gpOnekByMnJYezYsaSmpjJo0CAWLFhAZWUl2dnZAGRlZdG1a1fy8vIAePTRR7nssstITk7m+PHjzJ07ly+++II777zTtZ9ERERE5CycDj1jxozh6NGjzJgxg5KSElJSUsjPz3cMbi4uLiYw8MwJpG+++YZx48ZRUlJCp06dGDhwIO+99x4XXnih6z6FiIiISDMCDC+Y5ri8vJyoqCjKysqIjIz0dDsiIiLihfTsLREREfELCj0iIiLiFxR6RERExC8o9IiIiIhfUOgRERERv6DQIyIiIn5BoUdERET8gkKPiIiI+AWFHhEREfELCj0iIuLVamtrmT59Oj169KB9+/YkJSXx2GOP0dwDBzZu3Mgll1xCSEgIycnJrF69ut7r7777Ltdffz3x8fEEBATw8ssvN9hHSUkJI0aMID4+ngkTJmC32134ycTVFHpERMSrzZ49myVLlrBo0SJ27drF7NmzmTNnDgsXLmxym3379jFy5EiuvPJKtm/fzr333sudd97Jhg0bHDWVlZUMGDCAxYsXN7mf6dOnk5qayhtvvMHnn3/O2rVrXfrZxLWcfuCoiIhIW/Lee+8xatQoRo4cCUBiYiJ//vOf2bx5c5PbLF26lB49evDkk08CcMEFF7Bp0yaeeuopMjMzARgxYgQjRow463t/8803XH311fTr14+ePXty/Phx13wosYTO9IiIiFcbPHgwBQUF/Oc//wHgo48+YtOmTWcNLIWFhWRkZNRbl5mZSWFhoVPvPWXKFCZOnEhISAhbt24lKyvL+Q8gbqMzPSIi4tWmTJlCeXk5ffr0wWazUVtby+OPP86vfvWrJrcpKSkhJiam3rqYmBjKy8s5efIk7du3N/XeqampHDp0iGPHjhEbG9uqzyHWU+gRERGv9uKLL/KnP/2JNWvW0LdvX8cYnfj4eMaOHWv5+wcFBSnweAmFHhER8WoPPPAAU6ZM4aabbgKgX79+fPHFF+Tl5TUZemJjYyktLa23rrS0lMjISNNnecT7aEyPiIh4taqqKgID6/85s9lsZ719PD09nYKCgnrr3nrrLdLT0y3pUdoGnekRERGvdv311/P444/TrVs3+vbty7Zt25g/fz633367o2bq1KkcOnSI5557DoDf/va3LFq0iEmTJnH77bfzj3/8gxdffJHXXnvNsU1FRQVFRUWO7/ft28f27dvp3Lkz3bp1c98HFJcJMJqbvakNKC8vJyoqirKyMiIjIz3djoiItCEnTpxg+vTp/PWvf+XIkSPEx8dz8803M2PGDIKDgwG47bbb2L9/Pxs3bnRst3HjRu677z527tzJeeedx/Tp07ntttvqvX7llVc2eL+xY8c2mMhQvINCj4iIiPgFjekRERERv6DQIyIi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",
|
|
"text/plain": [
|
|
"<Figure size 640x480 with 1 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Angles: [-34.134, 65.045, 57.033, 8.013, -90.0, 0.0]\n",
|
|
"Circle position (cx, cy): (0.11, -0.075)\n",
|
|
"Shoulder (x, y, z): (0.211, 0.074, 0.385)\n",
|
|
"Elbow (x, y, z): (0.429, 0.395, 0.44)\n",
|
|
"Wrist (x, y, z): (0.5, 0.5, 0.44)\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"image/png": "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1app5syZ6t27t3w+nyIiInTllVc63X6HX92Tu2HDhkpISFBsbKzefvtt9fWne0YEKHaRwa80bWr/qve3y3/btZM2bJC6dJESE6Xbb5f27i3YOleulTRL+vmckwhmSioufzs3btxYjRo10uzZs7VmzRp988036t27tyTlaRdZ5cqVJem8m8EdOHAg67nciI6O1tVXX62tLg+8FSOMYOBXmjWzFx1u3SpddZXX1eQUFWV3kd19t9Svn3TNNfbYTPfu+RvNTImUlJBz2SOSitssWomJiZowYYL27Nmjdu3aqXp1O5Vns2bNcr2LrFatWqpcubIWLVqUNeFlWlqaVqxYoaSkpFzX8tNPP2nbtm15PskgULVu3Vq9e/fOCvVCZwA/cvSoMaVKGTN6dNFuNzU11UgyqampuXr94cPGdO9ujGTM3Xcbc+BA3ra39owxOmWMTPbjamPM8TzWHQx+/PFHU7p0aRMeHm7efPPNfK9nzJgxJjo62sydO9esX7/edOrUydSqVcucPHky6zVt2rQxEydOzOoPHjzYLF682OzYscMsXbrUtGvXzpQvX94cPHiwQJ8pUNx4441mxowZ5y2fNWuWKVOmjPn++++zliUlJZk6deqY48dz/11KwMDv9O5tTGysMWfOFN028xowZ/3zn8aUL29MhQrGvPNO7t5zyhgT92POcAkxxizLW8lBpWfPniYmJsakp6fnex2ZmZnmqaeeMpUqVTIlS5Y0bdu2NZs3b87xmtjYWDN8+PCsfrdu3UyVKlVMeHi4qVatmunWrZvZunVrvmsINBcLGGOM6dq1q2nevLk5ffq0mT9/vilRooRZvXp1ntZPwMDvrFplRwbvv19028xvwBhjzP79xtx1l625Rw9jUlIu/fqnTM5wkTHmT3kvOai0adPGPPTQQ16XUexcKmBSUlLMFVdcYZKSkkylSpXMM888k+f1EzDwS82bG9OhQ9FtryABY4wxmZnG/OMfxkRHG1OlijEffHDh160yxoRm5gyXa4wx+f+7PbClpKSYd99914SEhJjvvvvO63KC3jPPPGPKlCmT9QgJCTElS5bMsWzXrl1Zr//444+NJHPdddeZjIyMPG+Pg/zwSw8+aE8F3rZNusRUUn7D55Puu0+66SZ7llnHjvbrc8/ZaWAkKV126peMX50QECZptqQivjuB32jcuLGOHj2qsWPH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",
|
|
"text/plain": [
|
|
"<Figure size 640x480 with 1 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"def draw_arm(x, y, z, details=False):\n",
|
|
" draw_arm_side_view(x,y,z, details=details)\n",
|
|
" draw_arm_top_view(x,y,z, details=details)\n",
|
|
"\n",
|
|
"draw_arm(0.5,0.5,0.3, details=True)"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Python 3",
|
|
"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.10.4"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 2
|
|
}
|