|
46 | 46 | { |
47 | 47 | "metadata": { |
48 | 48 | "ExecuteTime": { |
49 | | - "end_time": "2026-02-20T14:06:45.056822Z", |
50 | | - "start_time": "2026-02-20T14:06:45.042313Z" |
| 49 | + "end_time": "2026-02-20T15:10:25.892287Z", |
| 50 | + "start_time": "2026-02-20T15:10:25.874186Z" |
51 | 51 | } |
52 | 52 | }, |
53 | 53 | "cell_type": "code", |
|
56 | 56 | "import numpy as np" |
57 | 57 | ], |
58 | 58 | "outputs": [], |
59 | | - "execution_count": 13 |
| 59 | + "execution_count": 63 |
60 | 60 | }, |
61 | 61 | { |
62 | 62 | "metadata": {}, |
|
94 | 94 | { |
95 | 95 | "metadata": { |
96 | 96 | "ExecuteTime": { |
97 | | - "end_time": "2026-02-20T14:06:45.072929Z", |
98 | | - "start_time": "2026-02-20T14:06:45.058627Z" |
| 97 | + "end_time": "2026-02-20T15:10:25.906372Z", |
| 98 | + "start_time": "2026-02-20T15:10:25.892785Z" |
99 | 99 | } |
100 | 100 | }, |
101 | 101 | "cell_type": "code", |
|
154 | 154 | ] |
155 | 155 | } |
156 | 156 | ], |
157 | | - "execution_count": 14 |
| 157 | + "execution_count": 64 |
| 158 | + }, |
| 159 | + { |
| 160 | + "metadata": {}, |
| 161 | + "cell_type": "markdown", |
| 162 | + "source": [ |
| 163 | + "# Challenge 1\n", |
| 164 | + "\n", |
| 165 | + "To solve this challenge, we notice the patterns in the computation. You can change to the same link values of exercise a to test that this is correct." |
| 166 | + ] |
| 167 | + }, |
| 168 | + { |
| 169 | + "metadata": { |
| 170 | + "ExecuteTime": { |
| 171 | + "end_time": "2026-02-20T15:10:25.918860Z", |
| 172 | + "start_time": "2026-02-20T15:10:25.907159Z" |
| 173 | + } |
| 174 | + }, |
| 175 | + "cell_type": "code", |
| 176 | + "source": [ |
| 177 | + "# Consider manipulator DoFs as the length of the following lists.\n", |
| 178 | + "# Consider it as the configuration space of the RRR...RRR robot\n", |
| 179 | + "q = [pi/4.0, -pi/8.0, pi/12.0, -pi/3.0] # Increase length of q if you'd like to check\n", |
| 180 | + "l = [1, 1, 1, 1] # l must be same size of q\n", |
| 181 | + "\n", |
| 182 | + "if len(q) != len(l):\n", |
| 183 | + " raise Exception(\"q and l are not the same length\")\n", |
| 184 | + "\n", |
| 185 | + "def c_n(q, n_frame):\n", |
| 186 | + " \"\"\"\n", |
| 187 | + " Get cos(q_0 + q_1 + ... + q_n).\n", |
| 188 | + " \"\"\"\n", |
| 189 | + " q_sum = 0\n", |
| 190 | + " c_result = 0\n", |
| 191 | + " for i in range(n_frame+1):\n", |
| 192 | + " qi = q[i]\n", |
| 193 | + " q_sum += qi # First will be q_0, then q_0 + q_1, then...\n", |
| 194 | + " c_result = cos(q_sum) # First will be cos(q_0), then cos(q_0 + q_1), then...\n", |
| 195 | + " return c_result\n", |
| 196 | + "\n", |
| 197 | + "def s_n(q, n_frame):\n", |
| 198 | + " \"\"\"\n", |
| 199 | + " Get sin(q_0 + q_1 + ... + q_n).\n", |
| 200 | + " \"\"\"\n", |
| 201 | + " q_sum = 0\n", |
| 202 | + " s_result = 0\n", |
| 203 | + " for i in range(n_frame+1):\n", |
| 204 | + " qi = q[i]\n", |
| 205 | + " q_sum += qi # First will be q_0, then q_0 + q_1, then...\n", |
| 206 | + " s_result = sin(q_sum) # First will be sin(q_0), then sin(q_0 + q_1), then...\n", |
| 207 | + " return s_result\n", |
| 208 | + "\n", |
| 209 | + "def px_n(q, l, n_frame):\n", |
| 210 | + " \"\"\"\n", |
| 211 | + " Get l_0*cos(q_0) + l_1*cos(q_0 + q_1) + ... + l_n*cos(q_0 + q_1 + ... + q_n).\n", |
| 212 | + " \"\"\"\n", |
| 213 | + " px = 0\n", |
| 214 | + " for i in range(n_frame + 1):\n", |
| 215 | + " li = l[i]\n", |
| 216 | + " px += li * c_n(q, i)\n", |
| 217 | + " return px\n", |
| 218 | + "\n", |
| 219 | + "def py_n(q, l, n_frame):\n", |
| 220 | + " \"\"\"\n", |
| 221 | + " Get l_0*sin(q_0) + l_1*sin(q_0 + q_1) + ... + l_n*sin(q_0 + q_1 + ... + q_n).\n", |
| 222 | + " \"\"\"\n", |
| 223 | + " py = 0\n", |
| 224 | + " for i in range(n_frame + 1):\n", |
| 225 | + " li = l[i]\n", |
| 226 | + " py += li * s_n(q, i)\n", |
| 227 | + " return py\n", |
| 228 | + "\n", |
| 229 | + "\n", |
| 230 | + "def j_n(q, l, n_frame):\n", |
| 231 | + " \"\"\"\n", |
| 232 | + " Construct the n-th column of the Jacobian matrix.\n", |
| 233 | + " \"\"\"\n", |
| 234 | + " N = len(q)\n", |
| 235 | + "\n", |
| 236 | + " pnx = px_n(q, l, n_frame-1) # starts at 0\n", |
| 237 | + " pny = py_n(q, l, n_frame-1) # starts at 0\n", |
| 238 | + " pNx = px_n(q, l, N-1)\n", |
| 239 | + " pNy = py_n(q, l, N-1)\n", |
| 240 | + "\n", |
| 241 | + " px = pNx - pnx\n", |
| 242 | + " py = pNy - pny\n", |
| 243 | + "\n", |
| 244 | + " jn = np.array(\n", |
| 245 | + " [[-py],\n", |
| 246 | + " [px],\n", |
| 247 | + " [1]]\n", |
| 248 | + " )\n", |
| 249 | + " return jn\n", |
| 250 | + "\n", |
| 251 | + "# Jacobian\n", |
| 252 | + "J = j_n(q, l, 0)\n", |
| 253 | + "for i in range(1,len(q)):\n", |
| 254 | + " J = np.hstack((J, j_n(q, l, i))) # We stack the columns horizontally\n", |
| 255 | + "print(J)\n" |
| 256 | + ], |
| 257 | + "outputs": [ |
| 258 | + { |
| 259 | + "name": "stdout", |
| 260 | + "output_type": "stream", |
| 261 | + "text": [ |
| 262 | + "[[-1.31586821 -0.60876143 -0.226078 0.38268343]\n", |
| 263 | + " [ 3.34821919 2.64111241 1.71723287 0.92387953]\n", |
| 264 | + " [ 1. 1. 1. 1. ]]\n" |
| 265 | + ] |
| 266 | + } |
| 267 | + ], |
| 268 | + "execution_count": 65 |
158 | 269 | } |
159 | 270 | ], |
160 | 271 | "metadata": { |
|
0 commit comments