{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Elementary Examples in Inverse Dynamics\n",
"\n",
"Falk Mielke, FunMorph, Universiteit Antwerpen\n",
"\n",
"You can download this notebook [here](user://notebooks/ID_LMX2_Vinyl.ipynb?download&target=_blank)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This is one part of a series of blog posts on Inverse Dynamics.\n",
"- [Prologue A: Wrench Town Rock](../id_lmx0a_wrenches)\n",
"- [Prologue B: The Fictitious Force Awakens](../id_lmx0b_fforces)\n",
"- [Elementary Example 1: Stuttering Motor (Euler Force)](../id_lmx1_stutter)\n",
"- [Elementary Example 2: Needle On A Vinyl (Centrifugal Force)](../id_lmx2_vinyl)\n",
"- [Elementary Example 3: Radial Slider (Coriolis Force)](../id_lmx3_slider)\n",
"- [Application: N-Link Inverse Dynamics](../id_lmx4_nlink)"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import numpy as NP # numerics\n",
"import sympy as SYM # symbolic operations\n",
"import sympy.physics.mechanics as MECH # some physics/mechanics tools\n",
"import matplotlib.pyplot as MPP # plotting\n",
"\n",
"import WrenchToolbox as WT # contains an improved \"Wrench\" object\n",
"\n",
"# printing of formulas\n",
"SYM.init_printing(use_latex='mathjax', pretty_print = False)\n",
"MECH.init_vprinting(use_latex='mathjax', pretty_print = False)\n",
"\n",
"\n",
"# shorthand to get the basis of a reference frame\n",
"GetCoordinates = lambda rf: [rf[idx] for idx in rf.indices]\n",
"\n",
"# transforming a sympy vector to a matrix\n",
"MatrixToVector = lambda mat, rf: sum([elm * base for elm, base in zip(mat, GetCoordinates(rf)) ])\n",
"\n",
"\n",
"# Steiner's Theorem, generalized form \n",
"# [modern robotics, page 245]\n",
"GeneralizedSteiner = lambda mass, columnvector: \\\n",
" SYM.simplify( \\\n",
" mass * ( (columnvector.T*columnvector)[0] * SYM.eye(3) \\\n",
" - columnvector*columnvector.T \\\n",
" ) \\\n",
" )"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The custom Wrench Toolbox [can be downloaded here.](http://mielke-bio.info/share/WrenchToolbox.py?download&target=_blank)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Elementary Example 1: A Needle On A Vinyl\n",
"\n",
"This is one of my favorite examples.\n",
"\n",
"In my basic physics courses, we covered an exercise involving a massless person on a centrifuge, who would stretch their arms in and out. \n",
"There also was an assessment with James Bond, traversing [Dr Evil's evil centrifuge](https://xkcd.com/123?target=_blank). \n",
"I never remembered the solutions, but these kind of settings were entertaining. \n",
"\n",
"In memory of these fun undergrad exercises, I'll dedicate this post to all the physics tutors and supervisors who have to come up with simple (thereby solvable) problems just entertaining enough to keep students motivated."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Consider the following situation:"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"As before, there is a central rotation in the problem. \n",
"Think of it as a (massless) vinyl peacefully rotating on a record player. \n",
"After some strenuous argument, my supervisors and I have concluded that the record should best be one of \"The Rolling Stones\". \n",
"\n",
"(Feel free to go now and play a record while reading on.)\n",
"\n",
"The argument was strenuous because I suggested to attach a (massless) needle to the record, which you certainly should not do with real records, and most certainly not with those of your supervisor. \n",
"That needle would be positioned at radius $l$ (as in \"length\") from the center, pointing upwards. \n",
"At the tip, at height $h$, there would be a point mass of mass $m$. \n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Too abstract? Here is a biologically motivated, analogous situation.\n",
"\n",
"Chances are that you are sitting on an office chair right now. \n",
"Please follow me on this exercise:\n",
"- Roll a bit back from your table, so that you have an arm's length space in all directions (the biological arm's length principle).\n",
"- Now stretch out one arm and hand (palm facing upwards).\n",
"- Next, flex your elbow, so that the hand is above your elbow.\n",
"- Self-administer some rotational acceleration to your chair, e.g. by the feet or by a fancy remote control and motor. You should now rotate about a vertical axis, close to your spine.\n",
"\n",
"Fun, right? Do you feel a force pulling out your arm? \n",
"Hint: if not, go faster or ask a colleague to spin you.\n",
"Second hint: if you are concerned about statistics on this exercise, better increase sample size. \n",
"\n",
"If you felt a pulling force, that one is actually a fictitious force. The **Centrifugal force**. \n",
"We will isolate it in the example below.\n",
"\n",
"\n",
"Or, at least, I hope to isolate it. \n",
"The most sensitive ones among my readers might have also felt a **Coriolis force**. \n",
"Or not? \n",
"Theoretically, there shouldn't be one. \n",
"But this notebook below holds a little surprise."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Definitions"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Again, we need a zoo of `sympy` symbols. But the procedure is analogous to the [introductory example](../lmx0_wrenches)."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/latex": [
"$\\displaystyle \\left\\{ \\operatorname{φ}\\left(t\\right) : \\frac{2.0 \\pi t}{T}\\right\\}$"
],
"text/plain": [
"{φ: 2.0*pi*t/T}"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# time, length, mass, gravitational acceleration, height (i.e. second segment length)\n",
"t, l, m, h = SYM.symbols('t, l, m, h', real = True)\n",
"\n",
"# set the period of rotation\n",
"period = SYM.symbols('T', real = True)\n",
"\n",
"# this defines the angular velocity by 2π/T\n",
"φdot = 2.*SYM.pi/period \n",
"\n",
"# the angle φ is a function of time\n",
"φ = SYM.Function('φ')(t)\n",
"\n",
"# the angular velocity is equal to the first derivative of the angle\n",
"φ_function = SYM.integrate(φdot, t)\n",
"\n",
"# we will store this for substitution later, \n",
"# for being able to calculate with angles, and then break it down to time.\n",
"φ_substitutes = {φ: φ_function}\n",
"\n",
"φ_substitutes"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We will also meet that handy `PlugAllIn` function again."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"constants = { l: 1. # m \\\n",
" , h: 0.25 # m \\\n",
" , m: 1. # kg \\\n",
" , period: 2.*SYM.pi # s \\\n",
" , SYM.pi: NP.pi # = 3.0 \\\n",
" }\n",
"\n",
"# this function will substitute and simplify\n",
"PlugAllIn = lambda expression: SYM.simplify(SYM.nsimplify(SYM.simplify( \\\n",
" expression.subs(φ_substitutes).doit().subs(constants).subs(constants) \\\n",
" )))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Reference Frames"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"As before, there is a static `world` $\\{S\\}$ in which our system (`body` $\\{B\\}$) rotates."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/latex": [
"$\\displaystyle \\left[\\begin{matrix}0 & 0 & \\frac{2.0 \\pi}{T}\\end{matrix}\\right]$"
],
"text/plain": [
"Matrix([[0, 0, 2.0*pi/T]])"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"world = MECH.ReferenceFrame('S')\n",
"\n",
"# initialize the {B} frame as rotated relative to the world by φ around the world's z axis.\n",
"body = world.orientnew('B', 'Axis', (φ, world.z))\n",
"\n",
"# we give the body frame angular velocity and acceleration\n",
"body.set_ang_vel(world, φdot*world.z)\n",
"body.set_ang_acc(world, φdot.diff(t)*world.z) # should be zero in our case\n",
"\n",
"body.ang_vel_in(world).to_matrix(world).T"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Here comes the dictionary with the transformation matrices:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/latex": [
"$\\displaystyle \\left[\\begin{matrix}\\operatorname{cos}\\left(t\\right) & - \\operatorname{sin}\\left(t\\right) & 0\\\\\\operatorname{sin}\\left(t\\right) & \\operatorname{cos}\\left(t\\right) & 0\\\\0 & 0 & 1\\end{matrix}\\right]$"
],
"text/plain": [
"Matrix([\n",
"[cos(t), -sin(t), 0],\n",
"[sin(t), cos(t), 0],\n",
"[ 0, 0, 1]])"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# prepare a list of (label/frame) tuples.\n",
"frames = [('S', world), ('B', body)]\n",
"\n",
"# \"trafo\" dict will store transformation matrices \"to\" any frame \"from\" another frame.\n",
"trafo = {label: {} for label, _ in frames}\n",
"for label_from, frame_from in frames:\n",
" for label_to, frame_to in frames:\n",
" trafo[label_to][label_from] = SYM.simplify(frame_to.dcm(frame_from))\n",
"\n",
"# display example\n",
"PlugAllIn(trafo['S']['B'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"All of these transformations will look somehow familiar after a few notebooks. \n",
"But does this rotation matrix make sense?"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Points"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This time, compared to the introduction, there is a kink in the system: the joint (elbow joint in the office chair experiment). And as opposed to the introductory settings, the joint does not coincide with the origin.\n",
"\n",
"We define the chain of segments from proximal (origin) to distal (point mass)."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[-sin(t) cos(t) 1/4]\n",
"[-cos(t) -sin(t) 0]\n",
"[sin(t) -cos(t) 0]\n"
]
}
],
"source": [
"### define the origin\n",
"origin = MECH.Point('O')\n",
"\n",
"# the origin does never move\n",
"origin.set_vel(world, 0)\n",
"origin.set_acc(world, 0)\n",
"\n",
"\n",
"### the joint\n",
"joint = MECH.Point('J')\n",
"joint.set_pos(origin, l * body.y)\n",
"\n",
"## set position vector time derivatives\n",
"# (i) in the body frame\n",
"joint.set_vel(body, 0)\n",
"joint.set_acc(body, 0)\n",
"\n",
"# (ii) in the static frame\n",
"joint.set_vel(world, joint.pos_from(origin).diff(t, world).simplify())\n",
"joint.set_acc(world, joint.vel(world).diff(t, world).simplify())\n",
"\n",
"\n",
"\n",
"### a point mass at a height above the joint\n",
"pointmass = MECH.Point('C')\n",
"\n",
"# iteratively initialize pointmass\n",
"pointmass.set_pos(joint, h * body.z)\n",
" \n",
"# points do not move relative to the body frame\n",
"pointmass.set_vel(body, pointmass.pos_from(joint).diff(t, body).simplify())\n",
"pointmass.set_acc(body, pointmass.vel(body).diff(t, body).simplify())\n",
"\n",
"# set velocity/acceleration of point in static rf\n",
"pointmass.set_vel(world, pointmass.pos_from(origin).diff(t, world).simplify())\n",
"pointmass.set_acc(world, pointmass.vel(world).diff(t, world).simplify())\n",
"\n",
" \n",
"# print the point accelerations\n",
"SYM.pprint(PlugAllIn(pointmass.pos_from(origin).express(world).to_matrix(world)).T)\n",
"SYM.pprint(PlugAllIn(pointmass.vel(world).express(world).to_matrix(world)).T)\n",
"SYM.pprint(PlugAllIn(pointmass.acc(world).express(world).to_matrix(world)).T)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note that the point mass is also the COM."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Inertial Properties"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Again, point mass brings no mass moment of inertia relative to its position - but when taken relative to joint or origin, a Steiner component emerges."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/latex": [
"$\\displaystyle \\left[\\begin{matrix}\\frac{17 \\operatorname{cos}\\left(t\\right)}{16} & - \\frac{\\operatorname{sin}\\left(t\\right)}{16} & \\frac{\\operatorname{sin}\\left(t\\right)}{4}\\\\\\frac{17 \\operatorname{sin}\\left(t\\right)}{16} & \\frac{\\operatorname{cos}\\left(t\\right)}{16} & - \\frac{\\operatorname{cos}\\left(t\\right)}{4}\\\\0 & - \\frac{1}{4} & 1\\end{matrix}\\right]$"
],
"text/plain": [
"Matrix([\n",
"[17*cos(t)/16, -sin(t)/16, sin(t)/4],\n",
"[17*sin(t)/16, cos(t)/16, -cos(t)/4],\n",
"[ 0, -1/4, 1]])"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# zero inertia relative to the com (because we have point masses)\n",
"inertia = MECH.inertia(body, 0, 0, 0)\n",
"\n",
"I_B = {}\n",
"# the system has an inertia relative to the origin, which coincides with the center of mass.\n",
"for pt, refpoint in [('P', pointmass), ('J', joint), ('O', origin)]:\n",
" I_B[pt] = inertia.to_matrix(body)\\\n",
" + GeneralizedSteiner( m, pointmass.pos_from(refpoint).express(body).to_matrix(body) ) \n",
"\n",
"\n",
"# all the I's can be transformed to the inertial reference frame\n",
"I_S = {}\n",
"for refpoint in I_B.keys():\n",
" I_S[refpoint] = SYM.simplify(trafo['S']['B'] * I_B[refpoint] )\n",
"\n",
"# print an example\n",
"PlugAllIn(I_S['O'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Even though it is just a point mass, $I$ can get respectably complex."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Kinematics\n",
"\n",
"\n",
"As usual, we would like to exactly know each object's position and rotation for all times. "
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"# shorthands for the derivative levels\n",
"p = 0 # zero'th derivative: the position vector\n",
"v = 1 # first derivative: the velocity\n",
"a = 2 # second derivative: the acceleration"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"# prepare an empty dictionary\n",
"x = {}\n",
"\n",
"# start with the position vectors\n",
"x['S'] = {pt: [pointmass.pos_from(refpoint).express(world).to_matrix(world)] \\\n",
" for pt, refpoint in [('O', origin), ('J', joint), ('P', pointmass)] \\\n",
" }\n",
"x['B'] = {pt: [pointmass.pos_from(refpoint).express(body).to_matrix(body)] \\\n",
" for pt, refpoint in [('O', origin), ('J', joint), ('P', pointmass)] \\\n",
" }\n",
"\n",
"# automatically get time derivatives, in loops\n",
"# loop reference frames\n",
"for frame in x.keys():\n",
" # loop reference points\n",
" for refpoint in x[frame].keys():\n",
" # loop differentials\n",
" for diff_nr in range(2): \n",
" x[frame][refpoint].append(SYM.simplify(x[frame][refpoint][-1].diff(t)))\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Analogously, store the rotational movement in an $\\omega$ dictionary. Once more, $\\omega$ is identical to $\\varphi$, because the example is simple. However, I prefer the distinct notation of $\\omega$ as the total angle of rotation of the \"free body\" in the world."
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[0 0 0]\n",
"[0 0 0]\n"
]
}
],
"source": [
"# the same dictionary magic as above\n",
"ω = {}\n",
"\n",
"# angular positions\n",
"ω['S'] = [SYM.Matrix([[0],[0],[φ]])]\n",
"ω['B'] = [SYM.Matrix([[0],[0],[0]])]\n",
"\n",
"# time derivatives\n",
"for frame in ω.keys():\n",
" for diff_nr in range(2): \n",
" ω[frame].append(SYM.simplify(ω[frame][-1].diff(t)))\n",
"\n",
"# quick check:\n",
"SYM.pprint(PlugAllIn(ω['S'][v] - body.ang_vel_in(world).to_matrix(world)).T)\n",
"SYM.pprint(PlugAllIn(ω['B'][v] - body.ang_vel_in(body).to_matrix(body)).T)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Visualization"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"... using `lambdify`."
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"time = NP.linspace(0., 2*NP.pi, 60, endpoint = False)\n",
"position = SYM.lambdify(t, PlugAllIn(x['S']['O'][0]), 'numpy')\n",
"lin_velocity = SYM.lambdify(t, PlugAllIn(x['S']['O'][1]), 'numpy')\n",
"lin_acceleration = SYM.lambdify(t, PlugAllIn(x['S']['O'][2]), 'numpy')\n",
"ang_velocity = SYM.lambdify(t, PlugAllIn(ω['S'][1]), 'numpy')\n",
"ang_acceleration = SYM.lambdify(t, PlugAllIn(ω['S'][2]), 'numpy')\n",
"# position(time)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
":2: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray\n",
" return (array([[-sin(t)], [cos(t)], [1/4]]))\n"
]
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"