6. Symbolics using SymPy

6. Symbolics using SymPy

This example is also available as a Jupyter notebook that can be run locally The notebook can be found in the examples directory of the package. If the notebooks are missing, you may need to run using Pkg; Pkg.build().

Setup

using RigidBodyDynamics
using StaticArrays
using SymPy
  Updating registry at `~/.julia/registries/General`
  Updating git-repo `https://github.com/JuliaRegistries/General.git`
[?25l[?25h┌ Warning: Module JSON with build ID 69537206423 is missing from the cache.
│ This may mean JSON [682c06a0-de6a-54ab-a142-c8b1cf79cde6] does not support precompilation but is imported by a module that does.
└ @ Base loading.jl:947
┌ Warning: Module JSON with build ID 69537206423 is missing from the cache.
│ This may mean JSON [682c06a0-de6a-54ab-a142-c8b1cf79cde6] does not support precompilation but is imported by a module that does.
└ @ Base loading.jl:947
┌ Warning: Module JSON with build ID 69537206423 is missing from the cache.
│ This may mean JSON [682c06a0-de6a-54ab-a142-c8b1cf79cde6] does not support precompilation but is imported by a module that does.
└ @ Base loading.jl:947
┌ Warning: Module JSON with build ID 69537206423 is missing from the cache.
│ This may mean JSON [682c06a0-de6a-54ab-a142-c8b1cf79cde6] does not support precompilation but is imported by a module that does.
└ @ Base loading.jl:947
┌ Warning: Module JSON with build ID 69537206423 is missing from the cache.
│ This may mean JSON [682c06a0-de6a-54ab-a142-c8b1cf79cde6] does not support precompilation but is imported by a module that does.
└ @ Base loading.jl:947
┌ Warning: Module JSON with build ID 69537206423 is missing from the cache.
│ This may mean JSON [682c06a0-de6a-54ab-a142-c8b1cf79cde6] does not support precompilation but is imported by a module that does.
└ @ Base loading.jl:947
┌ Warning: Module JSON with build ID 69537206423 is missing from the cache.
│ This may mean JSON [682c06a0-de6a-54ab-a142-c8b1cf79cde6] does not support precompilation but is imported by a module that does.
└ @ Base loading.jl:947
[ Info: Installing sympy via the Conda sympy package...
[ Info: Running `conda install -q -y sympy` in root environment
Collecting package metadata (current_repodata.json): ...working... done
Solving environment: ...working... done

## Package Plan ##

  environment location: /home/travis/.julia/conda/3

  added / updated specs:
    - sympy


The following packages will be downloaded:

    package                    |            build
    ---------------------------|-----------------
    fastcache-1.1.0            |   py37h7b6447c_0          30 KB
    gmp-6.1.2                  |       h6c8ec71_1         514 KB
    gmpy2-2.0.8                |   py37h10f8cd9_2         150 KB
    mpc-1.1.0                  |       h10f8cd9_1          90 KB
    mpfr-4.0.1                 |       hdf1c602_3         429 KB
    mpmath-1.1.0               |           py37_0         766 KB
    sympy-1.4                  |           py37_0         7.9 MB
    ------------------------------------------------------------
                                           Total:         9.9 MB

The following NEW packages will be INSTALLED:

  fastcache          pkgs/main/linux-64::fastcache-1.1.0-py37h7b6447c_0
  gmp                pkgs/main/linux-64::gmp-6.1.2-h6c8ec71_1
  gmpy2              pkgs/main/linux-64::gmpy2-2.0.8-py37h10f8cd9_2
  mpc                pkgs/main/linux-64::mpc-1.1.0-h10f8cd9_1
  mpfr               pkgs/main/linux-64::mpfr-4.0.1-hdf1c602_3
  mpmath             pkgs/main/linux-64::mpmath-1.1.0-py37_0
  sympy              pkgs/main/linux-64::sympy-1.4-py37_0


Preparing transaction: ...working... done
Verifying transaction: ...working... done
Executing transaction: ...working... done

Create symbolic parameters

inertias = @syms m_1 m_2 I_1 I_2 positive = true
lengths = @syms l_1 l_2 c_1 c_2 real = true
gravitational_acceleration = @syms g real = true
params = [inertias..., lengths..., gravitational_acceleration...]
transpose(params)
1×9 LinearAlgebra.Transpose{SymPy.Sym,Array{SymPy.Sym,1}}:
 m_1  m_2  I_1  I_2  l_1  l_2  c_1  c_2  g

Create double pendulum Mechanism

A Mechanism contains the joint layout and inertia parameters, but no state information.

T = Sym # the 'scalar type' of the Mechanism we'll construct
axis = SVector(zero(T), one(T), zero(T)) # axis of rotation for each of the joints
double_pendulum = Mechanism(RigidBody{T}("world"); gravity = SVector(zero(T), zero(T), g))
world = root_body(double_pendulum) # the fixed 'world' rigid body
RigidBody: "world"

Attach the first (upper) link to the world via a revolute joint named 'shoulder'

inertia1 = SpatialInertia(CartesianFrame3D("upper_link"),
    moment=I_1 * axis * transpose(axis),
    com=SVector(zero(T), zero(T), c_1),
    mass=m_1)
body1 = RigidBody(inertia1)
joint1 = Joint("shoulder", Revolute(axis))
joint1_to_world = one(Transform3D{T}, frame_before(joint1), default_frame(world));
attach!(double_pendulum, world, body1, joint1,
    joint_pose = joint1_to_world);

Attach the second (lower) link to the world via a revolute joint named 'elbow'

inertia2 = SpatialInertia(CartesianFrame3D("lower_link"),
    moment=I_2 * axis * transpose(axis),
    com=SVector(zero(T), zero(T), c_2),
    mass=m_2)
body2 = RigidBody(inertia2)
joint2 = Joint("elbow", Revolute(axis))
joint2_to_body1 = Transform3D(
    frame_before(joint2), default_frame(body1), SVector(zero(T), zero(T), l_1))
attach!(double_pendulum, body1, body2, joint2,
    joint_pose = joint2_to_body1)

Create MechanismState associated with the double pendulum Mechanism

A MechanismState stores all state-dependent information associated with a Mechanism.

x = MechanismState(double_pendulum);

Set the joint configuration vector of the MechanismState to a new vector of symbolic variables

q = configuration(x)
for i in eachindex(q)
    q[i] = symbols("q_$i", real = true)
end

Set the joint velocity vector of the MechanismState to a new vector of symbolic variables

v = velocity(x)
for i in eachindex(v)
    v[i] = symbols("v_$i", real = true)
end

Compute dynamical quantities in symbolic form

Mass matrix

simplify.(mass_matrix(x))
2×2 Array{SymPy.Sym,2}:
 I_1 + I_2 + 2*c_2*l_1*m_2*cos(q_2) + l_1^2*m_2  I_2 + c_2*l_1*m_2*cos(q_2)
                     I_2 + c_2*l_1*m_2*cos(q_2)                         I_2

Kinetic energy

simplify(kinetic_energy(x))
     2        2                   2
I₁⋅v₁    I₂⋅v₁               I₂⋅v₂               2
────── + ────── + I₂⋅v₁⋅v₂ + ────── + c₂⋅l₁⋅m₂⋅v₁ ⋅cos(q₂) + c₂⋅l₁⋅m₂⋅v₁⋅v₂⋅co
  2        2                   2

          2      2
        l₁ ⋅m₂⋅v₁
s(q₂) + ──────────
            2

Potential energy

simplify(gravitational_potential_energy(x))
-g⋅(c₁⋅m₁⋅cos(q₁) + c₂⋅m₂⋅cos(q₁ + q₂) + l₁⋅m₂⋅cos(q₁))

This page was generated using Literate.jl.