|
1 | 1 | {
|
2 | 2 | "cells": [
|
3 | 3 | {
|
| 4 | + "attachments": {}, |
4 | 5 | "cell_type": "markdown",
|
5 | 6 | "metadata": {},
|
6 | 7 | "source": [
|
7 | 8 | "# Determine derivative of Jacobian from angular velocity to exponential rates\n",
|
8 | 9 | "\n",
|
9 |
| - "Peter Corke 2021\n", |
| 10 | + "Peter Corke 2021, updated 1/23\n", |
10 | 11 | "\n",
|
11 |
| - "SymPy code to deterine the time derivative of the mapping from angular velocity to exponential coordinate rates." |
| 12 | + "SymPy code to determine the time derivative of the mapping from angular velocity to exponential coordinate rates." |
12 | 13 | ]
|
13 | 14 | },
|
14 | 15 | {
|
15 | 16 | "cell_type": "code",
|
16 |
| - "execution_count": 2, |
| 17 | + "execution_count": null, |
17 | 18 | "metadata": {},
|
18 | 19 | "outputs": [],
|
19 | 20 | "source": [
|
20 | 21 | "from sympy import *"
|
21 | 22 | ]
|
22 | 23 | },
|
23 | 24 | {
|
| 25 | + "attachments": {}, |
24 | 26 | "cell_type": "markdown",
|
25 | 27 | "metadata": {},
|
26 | 28 | "source": [
|
27 |
| - "A rotation matrix can be expressed in terms of exponential coordinates (also called Euler vector)\n", |
| 29 | + "A rotation matrix can be expressed in terms of exponential coordinates (also called the Euler vector)\n", |
28 | 30 | "\n",
|
29 | 31 | "$\n",
|
30 | 32 | "\\mathbf{R} = e^{[\\varphi]_\\times} \n",
|
|
37 | 39 | "\\dot{\\varphi} = \\mathbf{A} \\omega\n",
|
38 | 40 | "$\n",
|
39 | 41 | "\n",
|
40 |
| - "where $\\mathbf{A}$ is given by (2.107) of [Robot Dynamics Lecture Notes, Robotic Systems Lab, ETH Zurich, 2018](https://ethz.ch/content/dam/ethz/special-interest/mavt/robotics-n-intelligent-systems/rsl-dam/documents/RobotDynamics2018/RD_HS2018script.pdf)\n", |
| 42 | + "where $\\mathbf{A}$ is given by (2.107) of [Robot Dynamics Lecture Notes, Robotic Systems Lab, ETH Zurich, 2017](https://ethz.ch/content/dam/ethz/special-interest/mavt/robotics-n-intelligent-systems/rsl-dam/documents/RobotDynamics2017/RD_HS2017script.pdf)\n", |
41 | 43 | "\n",
|
42 | 44 | "\n",
|
43 | 45 | "$\n",
|
44 |
| - "\\mathbf{A} = \\mathbf{1}_{3 \\times 3} - \\frac{1}{2} [v]_\\times + [v]^2_\\times \\frac{1}{\\theta^2} \\left( 1 - \\frac{\\theta}{2} \\frac{\\sin \\theta}{1 - \\cos \\theta} \\right)\n", |
| 46 | + "\\mathbf{A} = \\mathbf{1}_{3 \\times 3} - \\frac{1}{2} [\\varphi]_\\times + [\\varphi]^2_\\times \\frac{1}{\\theta^2} \\left( 1 - \\frac{\\theta}{2} \\frac{\\sin \\theta}{1 - \\cos \\theta} \\right),\n", |
45 | 47 | "$\n",
|
46 |
| - "where $\\theta = \\| \\varphi \\|$ and $v = \\hat{\\varphi}$\n", |
| 48 | + "where $\\theta = \\| \\varphi \\|$\n", |
47 | 49 | "\n",
|
48 | 50 | "We simplify the equation as\n",
|
49 | 51 | "\n",
|
50 | 52 | "$\n",
|
51 |
| - "\\mathbf{A} = \\mathbf{1}_{3 \\times 3} - \\frac{1}{2} [v]_\\times + [v]^2_\\times \\Theta\n", |
| 53 | + "\\mathbf{A} = \\mathbf{1}_{3 \\times 3} - \\frac{1}{2} [\\varphi]_\\times + [\\varphi]^2_\\times \\Theta\n", |
52 | 54 | "$\n",
|
53 | 55 | "\n",
|
54 | 56 | "where\n",
|
|
59 | 61 | "We can find the derivative using the chain rule\n",
|
60 | 62 | "\n",
|
61 | 63 | "$\n",
|
62 |
| - "\\dot{\\mathbf{A}} = - \\frac{1}{2} [\\dot{v}]_\\times + 2 [v]_\\times [\\dot{v}]_\\times \\Theta + [v]^2_\\times \\dot{\\Theta}\n", |
| 64 | + "\\dot{\\mathbf{A}} = - \\frac{1}{2} [\\dot{\\varphi}]_\\times + \\left( [\\varphi]_\\times [\\dot{\\varphi}]_\\times + [\\dot{\\varphi}]_\\times[\\varphi]_\\times \\right) \\Theta + [\\varphi]^2_\\times \\dot{\\Theta}\n", |
| 65 | + "$\n", |
| 66 | + "\n", |
| 67 | + "noting that the derivative of a matrix squared is\n", |
| 68 | + "\n", |
| 69 | + "$\n", |
| 70 | + "\\frac{d}{dt} (\\mathbf{M}^2) = (\\frac{d}{dt} \\mathbf{M}) \\mathbf{M} + \\mathbf{M} (\\frac{d}{dt} \\mathbf{M})\n", |
63 | 71 | "$\n",
|
64 | 72 | "\n",
|
65 | 73 | "We start by defining some symbols"
|
66 | 74 | ]
|
67 | 75 | },
|
68 | 76 | {
|
69 | 77 | "cell_type": "code",
|
70 |
| - "execution_count": 21, |
| 78 | + "execution_count": null, |
71 | 79 | "metadata": {},
|
72 | 80 | "outputs": [],
|
73 | 81 | "source": [
|
74 |
| - "Theta, theta, theta_dot, t = symbols('Theta theta theta_dot t', real=True)" |
| 82 | + "theta, theta_dot, t = symbols('theta theta_dot t', real=True)" |
75 | 83 | ]
|
76 | 84 | },
|
77 | 85 | {
|
|
83 | 91 | },
|
84 | 92 | {
|
85 | 93 | "cell_type": "code",
|
86 |
| - "execution_count": 22, |
| 94 | + "execution_count": null, |
87 | 95 | "metadata": {},
|
88 | 96 | "outputs": [],
|
89 | 97 | "source": [
|
90 |
| - "theta_t = Function(theta)(t)" |
| 98 | + "theta_t = Function(theta)(t)\n", |
| 99 | + "theta_t" |
91 | 100 | ]
|
92 | 101 | },
|
93 | 102 | {
|
94 | 103 | "cell_type": "code",
|
95 |
| - "execution_count": 23, |
| 104 | + "execution_count": null, |
96 | 105 | "metadata": {},
|
97 |
| - "outputs": [ |
98 |
| - { |
99 |
| - "data": { |
100 |
| - "text/latex": [ |
101 |
| - "$\\displaystyle \\frac{1 - \\frac{\\theta{\\left(t \\right)} \\sin{\\left(\\theta{\\left(t \\right)} \\right)}}{2 \\left(1 - \\cos{\\left(\\theta{\\left(t \\right)} \\right)}\\right)}}{\\theta^{2}{\\left(t \\right)}}$" |
102 |
| - ], |
103 |
| - "text/plain": [ |
104 |
| - "(1 - theta(t)*sin(theta(t))/(2*(1 - cos(theta(t)))))/theta(t)**2" |
105 |
| - ] |
106 |
| - }, |
107 |
| - "execution_count": 23, |
108 |
| - "metadata": {}, |
109 |
| - "output_type": "execute_result" |
110 |
| - } |
111 |
| - ], |
| 106 | + "outputs": [], |
112 | 107 | "source": [
|
113 | 108 | "Theta = 1 / theta_t ** 2 * (1 - theta_t / 2 * sin(theta_t) / (1 - cos(theta_t)))\n",
|
114 | 109 | "Theta"
|
|
123 | 118 | },
|
124 | 119 | {
|
125 | 120 | "cell_type": "code",
|
126 |
| - "execution_count": 24, |
| 121 | + "execution_count": null, |
127 | 122 | "metadata": {},
|
128 |
| - "outputs": [ |
129 |
| - { |
130 |
F42D
code> | - "data": { |
131 |
| - "text/latex": [ |
132 |
| - "$\\displaystyle - \\frac{2 \\left(1 - \\frac{\\theta{\\left(t \\right)} \\sin{\\left(\\theta{\\left(t \\right)} \\right)}}{2 \\left(1 - \\cos{\\left(\\theta{\\left(t \\right)} \\right)}\\right)}\\right) \\frac{d}{d t} \\theta{\\left(t \\right)}}{\\theta^{3}{\\left(t \\right)}} + \\frac{- \\frac{\\theta{\\left(t \\right)} \\cos{\\left(\\theta{\\left(t \\right)} \\right)} \\frac{d}{d t} \\theta{\\left(t \\right)}}{2 \\left(1 - \\cos{\\left(\\theta{\\left(t \\right)} \\right)}\\right)} - \\frac{\\sin{\\left(\\theta{\\left(t \\right)} \\right)} \\frac{d}{d t} \\theta{\\left(t \\right)}}{2 \\left(1 - \\cos{\\left(\\theta{\\left(t \\right)} \\right)}\\right)} + \\frac{\\theta{\\left(t \\right)} \\sin^{2}{\\left(\\theta{\\left(t \\right)} \\right)} \\frac{d}{d t} \\theta{\\left(t \\right)}}{2 \\left(1 - \\cos{\\left(\\theta{\\left(t \\right)} \\right)}\\right)^{2}}}{\\theta^{2}{\\left(t \\right)}}$" |
133 |
| - ], |
134 |
| - "text/plain": [ |
135 |
| - "-2*(1 - theta(t)*sin(theta(t))/(2*(1 - cos(theta(t)))))*Derivative(theta(t), t)/theta(t)**3 + (-theta(t)*cos(theta(t))*Derivative(theta(t), t)/(2*(1 - cos(theta(t)))) - sin(theta(t))*Derivative(theta(t), t)/(2*(1 - cos(theta(t)))) + theta(t)*sin(theta(t))**2*Derivative(theta(t), t)/(2*(1 - cos(theta(t)))**2))/theta(t)**2" |
136 |
| - ] |
137 |
| - }, |
138 |
| - "execution_count": 24, |
139 |
| - "metadata": {}, |
140 |
| - "output_type": "execute_result" |
141 |
| - } |
142 |
| - ], |
| 123 | + "outputs": [], |
143 | 124 | "source": [
|
144 | 125 | "T_dot = Theta.diff(t)\n",
|
145 | 126 | "T_dot"
|
|
156 | 137 | },
|
157 | 138 | {
|
158 | 139 | "cell_type": "code",
|
159 |
| - "execution_count": 25, |
| 140 | + "execution_count": null, |
160 | 141 | "metadata": {},
|
161 | 142 | "outputs": [],
|
162 | 143 | "source": [
|
163 |
| - "T_dot = T_dot.subs([(theta_t.diff(t), theta_dot), (theta_t, theta)])" |
| 144 | + "T_dot = T_dot.subs([(theta_t.diff(t), theta_dot), (theta_t, theta)])\n", |
| 145 | + "T_dot" |
164 | 146 | ]
|
165 | 147 | },
|
166 | 148 | {
|
167 | 149 | "cell_type": "code",
|
168 |
| - "execution_count": 26, |
| 150 | + "execution_count": null, |
169 | 151 | "metadata": {},
|
170 |
| - "outputs": [ |
171 |
| - { |
172 |
| - "data": { |
173 |
| - "text/plain": [ |
174 |
| - "'(-1/2*theta*theta_dot*math.cos(theta)/(1 - math.cos(theta)) + (1/2)*theta*theta_dot*math.sin(theta)**2/(1 - math.cos(theta))**2 - 1/2*theta_dot*math.sin(theta)/(1 - math.cos(theta)))/theta**2 - 2*theta_dot*(-1/2*theta*math.sin(theta)/(1 - math.cos(theta)) + 1)/theta**3'" |
175 |
| - ] |
176 |
| - }, |
177 |
| - "execution_count": 26, |
178 |
| - "metadata": {}, |
179 |
| - "output_type": "execute_result" |
180 |
| - } |
181 |
| - ], |
| 152 | + "outputs": [], |
182 | 153 | "source": [
|
183 | 154 | "pycode(T_dot)"
|
184 | 155 | ]
|
|
192 | 163 | },
|
193 | 164 | {
|
194 | 165 | "cell_type": "code",
|
195 |
| - "execution_count": 38, |
| 166 | + "execution_count": null, |
196 | 167 | "metadata": {},
|
197 | 168 | "outputs": [],
|
198 | 169 | "source": [
|
|
217 | 188 | },
|
218 | 189 | {
|
219 | 190 | "cell_type": "code",
|
220 |
| - "execution_count": 40, |
| 191 | + "execution_count": null, |
221 | 192 | "metadata": {},
|
222 |
| - "outputs": [ |
223 |
| - { |
224 |
| - "data": { |
225 |
| - "text/latex": [ |
226 |
| - "$\\displaystyle \\sqrt{\\varphi_{0}^{2}{\\left(t \\right)} + \\varphi_{1}^{2}{\\left(t \\right)} + \\varphi_{2}^{2}{\\left(t \\right)}}$" |
227 |
| - ], |
228 |
| - "text/plain": [ |
229 |
| - "sqrt(varphi_0(t)**2 + varphi_1(t)**2 + varphi_2(t)**2)" |
230 |
| - ] |
231 |
| - }, |
232 |
| - "execution_count": 40, |
233 |
| - "metadata": {}, |
234 |
| - "output_type": "execute_result" |
235 |
| - } |
236 |
| - ], |
| 193 | + "outputs": [], |
237 | 194 | "source": [
|
238 | 195 | "theta = Matrix(phi_t).norm()\n",
|
239 | 196 | "theta"
|
|
248 | 205 | },
|
249 | 206 | {
|
250 | 207 | "cell_type": "code",
|
251 |
| - "execution_count": 41, |
| 208 | + "execution_count": null, |
252 | 209 | "metadata": {},
|
253 |
| - "outputs": [ |
254 |
| - { |
255 |
| - "data": { |
256 |
| - "text/latex": [ |
257 |
| - "$\\displaystyle \\frac{\\varphi_{0}{\\left(t \\right)} \\frac{d}{d t} \\varphi_{0}{\\left(t \\right)} + \\varphi_{1}{\\left(t \\right)} \\frac{d}{d t} \\varphi_{1}{\\left(t \\right)} + \\varphi_{2}{\\left(t \\right)} \\frac{d}{d t} \\varphi_{2}{\\left(t \\right)}}{\\sqrt{\\varphi_{0}^{2}{\\left(t \\right)} + \\varphi_{1}^{2}{\\left(t \\right)} + \\varphi_{2}^{2}{\\left(t \\right)}}}$" |
258 |
| - ], |
259 |
| - "text/plain": [ |
260 |
| - "(varphi_0(t)*Derivative(varphi_0(t), t) + varphi_1(t)*Derivative(varphi_1(t), t) + varphi_2(t)*Derivative(varphi_2(t), t))/sqrt(varphi_0(t)**2 + varphi_1(t)**2 + varphi_2(t)**2)" |
261 |
| - ] |
262 |
| - }, |
263 |
| - "execution_count": 41, |
264 |
| - "metadata": {}, |
265 |
| - "output_type": "execute_result" |
266 |
| - } |
267 |
| - ], |
| 210 | + "outputs": [], |
268 | 211 | "source": [
|
269 | 212 | "theta_dot = theta.diff(t)\n",
|
270 | 213 | "theta_dot"
|
|
279 | 222 | },
|
280 | 223 | {
|
281 | 224 | "cell_type": "code",
|
282 |
| - "execution_count": 42, |
| 225 | + "execution_count": null, |
283 | 226 | "metadata": {},
|
284 |
| - "outputs": [ |
285 |
| - { |
286 |
| - "data": { |
287 |
| - "text/latex": [ |
288 |
| - "$\\displaystyle \\frac{\\varphi_{0} \\varphi_{0 dot} + \\varphi_{1} \\varphi_{1 dot} + \\varphi_{2} \\varphi_{2 dot}}{\\sqrt{\\varphi_{0}^{2} + \\varphi_{1}^{2} + \\varphi_{2}^{2}}}$" |
289 |
| - ], |
290 |
| - "text/plain": [ |
291 |
| - "(varphi_0*varphi_0_dot + varphi_1*varphi_1_dot + varphi_2*varphi_2_dot)/sqrt(varphi_0**2 + varphi_1**2 + varphi_2**2)" |
292 |
| - ] |
293 |
| - }, |
294 |
| - "execution_count": 42, |
295 |
| - "metadata": {}, |
296 |
| - "output_type": "execute_result" |
297 |
| - } |
298 |
| - ], |
| 227 | + "outputs": [], |
299 | 228 | "source": [
|
300 | 229 | "theta_dot = theta_dot.subs(a for a in zip(phi_d, phi_n))\n",
|
301 | 230 | "theta_dot = theta_dot.subs(a for a in zip(phi_t, phi))\n",
|
|
311 | 240 | },
|
312 | 241 | {
|
313 | 242 | "cell_type": "code",
|
314 |
| - "execution_count": 7, |
| 243 | + "execution_count": null, |
315 | 244 | "metadata": {},
|
316 |
| - "outputs": [ |
317 |
| - { |
318 |
| - "name": "stdout", |
319 |
| - "output_type": "stream", |
320 |
| - "text": [ |
321 |
| - "exp(A(t))*Derivative(A(t), t)\n" |
322 |
| - ] |
323 |
| - } |
324 |
| - ], |
| 245 | + "outputs": [], |
325 | 246 | "source": [
|
326 | 247 | "A, t = symbols('A t', real=True)\n",
|
327 | 248 | "A_t = Function(A)(t)\n",
|
|
332 | 253 | ],
|
333 | 254 | "metadata": {
|
334 | 255 | "kernelspec": {
|
335 |
| - "display_name": "Python 3", |
| 256 | + "display_name": "Python 3.8.5 ('dev')", |
336 | 257 | "language": "python",
|
337 | 258 | "name": "python3"
|
338 | 259 | },
|
|
376 | 297 | "_Feature"
|
377 | 298 | ],
|
378 | 299 | "window_display": false
|
| 300 | + }, |
| 301 | + "vscode": { |
| 302 | + "interpreter": { |
| 303 | + "hash": "b7d6b0d76025b9176285a6442c3dd6dd39bcfe7241029b7898b7106bd5e9b472" |
| 304 | + } |
379 | 305 | }
|
380 | 306 | },
|
381 | 307 | "nbformat": 4,
|
|
0 commit comments