├── Homework_1.ipynb ├── Homework_2.ipynb ├── Homework_3.ipynb ├── Readme.md ├── figures ├── spatial_3R.png └── spatial_3R.svg ├── kinematics.ipynb ├── planar_2R_robot.urdf ├── sim_env_setup.ipynb ├── spatial_3R_robot.urdf └── torque_control.ipynb /Homework_1.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Homework: Problem 1\n", 8 | "\n", 9 | "a) Implement a PD based trajectory-tracking controller for the robot.\n", 10 | "\n", 11 | "b) Use the controller to track the end-effector trajectories defined by the function 'trajectory(t)' which is implemented in this file. \n", 12 | "\n", 13 | "c) Provide plots comparing the desired and actual values to show the tracking performance of the controller. Show plots for the joint angles and the end-effector co-ordinates." 14 | ] 15 | }, 16 | { 17 | "cell_type": "code", 18 | "execution_count": 10, 19 | "metadata": {}, 20 | "outputs": [], 21 | "source": [ 22 | "###############################\n", 23 | "# Import the necessary modules\n", 24 | "###############################\n", 25 | "\n", 26 | "# The PyBullet physics simulation library\n", 27 | "import pybullet as p\n", 28 | "import pybullet_data\n", 29 | "\n", 30 | "# Numpy for numerical calculations and manipulations\n", 31 | "import numpy as np\n", 32 | "import math\n", 33 | "\n", 34 | "# Matplotlib to create the necessary plots\n", 35 | "import matplotlib.pyplot as plt" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": 11, 41 | "metadata": {}, 42 | "outputs": [], 43 | "source": [ 44 | "#################################################################\n", 45 | "# Forward and Inverse kinematics modules for the serial-2R robot\n", 46 | "#################################################################\n", 47 | "\n", 48 | "def forward_kinematics(theta1, theta2, l1, l2):\n", 49 | " '''\n", 50 | " Forward kinematics module for a serial-2R chain.\n", 51 | " The base of the manipulator is assumed to be placed at the\n", 52 | " coordinates [0,0].\n", 53 | " All the joints allow rotation about the positive Z-axis.\n", 54 | " Args:\n", 55 | " --- theta1: Angle between the link l1 and the positive x-axis (in radians)\n", 56 | " --- theta2: Relative angle between link l1 and link l2 (in radians)\n", 57 | " --- l1: Length of link l1 (in m)\n", 58 | " --- l2: Length of link l2 (in m)\n", 59 | " Ret:\n", 60 | " --- [x, y]: Position co-ordinates of the end-effector (in m)\n", 61 | " '''\n", 62 | " x = l1*math.cos(theta1) + l2*math.cos(theta1 + theta2)\n", 63 | " y = l1*math.sin(theta1) + l2*math.sin(theta1 + theta2)\n", 64 | " return [x, y]\n", 65 | "\n", 66 | "def inverse_kinematics(x, y, l1, l2, branch=1):\n", 67 | " '''\n", 68 | " Inverse kinematics modules for the serial-2R manipulator.\n", 69 | " The base of the manipulator is placed at [0,0].\n", 70 | " Axis of rotation is the Z+ axis.\n", 71 | " Args:\n", 72 | " --- x : X co-ordinate of the end-effector\n", 73 | " --- y : Y co-ordinate of the end-effector\n", 74 | " --- l1: Length of link l1\n", 75 | " --- l2: Length of link l2\n", 76 | " --- branch: Branch of the inverse kinematics solution.\n", 77 | " Ret:\n", 78 | " --- valid: Binary variable indicating if the solution is valid or not\n", 79 | " --- [theta1, theta2]: Angles made by link l1 w.r.t X+ axis and the relative\n", 80 | " angle between links l1 and l2 respectively.\n", 81 | " '''\n", 82 | " a = 2*x*l2\n", 83 | " b = 2*y*l2\n", 84 | " c = l1*l1 - x*x - y*y - l2*l2 \n", 85 | " psi = math.atan2(b, a)\n", 86 | " d = -c/math.sqrt(a*a + b*b)\n", 87 | " \n", 88 | " if (d < -1) or (d > 1):\n", 89 | " print(\"Position out of workspace.\")\n", 90 | " return False, [0,0]\n", 91 | " if branch == 1:\n", 92 | " theta12 = psi + math.acos(-c/math.sqrt(a*a + b*b))\n", 93 | " else:\n", 94 | " theta12 = psi - math.acos(-c/math.sqrt(a*a + b*b))\n", 95 | " \n", 96 | " theta1 = math.atan2((y - l2*math.sin(theta12))/l1, (x - l2*math.cos(theta12))/l1)\n", 97 | " return True, [theta1, theta12-theta1]" 98 | ] 99 | }, 100 | { 101 | "cell_type": "code", 102 | "execution_count": 12, 103 | "metadata": {}, 104 | "outputs": [], 105 | "source": [ 106 | "##############################################################\n", 107 | "# Create an instance of the Physics Server and connect to it\n", 108 | "##############################################################\n", 109 | "\n", 110 | "# Use p.DIRECT to connect to the server without rendering a GUI\n", 111 | "# Use p.GUI to create a GUI to render the simulation\n", 112 | "client = p.connect(p.DIRECT) # or p.GUI\n", 113 | "\n", 114 | "\n", 115 | "# Load the URDF of the plane that forms the ground\n", 116 | "p.setAdditionalSearchPath(pybullet_data.getDataPath()) # Set the search path to find the plane.urdf file\n", 117 | "plane = p.loadURDF(\"plane.urdf\")\n", 118 | "\n", 119 | "\n", 120 | "# Load the URDF of the robot\n", 121 | "robot = p.loadURDF(\"planar_2R_robot.urdf\")" 122 | ] 123 | }, 124 | { 125 | "cell_type": "code", 126 | "execution_count": 13, 127 | "metadata": {}, 128 | "outputs": [], 129 | "source": [ 130 | "##################################################\n", 131 | "# Set the necessary parameters for the simulation\n", 132 | "##################################################\n", 133 | "\n", 134 | "# Set the Gravity vector\n", 135 | "p.setGravity(0,0,-9.81, physicsClientId = client)\n", 136 | "\n", 137 | "# Set the simulation time-step\n", 138 | "p.setTimeStep(0.001) #The lower this is, more accurate the simulation \n", 139 | "\n", 140 | "# You can be faster than real-time if you choose\n", 141 | "#p.setRealTimeSimulation(0) # we want to be faster than real time." 142 | ] 143 | }, 144 | { 145 | "cell_type": "code", 146 | "execution_count": 14, 147 | "metadata": {}, 148 | "outputs": [], 149 | "source": [ 150 | "#################################\n", 151 | "# Enable the motors on the joints \n", 152 | "#################################\n", 153 | "\n", 154 | "# This step is required to enable torque control. Refer to the documentation for more details.\n", 155 | "p.setJointMotorControl2(robot, 1, p.VELOCITY_CONTROL, force=0)\n", 156 | "p.setJointMotorControl2(robot, 2, p.VELOCITY_CONTROL, force=0)" 157 | ] 158 | }, 159 | { 160 | "cell_type": "code", 161 | "execution_count": 15, 162 | "metadata": {}, 163 | "outputs": [ 164 | { 165 | "data": { 166 | "image/png": "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\n", 167 | "text/plain": [ 168 | "
" 169 | ] 170 | }, 171 | "metadata": { 172 | "needs_background": "light" 173 | }, 174 | "output_type": "display_data" 175 | } 176 | ], 177 | "source": [ 178 | "#######################################\n", 179 | "# Define functions for the trajectories\n", 180 | "#######################################\n", 181 | "\n", 182 | "\n", 183 | "def trajectory(t):\n", 184 | " '''\n", 185 | " A function to specify the trajectory\n", 186 | " Args:\n", 187 | " t: time\n", 188 | " Returns:\n", 189 | " x: X coordinate of the end-effector\n", 190 | " y: Y coordinate of the end-effector\n", 191 | " '''\n", 192 | " \n", 193 | " r = 0.4\n", 194 | " omega = 2*np.pi*2\n", 195 | " \n", 196 | " # Centre of trajectory\n", 197 | " [x0, y0] = [0.5, 0.5]\n", 198 | " \n", 199 | " x = x0 + r*np.cos(omega*t)\n", 200 | " y = y0 + r*np.sin(omega*t)\n", 201 | " \n", 202 | " return x, y\n", 203 | "\n", 204 | "# Plot the trajectory\n", 205 | "x_plt = []; y_plt = [];\n", 206 | "for t in np.arange(0, 5, 0.005):\n", 207 | " x, y = trajectory(t)\n", 208 | " x_plt.append(x)\n", 209 | " y_plt.append(y)\n", 210 | " \n", 211 | " \n", 212 | "\n", 213 | "\n", 214 | "plt.plot(x_plt, y_plt, 'red')\n", 215 | " \n", 216 | "plt.show()\n" 217 | ] 218 | }, 219 | { 220 | "cell_type": "code", 221 | "execution_count": 16, 222 | "metadata": {}, 223 | "outputs": [], 224 | "source": [ 225 | "##########################################\n", 226 | "# Control loop to follow the trajectory\n", 227 | "##########################################\n", 228 | "\n", 229 | "# WRITE YOUR CODE HERE #\n" 230 | ] 231 | }, 232 | { 233 | "cell_type": "code", 234 | "execution_count": 17, 235 | "metadata": {}, 236 | "outputs": [], 237 | "source": [ 238 | "##########################################\n", 239 | "# Plot the data in joint-space\n", 240 | "##########################################\n", 241 | "\n", 242 | "# WRITE YOUR CODE HERE #\n" 243 | ] 244 | }, 245 | { 246 | "cell_type": "code", 247 | "execution_count": 18, 248 | "metadata": {}, 249 | "outputs": [], 250 | "source": [ 251 | "##########################################\n", 252 | "# Plot the data in task-space\n", 253 | "##########################################\n", 254 | "\n", 255 | "# WRITE YOUR CODE HERE #\n" 256 | ] 257 | } 258 | ], 259 | "metadata": { 260 | "kernelspec": { 261 | "display_name": "Python [conda env:pybt] *", 262 | "language": "python", 263 | "name": "conda-env-pybt-py" 264 | }, 265 | "language_info": { 266 | "codemirror_mode": { 267 | "name": "ipython", 268 | "version": 3 269 | }, 270 | "file_extension": ".py", 271 | "mimetype": "text/x-python", 272 | "name": "python", 273 | "nbconvert_exporter": "python", 274 | "pygments_lexer": "ipython3", 275 | "version": "3.7.5" 276 | } 277 | }, 278 | "nbformat": 4, 279 | "nbformat_minor": 2 280 | } 281 | -------------------------------------------------------------------------------- /Homework_2.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Homework: Problem 2\n", 8 | "\n", 9 | "a) Implement the forward kinematics and inverse kinematics for a spatial-3R robot shown below. The lengths of the links L1, L2 and L3 are all 1m. The first revolute joint rotates about an axis that is vertical in the plane of the page. The second and third revolute joints rotate about axes that are normal to the page.\n", 10 | "\n", 11 | "\n", 12 | "b) Implement a PD based trajectory-tracking controller for the robot to track the end-effector trajectories defined by the function 'trajectory(t)' which is implemented in this file. \n", 13 | "\n", 14 | "c) Provide plots comparing the desired and actual values to show the tracking performance of the controller. Show plots for the joint angles and the end-effector co-ordinates." 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "
\n", 22 | "\n", 23 | "
" 24 | ] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": null, 29 | "metadata": {}, 30 | "outputs": [], 31 | "source": [ 32 | "###############################\n", 33 | "# Import the necessary modules\n", 34 | "###############################\n", 35 | "\n", 36 | "# The PyBullet physics simulation library\n", 37 | "import pybullet as p\n", 38 | "import pybullet_data\n", 39 | "\n", 40 | "# Numpy for numerical calculations and manipulations\n", 41 | "import numpy as np\n", 42 | "import math\n", 43 | "\n", 44 | "# Matplotlib to create the necessary plots\n", 45 | "import matplotlib.pyplot as plt\n", 46 | "from mpl_toolkits.mplot3d import Axes3D" 47 | ] 48 | }, 49 | { 50 | "cell_type": "code", 51 | "execution_count": 25, 52 | "metadata": {}, 53 | "outputs": [], 54 | "source": [ 55 | "#################################################################\n", 56 | "# Forward and Inverse kinematics modules for the spatial-3R robot\n", 57 | "#################################################################\n", 58 | "\n", 59 | "def forward_kinematics(theta1, theta2, theta3, l1, l2, l3):\n", 60 | " '''\n", 61 | " Forward kinematics module for a spatial-3R chain.\n", 62 | " The base of the manipulator is assumed to be placed at the\n", 63 | " coordinates [0,0, 0].\n", 64 | " All the joints allow rotation about the positive Z-axis.\n", 65 | " Args:\n", 66 | " --- theta1: Angle between the link l1 and the positive x-axis (in radians)\n", 67 | " --- theta2: Relative angle between link l1 and link l2 (in radians)\n", 68 | " --- theta3: Relative angle between link l2 and l3 (in radians)\n", 69 | " --- l1: Length of link l1 (in m)\n", 70 | " --- l2: Length of link l2 (in m)\n", 71 | " --- l3: Lenght of link l3 (in m)\n", 72 | " Ret:\n", 73 | " --- [x, y, z]: Position co-ordinates of the end-effector (in m)\n", 74 | " '''\n", 75 | " \n", 76 | " # WRITE YOUR CODE HERE #\n", 77 | " \n", 78 | " return [x, y, z]\n", 79 | "\n", 80 | "def inverse_kinematics(x, y, z, l1, l2, l3, branch=1):\n", 81 | " '''\n", 82 | " Inverse kinematics modules for the serial-3R manipulator.\n", 83 | " The base of the manipulator is placed at [0,0, 0]. \n", 84 | " Args:\n", 85 | " --- x : X co-ordinate of the end-effector\n", 86 | " --- y : Y co-ordinate of the end-effector\n", 87 | " --- z : Z co-ordinate of the end-effector\n", 88 | " --- l1: Length of link l1\n", 89 | " --- l2: Length of link l2\n", 90 | " --- l3: Length of link l3\n", 91 | " --- branch: Branch of the inverse kinematics solution.\n", 92 | " Ret:\n", 93 | " --- valid: Binary variable indicating if the solution is valid or not\n", 94 | " --- [theta1, theta2, theta3]: Angles made by link l1 w.r.t X+ axis and the relative\n", 95 | " angle between links l1 and l2, and relative angle between links l2 and l3 respectively.\n", 96 | " '''\n", 97 | "\n", 98 | " # WRITE YOUR CODE HERE #\n", 99 | " \n", 100 | " # Solution found; return the joint angles\n", 101 | " return True, [theta1, theta2, theta3]" 102 | ] 103 | }, 104 | { 105 | "cell_type": "code", 106 | "execution_count": 26, 107 | "metadata": {}, 108 | "outputs": [], 109 | "source": [ 110 | "##############################################################\n", 111 | "# Create an instance of the Physics Server and connect to it\n", 112 | "##############################################################\n", 113 | "\n", 114 | "# Use p.DIRECT to connect to the server without rendering a GUI\n", 115 | "# Use p.GUI to create a GUI to render the simulation\n", 116 | "client = p.connect(p.DIRECT) # or p.GUI\n", 117 | "\n", 118 | "\n", 119 | "# Load the URDF of the plane that forms the ground\n", 120 | "p.setAdditionalSearchPath(pybullet_data.getDataPath()) # Set the search path to find the plane.urdf file\n", 121 | "plane = p.loadURDF(\"plane.urdf\")\n", 122 | "\n", 123 | "\n", 124 | "# Load the URDF of the robot\n", 125 | "robot = p.loadURDF(\"spatial_3R_robot.urdf\")" 126 | ] 127 | }, 128 | { 129 | "cell_type": "code", 130 | "execution_count": 27, 131 | "metadata": {}, 132 | "outputs": [], 133 | "source": [ 134 | "##################################################\n", 135 | "# Set the necessary parameters for the simulation\n", 136 | "##################################################\n", 137 | "\n", 138 | "# Set the Gravity vector\n", 139 | "p.setGravity(0,0,-9.81, physicsClientId = client)\n", 140 | "\n", 141 | "# Set the simulation time-step\n", 142 | "p.setTimeStep(0.001) #The lower this is, more accurate the simulation \n", 143 | "\n", 144 | "# You can be faster than real-time if you choose\n", 145 | "#p.setRealTimeSimulation(0) # we want to be faster than real time." 146 | ] 147 | }, 148 | { 149 | "cell_type": "code", 150 | "execution_count": 29, 151 | "metadata": {}, 152 | "outputs": [], 153 | "source": [ 154 | "#################################\n", 155 | "# Enable the motors on the joints \n", 156 | "#################################\n", 157 | "\n", 158 | "# This step is required to enable torque control. Refer to the documentation for more details.\n", 159 | "p.setJointMotorControl2(robot, 0, p.VELOCITY_CONTROL, force=0)\n", 160 | "p.setJointMotorControl2(robot, 1, p.VELOCITY_CONTROL, force=0)\n", 161 | "p.setJointMotorControl2(robot, 2, p.VELOCITY_CONTROL, force=0)" 162 | ] 163 | }, 164 | { 165 | "cell_type": "code", 166 | "execution_count": 50, 167 | "metadata": {}, 168 | "outputs": [ 169 | { 170 | "data": { 171 | "image/png": "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\n", 172 | "text/plain": [ 173 | "
" 174 | ] 175 | }, 176 | "metadata": { 177 | "needs_background": "light" 178 | }, 179 | "output_type": "display_data" 180 | } 181 | ], 182 | "source": [ 183 | "#######################################\n", 184 | "# Define functions for the trajectories\n", 185 | "#######################################\n", 186 | "\n", 187 | "\n", 188 | "def trajectory(t):\n", 189 | " '''\n", 190 | " A function to specify the trajectory\n", 191 | " Args:\n", 192 | " t: time\n", 193 | " Returns:\n", 194 | " x: X coordinate of the end-effector\n", 195 | " y: Y coordinate of the end-effector\n", 196 | " z: Z coordinate of the end-effector\n", 197 | " '''\n", 198 | " \n", 199 | " r = 0.4\n", 200 | " a = 0.05\n", 201 | " \n", 202 | " omega = 2*np.pi*2\n", 203 | " omega_z = 2*np.pi*10\n", 204 | " \n", 205 | " # Centre of the trajectory\n", 206 | " [x0, y0, z0] = [0.5, 0.5,0.25]\n", 207 | " \n", 208 | " x = x0 + r*np.cos(omega*t)\n", 209 | " y = y0 + r*np.sin(omega*t)\n", 210 | " z = z0 + a*np.sin(omega_z * t);\n", 211 | " \n", 212 | " return x, y, z\n", 213 | "\n", 214 | "\n", 215 | "# Plot the trajectory\n", 216 | "x_plt = []; y_plt = []; z_plt = []\n", 217 | "for t in np.arange(0, 5, 0.005):\n", 218 | " x, y, z = trajectory(t)\n", 219 | " x_plt.append(x)\n", 220 | " y_plt.append(y)\n", 221 | " z_plt.append(z)\n", 222 | " \n", 223 | "\n", 224 | "ax = plt.axes( projection = '3d')\n", 225 | "ax.plot3D(x_plt, y_plt, z_plt, 'red')\n", 226 | " \n", 227 | "plt.show()" 228 | ] 229 | }, 230 | { 231 | "cell_type": "code", 232 | "execution_count": 7, 233 | "metadata": {}, 234 | "outputs": [], 235 | "source": [ 236 | "##########################################\n", 237 | "# Control loop to follow the trajectory\n", 238 | "##########################################\n", 239 | "\n", 240 | "# WRITE YOUR CODE HERE #\n" 241 | ] 242 | }, 243 | { 244 | "cell_type": "code", 245 | "execution_count": 8, 246 | "metadata": {}, 247 | "outputs": [], 248 | "source": [ 249 | "##########################################\n", 250 | "# Plot the data in joint-space\n", 251 | "##########################################\n", 252 | "\n", 253 | "# WRITE YOUR CODE HERE #\n" 254 | ] 255 | }, 256 | { 257 | "cell_type": "code", 258 | "execution_count": 9, 259 | "metadata": {}, 260 | "outputs": [], 261 | "source": [ 262 | "##########################################\n", 263 | "# Plot the data in task-space\n", 264 | "##########################################\n", 265 | "\n", 266 | "# WRITE YOUR CODE HERE #\n" 267 | ] 268 | } 269 | ], 270 | "metadata": { 271 | "celltoolbar": "Raw Cell Format", 272 | "kernelspec": { 273 | "display_name": "Python [conda env:pybt] *", 274 | "language": "python", 275 | "name": "conda-env-pybt-py" 276 | }, 277 | "language_info": { 278 | "codemirror_mode": { 279 | "name": "ipython", 280 | "version": 3 281 | }, 282 | "file_extension": ".py", 283 | "mimetype": "text/x-python", 284 | "name": "python", 285 | "nbconvert_exporter": "python", 286 | "pygments_lexer": "ipython3", 287 | "version": "3.7.5" 288 | } 289 | }, 290 | "nbformat": 4, 291 | "nbformat_minor": 2 292 | } 293 | -------------------------------------------------------------------------------- /Homework_3.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Homework: Problem 3\n", 8 | "\n", 9 | "Design a neural network to solve the inverse kinematics for the spatial 3R robot. \n", 10 | "\n", 11 | "a) Generate data to train and test the neural network using the forward kinematics function. \n", 12 | "\n", 13 | "b) Use the test data to verify the output of the trained network. Ensure that the error is less than 0.1 degrees for each joint angle. \n", 14 | "Test the data on atleast 5 random points in the workspace of the robot.\n", 15 | "\n", 16 | "c) Generate the training graph.\n", 17 | "\n", 18 | "\n", 19 | "Note: Use the code for the forward kinematics of the spatial-3R robot from the previous problem." 20 | ] 21 | }, 22 | { 23 | "cell_type": "markdown", 24 | "metadata": {}, 25 | "source": [ 26 | "
\n", 27 | "\n", 28 | "
" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": null, 34 | "metadata": {}, 35 | "outputs": [], 36 | "source": [ 37 | "###############################\n", 38 | "# Import the necessary modules\n", 39 | "###############################\n", 40 | "# Numpy for numerical calculations and manipulations\n", 41 | "import numpy as np\n", 42 | "import math\n", 43 | "\n", 44 | "# Matplotlib to create the necessary plots\n", 45 | "import matplotlib.pyplot as plt\n", 46 | "from mpl_toolkits.mplot3d import Axes3D\n", 47 | "\n", 48 | "# Import any other necessary modules (TensorFlow, PyTorch etc.)" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": 25, 54 | "metadata": {}, 55 | "outputs": [], 56 | "source": [ 57 | "#################################################################\n", 58 | "# Forward and Inverse kinematics modules for the spatial-3R robot\n", 59 | "#################################################################\n", 60 | "\n", 61 | "def forward_kinematics(theta1, theta2, theta3, l1, l2, l3):\n", 62 | " '''\n", 63 | " Forward kinematics module for a spatial-3R chain.\n", 64 | " The base of the manipulator is assumed to be placed at the\n", 65 | " coordinates [0,0, 0].\n", 66 | " All the joints allow rotation about the positive Z-axis.\n", 67 | " Args:\n", 68 | " --- theta1: Angle between the link l1 and the positive x-axis (in radians)\n", 69 | " --- theta2: Relative angle between link l1 and link l2 (in radians)\n", 70 | " --- theta3: Relative angle between link l2 and l3 (in radians)\n", 71 | " --- l1: Length of link l1 (in m)\n", 72 | " --- l2: Length of link l2 (in m)\n", 73 | " --- l3: Lenght of link l3 (in m)\n", 74 | " Ret:\n", 75 | " --- [x, y, z]: Position co-ordinates of the end-effector (in m)\n", 76 | " '''\n", 77 | " \n", 78 | " # WRITE YOUR CODE HERE #\n", 79 | " \n", 80 | " return [x, y, z]" 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "execution_count": 9, 86 | "metadata": {}, 87 | "outputs": [], 88 | "source": [ 89 | "##########################################\n", 90 | "# Create the training + test data set\n", 91 | "##########################################\n", 92 | "\n", 93 | "\n" 94 | ] 95 | }, 96 | { 97 | "cell_type": "code", 98 | "execution_count": null, 99 | "metadata": {}, 100 | "outputs": [], 101 | "source": [ 102 | "##########################################\n", 103 | "# Train the network on the data set\n", 104 | "##########################################\n", 105 | "\n", 106 | "# WRITE YOUR CODE HERE #\n", 107 | "\n", 108 | "\n", 109 | "# Plot the training graph" 110 | ] 111 | }, 112 | { 113 | "cell_type": "code", 114 | "execution_count": null, 115 | "metadata": {}, 116 | "outputs": [], 117 | "source": [ 118 | "##########################################\n", 119 | "# Test the network on the data set\n", 120 | "##########################################\n", 121 | "\n", 122 | "# WRITE YOUR CODE HERE #\n", 123 | "\n", 124 | "# Ensure the error is less than 0.1 degrees for each joint angle. Test the network on atleast 5 randomly generated\n", 125 | "# data points." 126 | ] 127 | } 128 | ], 129 | "metadata": { 130 | "celltoolbar": "Raw Cell Format", 131 | "kernelspec": { 132 | "display_name": "Python [conda env:pybt] *", 133 | "language": "python", 134 | "name": "conda-env-pybt-py" 135 | }, 136 | "language_info": { 137 | "codemirror_mode": { 138 | "name": "ipython", 139 | "version": 3 140 | }, 141 | "file_extension": ".py", 142 | "mimetype": "text/x-python", 143 | "name": "python", 144 | "nbconvert_exporter": "python", 145 | "pygments_lexer": "ipython3", 146 | "version": "3.7.5" 147 | } 148 | }, 149 | "nbformat": 4, 150 | "nbformat_minor": 2 151 | } 152 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | ## Setup 2 | 3 | To install Anaconda follow the instructions in the following webpage: 4 | https://www.digitalocean.com/community/tutorials/how-to-install-anaconda-on-ubuntu-18-04-quickstart 5 | 6 | Create a conda environment for the PyBullet tutorial: 7 | ``` 8 | $ conda create --name pyb_env 9 | ``` 10 | Switch to the newly create environment (you will notice the name of the environment on the command line in the extreme left): 11 | ``` 12 | $ conda activate pyb_env 13 | ``` 14 | 15 | Once in the desired environment install the following packages: 16 | ``` 17 | $ conda install nb_conda_kernels 18 | ``` 19 | 20 | Install PyBullet (while in the environment): 21 | ``` 22 | $ pip install pybullet 23 | ``` 24 | 25 | Install Matplotlib (while in the environment): 26 | ``` 27 | $ conda install matplotlib 28 | ``` 29 | 30 | 31 | 32 | To check the installation launch: 33 | ``` 34 | $ python 35 | ``` 36 | 37 | Inside the python environment import the pybullet and matplotlib libraries: 38 | ``` 39 | >> import pybullet 40 | >> import matplotlib 41 | ``` 42 | If this command executes without any error then the installation is successful. 43 | 44 | 45 | Check the Jupyter notebook by running the following command in the bash shell: 46 | ``` 47 | $ jupyter notebook 48 | ``` 49 | This command will provide a URL. Run the URL in a browser (Firefox). If a web page opens up, then the Jupyter software is successfully installed. 50 | 51 | 52 | 53 | ## Agenda 54 | 55 | * Kinematics of a serial-2R manipulator (notebook: kinematics.ipynb) 56 | * Forward kinematics 57 | * Inverse kinematics 58 | * Verification of the FK and IK modules against each other 59 | 60 | 61 | * Introduction to PyBullet (notebook: sim_env_setup.ipynb) 62 | * How to start a PyBullet session 63 | * Settings the simulation parameters in PyBullet 64 | * Loading URDF files in PyBullet 65 | 66 | 67 | * Torque control of robot state in PyBullet (notebook: torque_control.ipynb) 68 | * Obtaining joint information 69 | * Setting the control mode (and enabling the motors) 70 | * Control of joint torque 71 | 72 | 73 | * PID control of robot (notebook: torque_control.ipynb) 74 | * Reading the joint state 75 | * Determining the control action 76 | * Setting the required control torque 77 | 78 | 79 | * Point-to-point tracking of end-effector (notebook: torque_control.ipynb) 80 | * Obtaining the required joint angles to reach the desired end-effector position 81 | * Simulating a PID position control loop to reach the desired end-effector position 82 | 83 | 84 | ## References 85 | * [PyBullet Quick start guide.](https://usermanual.wiki/Document/pybullet20quickstart20guide.479068914/html) 86 | 87 | * [Introduction to PyBullet.](https://alexanderfabisch.github.io/pybullet.html) 88 | 89 | * [Kinematics of serial-2R manipulators.](https://ed.iitm.ac.in/~sandipan/files/serialkinematicsv2.pdf) 90 | 91 | 92 | ## Additional References 93 | * [OpenAI Gym](https://gym.openai.com/) 94 | 95 | * [Building a balance bot with OpenAI gym and PyBullet](https://backyardrobotics.wordpress.com/2017/11/27/build-a-balancing-bot-with-openai-gym-pt-i-setting-up/) 96 | -------------------------------------------------------------------------------- /figures/spatial_3R.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityasagi/robotics_tutorial/08bf79241bf4e065c69226dc1f5a0dae2d30764d/figures/spatial_3R.png -------------------------------------------------------------------------------- /figures/spatial_3R.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 25 | 33 | 38 | 39 | 47 | 52 | 53 | 61 | 66 | 67 | 75 | 80 | 81 | 89 | 94 | 95 | 103 | 108 | 109 | 117 | 122 | 123 | 129 | 135 | 141 | 147 | 148 | 169 | 171 | 172 | 174 | image/svg+xml 175 | 177 | 178 | 179 | 180 | 181 | 185 | 188 | 192 | 196 | 200 | 204 | 210 | 216 | 230 | 244 | 257 | 260 | 264 | 268 | 272 | 276 | 280 | 281 | 284 | 288 | 292 | 296 | 300 | 304 | 305 | 311 | 315 | 319 | 323 | 327 | 331 | 335 | L1 342 | L2 349 | 350 | L3 357 | 358 | 359 | 360 | -------------------------------------------------------------------------------- /kinematics.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "def forward_kinematics(theta1, theta2, l1, l2):\n", 10 | " '''\n", 11 | " Forward kinematics module for a serial-2R chain.\n", 12 | " The base of the manipulator is assumed to be placed at the\n", 13 | " coordinates [0,0].\n", 14 | " All the joints allow rotation about the positive Z-axis.\n", 15 | " Args:\n", 16 | " --- theta1: Angle between the link l1 and the positive x-axis (in radians)\n", 17 | " --- theta2: Relative angle between link l1 and link l2 (in radians)\n", 18 | " --- l1: Length of link l1 (in m)\n", 19 | " --- l2: Length of link l2 (in m)\n", 20 | " Ret:\n", 21 | " --- [x, y]: Position co-ordinates of the end-effector (in m)\n", 22 | " '''\n", 23 | " x = l1*math.cos(theta1) + l2*math.cos(theta1 + theta2)\n", 24 | " y = l1*math.sin(theta1) + l2*math.sin(theta1 + theta2)\n", 25 | " return [x, y]\n", 26 | "\n", 27 | "def inverse_kinematics(x, y, l1, l2, branch=1):\n", 28 | " '''\n", 29 | " Inverse kinematics modules for the serial-2R manipulator.\n", 30 | " The base of the manipulator is placed at [0,0].\n", 31 | " Axis of rotation is the Z+ axis.\n", 32 | " Args:\n", 33 | " --- x : X co-ordinate of the end-effector\n", 34 | " --- y : Y co-ordinate of the end-effector\n", 35 | " --- l1: Length of link l1\n", 36 | " --- l2: Length of link l2\n", 37 | " --- branch: Branch of the inverse kinematics solution.\n", 38 | " Ret:\n", 39 | " --- valid: Binary variable indicating if the solution is valid or not\n", 40 | " --- [theta1, theta2]: Angles made by link l1 w.r.t X+ axis and the relative\n", 41 | " angle between links l1 and l2 respectively.\n", 42 | " '''\n", 43 | " a = 2*x*l2\n", 44 | " b = 2*y*l2\n", 45 | " c = l1*l1 - x*x - y*y - l2*l2 \n", 46 | " psi = math.atan2(b, a)\n", 47 | " d = -c/math.sqrt(a*a + b*b)\n", 48 | " \n", 49 | " if (d < -1) or (d > 1):\n", 50 | " print(\"Position out of workspace.\")\n", 51 | " return False, [0,0]\n", 52 | " if branch == 1:\n", 53 | " theta12 = psi + math.acos(-c/math.sqrt(a*a + b*b))\n", 54 | " else:\n", 55 | " theta12 = psi - math.acos(-c/math.sqrt(a*a + b*b))\n", 56 | " \n", 57 | " theta1 = math.atan2((y - l2*math.sin(theta12))/l1, (x - l2*math.cos(theta12))/l1)\n", 58 | " return True, [theta1, theta12-theta1]" 59 | ] 60 | }, 61 | { 62 | "cell_type": "code", 63 | "execution_count": 2, 64 | "metadata": {}, 65 | "outputs": [ 66 | { 67 | "name": "stdout", 68 | "output_type": "stream", 69 | "text": [ 70 | "-4.996003610813204e-16 8.326672684688674e-16\n", 71 | "-1.1102230246251565e-16 1.1102230246251565e-16\n", 72 | "5.551115123125783e-16 -8.881784197001252e-16\n", 73 | "-4.440892098500626e-16 6.661338147750939e-16\n", 74 | "1.1102230246251565e-16 0.0\n", 75 | "1.1102230246251565e-16 -2.220446049250313e-16\n", 76 | "0.0 -1.1102230246251565e-16\n", 77 | "7.771561172376096e-16 -1.2212453270876722e-15\n", 78 | "-1.7763568394002505e-15 2.55351295663786e-15\n", 79 | "9.575673587391975e-16 -1.5543122344752192e-15\n", 80 | "-4.107825191113079e-15 6.161737786669619e-15\n", 81 | "-4.163336342344337e-16 7.771561172376096e-16\n", 82 | "4.163336342344337e-17 0.0\n", 83 | "1.1102230246251565e-16 -1.1102230246251565e-16\n", 84 | "-5.551115123125783e-16 9.992007221626409e-16\n", 85 | "1.1102230246251565e-16 -2.220446049250313e-16\n", 86 | "-7.771561172376096e-16 1.2212453270876722e-15\n", 87 | "-1.1102230246251565e-16 1.1102230246251565e-16\n", 88 | "-1.3322676295501878e-15 1.9984014443252818e-15\n", 89 | "4.440892098500626e-16 -6.661338147750939e-16\n", 90 | "1.3322676295501878e-15 -2.1094237467877974e-15\n", 91 | "3.885780586188048e-16 -6.661338147750939e-16\n", 92 | "1.1102230246251565e-16 0.0\n", 93 | "-2.220446049250313e-15 3.3306690738754696e-15\n", 94 | "-5.828670879282072e-16 8.604228440844963e-16\n", 95 | "-6.661338147750939e-16 1.2212453270876722e-15\n", 96 | "3.3306690738754696e-16 -5.551115123125783e-16\n", 97 | "-4.718447854656915e-16 6.938893903907228e-16\n", 98 | "-1.2212453270876722e-15 1.887379141862766e-15\n", 99 | "1.1102230246251565e-16 -3.3306690738754696e-16\n", 100 | "-2.220446049250313e-16 1.1102230246251565e-16\n", 101 | "2.0539125955565396e-15 -3.0531133177191805e-15\n", 102 | "1.1102230246251565e-16 -4.440892098500626e-16\n", 103 | "1.7763568394002505e-15 -2.55351295663786e-15\n", 104 | "1.942890293094024e-15 -2.942091015256665e-15\n", 105 | "-1.3877787807814457e-15 2.1649348980190553e-15\n", 106 | "6.661338147750939e-16 -1.0547118733938987e-15\n", 107 | "-1.970645868709653e-15 2.914335439641036e-15\n", 108 | "5.551115123125783e-17 0.0\n", 109 | "-4.649058915617843e-16 7.771561172376096e-16\n", 110 | "-2.9976021664879227e-15 4.551914400963142e-15\n", 111 | "1.0547118733938987e-15 -1.5543122344752192e-15\n", 112 | "-1.609823385706477e-15 2.609024107869118e-15\n", 113 | "1.700029006457271e-16 -5.551115123125783e-16\n", 114 | "-9.325873406851315e-15 1.3877787807814457e-14\n", 115 | "-2.220446049250313e-16 3.3306690738754696e-16\n", 116 | "-5.551115123125783e-16 7.771561172376096e-16\n", 117 | "3.774758283725532e-15 -5.662137425588298e-15\n", 118 | "-1.4432899320127035e-15 2.220446049250313e-15\n", 119 | "-3.3306690738754696e-16 4.440892098500626e-16\n", 120 | "2.220446049250313e-16 -5.551115123125783e-16\n", 121 | "-5.646524914304507e-16 8.604228440844963e-16\n", 122 | "-6.661338147750939e-16 1.1102230246251565e-15\n", 123 | "6.661338147750939e-15 -9.992007221626409e-15\n", 124 | "-7.216449660063518e-16 1.2212453270876722e-15\n", 125 | "0.0 0.0\n", 126 | "3.3306690738754696e-16 -5.551115123125783e-16\n", 127 | "-1.5959455978986625e-16 2.220446049250313e-16\n", 128 | "1.4432899320127035e-15 -1.9984014443252818e-15\n", 129 | "1.8457457784393227e-15 -2.7755575615628914e-15\n", 130 | "4.996003610813204e-16 -9.992007221626409e-16\n", 131 | "0.0 -1.1102230246251565e-16\n", 132 | "-3.885780586188048e-16 6.661338147750939e-16\n", 133 | "-7.077671781985373e-16 9.992007221626409e-16\n", 134 | "-4.274358644806853e-15 6.38378239159465e-15\n", 135 | "5.551115123125783e-17 -5.551115123125783e-17\n", 136 | "-5.551115123125783e-16 8.881784197001252e-16\n", 137 | "4.579669976578771e-16 -7.771561172376096e-16\n", 138 | "9.992007221626409e-16 -1.4432899320127035e-15\n", 139 | "-3.3306690738754696e-16 5.551115123125783e-16\n", 140 | "-3.4416913763379853e-15 5.218048215738236e-15\n", 141 | "-3.3306690738754696e-16 6.661338147750939e-16\n", 142 | "8.881784197001252e-16 -1.3322676295501878e-15\n", 143 | "-7.771561172376096e-16 1.2212453270876722e-15\n", 144 | "4.440892098500626e-16 -6.661338147750939e-16\n", 145 | "-2.220446049250313e-16 3.3306690738754696e-16\n", 146 | "1.3877787807814457e-16 -3.3306690738754696e-16\n", 147 | "5.551115123125783e-16 -8.881784197001252e-16\n", 148 | "4.440892098500626e-16 -5.551115123125783e-16\n", 149 | "6.661338147750939e-16 -9.992007221626409e-16\n", 150 | "-1.1102230246251565e-16 2.220446049250313e-16\n", 151 | "-5.551115123125783e-17 1.1102230246251565e-16\n", 152 | "0.0 0.0\n", 153 | "-1.7763568394002505e-15 2.6645352591003757e-15\n", 154 | "3.3306690738754696e-16 -5.551115123125783e-16\n", 155 | "1.432187701766452e-14 -2.1316282072803006e-14\n", 156 | "-2.220446049250313e-15 3.3306690738754696e-15\n", 157 | "-4.718447854656915e-16 8.881784197001252e-16\n", 158 | "-3.0531133177191805e-16 4.440892098500626e-16\n", 159 | "-1.1102230246251565e-16 1.1102230246251565e-16\n", 160 | "-5.233591338082988e-13 7.850387007124482e-13\n", 161 | "-2.220446049250313e-16 4.440892098500626e-16\n", 162 | "-2.55351295663786e-15 3.9968028886505635e-15\n", 163 | "-1.1102230246251565e-16 2.220446049250313e-16\n", 164 | "1.1102230246251565e-16 -1.1102230246251565e-16\n", 165 | "-3.3306690738754696e-16 4.440892098500626e-16\n", 166 | "-1.1102230246251565e-15 1.887379141862766e-15\n", 167 | "5.551115123125783e-16 -8.881784197001252e-16\n", 168 | "-1.1102230246251565e-16 2.220446049250313e-16\n", 169 | "-3.0531133177191805e-16 4.440892098500626e-16\n", 170 | "-4.440892098500626e-16 7.771561172376096e-16\n", 171 | "1.1102230246251565e-16 -3.3306690738754696e-16\n", 172 | "-1.1102230246251565e-16 0.0\n", 173 | "-5.551115123125783e-16 9.992007221626409e-16\n", 174 | "-4.440892098500626e-16 7.771561172376096e-16\n", 175 | "-5.551115123125783e-16 7.771561172376096e-16\n", 176 | "-9.43689570931383e-16 1.3877787807814457e-15\n", 177 | "-6.106226635438361e-16 6.661338147750939e-16\n", 178 | "8.326672684688674e-17 -8.326672684688674e-17\n", 179 | "6.106226635438361e-16 -8.326672684688674e-16\n", 180 | "2.8033131371785203e-15 -4.3298697960381105e-15\n", 181 | "4.996003610813204e-16 -6.661338147750939e-16\n", 182 | "8.049116928532385e-16 -1.2212453270876722e-15\n", 183 | "1.0547118733938987e-15 -1.4988010832439613e-15\n", 184 | "7.28583859910259e-17 -1.1102230246251565e-16\n", 185 | "-1.3322676295501878e-15 2.1094237467877974e-15\n", 186 | "7.771561172376096e-16 -1.3322676295501878e-15\n", 187 | "-1.5543122344752192e-15 2.4424906541753444e-15\n", 188 | "1.1102230246251565e-15 -1.4432899320127035e-15\n", 189 | "0.0 -2.220446049250313e-16\n", 190 | "8.881784197001252e-16 -1.4432899320127035e-15\n", 191 | "7.771561172376096e-16 -1.1102230246251565e-15\n", 192 | "-8.881784197001252e-15 1.3322676295501878e-14\n", 193 | "7.91033905045424e-16 -1.1102230246251565e-15\n", 194 | "-1.1102230246251565e-16 2.220446049250313e-16\n", 195 | "2.220446049250313e-16 -3.3306690738754696e-16\n", 196 | "-3.3306690738754696e-16 6.661338147750939e-16\n", 197 | "-3.3306690738754696e-16 5.551115123125783e-16\n", 198 | "-1.1102230246251565e-16 3.3306690738754696e-16\n", 199 | "1.1102230246251565e-16 -1.1102230246251565e-16\n", 200 | "-3.0531133177191805e-16 4.440892098500626e-16\n", 201 | "8.881784197001252e-16 -1.2212453270876722e-15\n", 202 | "7.771561172376096e-16 -1.3322676295501878e-15\n", 203 | "-1.2212453270876722e-15 1.7763568394002505e-15\n", 204 | "-3.191891195797325e-16 5.551115123125783e-16\n", 205 | "0.0 0.0\n", 206 | "0.0 0.0\n", 207 | "-5.551115123125783e-16 7.771561172376096e-16\n", 208 | "1.1102230246251565e-16 -2.220446049250313e-16\n", 209 | "-7.355227538141662e-16 1.1657341758564144e-15\n", 210 | "-3.191891195797325e-16 4.440892098500626e-16\n", 211 | "-1.1102230246251565e-15 1.4432899320127035e-15\n", 212 | "6.38378239159465e-16 -9.992007221626409e-16\n", 213 | "-1.429412144204889e-15 2.220446049250313e-15\n", 214 | "5.551115123125783e-16 -7.771561172376096e-16\n", 215 | "9.992007221626409e-16 -1.5543122344752192e-15\n", 216 | "-2.0816681711721685e-16 4.440892098500626e-16\n", 217 | "1.1102230246251565e-15 -1.6653345369377348e-15\n", 218 | "2.7755575615628914e-16 -4.440892098500626e-16\n", 219 | "4.440892098500626e-16 -7.771561172376096e-16\n", 220 | "-1.7763568394002505e-15 2.55351295663786e-15\n", 221 | "1.1102230246251565e-16 -1.1102230246251565e-16\n", 222 | "4.996003610813204e-16 -7.771561172376096e-16\n", 223 | "2.220446049250313e-16 -2.220446049250313e-16\n", 224 | "1.5959455978986625e-16 -2.220446049250313e-16\n", 225 | "1.6653345369377348e-16 -2.220446049250313e-16\n", 226 | "-2.6645352591003757e-15 3.9968028886505635e-15\n", 227 | "-2.220446049250313e-16 3.3306690738754696e-16\n", 228 | "-2.220446049250313e-16 3.3306690738754696e-16\n", 229 | "6.661338147750939e-16 -1.1102230246251565e-15\n", 230 | "-3.3306690738754696e-16 5.551115123125783e-16\n", 231 | "-2.7755575615628914e-16 3.885780586188048e-16\n", 232 | "7.771561172376096e-16 -1.1102230246251565e-15\n", 233 | "1.6375789613221059e-15 -2.55351295663786e-15\n", 234 | "-1.1102230246251565e-16 3.3306690738754696e-16\n", 235 | "-2.220446049250313e-16 4.440892098500626e-16\n", 236 | "4.440892098500626e-16 -6.661338147750939e-16\n", 237 | "0.0 0.0\n", 238 | "-3.3306690738754696e-16 5.551115123125783e-16\n", 239 | "5.440092820663267e-15 -8.104628079763643e-15\n", 240 | "6.38378239159465e-16 -9.992007221626409e-16\n", 241 | "-2.7755575615628914e-16 3.885780586188048e-16\n", 242 | "1.4432899320127035e-15 -2.220446049250313e-15\n", 243 | "-3.885780586188048e-16 7.216449660063518e-16\n", 244 | "-8.881784197001252e-16 1.5543122344752192e-15\n", 245 | "-1.1102230246251565e-15 1.5543122344752192e-15\n", 246 | "3.3306690738754696e-16 -5.551115123125783e-16\n", 247 | "-1.4432899320127035e-15 2.220446049250313e-15\n", 248 | "1.6167622796103842e-15 -2.4424906541753444e-15\n", 249 | "3.3306690738754696e-16 -4.440892098500626e-16\n", 250 | "8.881784197001252e-16 -1.3322676295501878e-15\n", 251 | "-4.718447854656915e-16 7.771561172376096e-16\n", 252 | "1.0408340855860843e-16 -1.1102230246251565e-16\n", 253 | "5.551115123125783e-17 0.0\n", 254 | "-4.996003610813204e-16 7.216449660063518e-16\n", 255 | "1.3322676295501878e-15 -1.9984014443252818e-15\n", 256 | "-6.661338147750939e-16 1.2212453270876722e-15\n", 257 | "5.551115123125783e-16 -1.1102230246251565e-15\n", 258 | "3.630429290524262e-14 -5.4511950509095186e-14\n", 259 | "0.0 -1.1102230246251565e-16\n", 260 | "4.440892098500626e-16 -5.551115123125783e-16\n", 261 | "5.551115123125783e-16 -7.771561172376096e-16\n", 262 | "-5.551115123125783e-16 8.326672684688674e-16\n", 263 | "1.3183898417423734e-15 -1.9984014443252818e-15\n", 264 | "-1.1102230246251565e-15 1.7763568394002505e-15\n", 265 | "4.440892098500626e-16 -6.661338147750939e-16\n", 266 | "7.216449660063518e-16 -1.0547118733938987e-15\n", 267 | "1.1102230246251565e-16 0.0\n", 268 | "-5.627442956068762e-15 8.444633881055097e-15\n", 269 | "-2.220446049250313e-16 2.220446049250313e-16\n", 270 | "-1.8041124150158794e-16 2.7755575615628914e-16\n", 271 | "0.0 1.1102230246251565e-16\n", 272 | "-7.771561172376096e-16 1.2212453270876722e-15\n", 273 | "1.1102230246251565e-16 -2.220446049250313e-16\n", 274 | "2.220446049250313e-16 -3.3306690738754696e-16\n", 275 | "-1.1102230246251565e-16 0.0\n", 276 | "-3.3306690738754696e-16 5.551115123125783e-16\n", 277 | "1.304512053934559e-15 -1.887379141862766e-15\n", 278 | "5.342948306008566e-16 -8.881784197001252e-16\n", 279 | "-3.885780586188048e-16 6.106226635438361e-16\n", 280 | "-9.43689570931383e-16 1.5543122344752192e-15\n", 281 | "1.7763568394002505e-15 -2.6645352591003757e-15\n", 282 | "1.0436096431476471e-14 -1.5654144647214707e-14\n", 283 | "-1.8596235662471372e-15 2.886579864025407e-15\n", 284 | "-1.1102230246251565e-16 4.440892098500626e-16\n", 285 | "0.0 -1.1102230246251565e-16\n", 286 | "3.0253577421035516e-15 -4.524158825347513e-15\n", 287 | "-7.771561172376096e-16 9.992007221626409e-16\n", 288 | "1.2212453270876722e-15 -1.7763568394002505e-15\n", 289 | "-2.220446049250313e-16 3.3306690738754696e-16\n", 290 | "0.0 0.0\n", 291 | "0.0 -1.1102230246251565e-16\n", 292 | "-6.661338147750939e-16 1.1102230246251565e-15\n", 293 | "2.636779683484747e-16 -4.440892098500626e-16\n", 294 | "2.220446049250313e-16 -5.551115123125783e-16\n", 295 | "-9.43689570931383e-16 1.4988010832439613e-15\n", 296 | "-2.3869795029440866e-15 3.608224830031759e-15\n", 297 | "-2.220446049250313e-16 4.440892098500626e-16\n", 298 | "4.0939474033052647e-16 -6.661338147750939e-16\n", 299 | "6.661338147750939e-16 -1.1102230246251565e-15\n", 300 | "-2.220446049250313e-16 3.3306690738754696e-16\n", 301 | "2.220446049250313e-16 -4.440892098500626e-16\n", 302 | "-1.1102230246251565e-16 1.1102230246251565e-16\n", 303 | "3.3306690738754696e-16 -4.440892098500626e-16\n", 304 | "3.3306690738754696e-16 -6.661338147750939e-16\n", 305 | "8.881784197001252e-16 -1.2212453270876722e-15\n", 306 | "6.661338147750939e-16 -1.1102230246251565e-15\n", 307 | "-1.2212453270876722e-15 1.887379141862766e-15\n", 308 | "-8.881784197001252e-16 1.3322676295501878e-15\n", 309 | "-1.3322676295501878e-15 1.9984014443252818e-15\n", 310 | "1.5543122344752192e-15 -2.55351295663786e-15\n", 311 | "-1.0447198661722723e-13 1.567634910770721e-13\n", 312 | "4.996003610813204e-16 -6.661338147750939e-16\n", 313 | "-1.6653345369377348e-15 2.55351295663786e-15\n", 314 | "0.0 -1.1102230246251565e-16\n", 315 | "1.734723475976807e-15 -2.609024107869118e-15\n", 316 | "-1.1102230246251565e-16 2.220446049250313e-16\n", 317 | "8.049116928532385e-16 -1.2212453270876722e-15\n", 318 | "-1.1102230246251565e-16 1.1102230246251565e-16\n", 319 | "-1.5543122344752192e-15 2.4424906541753444e-15\n", 320 | "1.2628786905111156e-15 -1.942890293094024e-15\n", 321 | "-3.885780586188048e-16 5.551115123125783e-16\n", 322 | "7.771561172376096e-16 -1.1102230246251565e-15\n", 323 | "-2.220446049250313e-16 3.3306690738754696e-16\n", 324 | "-3.802513859341161e-15 5.745404152435185e-15\n", 325 | "-1.1102230246251565e-16 0.0\n", 326 | "7.771561172376096e-16 -1.3322676295501878e-15\n", 327 | "-5.551115123125783e-16 7.771561172376096e-16\n", 328 | "0.0 1.1102230246251565e-16\n", 329 | "-1.1102230246251565e-16 1.1102230246251565e-16\n", 330 | "1.0130785099704553e-15 -1.5543122344752192e-15\n", 331 | "-7.771561172376096e-16 1.2212453270876722e-15\n", 332 | "-9.992007221626409e-16 1.6653345369377348e-15\n", 333 | "-9.992007221626409e-16 1.4432899320127035e-15\n", 334 | "6.661338147750939e-16 -1.1102230246251565e-15\n", 335 | "5.551115123125783e-17 0.0\n", 336 | "-3.608224830031759e-16 5.551115123125783e-16\n", 337 | "-1.7208456881689926e-15 2.581268532253489e-15\n", 338 | "1.7763568394002505e-15 -2.6645352591003757e-15\n", 339 | "-6.661338147750939e-16 9.992007221626409e-16\n", 340 | "3.3306690738754696e-16 -6.661338147750939e-16\n", 341 | "1.4710455076283324e-15 -2.192690473634684e-15\n", 342 | "-5.273559366969494e-16 9.992007221626409e-16\n", 343 | "-7.355227538141662e-16 1.0547118733938987e-15\n", 344 | "2.7755575615628914e-17 -1.1102230246251565e-16\n", 345 | "6.938893903907228e-18 0.0\n", 346 | "1.5543122344752192e-15 -2.3314683517128287e-15\n", 347 | "-3.3306690738754696e-16 8.881784197001252e-16\n", 348 | "4.884981308350689e-15 -7.327471962526033e-15\n", 349 | "4.440892098500626e-16 -6.661338147750939e-16\n", 350 | "1.734723475976807e-15 -2.609024107869118e-15\n", 351 | "-5.551115123125783e-17 1.1102230246251565e-16\n", 352 | "4.9404924595819466e-15 -7.438494264988549e-15\n", 353 | "-3.608224830031759e-16 5.828670879282072e-16\n", 354 | "0.0 -1.1102230246251565e-16\n", 355 | "-6.800116025829084e-16 9.992007221626409e-16\n", 356 | "3.3306690738754696e-16 -3.3306690738754696e-16\n", 357 | "3.83026943495679e-15 -5.773159728050814e-15\n", 358 | "0.0 0.0\n", 359 | "-8.326672684688674e-17 1.1102230246251565e-16\n", 360 | "4.440892098500626e-16 -6.661338147750939e-16\n", 361 | "-8.881784197001252e-16 1.4432899320127035e-15\n", 362 | "1.887379141862766e-15 -2.886579864025407e-15\n", 363 | "-1.4432899320127035e-15 2.4424906541753444e-15\n", 364 | "-1.6653345369377348e-16 1.1102230246251565e-16\n", 365 | "3.3306690738754696e-16 -5.551115123125783e-16\n", 366 | "-4.996003610813204e-16 5.551115123125783e-16\n", 367 | "2.220446049250313e-16 -4.440892098500626e-16\n", 368 | "-2.3592239273284576e-16 3.7470027081099033e-16\n", 369 | "4.440892098500626e-16 -6.661338147750939e-16\n", 370 | "1.6653345369377348e-16 -3.3306690738754696e-16\n", 371 | "4.440892098500626e-16 -7.771561172376096e-16\n", 372 | "0.0 -1.1102230246251565e-16\n", 373 | "-1.8318679906315083e-15 2.7200464103316335e-15\n", 374 | "1.1102230246251565e-16 -1.1102230246251565e-16\n", 375 | "8.604228440844963e-16 -1.4432899320127035e-15\n", 376 | "3.1086244689504383e-15 -4.6629367034256575e-15\n", 377 | "8.881784197001252e-16 -1.2212453270876722e-15\n", 378 | "-9.992007221626409e-16 1.6653345369377348e-15\n", 379 | "-2.220446049250313e-16 1.1102230246251565e-16\n", 380 | "-1.3877787807814457e-15 2.1649348980190553e-15\n", 381 | "-4.440892098500626e-16 6.661338147750939e-16\n", 382 | "-1.1102230246251565e-16 0.0\n", 383 | "2.220446049250313e-16 -4.440892098500626e-16\n", 384 | "8.271161533457416e-15 -1.2490009027033011e-14\n", 385 | "-1.6653345369377348e-16 3.3306690738754696e-16\n", 386 | "3.608224830031759e-16 -5.551115123125783e-16\n", 387 | "1.8388068845354155e-15 -2.7478019859472624e-15\n", 388 | "5.065392549852277e-16 -9.992007221626409e-16\n", 389 | "-1.0755285551056204e-16 1.1102230246251565e-16\n", 390 | "1.1657341758564144e-15 -1.8318679906315083e-15\n", 391 | "0.0 1.1102230246251565e-16\n", 392 | "-2.3869795029440866e-15 3.608224830031759e-15\n", 393 | "-5.551115123125783e-16 9.992007221626409e-16\n", 394 | "1.1102230246251565e-16 -3.3306690738754696e-16\n", 395 | "7.125376677574735e-16 -1.1102230246251565e-15\n", 396 | "-6.661338147750939e-15 9.936496070395151e-15\n", 397 | "5.2735593669694936e-15 -7.882583474838611e-15\n", 398 | "0.0 0.0\n", 399 | "-9.992007221626409e-16 1.3322676295501878e-15\n", 400 | "2.220446049250313e-16 -4.440892098500626e-16\n", 401 | "3.3306690738754696e-16 -5.551115123125783e-16\n", 402 | "-6.661338147750939e-16 9.992007221626409e-16\n", 403 | "4.996003610813204e-16 -8.326672684688674e-16\n", 404 | "9.992007221626409e-16 -1.6653345369377348e-15\n", 405 | "-1.2212453270876722e-15 1.7763568394002505e-15\n", 406 | "6.938893903907228e-16 -1.1102230246251565e-15\n", 407 | "-1.1102230246251565e-16 1.1102230246251565e-16\n", 408 | "4.996003610813204e-16 -9.992007221626409e-16\n", 409 | "-3.3306690738754696e-16 4.440892098500626e-16\n", 410 | "-4.6074255521944e-15 6.938893903907228e-15\n", 411 | "-2.7755575615628914e-15 4.107825191113079e-15\n", 412 | "0.0 0.0\n", 413 | "-1.6653345369377348e-16 3.3306690738754696e-16\n", 414 | "9.992007221626409e-15 -1.4988010832439613e-14\n", 415 | "-1.1102230246251565e-16 2.220446049250313e-16\n", 416 | "-1.3322676295501878e-15 2.3314683517128287e-15\n", 417 | "8.326672684688674e-17 -2.220446049250313e-16\n", 418 | "1.942890293094024e-16 -4.440892098500626e-16\n", 419 | "1.8318679906315083e-15 -2.7755575615628914e-15\n", 420 | "-6.472600233564663e-14 9.720002580593246e-14\n", 421 | "3.164135620181696e-15 -4.718447854656915e-15\n", 422 | "-3.3306690738754696e-16 7.771561172376096e-16\n", 423 | "-2.7755575615628914e-16 5.551115123125783e-16\n", 424 | "4.440892098500626e-16 -6.661338147750939e-16\n", 425 | "-1.1102230246251565e-16 3.3306690738754696e-16\n", 426 | "2.220446049250313e-16 -3.3306690738754696e-16\n", 427 | "1.5737411374061594e-14 -2.3619994848900205e-14\n", 428 | "-2.220446049250313e-16 5.551115123125783e-16\n", 429 | "1.3183898417423734e-15 -2.0539125955565396e-15\n", 430 | "2.6645352591003757e-15 -3.9968028886505635e-15\n", 431 | "-3.3306690738754696e-16 5.551115123125783e-16\n", 432 | "6.938893903907228e-17 -1.1102230246251565e-16\n", 433 | "-6.38378239159465e-16 9.992007221626409e-16\n", 434 | "-7.216449660063518e-16 1.1102230246251565e-15\n", 435 | "3.885780586188048e-15 -5.88418203051333e-15\n", 436 | "-1.1102230246251565e-16 4.440892098500626e-16\n", 437 | "-8.881784197001252e-16 1.4432899320127035e-15\n", 438 | "6.591949208711867e-17 -1.1102230246251565e-16\n", 439 | "9.992007221626409e-16 -1.7763568394002505e-15\n", 440 | "2.220446049250313e-16 -4.440892098500626e-16\n", 441 | "-1.1102230246251565e-16 2.220446049250313e-16\n", 442 | "-1.4988010832439613e-15 2.220446049250313e-15\n", 443 | "1.3322676295501878e-15 -1.9984014443252818e-15\n", 444 | "-3.5388358909926865e-16 6.661338147750939e-16\n", 445 | "-3.608224830031759e-16 4.440892098500626e-16\n", 446 | "3.941291737419306e-15 -5.88418203051333e-15\n", 447 | "-1.3322676295501878e-15 2.220446049250313e-15\n", 448 | "1.1102230246251565e-16 0.0\n", 449 | "1.1102230246251565e-15 -1.7763568394002505e-15\n", 450 | "2.2898349882893854e-15 -3.497202527569243e-15\n", 451 | "8.881784197001252e-16 -1.2212453270876722e-15\n", 452 | "-6.245004513516506e-17 2.220446049250313e-16\n", 453 | "6.106226635438361e-16 -1.1102230246251565e-15\n", 454 | "-1.6653345369377348e-16 2.220446049250313e-16\n", 455 | "-5.384581669432009e-15 8.049116928532385e-15\n", 456 | "-1.120215031846783e-13 1.680877659282487e-13\n", 457 | "-5.828670879282072e-15 8.770761894538737e-15\n", 458 | "7.771561172376096e-16 -1.2212453270876722e-15\n", 459 | "-7.216449660063518e-16 1.1657341758564144e-15\n", 460 | "-1.9567680809018384e-15 2.9559688030644793e-15\n", 461 | "-5.551115123125783e-17 1.1102230246251565e-16\n", 462 | "-3.3306690738754696e-16 4.440892098500626e-16\n", 463 | "-4.440892098500626e-16 6.661338147750939e-16\n", 464 | "6.38378239159465e-16 -9.992007221626409e-16\n", 465 | "-1.6653345369377348e-16 1.1102230246251565e-16\n", 466 | "4.218847493575595e-15 -6.328271240363392e-15\n", 467 | "1.4432899320127035e-15 -2.1094237467877974e-15\n", 468 | "-9.992007221626409e-16 1.5543122344752192e-15\n", 469 | "-3.6637359812630166e-15 5.551115123125783e-15\n", 470 | "-4.440892098500626e-16 8.881784197001252e-16\n", 471 | "1.6653345369377348e-16 -1.1102230246251565e-16\n", 472 | "1.1102230246251565e-16 0.0\n", 473 | "4.551914400963142e-15 -6.994405055138486e-15\n", 474 | "-6.938893903907228e-16 1.0824674490095276e-15\n", 475 | "0.0 1.1102230246251565e-16\n", 476 | "-1.4988010832439613e-15 2.275957200481571e-15\n", 477 | "1.6653345369377348e-16 -2.220446049250313e-16\n", 478 | "4.996003610813204e-16 -6.661338147750939e-16\n", 479 | "-7.771561172376096e-16 1.3322676295501878e-15\n", 480 | "1.6653345369377348e-16 -4.440892098500626e-16\n", 481 | "5.551115123125783e-16 -8.881784197001252e-16\n", 482 | "-9.992007221626409e-16 1.4432899320127035e-15\n", 483 | "-1.1102230246251565e-16 1.1102230246251565e-16\n", 484 | "-1.9984014443252818e-15 2.9976021664879227e-15\n", 485 | "-2.220446049250313e-16 3.3306690738754696e-16\n", 486 | "-5.551115123125783e-16 7.771561172376096e-16\n", 487 | "-5.3488029977399876e-15 8.028300246820663e-15\n", 488 | "3.4139358007223564e-15 -5.134781488891349e-15\n", 489 | "3.608224830031759e-16 -6.661338147750939e-16\n", 490 | "5.551115123125783e-16 -8.881784197001252e-16\n", 491 | "3.885780586188048e-16 -8.881784197001252e-16\n", 492 | "1.0269562977782698e-15 -1.5265566588595902e-15\n", 493 | "5.984102102729594e-14 -8.97615315409439e-14\n", 494 | "5.551115123125783e-17 -1.1102230246251565e-16\n", 495 | "2.7755575615628914e-17 -1.1102230246251565e-16\n", 496 | "4.440892098500626e-16 -6.661338147750939e-16\n", 497 | "1.1102230246251565e-16 -2.220446049250313e-16\n", 498 | "3.3306690738754696e-16 -4.440892098500626e-16\n", 499 | "2.220446049250313e-16 -4.440892098500626e-16\n", 500 | "4.440892098500626e-16 -6.661338147750939e-16\n", 501 | "-4.996003610813204e-16 7.216449660063518e-16\n", 502 | "-2.220446049250313e-16 3.3306690738754696e-16\n", 503 | "6.661338147750939e-16 -9.992007221626409e-16\n", 504 | "0.0 1.1102230246251565e-16\n", 505 | "-1.887379141862766e-15 2.7755575615628914e-15\n", 506 | "7.771561172376096e-16 -1.2212453270876722e-15\n", 507 | "-1.3322676295501878e-15 2.220446049250313e-15\n", 508 | "3.3306690738754696e-16 -6.661338147750939e-16\n", 509 | "-3.3306690738754696e-16 5.551115123125783e-16\n", 510 | "-9.71445146547012e-17 1.6653345369377348e-16\n", 511 | "1.7763568394002505e-15 -2.7755575615628914e-15\n", 512 | "-2.220446049250313e-16 1.1102230246251565e-16\n", 513 | "-2.0583534876550402e-13 3.0878077872387166e-13\n", 514 | "-1.1102230246251565e-16 1.1102230246251565e-16\n", 515 | "2.831068712794149e-15 -4.218847493575595e-15\n", 516 | "-3.5388358909926865e-16 5.551115123125783e-16\n", 517 | "1.1102230246251565e-16 -1.1102230246251565e-16\n", 518 | "1.4432899320127035e-15 -2.1094237467877974e-15\n", 519 | "6.661338147750939e-16 -1.2212453270876722e-15\n", 520 | "1.205632815803881e-16 -1.6653345369377348e-16\n", 521 | "1.1102230246251565e-16 -1.1102230246251565e-16\n", 522 | "-8.673617379884035e-19 0.0\n", 523 | "0.0 1.1102230246251565e-16\n", 524 | "5.551115123125783e-16 -8.881784197001252e-16\n", 525 | "-5.551115123125783e-17 2.220446049250313e-16\n", 526 | "1.1102230246251565e-16 -2.220446049250313e-16\n", 527 | "3.219646771412954e-15 -4.884981308350689e-15\n", 528 | "4.440892098500626e-16 -7.771561172376096e-16\n", 529 | "-5.551115123125783e-16 9.992007221626409e-16\n", 530 | "7.979727989493313e-16 -1.1657341758564144e-15\n", 531 | "-3.302913498259841e-14 4.954370247389761e-14\n", 532 | "-5.290906601729262e-16 8.881784197001252e-16\n", 533 | "-3.885780586188048e-16 4.440892098500626e-16\n", 534 | "2.3869795029440866e-15 -3.497202527569243e-15\n", 535 | "-1.1379786002407855e-15 1.7763568394002505e-15\n", 536 | "-9.992007221626409e-16 1.609823385706477e-15\n", 537 | "6.661338147750939e-16 -9.992007221626409e-16\n", 538 | "1.1102230246251565e-16 -1.1102230246251565e-16\n", 539 | "-2.220446049250313e-16 3.3306690738754696e-16\n", 540 | "-6.106226635438361e-16 9.992007221626409e-16\n", 541 | "0.0 0.0\n", 542 | "-1.1102230246251565e-16 2.220446049250313e-16\n", 543 | "-3.2751579226442118e-15 4.9960036108132044e-15\n", 544 | "-1.1102230246251565e-16 1.1102230246251565e-16\n", 545 | "-2.498001805406602e-16 4.440892098500626e-16\n", 546 | "-4.579669976578771e-15 6.827871601444713e-15\n", 547 | "1.1102230246251565e-15 -1.7763568394002505e-15\n", 548 | "5.551115123125783e-17 -1.1102230246251565e-16\n", 549 | "4.996003610813204e-16 -8.881784197001252e-16\n", 550 | "5.551115123125783e-16 -8.881784197001252e-16\n", 551 | "-7.93809462606987e-15 1.1934897514720433e-14\n", 552 | "1.7763568394002505e-15 -2.6645352591003757e-15\n", 553 | "-1.1102230246251565e-16 1.6653345369377348e-16\n", 554 | "-3.3306690738754696e-16 5.551115123125783e-16\n", 555 | "-6.8833827526759706e-15 1.0325074129013956e-14\n", 556 | "-3.3306690738754696e-16 6.661338147750939e-16\n", 557 | "-9.992007221626409e-16 1.5543122344752192e-15\n", 558 | "-2.220446049250313e-16 5.551115123125783e-16\n", 559 | "-7.216449660063518e-16 1.1657341758564144e-15\n", 560 | "1.4432899320127035e-15 -2.220446049250313e-15\n", 561 | "1.1102230246251565e-16 -1.1102230246251565e-16\n", 562 | "5.35682609381638e-15 -8.076872504148014e-15\n", 563 | "-1.1102230246251565e-16 1.1102230246251565e-16\n", 564 | "-3.885780586188048e-16 7.771561172376096e-16\n", 565 | "2.275957200481571e-15 -3.497202527569243e-15\n", 566 | "1.1102230246251565e-15 -1.7763568394002505e-15\n", 567 | "3.885780586188048e-16 -5.551115123125783e-16\n", 568 | "2.220446049250313e-16 -4.440892098500626e-16\n", 569 | "3.885780586188048e-16 -4.996003610813204e-16\n", 570 | "1.9984014443252818e-15 -2.9976021664879227e-15\n", 571 | "-1.0408340855860843e-15 1.6653345369377348e-15\n", 572 | "-1.4432899320127035e-15 2.1094237467877974e-15\n", 573 | "-2.1094237467877974e-15 3.219646771412954e-15\n", 574 | "-5.828670879282072e-16 7.771561172376096e-16\n", 575 | "6.661338147750939e-16 -1.1102230246251565e-15\n", 576 | "-3.885780586188048e-16 7.771561172376096e-16\n", 577 | "5.551115123125783e-16 -9.992007221626409e-16\n", 578 | "-2.7755575615628914e-16 6.661338147750939e-16\n", 579 | "-3.3306690738754696e-16 4.440892098500626e-16\n", 580 | "1.3322676295501878e-15 -2.1094237467877974e-15\n", 581 | "-6.938893903907228e-17 1.1102230246251565e-16\n", 582 | "8.881784197001252e-16 -1.3322676295501878e-15\n", 583 | "2.814415367424772e-13 -4.221067939624845e-13\n", 584 | "-7.771561172376096e-16 1.1102230246251565e-15\n", 585 | "2.9976021664879227e-15 -4.440892098500626e-15\n", 586 | "2.886579864025407e-15 -4.385380947269368e-15\n", 587 | "-1.1171619185290638e-15 1.7208456881689926e-15\n", 588 | "2.3314683517128287e-15 -3.552713678800501e-15\n", 589 | "1.4988010832439613e-15 -2.3869795029440866e-15\n", 590 | "5.551115123125783e-17 -2.220446049250313e-16\n", 591 | "-1.2712053631958042e-14 1.9095836023552692e-14\n", 592 | "-4.440892098500626e-16 7.771561172376096e-16\n", 593 | "1.797173521111972e-15 -2.7755575615628914e-15\n", 594 | "4.440892098500626e-16 -7.771561172376096e-16\n", 595 | "1.3322676295501878e-15 -2.1094237467877974e-15\n", 596 | "3.941291737419306e-15 -5.9396931817445875e-15\n", 597 | "1.1102230246251565e-15 -1.7763568394002505e-15\n", 598 | "7.771561172376096e-16 -1.1102230246251565e-15\n", 599 | "1.7763568394002505e-15 -2.6645352591003757e-15\n", 600 | "-9.992007221626409e-16 1.3322676295501878e-15\n", 601 | "6.661338147750939e-16 -7.771561172376096e-16\n", 602 | "-8.881784197001252e-16 1.3322676295501878e-15\n", 603 | "1.1102230246251565e-15 -1.6653345369377348e-15\n", 604 | "-1.3322676295501878e-15 2.3314683517128287e-15\n", 605 | "-1.4432899320127035e-15 1.9984014443252818e-15\n", 606 | "0.0 0.0\n", 607 | "-4.440892098500626e-16 6.661338147750939e-16\n", 608 | "8.049116928532385e-16 -1.4432899320127035e-15\n", 609 | "8.881784197001252e-16 -1.3322676295501878e-15\n", 610 | "-8.326672684688674e-17 1.1102230246251565e-16\n", 611 | "1.1102230246251565e-16 -1.1102230246251565e-16\n", 612 | "5.551115123125783e-17 -5.551115123125783e-17\n", 613 | "-8.881784197001252e-16 1.2212453270876722e-15\n", 614 | "3.11972669919669e-14 -4.6851411639181606e-14\n", 615 | "-1.1102230246251565e-16 0.0\n", 616 | "-1.0824674490095276e-15 1.6653345369377348e-15\n", 617 | "-2.6645352591003757e-15 3.9968028886505635e-15\n", 618 | "-2.2898349882893854e-15 3.608224830031759e-15\n", 619 | "-1.1102230246251565e-16 1.1102230246251565e-16\n", 620 | "2.220446049250313e-16 -3.3306690738754696e-16\n", 621 | "-3.885780586188048e-16 6.106226635438361e-16\n", 622 | "4.718447854656915e-16 -7.771561172376096e-16\n", 623 | "6.661338147750939e-16 -1.2212453270876722e-15\n", 624 | "5.551115123125783e-16 -7.771561172376096e-16\n", 625 | "-1.0547118733938987e-15 1.609823385706477e-15\n", 626 | "-2.1094237467877974e-15 3.219646771412954e-15\n", 627 | "6.661338147750939e-16 -1.1102230246251565e-15\n", 628 | "-5.551115123125783e-17 5.551115123125783e-17\n", 629 | "-6.106226635438361e-16 9.43689570931383e-16\n", 630 | "1.1102230246251565e-15 -1.6653345369377348e-15\n", 631 | "-5.828670879282072e-16 9.992007221626409e-16\n", 632 | "2.831068712794149e-15 -4.274358644806853e-15\n", 633 | "-2.220446049250313e-16 1.1102230246251565e-16\n", 634 | "7.771561172376096e-16 -1.3322676295501878e-15\n", 635 | "5.551115123125783e-16 -9.992007221626409e-16\n", 636 | "5.551115123125783e-17 -1.1102230246251565e-16\n", 637 | "0.0 0.0\n", 638 | "4.996003610813204e-16 -7.216449660063518e-16\n", 639 | "-5.551115123125783e-17 0.0\n", 640 | "-1.1102230246251565e-16 2.220446049250313e-16\n", 641 | "-6.661338147750939e-16 1.1102230246251565e-15\n", 642 | "-3.3306690738754696e-16 4.440892098500626e-16\n", 643 | "1.0824674490095276e-15 -1.6653345369377348e-15\n", 644 | "-5.828670879282072e-16 9.992007221626409e-16\n", 645 | "1.1157741397482823e-14 -1.6708856520608606e-14\n", 646 | "3.3306690738754696e-16 -4.440892098500626e-16\n", 647 | "-2.7755575615628914e-16 4.440892098500626e-16\n", 648 | "-1.1102230246251565e-16 1.1102230246251565e-16\n", 649 | "-1.609823385706477e-15 2.4980018054066022e-15\n", 650 | "-1.6653345369377348e-16 3.3306690738754696e-16\n", 651 | "3.3306690738754696e-16 -5.551115123125783e-16\n", 652 | "-3.3306690738754696e-16 4.440892098500626e-16\n", 653 | "7.771561172376096e-16 -1.2212453270876722e-15\n", 654 | "-3.3306690738754696e-16 4.440892098500626e-16\n", 655 | "3.608224830031759e-16 -6.661338147750939e-16\n", 656 | "-1.27675647831893e-15 1.942890293094024e-15\n", 657 | "2.220446049250313e-16 -5.551115123125783e-16\n", 658 | "-1.2212453270876722e-15 1.7763568394002505e-15\n", 659 | "2.7755575615628914e-16 -4.996003610813204e-16\n", 660 | "1.1102230246251565e-16 0.0\n", 661 | "1.5543122344752192e-15 -2.3314683517128287e-15\n", 662 | "-1.1102230246251565e-16 2.220446049250313e-16\n", 663 | "-4.440892098500626e-15 6.661338147750939e-15\n", 664 | "-1.1796119636642288e-15 1.8318679906315083e-15\n", 665 | "-2.0611984341556422e-14 3.0933589023618424e-14\n", 666 | "-3.903127820947816e-16 6.661338147750939e-16\n", 667 | "-3.0531133177191805e-16 4.440892098500626e-16\n", 668 | "1.1102230246251565e-16 -1.1102230246251565e-16\n", 669 | "-2.7755575615628914e-17 2.7755575615628914e-17\n", 670 | "-5.551115123125783e-16 1.1102230246251565e-15\n", 671 | "-1.734723475976807e-15 2.609024107869118e-15\n", 672 | "-2.220446049250313e-16 2.220446049250313e-16\n", 673 | "-7.771561172376096e-16 1.2212453270876722e-15\n", 674 | "-5.689893001203927e-15 8.576472865229334e-15\n", 675 | "1.0103029524088925e-14 -1.4988010832439613e-14\n", 676 | "-1.1102230246251565e-16 3.3306690738754696e-16\n", 677 | "2.498001805406602e-16 -3.3306690738754696e-16\n", 678 | "-1.1102230246251565e-15 1.7763568394002505e-15\n", 679 | "7.632783294297951e-16 -1.2212453270876722e-15\n", 680 | "-4.440892098500626e-16 9.992007221626409e-16\n", 681 | "8.881784197001252e-16 -1.3322676295501878e-15\n", 682 | "-7.129713486264677e-16 1.1102230246251565e-15\n", 683 | "3.3306690738754696e-16 -5.551115123125783e-16\n", 684 | "2.7755575615628914e-17 1.1102230246251565e-16\n", 685 | "7.494005416219807e-16 -1.3322676295501878e-15\n", 686 | "-1.1102230246251565e-16 0.0\n", 687 | "1.6653345369377348e-15 -2.55351295663786e-15\n", 688 | "-3.3306690738754696e-16 6.661338147750939e-16\n", 689 | "2.4424906541753444e-15 -3.774758283725532e-15\n", 690 | "6.328271240363392e-15 -9.547918011776346e-15\n", 691 | "1.3100631690576847e-14 -1.965094753586527e-14\n", 692 | "-8.881784197001252e-16 1.5543122344752192e-15\n", 693 | "6.661338147750939e-16 -1.1102230246251565e-15\n", 694 | "-1.1102230246251565e-16 1.1102230246251565e-16\n", 695 | "-1.3433698597964394e-14 2.020605904817785e-14\n", 696 | "-1.7763568394002505e-15 2.6645352591003757e-15\n", 697 | "-1.942890293094024e-16 3.3306690738754696e-16\n", 698 | "-3.3306690738754696e-16 4.440892098500626e-16\n", 699 | "6.661338147750939e-16 -8.881784197001252e-16\n", 700 | "-1.5265566588595902e-16 2.7755575615628914e-16\n", 701 | "-2.220446049250313e-16 3.3306690738754696e-16\n", 702 | "-3.885780586188048e-16 6.106226635438361e-16\n", 703 | "-1.7763568394002505e-15 2.7755575615628914e-15\n", 704 | "7.771561172376096e-16 -1.1102230246251565e-15\n", 705 | "4.718447854656915e-16 -7.771561172376096e-16\n", 706 | "-3.3306690738754696e-16 5.551115123125783e-16\n", 707 | "-1.1102230246251565e-16 2.220446049250313e-16\n", 708 | "2.3592239273284576e-16 -3.3306690738754696e-16\n", 709 | "2.7478019859472624e-15 -4.135580766728708e-15\n", 710 | "-3.885780586188048e-16 6.661338147750939e-16\n", 711 | "4.996003610813204e-16 -7.771561172376096e-16\n", 712 | "-9.992007221626409e-16 1.6653345369377348e-15\n", 713 | "0.0 -1.1102230246251565e-16\n", 714 | "5.551115123125783e-16 -8.881784197001252e-16\n", 715 | "-5.551115123125783e-16 7.771561172376096e-16\n", 716 | "-2.6645352591003757e-15 3.9968028886505635e-15\n", 717 | "1.6653345369377348e-16 -2.7755575615628914e-16\n", 718 | "1.609823385706477e-15 -2.3869795029440866e-15\n", 719 | "-1.5543122344752192e-15 2.4424906541753444e-15\n", 720 | "2.0761170560490427e-14 -3.108624468950438e-14\n", 721 | "-2.220446049250313e-16 4.440892098500626e-16\n", 722 | "1.1934897514720433e-15 -1.887379141862766e-15\n", 723 | "-3.164135620181696e-15 4.718447854656915e-15\n", 724 | "-3.3306690738754696e-16 5.551115123125783e-16\n", 725 | "5.10702591327572e-15 -7.66053886991358e-15\n", 726 | "7.771561172376096e-16 -9.992007221626409e-16\n", 727 | "6.661338147750939e-16 -1.1102230246251565e-15\n", 728 | "9.992007221626409e-16 -1.3322676295501878e-15\n", 729 | "2.220446049250313e-16 -3.3306690738754696e-16\n", 730 | "4.440892098500626e-16 -6.661338147750939e-16\n", 731 | "2.220446049250313e-16 -5.551115123125783e-16\n", 732 | "-9.43689570931383e-16 1.4988010832439613e-15\n", 733 | "3.469446951953614e-16 -5.551115123125783e-16\n", 734 | "2.220446049250313e-16 -5.551115123125783e-16\n", 735 | "1.1102230246251565e-16 0.0\n", 736 | "2.0469737016526324e-16 -4.440892098500626e-16\n", 737 | "-2.7755575615628914e-16 3.885780586188048e-16\n", 738 | "-1.083855227790309e-14 1.625088952295073e-14\n", 739 | "4.440892098500626e-16 -6.661338147750939e-16\n", 740 | "3.8163916471489756e-17 0.0\n", 741 | "-1.6653345369377348e-16 2.7755575615628914e-16\n", 742 | "-3.3306690738754696e-16 6.661338147750939e-16\n", 743 | "3.608224830031759e-16 -5.551115123125783e-16\n", 744 | "3.608224830031759e-16 -6.661338147750939e-16\n", 745 | "-4.440892098500626e-16 6.661338147750939e-16\n", 746 | "-1.7591483825185605e-13 2.639000129533997e-13\n", 747 | "3.219646771412954e-15 -4.829470157119431e-15\n", 748 | "2.7755575615628914e-16 -3.885780586188048e-16\n", 749 | "-6.661338147750939e-16 1.1102230246251565e-15\n", 750 | "-5.551115123125783e-16 8.881784197001252e-16\n", 751 | "3.552713678800501e-15 -5.329070518200751e-15\n", 752 | "4.440892098500626e-16 -8.881784197001252e-16\n", 753 | "-2.1843638009499955e-14 3.276545701424993e-14\n", 754 | "-1.3322676295501878e-15 1.9984014443252818e-15\n", 755 | "-7.771561172376096e-16 1.1102230246251565e-15\n", 756 | "-8.326672684688674e-17 1.1102230246251565e-16\n", 757 | "-2.3314683517128287e-15 3.4416913763379853e-15\n", 758 | "0.0 0.0\n", 759 | "0.0 -1.1102230246251565e-16\n", 760 | "3.219646771412954e-15 -4.884981308350689e-15\n", 761 | "4.996003610813204e-16 -8.881784197001252e-16\n", 762 | "-1.7763568394002505e-15 2.55351295663786e-15\n", 763 | "1.5543122344752192e-15 -2.4424906541753444e-15\n", 764 | "4.440892098500626e-16 -8.881784197001252e-16\n", 765 | "6.661338147750939e-16 -1.1102230246251565e-15\n", 766 | "-5.551115123125783e-16 7.771561172376096e-16\n", 767 | "5.551115123125783e-17 2.220446049250313e-16\n", 768 | "-3.885780586188048e-15 5.88418203051333e-15\n", 769 | "-4.996003610813204e-16 7.771561172376096e-16\n", 770 | "-7.632783294297951e-16 1.2212453270876722e-15\n", 771 | "-4.996003610813204e-16 7.216449660063518e-16\n", 772 | "-1.2420620087993939e-15 1.887379141862766e-15\n", 773 | "-3.552713678800501e-15 5.329070518200751e-15\n", 774 | "5.440092820663267e-15 -8.215650382226158e-15\n", 775 | "2.498001805406602e-16 -5.551115123125783e-16\n", 776 | "-1.1102230246251565e-16 3.3306690738754696e-16\n", 777 | "-5.551115123125783e-16 8.881784197001252e-16\n", 778 | "-3.0531133177191805e-15 4.6074255521944e-15\n", 779 | "-3.9968028886505635e-15 5.995204332975845e-15\n", 780 | "6.661338147750939e-16 -1.1102230246251565e-15\n", 781 | "0.0 0.0\n", 782 | "-5.48172618408671e-16 8.326672684688674e-16\n", 783 | "0.0 0.0\n", 784 | "-2.220446049250313e-16 3.3306690738754696e-16\n", 785 | "-2.220446049250313e-16 5.551115123125783e-16\n", 786 | "-3.0531133177191805e-16 6.661338147750939e-16\n", 787 | "-1.717376241217039e-16 2.498001805406602e-16\n", 788 | "-3.0531133177191805e-16 5.551115123125783e-16\n", 789 | "-1.1102230246251565e-16 2.220446049250313e-16\n", 790 | "-1.6653345369377348e-16 2.220446049250313e-16\n", 791 | "1.97758476261356e-16 -3.3306690738754696e-16\n", 792 | "1.1102230246251565e-15 -1.7763568394002505e-15\n", 793 | "1.1102230246251565e-15 -1.6653345369377348e-15\n", 794 | "2.7755575615628914e-17 0.0\n", 795 | "4.440892098500626e-16 -7.771561172376096e-16\n", 796 | "4.440892098500626e-16 -7.771561172376096e-16\n", 797 | "-5.551115123125783e-16 8.881784197001252e-16\n", 798 | "4.996003610813204e-16 -6.661338147750939e-16\n", 799 | "-4.440892098500626e-16 6.661338147750939e-16\n", 800 | "-2.220446049250313e-16 3.3306690738754696e-16\n", 801 | "-2.220446049250313e-16 3.3306690738754696e-16\n", 802 | "-4.440892098500626e-16 6.661338147750939e-16\n", 803 | "-5.551115123125783e-16 9.992007221626409e-16\n", 804 | "-3.608224830031759e-16 5.551115123125783e-16\n", 805 | "-5.551115123125783e-16 7.771561172376096e-16\n", 806 | "-3.3306690738754696e-16 5.551115123125783e-16\n", 807 | "4.440892098500626e-16 -6.661338147750939e-16\n", 808 | "3.0531133177191805e-16 -4.440892098500626e-16\n", 809 | "-1.5508427875232655e-15 2.3869795029440866e-15\n", 810 | "3.219646771412954e-15 -4.6629367034256575e-15\n", 811 | "-6.661338147750939e-16 8.881784197001252e-16\n", 812 | "8.326672684688674e-15 -1.2545520178264269e-14\n", 813 | "-8.326672684688674e-16 1.27675647831893e-15\n", 814 | "-2.1094237467877974e-15 3.4416913763379853e-15\n", 815 | "4.440892098500626e-16 -6.661338147750939e-16\n", 816 | "1.1102230246251565e-15 -1.7763568394002505e-15\n", 817 | "-5.828670879282072e-16 9.159339953157541e-16\n", 818 | "2.7755575615628914e-16 -4.440892098500626e-16\n", 819 | "7.216449660063518e-16 -1.0547118733938987e-15\n", 820 | "3.3306690738754696e-16 -5.551115123125783e-16\n", 821 | "1.1657341758564144e-15 -1.7208456881689926e-15\n", 822 | "2.218364381079141e-14 -3.3285874057042975e-14\n", 823 | "1.1102230246251565e-16 -2.220446049250313e-16\n", 824 | "-4.440892098500626e-16 7.771561172376096e-16\n", 825 | "-3.885780586188048e-16 6.661338147750939e-16\n", 826 | "-4.440892098500626e-16 7.771561172376096e-16\n", 827 | "4.0939474033052647e-16 -7.771561172376096e-16\n", 828 | "1.1796119636642288e-15 -1.887379141862766e-15\n", 829 | "-2.220446049250313e-16 5.551115123125783e-16\n", 830 | "-6.106226635438361e-16 9.43689570931383e-16\n", 831 | "8.881784197001252e-16 -1.2212453270876722e-15\n", 832 | "2.3314683517128287e-15 -3.4416913763379853e-15\n", 833 | "1.3877787807814457e-15 -2.0539125955565396e-15\n", 834 | "-7.771561172376096e-16 1.2212453270876722e-15\n", 835 | "-1.3322676295501878e-15 1.9984014443252818e-15\n", 836 | "-2.2870594307278225e-14 3.430589146091734e-14\n", 837 | "2.220446049250313e-16 -5.551115123125783e-16\n", 838 | "4.440892098500626e-16 -9.992007221626409e-16\n", 839 | "0.0 1.1102230246251565e-16\n", 840 | "-1.0824674490095276e-15 1.6653345369377348e-15\n", 841 | "1.3461454173580023e-15 -2.0122792321330962e-15\n", 842 | "4.440892098500626e-16 -7.771561172376096e-16\n", 843 | "4.440892098500626e-16 -6.661338147750939e-16\n", 844 | "-7.771561172376096e-16 1.1102230246251565e-15\n", 845 | "2.0122792321330962e-16 -3.3306690738754696e-16\n", 846 | "9.43689570931383e-16 -1.3877787807814457e-15\n", 847 | "1.3530843112619095e-15 -1.9984014443252818e-15\n", 848 | "1.5265566588595902e-16 -3.3306690738754696e-16\n", 849 | "1.1102230246251565e-16 -1.1102230246251565e-16\n", 850 | "-4.884981308350689e-15 7.327471962526033e-15\n", 851 | "2.498001805406602e-16 -4.440892098500626e-16\n", 852 | "1.5543122344752192e-15 -2.4424906541753444e-15\n", 853 | "0.0 0.0\n", 854 | "-1.1102230246251565e-16 0.0\n", 855 | "1.887379141862766e-15 -2.7755575615628914e-15\n", 856 | "7.216449660063518e-16 -1.2212453270876722e-15\n", 857 | "0.0 1.1102230246251565e-16\n", 858 | "-1.1102230246251565e-15 1.6653345369377348e-15\n", 859 | "-3.6637359812630166e-15 5.551115123125783e-15\n", 860 | "-1.4432899320127035e-15 2.1094237467877974e-15\n", 861 | "2.3037127760972e-15 -3.552713678800501e-15\n", 862 | "-1.3322676295501878e-15 1.887379141862766e-15\n", 863 | "-1.0200174038743626e-15 1.5543122344752192e-15\n", 864 | "7.216449660063518e-16 -1.0547118733938987e-15\n", 865 | "-1.3322676295501878e-15 1.9984014443252818e-15\n", 866 | "1.1102230246251565e-16 -1.1102230246251565e-16\n", 867 | "0.0 1.1102230246251565e-16\n", 868 | "-3.3306690738754696e-16 4.440892098500626e-16\n", 869 | "1.5543122344752192e-15 -2.220446049250313e-15\n", 870 | "5.551115123125783e-17 -1.1102230246251565e-16\n", 871 | "-8.326672684688674e-17 1.1102230246251565e-16\n", 872 | "-7.771561172376096e-16 1.2212453270876722e-15\n", 873 | "8.881784197001252e-16 -1.3322676295501878e-15\n", 874 | "8.881784197001252e-16 -1.3322676295501878e-15\n", 875 | "-3.552713678800501e-15 5.2735593669694936e-15\n", 876 | "-1.6653345369377348e-15 2.4424906541753444e-15\n", 877 | "2.7755575615628914e-17 0.0\n", 878 | "-8.881784197001252e-16 1.3322676295501878e-15\n", 879 | "8.881784197001252e-16 -1.3322676295501878e-15\n", 880 | "-2.220446049250313e-16 4.440892098500626e-16\n", 881 | "-5.828670879282072e-16 9.992007221626409e-16\n", 882 | "9.992007221626409e-16 -1.6653345369377348e-15\n", 883 | "-1.0547118733938987e-15 1.7208456881689926e-15\n", 884 | "3.3306690738754696e-16 -6.661338147750939e-16\n", 885 | "-2.220446049250313e-16 5.551115123125783e-16\n", 886 | "-5.551115123125783e-17 1.1102230246251565e-16\n", 887 | "-1.1102230246251565e-16 1.1102230246251565e-16\n", 888 | "8.881784197001252e-16 -1.4432899320127035e-15\n", 889 | "3.3306690738754696e-16 -6.661338147750939e-16\n", 890 | "5.551115123125783e-16 -9.992007221626409e-16\n", 891 | "4.9960036108132044e-15 -7.438494264988549e-15\n", 892 | "6.938893903907228e-18 0.0\n", 893 | "-2.220446049250313e-16 3.3306690738754696e-16\n", 894 | "2.886579864025407e-15 -4.3298697960381105e-15\n", 895 | "-1.1102230246251565e-15 1.7763568394002505e-15\n", 896 | "-3.3306690738754696e-16 5.551115123125783e-16\n", 897 | "-7.91033905045424e-16 1.2212453270876722e-15\n", 898 | "4.440892098500626e-16 -6.661338147750939e-16\n", 899 | "-2.220446049250313e-16 3.3306690738754696e-16\n", 900 | "-1.1102230246251565e-16 4.440892098500626e-16\n", 901 | "-5.995204332975845e-15 8.881784197001252e-15\n", 902 | "2.220446049250313e-15 -3.3306690738754696e-15\n", 903 | "-3.3306690738754696e-16 5.551115123125783e-16\n", 904 | "-7.771561172376096e-16 1.1102230246251565e-15\n", 905 | "-5.551115123125783e-16 9.992007221626409e-16\n", 906 | "8.881784197001252e-16 -1.6653345369377348e-15\n", 907 | "7.216449660063518e-16 -1.1102230246251565e-15\n", 908 | "2.4980018054066022e-15 -3.83026943495679e-15\n", 909 | "5.551115123125783e-16 -7.771561172376096e-16\n", 910 | "3.0808688933348094e-15 -4.6351811278100286e-15\n", 911 | "1.1102230246251565e-16 -3.3306690738754696e-16\n", 912 | "-6.661338147750939e-16 9.992007221626409e-16\n", 913 | "5.551115123125783e-16 -8.881784197001252e-16\n", 914 | "1.8318679906315083e-15 -2.7200464103316335e-15\n", 915 | "-7.355227538141662e-16 1.2212453270876722e-15\n", 916 | "1.3877787807814457e-15 -2.0539125955565396e-15\n", 917 | "-2.7755575615628914e-16 6.661338147750939e-16\n", 918 | "7.771561172376096e-16 -1.3322676295501878e-15\n", 919 | "-3.774758283725532e-15 5.662137425588298e-15\n", 920 | "-2.3314683517128287e-15 3.552713678800501e-15\n", 921 | "1.1102230246251565e-16 -1.1102230246251565e-16\n", 922 | "2.220446049250313e-16 -4.440892098500626e-16\n", 923 | "3.1086244689504383e-15 -4.6629367034256575e-15\n", 924 | "1.1102230246251565e-16 -2.220446049250313e-16\n", 925 | "-5.551115123125783e-16 7.771561172376096e-16\n", 926 | "-7.216449660063518e-16 1.0547118733938987e-15\n", 927 | "-1.1379786002407855e-15 1.6653345369377348e-15\n", 928 | "6.661338147750939e-16 -1.2212453270876722e-15\n", 929 | "2.1094237467877974e-15 -3.219646771412954e-15\n", 930 | "-1.6653345369377348e-16 3.885780586188048e-16\n", 931 | "7.216449660063518e-16 -1.1657341758564144e-15\n", 932 | "4.163336342344337e-16 -7.771561172376096e-16\n", 933 | "0.0 0.0\n", 934 | "-5.273559366969494e-16 8.881784197001252e-16\n", 935 | "5.551115123125783e-16 -6.661338147750939e-16\n", 936 | "-3.3306690738754696e-16 6.661338147750939e-16\n", 937 | "4.718447854656915e-16 -8.881784197001252e-16\n", 938 | "-1.1102230246251565e-16 0.0\n", 939 | "2.220446049250313e-16 -4.440892098500626e-16\n", 940 | "-1.1102230246251565e-16 0.0\n", 941 | "-1.1102230246251565e-16 1.1102230246251565e-16\n", 942 | "5.551115123125783e-16 -7.771561172376096e-16\n", 943 | "7.355227538141662e-16 -1.1102230246251565e-15\n", 944 | "4.440892098500626e-16 -7.771561172376096e-16\n", 945 | "1.1102230246251565e-16 -1.1102230246251565e-16\n", 946 | "-3.3306690738754696e-16 5.551115123125783e-16\n", 947 | "2.3245294578089215e-16 -3.3306690738754696e-16\n", 948 | "5.551115123125783e-16 -1.1102230246251565e-15\n", 949 | "5.551115123125783e-17 1.1102230246251565e-16\n", 950 | "2.220446049250313e-16 -1.1102230246251565e-16\n", 951 | "-6.661338147750939e-16 1.1102230246251565e-15\n", 952 | "4.3021142204224816e-16 -7.771561172376096e-16\n", 953 | "-9.992007221626409e-16 1.4432899320127035e-15\n", 954 | "5.828670879282072e-16 -9.992007221626409e-16\n", 955 | "1.1102230246251565e-16 -3.3306690738754696e-16\n", 956 | "-4.440892098500626e-16 6.661338147750939e-16\n", 957 | "-1.5831086441764342e-13 2.374836438612249e-13\n", 958 | "-5.689893001203927e-16 8.881784197001252e-16\n", 959 | "-5.551115123125783e-16 7.771561172376096e-16\n", 960 | "7.438494264988549e-15 -1.1213252548714081e-14\n", 961 | "-4.996003610813204e-16 7.216449660063518e-16\n", 962 | "5.551115123125783e-16 -8.881784197001252e-16\n", 963 | "2.6333102365327932e-14 -3.9517000782751666e-14\n", 964 | "-1.1102230246251565e-16 1.1102230246251565e-16\n", 965 | "1.609823385706477e-15 -2.3869795029440866e-15\n", 966 | "-7.771561172376096e-16 1.2212453270876722e-15\n", 967 | "-6.661338147750939e-16 9.992007221626409e-16\n", 968 | "4.440892098500626e-16 -6.661338147750939e-16\n", 969 | "-8.881784197001252e-16 1.4432899320127035e-15\n", 970 | "-4.440892098500626e-16 7.771561172376096e-16\n", 971 | "-3.3306690738754696e-16 4.440892098500626e-16\n", 972 | "-9.992007221626409e-16 1.6653345369377348e-15\n", 973 | "2.220446049250313e-15 -3.6637359812630166e-15\n", 974 | "2.1094237467877974e-15 -3.219646771412954e-15\n", 975 | "-1.5543122344752192e-15 2.220446049250313e-15\n", 976 | "-2.9976021664879227e-15 4.551914400963142e-15\n", 977 | "-5.662137425588298e-15 8.548717289613705e-15\n", 978 | "-8.881784197001252e-16 1.4432899320127035e-15\n", 979 | "1.1102230246251565e-16 0.0\n", 980 | "-2.220446049250313e-16 5.551115123125783e-16\n", 981 | "-5.551115123125783e-16 8.881784197001252e-16\n", 982 | "1.5543122344752192e-15 -2.4424906541753444e-15\n", 983 | "-1.6653345369377348e-15 2.4424906541753444e-15\n", 984 | "3.935518577691255e-12 -5.90316684423442e-12\n", 985 | "8.881784197001252e-16 -1.2212453270876722e-15\n", 986 | "-3.497202527569243e-15 5.218048215738236e-15\n", 987 | "-5.551115123125783e-17 0.0\n", 988 | "-2.7807617319908218e-15 4.191091917959966e-15\n", 989 | "-2.8449465006019636e-16 4.440892098500626e-16\n", 990 | "3.885780586188048e-16 -6.661338147750939e-16\n", 991 | "1.1379786002407855e-15 -1.7763568394002505e-15\n", 992 | "1.0408340855860843e-15 -1.609823385706477e-15\n", 993 | "5.218048215738236e-15 -7.882583474838611e-15\n", 994 | "1.27675647831893e-15 -1.942890293094024e-15\n", 995 | "2.220446049250313e-16 -3.3306690738754696e-16\n", 996 | "1.4432899320127035e-15 -2.220446049250313e-15\n", 997 | "1.734723475976807e-17 0.0\n", 998 | "-3.3306690738754696e-16 6.661338147750939e-16\n", 999 | "0.0 0.0\n", 1000 | "0.0 0.0\n", 1001 | "-2.0816681711721685e-17 0.0\n", 1002 | "-8.881784197001252e-16 1.3322676295501878e-15\n", 1003 | "-3.3306690738754696e-16 4.440892098500626e-16\n", 1004 | "3.885780586188048e-16 -4.996003610813204e-16\n", 1005 | "6.661338147750939e-16 -1.1102230246251565e-15\n", 1006 | "-2.220446049250313e-16 4.440892098500626e-16\n", 1007 | "-4.996003610813204e-16 9.992007221626409e-16\n", 1008 | "-2.3175905639050143e-15 3.552713678800501e-15\n", 1009 | "8.881784197001252e-16 -1.3322676295501878e-15\n", 1010 | "5.273559366969494e-16 -6.661338147750939e-16\n", 1011 | "1.6653345369377348e-15 -2.6645352591003757e-15\n", 1012 | "7.216449660063518e-15 -1.0880185641326534e-14\n", 1013 | "-1.1102230246251565e-16 2.220446049250313e-16\n", 1014 | "-6.661338147750939e-16 8.881784197001252e-16\n", 1015 | "-1.1102230246251565e-15 1.7208456881689926e-15\n", 1016 | "4.440892098500626e-16 -7.771561172376096e-16\n", 1017 | "2.220446049250313e-16 -4.440892098500626e-16\n", 1018 | "9.992007221626409e-16 -1.7763568394002505e-15\n", 1019 | "0.0 0.0\n", 1020 | "-6.106226635438361e-16 9.992007221626409e-16\n", 1021 | "-1.1102230246251565e-16 4.440892098500626e-16\n", 1022 | "-6.328271240363392e-15 9.43689570931383e-15\n", 1023 | "4.163336342344337e-17 -1.1102230246251565e-16\n", 1024 | "-2.220446049250313e-16 4.440892098500626e-16\n", 1025 | "0.0 0.0\n", 1026 | "6.800116025829084e-16 -9.992007221626409e-16\n", 1027 | "2.220446049250313e-16 -2.220446049250313e-16\n", 1028 | "-3.3306690738754696e-16 5.551115123125783e-16\n", 1029 | "0.0 -1.1102230246251565e-16\n", 1030 | "9.43689570931383e-16 -1.4432899320127035e-15\n", 1031 | "1.3877787807814457e-17 -1.1102230246251565e-16\n", 1032 | "6.38378239159465e-16 -9.992007221626409e-16\n", 1033 | "-2.7755575615628914e-17 0.0\n", 1034 | "1.1102230246251565e-16 -2.220446049250313e-16\n", 1035 | "-9.992007221626409e-16 1.5543122344752192e-15\n", 1036 | "-3.019806626980426e-14 4.5352610555937645e-14\n", 1037 | "4.85722573273506e-16 -6.661338147750939e-16\n", 1038 | "-3.3306690738754696e-16 5.551115123125783e-16\n", 1039 | "-9.159339953157541e-16 1.3322676295501878e-15\n", 1040 | "-1.1657341758564144e-15 1.8318679906315083e-15\n", 1041 | "-4.6629367034256575e-15 7.105427357601002e-15\n", 1042 | "-2.220446049250313e-16 5.551115123125783e-16\n", 1043 | "0.0 1.1102230246251565e-16\n", 1044 | "-1.1102230246251565e-15 1.5543122344752192e-15\n", 1045 | "2.7755575615628914e-16 -3.3306690738754696e-16\n", 1046 | "-2.7755575615628914e-17 0.0\n", 1047 | "-4.440892098500626e-16 7.771561172376096e-16\n", 1048 | "-2.55351295663786e-15 3.774758283725532e-15\n", 1049 | "1.6653345369377348e-16 -2.220446049250313e-16\n", 1050 | "1.1102230246251565e-16 -2.220446049250313e-16\n", 1051 | "-1.1102230246251565e-15 1.7763568394002505e-15\n", 1052 | "2.220446049250313e-16 -1.1102230246251565e-16\n", 1053 | "1.1102230246251565e-16 -1.1102230246251565e-16\n", 1054 | "2.1094237467877974e-15 -3.3306690738754696e-15\n", 1055 | "6.106226635438361e-16 -9.992007221626409e-16\n", 1056 | "8.326672684688674e-17 -1.1102230246251565e-16\n", 1057 | "1.3322676295501878e-15 -2.1094237467877974e-15\n", 1058 | "-6.106226635438361e-16 8.881784197001252e-16\n", 1059 | "8.881784197001252e-16 -1.3322676295501878e-15\n", 1060 | "-1.2212453270876722e-15 1.887379141862766e-15\n", 1061 | "1.1102230246251565e-16 -3.3306690738754696e-16\n", 1062 | "-4.440892098500626e-16 6.661338147750939e-16\n", 1063 | "-2.220446049250313e-16 4.440892098500626e-16\n", 1064 | "-2.886579864025407e-15 4.3298697960381105e-15\n", 1065 | "-3.3306690738754696e-16 5.551115123125783e-16\n", 1066 | "1.2212453270876722e-15 -1.7763568394002505e-15\n", 1067 | "-5.551115123125783e-17 1.1102230246251565e-16\n", 1068 | "1.2101430968414206e-14 -1.8318679906315083e-14\n", 1069 | "-1.3988810110276972e-14 2.098321516541546e-14\n" 1070 | ] 1071 | } 1072 | ], 1073 | "source": [ 1074 | "#############\n", 1075 | "#Verification\n", 1076 | "#############\n", 1077 | "\n", 1078 | "#Verify the correctness of the FK and IK modules by \n", 1079 | "# checking them against each other.\n", 1080 | "\n", 1081 | "\n", 1082 | "import math\n", 1083 | "import numpy\n", 1084 | "\n", 1085 | "# Add know angles to check if the end-effector position is as desired\n", 1086 | "[x, y] = forward_kinematics(math.pi/2, 0, 1, 2)\n", 1087 | "\n", 1088 | "# Add end-effector positions for which the joint angles are known. \n", 1089 | "valid, [theta1, theta2] = inverse_kinematics(0, -3.0, 1, 2)\n", 1090 | "\n", 1091 | "\n", 1092 | "\n", 1093 | "# Verify the FK against IK for random inputs\n", 1094 | "# Random input -> FK -> IK -> Output\n", 1095 | "# Check that the output is the same as the random input\n", 1096 | "l1 = 1\n", 1097 | "l2 = 2\n", 1098 | "for _ in range(1000):\n", 1099 | " theta1 = numpy.random.rand()\n", 1100 | " theta2 = numpy.random.rand()\n", 1101 | "\n", 1102 | " [x, y] = forward_kinematics(theta1, theta2, l1, l2)\n", 1103 | " valid, [t1, t2] = inverse_kinematics(x, y, l1, l2)\n", 1104 | "\n", 1105 | " print(t1 - theta1, t2 - theta2)" 1106 | ] 1107 | } 1108 | ], 1109 | "metadata": { 1110 | "kernelspec": { 1111 | "display_name": "Python 3", 1112 | "language": "python", 1113 | "name": "python3" 1114 | }, 1115 | "language_info": { 1116 | "codemirror_mode": { 1117 | "name": "ipython", 1118 | "version": 3 1119 | }, 1120 | "file_extension": ".py", 1121 | "mimetype": "text/x-python", 1122 | "name": "python", 1123 | "nbconvert_exporter": "python", 1124 | "pygments_lexer": "ipython3", 1125 | "version": "3.8.8" 1126 | } 1127 | }, 1128 | "nbformat": 4, 1129 | "nbformat_minor": 2 1130 | } 1131 | -------------------------------------------------------------------------------- /planar_2R_robot.urdf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /sim_env_setup.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import pybullet as p\n", 10 | "import pybullet_data" 11 | ] 12 | }, 13 | { 14 | "cell_type": "markdown", 15 | "metadata": {}, 16 | "source": [ 17 | "Let us first load the URDF (Universal Robot Description Format) file for the robot we want to simulate" 18 | ] 19 | }, 20 | { 21 | "cell_type": "code", 22 | "execution_count": 2, 23 | "metadata": {}, 24 | "outputs": [], 25 | "source": [ 26 | "physicsClient = p.connect(p.GUI)\n", 27 | "p.setAdditionalSearchPath(pybullet_data.getDataPath()) #Loads the plane urdf file\n", 28 | "planeId = p.loadURDF(\"plane.urdf\")\n", 29 | "scara = p.loadURDF(\"planar_2R_robot.urdf\")" 30 | ] 31 | }, 32 | { 33 | "cell_type": "markdown", 34 | "metadata": {}, 35 | "source": [ 36 | "Now we need to set important parameters for our simulation. These need to be done at the start of every simulation that you may want to perform" 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": 3, 42 | "metadata": {}, 43 | "outputs": [], 44 | "source": [ 45 | "p.setGravity(0,0,-9.81, physicsClientId = physicsClient)\n", 46 | "p.setTimeStep(0.001) #THe lower this is, more accurate the simulation \n", 47 | "p.setRealTimeSimulation(0) # we want to be faster than real time :" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": null, 53 | "metadata": {}, 54 | "outputs": [], 55 | "source": [] 56 | } 57 | ], 58 | "metadata": { 59 | "kernelspec": { 60 | "display_name": "Python 3", 61 | "language": "python", 62 | "name": "python3" 63 | }, 64 | "language_info": { 65 | "codemirror_mode": { 66 | "name": "ipython", 67 | "version": 3 68 | }, 69 | "file_extension": ".py", 70 | "mimetype": "text/x-python", 71 | "name": "python", 72 | "nbconvert_exporter": "python", 73 | "pygments_lexer": "ipython3", 74 | "version": "3.8.8" 75 | } 76 | }, 77 | "nbformat": 4, 78 | "nbformat_minor": 2 79 | } 80 | -------------------------------------------------------------------------------- /spatial_3R_robot.urdf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /torque_control.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "###############################\n", 10 | "# Import the necessary modules\n", 11 | "###############################\n", 12 | "\n", 13 | "# The PyBullet physics simulation library\n", 14 | "import pybullet as p\n", 15 | "import pybullet_data\n", 16 | "\n", 17 | "# Numpy for numerical calculations and manipulations\n", 18 | "import numpy as np\n", 19 | "import math\n", 20 | "\n", 21 | "# Matplotlib to create the necessary plots\n", 22 | "import matplotlib.pyplot as plt" 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "execution_count": 2, 28 | "metadata": {}, 29 | "outputs": [], 30 | "source": [ 31 | "#################################################################\n", 32 | "# Forward and Inverse kinematics modules for the serial-2R robot\n", 33 | "#################################################################\n", 34 | "\n", 35 | "def forward_kinematics(theta1, theta2, l1, l2):\n", 36 | " '''\n", 37 | " Forward kinematics module for a serial-2R chain.\n", 38 | " The base of the manipulator is assumed to be placed at the\n", 39 | " coordinates [0,0].\n", 40 | " All the joints allow rotation about the positive Z-axis.\n", 41 | " Args:\n", 42 | " --- theta1: Angle between the link l1 and the positive x-axis (in radians)\n", 43 | " --- theta2: Relative angle between link l1 and link l2 (in radians)\n", 44 | " --- l1: Length of link l1 (in m)\n", 45 | " --- l2: Length of link l2 (in m)\n", 46 | " Ret:\n", 47 | " --- [x, y]: Position co-ordinates of the end-effector (in m)\n", 48 | " '''\n", 49 | " x = l1*math.cos(theta1) + l2*math.cos(theta1 + theta2)\n", 50 | " y = l1*math.sin(theta1) + l2*math.sin(theta1 + theta2)\n", 51 | " return [x, y]\n", 52 | "\n", 53 | "def inverse_kinematics(x, y, l1, l2, branch=1):\n", 54 | " '''\n", 55 | " Inverse kinematics modules for the serial-2R manipulator.\n", 56 | " The base of the manipulator is placed at [0,0].\n", 57 | " Axis of rotation is the Z+ axis.\n", 58 | " Args:\n", 59 | " --- x : X co-ordinate of the end-effector\n", 60 | " --- y : Y co-ordinate of the end-effector\n", 61 | " --- l1: Length of link l1\n", 62 | " --- l2: Length of link l2\n", 63 | " --- branch: Branch of the inverse kinematics solution.\n", 64 | " Ret:\n", 65 | " --- valid: Binary variable indicating if the solution is valid or not\n", 66 | " --- [theta1, theta2]: Angles made by link l1 w.r.t X+ axis and the relative\n", 67 | " angle between links l1 and l2 respectively.\n", 68 | " '''\n", 69 | " a = 2*x*l2\n", 70 | " b = 2*y*l2\n", 71 | " c = l1*l1 - x*x - y*y - l2*l2 \n", 72 | " psi = math.atan2(b, a)\n", 73 | " d = -c/math.sqrt(a*a + b*b)\n", 74 | " \n", 75 | " if (d < -1) or (d > 1):\n", 76 | " print(\"Position out of workspace.\")\n", 77 | " return False, [0,0]\n", 78 | " if branch == 1:\n", 79 | " theta12 = psi + math.acos(-c/math.sqrt(a*a + b*b))\n", 80 | " else:\n", 81 | " theta12 = psi - math.acos(-c/math.sqrt(a*a + b*b))\n", 82 | " \n", 83 | " theta1 = math.atan2((y - l2*math.sin(theta12))/l1, (x - l2*math.cos(theta12))/l1)\n", 84 | " return True, [theta1, theta12-theta1]" 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": 3, 90 | "metadata": {}, 91 | "outputs": [], 92 | "source": [ 93 | "##############################################################\n", 94 | "# Create an instance of the Physics Server and connect to it\n", 95 | "##############################################################\n", 96 | "\n", 97 | "# Use p.DIRECT to connect to the server without rendering a GUI\n", 98 | "# Use p.GUI to create a GUI to render the simulation\n", 99 | "client = p.connect(p.GUI) # or p.GUI\n", 100 | "\n", 101 | "\n", 102 | "# Load the URDF of the plane that forms the ground\n", 103 | "p.setAdditionalSearchPath(pybullet_data.getDataPath()) # Set the search path to find the plane.urdf file\n", 104 | "plane = p.loadURDF(\"plane.urdf\")\n", 105 | "\n", 106 | "\n", 107 | "# Load the URDF of the robot\n", 108 | "robot = p.loadURDF(\"planar_2R_robot.urdf\")" 109 | ] 110 | }, 111 | { 112 | "cell_type": "code", 113 | "execution_count": 4, 114 | "metadata": {}, 115 | "outputs": [], 116 | "source": [ 117 | "##################################################\n", 118 | "# Set the necessary parameters for the simulation\n", 119 | "##################################################\n", 120 | "\n", 121 | "# Set the Gravity vector\n", 122 | "p.setGravity(0,0,-9.81, physicsClientId = client)\n", 123 | "\n", 124 | "# Set the simulation time-step\n", 125 | "p.setTimeStep(0.001) #The lower this is, more accurate the simulation \n", 126 | "\n", 127 | "# You can be faster than real-time if you choose\n", 128 | "#p.setRealTimeSimulation(0) # we want to be faster than real time." 129 | ] 130 | }, 131 | { 132 | "cell_type": "code", 133 | "execution_count": 5, 134 | "metadata": {}, 135 | "outputs": [], 136 | "source": [ 137 | "#################################\n", 138 | "# Enable the motors on the joints \n", 139 | "#################################\n", 140 | "\n", 141 | "# This step is required to enable torque control. Refer to the documentation for more details.\n", 142 | "p.setJointMotorControl2(robot, 1, p.VELOCITY_CONTROL, force=0)\n", 143 | "p.setJointMotorControl2(robot, 2, p.VELOCITY_CONTROL, force=0)" 144 | ] 145 | }, 146 | { 147 | "cell_type": "code", 148 | "execution_count": 6, 149 | "metadata": {}, 150 | "outputs": [], 151 | "source": [ 152 | "################################################################################\n", 153 | "# Create a Proportional control loop to regulate the position of a single joint\n", 154 | "################################################################################\n", 155 | "\n", 156 | "# Define a sinusoidal trajectory\n", 157 | "dt = 0.001 # Simulation time-step\n", 158 | "f = 1.0 # Frequency of oscillation (1 Hz)\n", 159 | "omega = 2*math.pi*f # Angular frequency\n", 160 | "theta0 = 0 # Start position\n", 161 | "p_des = np.zeros(10000)\n", 162 | "for i in range(10000):\n", 163 | " t = i*dt\n", 164 | " p_des[i] = np.sin(theta0 + omega*t)\n", 165 | "\n", 166 | "\n", 167 | " \n", 168 | "\n", 169 | "p_gain = 1000 # Proportional gain\n", 170 | "d_gain = 500 # Derivative gain\n", 171 | "\n", 172 | "error = 0\n", 173 | "error_old = 0\n", 174 | "\n", 175 | "pos1 = []\n", 176 | "cf = []\n", 177 | "\n", 178 | "# Run the control loop\n", 179 | "for i in range(10000):\n", 180 | " \n", 181 | " # Get the joint state\n", 182 | " p_act, _, _, _ = p.getJointState(robot, 1)\n", 183 | " \n", 184 | " # Calculate the control input\n", 185 | " error_old = error\n", 186 | " error = p_des[i] - p_act\n", 187 | " error_d = (error - error_old)/dt\n", 188 | " control_force = p_gain * error + d_gain * error_d # PD control\n", 189 | " control_force = np.clip(control_force, -50, 50) # Saturation; to model the torque limit of the motors\n", 190 | " \n", 191 | " # Run the simulation for one time-step\n", 192 | " p.setJointMotorControl2(robot, 1, p.TORQUE_CONTROL, force=control_force)\n", 193 | " p.stepSimulation()\n", 194 | " \n", 195 | " # Store the data for plotting\n", 196 | " pos1.append(p_act)\n", 197 | " cf.append(control_force)\n", 198 | " " 199 | ] 200 | }, 201 | { 202 | "cell_type": "code", 203 | "execution_count": 7, 204 | "metadata": {}, 205 | "outputs": [ 206 | { 207 | "data": { 208 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAX0AAAD8CAYAAACb4nSYAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAABotElEQVR4nO39d5hlV3XgDf/2zTnWrdhZarViq9UIIQESSAQhYEgOBL9gHEYjM2D78xgPjMdjPO/r72UAe/wBtrFsbOyxEdhgEYUJBiFEUs7drU7V3VVdVffWzTnu749zTuVwwzkl0bV/z1NPVZ1z7l1n37vP2muvtfbaQkqJQqFQKLYHtuf6BhQKhUKxdSilr1AoFNsIpfQVCoViG6GUvkKhUGwjlNJXKBSKbYRS+gqFQrGNGFjpCyF2CiG+J4Q4IoR4WgjxW2tcI4QQHxdCnBBCPCGEODyoXIVCoVD0jsOE92gB/0VK+YgQIgg8LIT4tpTymSXX3Abs139eBPyl/luhUCgUW8jAlr6UckZK+Yj+dxE4AkysuOyNwD9IjZ8AESHE2KCyFQqFQtEbZlj6Cwgh9gDXAD9dcWoCOLfk/yn92Mwa73E7cDuA3+9/waWXXmrmLSoUCsUFzcMPPzwvpUysd940pS+ECABfBH5bSllYeXqNl6xZ/0FKeSdwJ8C1114rH3roIbNuUaFQKC54hBBnNjpvSvaOEMKJpvD/SUr5r2tcMgXsXPL/DuC8GbIVCoVC0T1mZO8I4NPAESnln65z2VeAd+lZPNcDeSnlKteOQqFQKKzFDPfOS4B3Ak8KIR7Tj/03YBeAlPJTwD3Aa4ETQAX4FRPkKhQKhaJHBlb6Usr7Wdtnv/QaCfznQWUpFIr+aTabTE1NUavVnutbUZiAx+Nhx44dOJ3Onl5navaOQqF4/jI1NUUwGGTPnj1oXlnFzypSStLpNFNTU+zdu7en16oyDArFNqFWqxGPx5XCvwAQQhCPx/uatSmlr1BsI5TCv3Do97tUSl+hUCi2EUrpKxSKLeXuu+9GCMHRo0c3vfbP/uzPqFQqfcv6zGc+w3vf+96+X78Zr33ta8nlcuRyOf7iL/5i4fj58+f5+Z//ecvkDoJS+gqFYku56667eOlLX8rnPve5Ta8dVOlbzT333EMkElml9MfHx/nCF77wHN7Z+iilr1AotoxSqcQPf/hDPv3pTy9T+u12m9/93d/lqquu4uDBg3ziE5/g4x//OOfPn+fmm2/m5ptvBiAQCCy85gtf+ALvfve7AfjqV7/Ki170Iq655hpe+cpXMjc3t+F9fOhDH+Kd73wnt9xyC/v37+ev//qvAS0r5v3vfz9XXnklV111FZ///OcBmJmZ4aabbuLQoUNceeWV/OAHPwBgz549zM/P84EPfICTJ09y6NAh3v/+9zM5OcmVV14JaAH0X/mVX+Gqq67immuu4Xvf+x6gzULe8pa38JrXvIb9+/fze7/3eyZ8wpujUjYVim3IH331aZ45v7JE1mBcPh7iD//DFRte86UvfYnXvOY1XHLJJcRiMR555BEOHz7MnXfeyenTp3n00UdxOBxkMhlisRh/+qd/yve+9z2GhoY2fN+XvvSl/OQnP0EIwd/8zd/wkY98hD/5kz/Z8DVPPPEEP/nJTyiXy1xzzTW87nWv48c//jGPPfYYjz/+OPPz87zwhS/kpptu4rOf/Sy33norv//7v0+73V41+/jwhz/MU089xWOPPQbA5OTkwrk///M/B+DJJ5/k6NGjvPrVr+bZZ58F4LHHHuPRRx/F7XZz4MAB3ve+97Fz506sRCl9hUKxZdx111389m//NgBve9vbuOuuuzh8+DDf+c53uOOOO3A4NJUUi8V6et+pqSne+ta3MjMzQ6PR6Cp3/Y1vfCNerxev18vNN9/MAw88wP3338/b3/527HY7IyMjvOxlL+PBBx/khS98Ib/6q79Ks9nkTW96E4cOHer63u6//37e9773AXDppZeye/fuBaX/ile8gnA4DMDll1/OmTNnlNJXKBTms5lFbgXpdJrvfve7PPXUUwghaLfbCCH4yEc+gpSyqxTEpdcszVF/3/vex+/8zu/whje8gXvvvZcPfehDPb2X8b9WPGA1N910E/fddx9f//rXeec738n73/9+3vWud20qA1j3PQHcbvfC33a7nVar1dV7DoLy6SsUii3hC1/4Au9617s4c+YMk5OTnDt3jr1793L//ffz6le/mk996lMLSi+TyQAQDAYpFosL7zEyMsKRI0fodDrcfffdC8fz+TwTE9reTX//93/f1f18+ctfplarkU6nuffeexdcOZ///Odpt9ukUinuu+8+rrvuOs6cOcPw8DD/8T/+R37t136NRx55ZNl7rbzPpdx000380z/9EwDP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\n", 209 | "text/plain": [ 210 | "
" 211 | ] 212 | }, 213 | "metadata": { 214 | "needs_background": "light" 215 | }, 216 | "output_type": "display_data" 217 | } 218 | ], 219 | "source": [ 220 | "################\n", 221 | "# Plot the data\n", 222 | "################\n", 223 | "plt.figure(2)\n", 224 | "plt.plot(pos1, label=\"Actual position\")\n", 225 | "plt.plot(p_des, label=\"Desired position\")\n", 226 | "plt.ylim([-2,2])\n", 227 | "#plt.plot(cf, label=\"Control Input\")\n", 228 | "plt.legend()\n", 229 | "plt.show()" 230 | ] 231 | }, 232 | { 233 | "cell_type": "code", 234 | "execution_count": 8, 235 | "metadata": {}, 236 | "outputs": [ 237 | { 238 | "name": "stdout", 239 | "output_type": "stream", 240 | "text": [ 241 | "[1. 0.5]\n", 242 | "[1.0460882504484459, 0.4700223903469647]\n" 243 | ] 244 | } 245 | ], 246 | "source": [ 247 | "##########################################################\n", 248 | "# Reach a specified point in the task-space of the robot\n", 249 | "##########################################################\n", 250 | "\n", 251 | "\n", 252 | "# Kinematics for serial-2R\n", 253 | "p1 = np.array([1.0, 0.5])\n", 254 | "p2 = np.array([0.5, 1.0])\n", 255 | "pt_des = p1 # or p2\n", 256 | "\n", 257 | "valid, [theta1, theta2] = inverse_kinematics(pt_des[0], pt_des[1], 1, 1)\n", 258 | "\n", 259 | "\n", 260 | "dt = 0.001 # simulation time-step\n", 261 | "p_gain = 200 # Proportional gain\n", 262 | "d_gain = 50 # Derivative gain\n", 263 | "error = 0\n", 264 | "error_old = 0\n", 265 | "desired_pos = np.array([theta1, theta2])\n", 266 | "for _ in range(1000):\n", 267 | " pos1, _, _, _ = p.getJointState(robot,1)\n", 268 | " pos2, _, _, _ = p.getJointState(robot,2)\n", 269 | " pos = np.array([pos1, pos2])\n", 270 | " error_old = error\n", 271 | " error = desired_pos - pos\n", 272 | " error_d = (error - error_old)/dt\n", 273 | " control_force = p_gain * error + d_gain * error_d\n", 274 | " p.setJointMotorControlArray(robot, [1,2], p.TORQUE_CONTROL, forces=control_force)\n", 275 | " p.stepSimulation()\n", 276 | "\n", 277 | " \n", 278 | "# Check if the robot has reached the desired position\n", 279 | "pos1, _, _, _ = p.getJointState(robot, 1)\n", 280 | "pos2, _, _, _ = p.getJointState(robot, 2)\n", 281 | "pt_act = forward_kinematics(pos1, pos2, 1, 1)\n", 282 | "\n", 283 | "print(pt_des)\n", 284 | "print(pt_act)" 285 | ] 286 | }, 287 | { 288 | "cell_type": "code", 289 | "execution_count": null, 290 | "metadata": {}, 291 | "outputs": [], 292 | "source": [] 293 | } 294 | ], 295 | "metadata": { 296 | "kernelspec": { 297 | "display_name": "Python 3", 298 | "language": "python", 299 | "name": "python3" 300 | }, 301 | "language_info": { 302 | "codemirror_mode": { 303 | "name": "ipython", 304 | "version": 3 305 | }, 306 | "file_extension": ".py", 307 | "mimetype": "text/x-python", 308 | "name": "python", 309 | "nbconvert_exporter": "python", 310 | "pygments_lexer": "ipython3", 311 | "version": "3.8.8" 312 | } 313 | }, 314 | "nbformat": 4, 315 | "nbformat_minor": 2 316 | } 317 | --------------------------------------------------------------------------------