{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import sympy as smp\n", "from scipy.integrate import odeint\n", "import matplotlib.pyplot as plt\n", "from matplotlib import animation\n", "from mpl_toolkits.mplot3d import Axes3D\n", "from matplotlib.animation import PillowWriter" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Preliminary\n", "\n", "Suppose we have the Lagrangian\n", "\n", "$$L = \\frac{1}{2} m_1 (\\dot{x}_1^2+\\dot{y}_1^2) + \\frac{1}{2} m_2 (\\dot{x}_2^2+\\dot{y}_2^2) -m_1gy_1 - m_2gy_2 $$\n", "\n", "We can remove some degrees of freedom by dividing by $m_1$ and some characteristic length $A$ of the problem\n", "\n", "$$\\frac{L}{A^2 m_1} = \\frac{1}{2} \\left(\\left(\\dot{\\frac{x_1}{A}}\\right)^2+\\left(\\dot{\\frac{y_1}{A}}\\right)^2 \\right) + \\frac{1}{2} \\frac{m_2}{m_1}\\left(\\left(\\dot{\\frac{x_2}{A}}\\right)^2+\\left(\\dot{\\frac{y_2}{A}}\\right)^2 \\right) -\\frac{g}{A}\\frac{y_1}{A} - \\frac{m_2}{m_1}\\frac{g}{A}\\frac{y_2}{A} $$\n", "\n", "This might look more complicated, by defining $m = m_2/m_1$ and putting primes such that $x' = x/A$ we get\n", "\n", "$$\\frac{L}{A^2 m_1} = \\frac{1}{2} (\\dot{x'}_1^2+\\dot{y'}_1^2) + \\frac{1}{2} m (\\dot{x'}_2^2+\\dot{y'}_2^2) -g'y_1' - mg'y_2' $$\n", "\n", "Note that $\\frac{L}{A^2 m_1}$ produces the same equations of motion as $L$ (for any $C$, $CL$ produces the same equations of motion as $L$). Thus we can solve the Lagrangian problem above, and then put in any values of $A$ and $m_1$ we want afterwards, and scale appropriately." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## The Problem\n", "\n", "The driven double pendulum with masses $m_1=1$ and $m_2=m$ and arm-lengths $L_1$ and $L_2$ has it upper arm connector to a motor that displaces the base with at $\\cos(\\omega t)$ where $\\omega$ is the driving frequency.\n", "\n", "
\n", " \n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "and thus\n", "\n", "* $x_1 = \\cos(\\omega t) + L_1 \\sin(\\theta_1)$\n", "* $x_2 = \\cos(\\omega t) + L_1 \\sin(\\theta_1) + L_2 \\sin(\\theta_2)$\n", "* $y_1 = -L_1 \\cos(\\theta_1)$\n", "* $y_2 = -L_1 \\cos(\\theta_1)-L_2 \\cos(\\theta_2)$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Define required variables for sympy" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "t, m, g, L1, L2, w, C, alph, beta = smp.symbols(r't m g L_1, L_2 \\omega C \\alpha \\beta')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Define $\\theta_1(t)$ and $\\theta_2(t)$ and declare them functions of time. Also get their first and second derivatives." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "the1, the2, = smp.symbols(r'\\theta_1, \\theta_2 ', cls=smp.Function)\n", "\n", "the1 = the1(t)\n", "the1_d = smp.diff(the1, t)\n", "the1_dd = smp.diff(the1_d, t)\n", "\n", "the2 = the2(t)\n", "the2_d = smp.diff(the2, t)\n", "the2_dd = smp.diff(smp.diff(the2, t), t)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Declare $x_1(\\theta_1)$, $y_1(\\theta_1)$ and $x_2(\\theta_1, \\theta_2)$, $y_2(\\theta_1, \\theta_2)$" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "x1, y1, x2, y2 = smp.symbols('x_1, y_1, x_2, y_2', cls=smp.Function)\n", "x1= x1(t, the1)\n", "y1= y1(t, the1)\n", "x2= x2(t, the1, the2)\n", "y2= y2(t, the1, the2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Put in the specific functional form of $x_1$, $y_1$, $x_2$, $y_2$" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "x1 = smp.cos(w*t)+L1*smp.sin(the1)\n", "y1 = -L1*smp.cos(the1)\n", "x2 = smp.cos(w*t)+L1*smp.sin(the1) + L2*smp.sin(the2)\n", "y2 = -L1*smp.cos(the1) -L2*smp.cos(the2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Define numerical functions for $v_{x1}$, $v_{y1}$, $v_{x2}$, $v_{y1}$" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle L_{1} \\cos{\\left(\\theta_{1}{\\left(t \\right)} \\right)} \\frac{d}{d t} \\theta_{1}{\\left(t \\right)} - \\omega \\sin{\\left(\\omega t \\right)}$" ], "text/plain": [ "L_1*cos(\\theta_1(t))*Derivative(\\theta_1(t), t) - \\omega*sin(\\omega*t)" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "smp.diff(x1, t)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [], "source": [ "vx1_f = smp.lambdify((t,w,L1,L2,the1,the2,the1_d,the2_d), smp.diff(x1, t))\n", "vx2_f = smp.lambdify((t,w,L1,L2,the1,the2,the1_d,the2_d), smp.diff(x2, t))\n", "vy1_f = smp.lambdify((t,w,L1,L2,the1,the2,the1_d,the2_d), smp.diff(y1, t))\n", "vy2_f = smp.lambdify((t,w,L1,L2,the1,the2,the1_d,the2_d), smp.diff(y2, t))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Define kinetic energy $T$, potential energy $V$, and Lagrangian $L=T-V$" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [], "source": [ "T = 1/2 * (smp.diff(x1, t)**2 + smp.diff(y1, t)**2) + \\\n", " 1/2 * m *(smp.diff(x2, t)**2 + + smp.diff(y2, t)**2)\n", "V = g*y1 + m*g*y2\n", "L = T-V" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Solve Lagranges Equations\n", "\n", "$$\\frac{\\partial L}{ \\partial \\theta} - \\frac{d}{dt}\\frac{\\partial L}{ \\partial \\dot{\\theta}} = 0$$" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [], "source": [ "LE1 = smp.diff(L, the1) - smp.diff(smp.diff(L, the1_d), t)\n", "LE1 = LE1.simplify()\n", "\n", "LE2 = smp.diff(L, the2) - smp.diff(smp.diff(L, the2_d), t)\n", "LE2 = LE2.simplify()" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle 1.0 L_{1} \\left(- L_{1} m \\frac{d^{2}}{d t^{2}} \\theta_{1}{\\left(t \\right)} - L_{1} \\frac{d^{2}}{d t^{2}} \\theta_{1}{\\left(t \\right)} - L_{2} m \\sin{\\left(\\theta_{1}{\\left(t \\right)} - \\theta_{2}{\\left(t \\right)} \\right)} \\left(\\frac{d}{d t} \\theta_{2}{\\left(t \\right)}\\right)^{2} - L_{2} m \\cos{\\left(\\theta_{1}{\\left(t \\right)} - \\theta_{2}{\\left(t \\right)} \\right)} \\frac{d^{2}}{d t^{2}} \\theta_{2}{\\left(t \\right)} + \\omega^{2} m \\cos{\\left(\\omega t \\right)} \\cos{\\left(\\theta_{1}{\\left(t \\right)} \\right)} + \\omega^{2} \\cos{\\left(\\omega t \\right)} \\cos{\\left(\\theta_{1}{\\left(t \\right)} \\right)} - g m \\sin{\\left(\\theta_{1}{\\left(t \\right)} \\right)} - g \\sin{\\left(\\theta_{1}{\\left(t \\right)} \\right)}\\right)$" ], "text/plain": [ "1.0*L_1*(-L_1*m*Derivative(\\theta_1(t), (t, 2)) - L_1*Derivative(\\theta_1(t), (t, 2)) - L_2*m*sin(\\theta_1(t) - \\theta_2(t))*Derivative(\\theta_2(t), t)**2 - L_2*m*cos(\\theta_1(t) - \\theta_2(t))*Derivative(\\theta_2(t), (t, 2)) + \\omega**2*m*cos(\\omega*t)*cos(\\theta_1(t)) + \\omega**2*cos(\\omega*t)*cos(\\theta_1(t)) - g*m*sin(\\theta_1(t)) - g*sin(\\theta_1(t)))" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "LE1" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle 1.0 L_{2} m \\left(L_{1} \\sin{\\left(\\theta_{1}{\\left(t \\right)} - \\theta_{2}{\\left(t \\right)} \\right)} \\left(\\frac{d}{d t} \\theta_{1}{\\left(t \\right)}\\right)^{2} - L_{1} \\cos{\\left(\\theta_{1}{\\left(t \\right)} - \\theta_{2}{\\left(t \\right)} \\right)} \\frac{d^{2}}{d t^{2}} \\theta_{1}{\\left(t \\right)} - L_{2} \\frac{d^{2}}{d t^{2}} \\theta_{2}{\\left(t \\right)} + \\omega^{2} \\cos{\\left(\\omega t \\right)} \\cos{\\left(\\theta_{2}{\\left(t \\right)} \\right)} - g \\sin{\\left(\\theta_{2}{\\left(t \\right)} \\right)}\\right)$" ], "text/plain": [ "1.0*L_2*m*(L_1*sin(\\theta_1(t) - \\theta_2(t))*Derivative(\\theta_1(t), t)**2 - L_1*cos(\\theta_1(t) - \\theta_2(t))*Derivative(\\theta_1(t), (t, 2)) - L_2*Derivative(\\theta_2(t), (t, 2)) + \\omega**2*cos(\\omega*t)*cos(\\theta_2(t)) - g*sin(\\theta_2(t)))" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "LE2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Since these are both equal to zero and linear in terms of $\\partial_t^2 \\theta_1$ and $\\partial_t^2 \\theta_2$, we can solve for everything in terms of $\\partial_t^2 \\theta_1$ and $\\partial_t^2 \\theta_2$ (this gives us two coupled second order ODEs)" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle \\frac{L_{2} m \\left(- L_{1} \\sin{\\left(\\theta_{1}{\\left(t \\right)} - \\theta_{2}{\\left(t \\right)} \\right)} \\left(\\frac{d}{d t} \\theta_{1}{\\left(t \\right)}\\right)^{2} - \\omega^{2} \\cos{\\left(\\omega t \\right)} \\cos{\\left(\\theta_{2}{\\left(t \\right)} \\right)} + g \\sin{\\left(\\theta_{2}{\\left(t \\right)} \\right)}\\right) \\cos{\\left(\\theta_{1}{\\left(t \\right)} - \\theta_{2}{\\left(t \\right)} \\right)}}{- L_{1} L_{2} m \\cos^{2}{\\left(\\theta_{1}{\\left(t \\right)} - \\theta_{2}{\\left(t \\right)} \\right)} - L_{2} \\left(- L_{1} m - L_{1}\\right)} - \\frac{L_{2} \\left(L_{2} m \\sin{\\left(\\theta_{1}{\\left(t \\right)} - \\theta_{2}{\\left(t \\right)} \\right)} \\left(\\frac{d}{d t} \\theta_{2}{\\left(t \\right)}\\right)^{2} - \\omega^{2} m \\cos{\\left(\\omega t \\right)} \\cos{\\left(\\theta_{1}{\\left(t \\right)} \\right)} - \\omega^{2} \\cos{\\left(\\omega t \\right)} \\cos{\\left(\\theta_{1}{\\left(t \\right)} \\right)} + g m \\sin{\\left(\\theta_{1}{\\left(t \\right)} \\right)} + g \\sin{\\left(\\theta_{1}{\\left(t \\right)} \\right)}\\right)}{- L_{1} L_{2} m \\cos^{2}{\\left(\\theta_{1}{\\left(t \\right)} - \\theta_{2}{\\left(t \\right)} \\right)} - L_{2} \\left(- L_{1} m - L_{1}\\right)}$" ], "text/plain": [ "L_2*m*(-L_1*sin(\\theta_1(t) - \\theta_2(t))*Derivative(\\theta_1(t), t)**2 - \\omega**2*cos(\\omega*t)*cos(\\theta_2(t)) + g*sin(\\theta_2(t)))*cos(\\theta_1(t) - \\theta_2(t))/(-L_1*L_2*m*cos(\\theta_1(t) - \\theta_2(t))**2 - L_2*(-L_1*m - L_1)) - L_2*(L_2*m*sin(\\theta_1(t) - \\theta_2(t))*Derivative(\\theta_2(t), t)**2 - \\omega**2*m*cos(\\omega*t)*cos(\\theta_1(t)) - \\omega**2*cos(\\omega*t)*cos(\\theta_1(t)) + g*m*sin(\\theta_1(t)) + g*sin(\\theta_1(t)))/(-L_1*L_2*m*cos(\\theta_1(t) - \\theta_2(t))**2 - L_2*(-L_1*m - L_1))" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sols = smp.solve([LE1, LE2], (the1_dd, the2_dd),\n", " simplify=False, rational=False)\n", "\n", "sols[the1_dd] #d^2 / dt^2 theta_1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Can we find driving frequencies that result in resonance. For simplicity:\n", "\n", "* Assume small angle approximation for $\\theta_1$ and $\\theta_2$\n", "* Assume $\\theta_1$ and $\\theta_2$ have solutions $\\theta_1(t) = C\\cos(\\omega t)$ and $\\theta_2(t) = C \\alpha \\cos(\\omega t)$" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle 1.0 L_{1} \\left(- L_{1} m \\frac{d^{2}}{d t^{2}} \\theta_{1}{\\left(t \\right)} - L_{1} \\frac{d^{2}}{d t^{2}} \\theta_{1}{\\left(t \\right)} - L_{2} m \\sin{\\left(\\theta_{1}{\\left(t \\right)} - \\theta_{2}{\\left(t \\right)} \\right)} \\left(\\frac{d}{d t} \\theta_{2}{\\left(t \\right)}\\right)^{2} - L_{2} m \\cos{\\left(\\theta_{1}{\\left(t \\right)} - \\theta_{2}{\\left(t \\right)} \\right)} \\frac{d^{2}}{d t^{2}} \\theta_{2}{\\left(t \\right)} + \\omega^{2} m \\cos{\\left(\\omega t \\right)} \\cos{\\left(\\theta_{1}{\\left(t \\right)} \\right)} + \\omega^{2} \\cos{\\left(\\omega t \\right)} \\cos{\\left(\\theta_{1}{\\left(t \\right)} \\right)} - g m \\sin{\\left(\\theta_{1}{\\left(t \\right)} \\right)} - g \\sin{\\left(\\theta_{1}{\\left(t \\right)} \\right)}\\right)$" ], "text/plain": [ "1.0*L_1*(-L_1*m*Derivative(\\theta_1(t), (t, 2)) - L_1*Derivative(\\theta_1(t), (t, 2)) - L_2*m*sin(\\theta_1(t) - \\theta_2(t))*Derivative(\\theta_2(t), t)**2 - L_2*m*cos(\\theta_1(t) - \\theta_2(t))*Derivative(\\theta_2(t), (t, 2)) + \\omega**2*m*cos(\\omega*t)*cos(\\theta_1(t)) + \\omega**2*cos(\\omega*t)*cos(\\theta_1(t)) - g*m*sin(\\theta_1(t)) - g*sin(\\theta_1(t)))" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "LE1" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [], "source": [ "a = LE1.subs([(smp.sin(the1-the2), the1-the2),\n", " (smp.cos(the1-the2), 1),\n", " (smp.cos(the1), 1),\n", " (smp.sin(the1), the1),\n", " (the1, C*smp.cos(w*t)),\n", " (the2, C*alph*smp.cos(w*t)),\n", " (m, 1),\n", " (L2, L1),\n", " ]).doit().series(C, 0, 2).removeO().simplify()" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [], "source": [ "b = LE2.subs([(smp.sin(the1-the2), the1-the2),\n", " (smp.cos(the1-the2), 1),\n", " (smp.cos(the1), 1),\n", " (smp.cos(the2), 1),\n", " (smp.sin(the1), the1),\n", " (smp.sin(the2), the2), \n", " (the1, C*smp.cos(w*t)),\n", " (the2, C*alph*smp.cos(w*t)),\n", " (m, 1),\n", " (L2, L1),\n", " ]).doit().series(C, 0, 2).removeO().simplify()" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [], "source": [ "yeet = smp.solve([a.args[1], b.args[2]], (w, alph))" ] }, { "cell_type": "code", "execution_count": 66, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle - \\sqrt{- \\frac{C g \\left(-2.0 + \\frac{1.4142135623731 \\left(C^{2} L_{1}^{2} + C L_{1} + 0.5\\right)^{0.5}}{C L_{1}} - \\frac{1}{C L_{1}}\\right)}{C L_{1} + 1.0}}$" ], "text/plain": [ "-sqrt(-C*g*(-2.0 + 1.4142135623731*(C**2*L_1**2 + C*L_1 + 0.5)**0.5/(C*L_1) - 1/(C*L_1))/(C*L_1 + 1.0))" ] }, "execution_count": 66, "metadata": {}, "output_type": "execute_result" } ], "source": [ "yeet[2][0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now set $\\beta = CL_1$ and take the limit as $\\beta \\to \\infty$." ] }, { "cell_type": "code", "execution_count": 67, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle - \\sqrt{- \\frac{C g \\left(-2.0 - \\frac{1.4142135623731 \\left(C^{2} L_{1}^{2} + C L_{1} + 0.5\\right)^{0.5}}{C L_{1}} - \\frac{1}{C L_{1}}\\right)}{C L_{1} + 1.0}}$" ], "text/plain": [ "-sqrt(-C*g*(-2.0 - 1.4142135623731*(C**2*L_1**2 + C*L_1 + 0.5)**0.5/(C*L_1) - 1/(C*L_1))/(C*L_1 + 1.0))" ] }, "execution_count": 67, "metadata": {}, "output_type": "execute_result" } ], "source": [ "yeet[0][0]" ] }, { "cell_type": "code", "execution_count": 82, "metadata": {}, "outputs": [ { "ename": "KeyboardInterrupt", "evalue": "", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", "\u001b[1;32m