Double pendulum equation of motion in python

What is a double pendulum?

Previously, in the article Equation of motion with sympy, I used sympy to derive the equation of motion of the spring-damper system. This time I would like to derive the equation of motion of the double pendulum. The double pendulum is often seen in physical mechanics, and as shown in the figure below, a pendulum is attached to the tip of the pendulum. It's just a double pendulum, but it's a complex movement that's incomparable to a single pendulum, so it's often mentioned in chaos and complex systems.

二重振り子.png

Formula

First, let's look at the equation of motion of a simple pendulum. (Imagine a single pendulum in the figure above.)

ml\ddot{\theta} + mg \sin\theta = 0

You can see that one item represents the inertial term and two items represent the gravity term, and the angular acceleration of the pendulum is proportional to the $ \ sin $ of the pendulum angle at that time. Next is the double pendulum. When it comes to deriving seriously, it will be a long story using the Lagrange function, so this time I will check the formula Wikipedia 8C% E9% 87% 8D% E6% 8C% AF% E3% 82% 8A% E5% AD% 90) is taken quickly.

(m_1+m_2)l_1\ddot{\theta}_1 + m_2l_2\ddot{\theta}_2\cos(\theta_1 - \theta_2) + m_2l_2\dot{\theta}_2^2\sin(\theta_1 - \theta_2) + (m_1 + m_2)g\sin\theta_1 = 0
\\\
l_1l_2\ddot{\theta}_1\cos(\theta_1- \theta_2) + l_2^2\ddot{\theta}_2 - l_1l_2\dot{\theta}_1^2\sin(\theta_1 - \theta_2) + gl_2\sin\theta_2 = 0

Just by looking at the equation, you can see that it is considerably more complicated than the equation of motion of a simple pendulum.

SymPyBotics Last time, I used the physics.mechanics module of SymPy directly to derive the formula, but the rigid body like this time is a clause. I would like to use SymPyBotics, which makes it easier to derive mathematical formulas for objects connected by (link). Get it from github and install it.

git clone https://github.com/cdsousa/SymPyBotics.git
cd SymPyBotics
sudo python setup.py install

Create a double pendulum using SymPyBotics. Below is the code.

import sympybotics
rbtdef = sympybotics.RobotDef('Double Pendulum',
                              [(0, 'l_1', 0, 'q-pi/2'),
                               (0, 'l_2', 0, 'q')],
                              dh_convention='standard')
from sympy import symbols, Matrix, simplify, pprint
g = symbols('g')
rbtdef.gravityacc = Matrix([[0.0],[-g],[0.0]])
rbt = sympybotics.RobotDynCode(rbtdef)
for p in rbt.geo.p:
    pprint(simplify(p), use_unicode=False)

The place where you are calling sympybotics.RobotDef is where you are creating the double pendulum. [(0,'l_1', 0,'q'), (0,'l_2', 0,'q')] is the actual double pendulum parameter, but Denavit–Hartenberg parameter is a method of giving parameters used by robots. Briefly, l_1 and l_2 indicate the length of pendulum 1 and pendulum 2, and q indicates the angle of the pendulum, which are assigned to the variables q1 and q2 after the pendulum is created. The first angle is q1-pi / 2, which is added to adjust where the angle is measured. This is because SymPyBotics measures the angle from the positive x-axis, whereas the figure measures the angle from the negative y-axis. If you want to use a triple pendulum, [(0,'l_1', 0,'q-pi / 2'), (0,'l_2', 0,'q'), (0,'l_3', 0,' q')] . The last print I wrote outputs an expression that expresses the position of the pendulum, which is as follows.

[l_1*sin(q1) ]
[            ]
[-l_1*cos(q1)]
[            ]
[     0      ]
[l_1*sin(q1) + l_2*sin(q1 + q2) ]
[                               ]
[-l_1*cos(q1) - l_2*cos(q1 + q2)]
[                               ]
[               0               ]
rbt.dyn.gen_all()
params = {'l_1x': 0.0, 'l_1y': 0.0,
          'l_2x': 0.0, 'l_2y': 0.0,
          'L_1zz': 0.0, 'L_2zz': 0.0}
mass = simplify(rbt.dyn.M.subs(params))
corioli = simplify(rbt.dyn.c.subs(params))
gravity = simplify(rbt.dyn.g.subs(params))

Next, each term (inertia term, centrifugal / Coriolis force term, gravity term) that is an element of the equation of motion is derived. Generated with rbt.dyn.gen_all () and delete unnecessary parameters (parameters related to the moment of inertia) this time.

eq = (mass * rbtdef.ddq + corioli + gravity).as_mutable()
eq[0, 0] -= eq[1, 0]
params = {rbtdef.ddq[1, 0]: rbtdef.ddq[1, 0] - rbtdef.ddq[0, 0],
          rbtdef.dq[1, 0]: rbtdef.dq[1, 0] - rbtdef.dq[0, 0],
          rbtdef.q[1, 0]: rbtdef.q[1, 0] - rbtdef.q[0, 0]}
print simplify(eq.subs(params))

Finally, we actually calculate the equation of motion. At the time of the first line, the equation of motion has been derived, but [Wikipedia](http://en.wikipedia.org/wiki/%E4%BA%8C%E9%87%8D%E6%8C% AF% E3% 82% 8A% E5% AD% 90) and the equations have been simplified and the variables have been changed to compare the results.

Matrix([
[l_1*(\ddot{q}_1*l_1*m_1 + \ddot{q}_1*l_1*m_2 + \ddot{q}_2*l_2*m_2*cos(q1 - q2) + \dot{q}_2**2*l_2*m_2*sin(q1 - q2) + g*m_1*sin(q1) + g*m_2*sin(q1))],
[                                                 l_2*m_2*(\ddot{q}_1*l_1*cos(q1 - q2) + \ddot{q}_2*l_2 - \dot{q}_1**2*l_1*sin(q1 - q2) + g*sin(q2))]])

It's a little hard to see, but if you think that the formula is equal to 0 and remove unnecessary variables, Wikipedia's equation of motion for the double pendulum E9% 87% 8D% E6% 8C% AF% E3% 82% 8A% E5% AD% 90 # .E9.81.8B.E5.8B.95.E6.96.B9.E7.A8.8B.E5. You can see that it matches BC.8F). This time it was a double pendulum, but it seems that it can also be applied to the derivation of equations of motion for multiple pendulums and robots.

Recommended Posts

Double pendulum equation of motion in python
Solving the equation of motion in Python (odeint)
Let Python calculate Euler-Lagrange's equation of motion
Find the solution of the nth-order equation in python
Equation of motion with sympy
Equivalence of objects in Python
Implementation of quicksort in Python
Have the equation graph of the linear function drawn in Python
Get Leap Motion data in Python.
Pixel manipulation of images in Python
Division of timedelta in Python 2.7 series
MySQL-automatic escape of parameters in python
Handling of JSON files in Python
Implementation of life game in Python
Waveform display of audio in Python
Law of large numbers in python
Implementation of original sorting in Python
Try using Leap Motion in Python
Conversion of string <-> date (date, datetime) in Python
Check the behavior of destructor in Python
(Bad) practice of using this in Python
General Theory of Relativity in Python: Introduction
Output tree structure of files in Python
Display a list of alphabets in Python 3
Summary of various for statements in Python
Prevent double launch in Python (improved version)
Gang of Four (GoF) Patterns in Python
The basics of running NoxPlayer in Python
Bulk replacement of strings in Python arrays
Project Euler # 16 "Sum of Powers" in Python
Traffic Safety-kun: Recognition of traffic signs in Python
Summary of built-in methods in Python list
Non-logical operator usage of or in python
In search of the fastest FizzBuzz in Python
Practical example of Hexagonal Architecture in Python
Project Euler # 17 "Number of Characters" in Python
Get rid of DICOM images in Python
Status of each Python processing system in 2020
Project Euler # 1 "Multiples of 3 and 5" in Python
Meaning of using DI framework in Python
Quadtree in Python --2
Python in optimization
CURL in python
Output the number of CPU cores in Python
Metaprogramming in Python
Draw a graph of a quadratic function in Python
Python 3.3 in Anaconda
Geocoding in python
Introduction of Python
SendKeys in Python
[Python] Sort the list of pathlib.Path in natural sort
Receive websocket of kabu station ® API in Python
Meta-analysis in Python
Unittest in python
Summary of how to import files in Python 3
Project Euler # 10 "sum of prime numbers" in Python
Unattended operation of Google Spreadsheets (etc.) in Python
Double pendulum simulation
Get the caller of a function in Python
View the result of geometry processing in Python
Epoch in Python