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 Activating environment at `~/work/RigidBodyDynamics.jl/RigidBodyDynamics.jl/examples/6. Symbolics using SymPy/Project.toml`
[ 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/runner/.julia/conda/3
added / updated specs:
- sympy
The following packages will be downloaded:
package | build
---------------------------|-----------------
gmp-6.2.1 | h2531618_2 539 KB
gmpy2-2.0.8 | py38hd5f6e3b_3 162 KB
mpc-1.1.0 | h10f8cd9_1 90 KB
mpfr-4.0.2 | hb69a4c5_1 487 KB
mpmath-1.2.1 | py38h06a4308_0 766 KB
sympy-1.8 | py38h06a4308_0 9.1 MB
------------------------------------------------------------
Total: 11.1 MB
The following NEW packages will be INSTALLED:
gmp pkgs/main/linux-64::gmp-6.2.1-h2531618_2
gmpy2 pkgs/main/linux-64::gmpy2-2.0.8-py38hd5f6e3b_3
mpc pkgs/main/linux-64::mpc-1.1.0-h10f8cd9_1
mpfr pkgs/main/linux-64::mpfr-4.0.2-hb69a4c5_1
mpmath pkgs/main/linux-64::mpmath-1.2.1-py38h06a4308_0
sympy pkgs/main/linux-64::sympy-1.8-py38h06a4308_0
Preparing transaction: ...working... done
Verifying transaction: ...working... done
Executing transaction: ...working... doneCreate symbolic parameters
- Masses: $m_1, m_2$
- Mass moments of inertia (about center of mass): $I_1, I_2$
- Link lengths: $l_1, l_2$
- Center of mass locations (w.r.t. preceding joint axis): $c_1, c_2$
- Gravitational acceleration: $g$
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)\[\left[ \begin{array}{rrrrrrrrr}m_{1}&m_{2}&I_{1}&I_{2}&l_{1}&l_{2}&c_{1}&c_{2}&g\end{array}\right]\]
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 bodyRigidBody: "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)Spanning tree:
Vertex: world (root)
Vertex: upper_link, Edge: shoulder
Vertex: lower_link, Edge: elbow
No non-tree joints.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)
endSet 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)
endCompute dynamical quantities in symbolic form
Mass matrix
simplify.(mass_matrix(x))\[\left[ \begin{array}{rr}I_{1} + I_{2} + 2 c_{2} l_{1} m_{2} \cos{\left(q_{2} \right)} + l_{1}^{2} m_{2}&I_{2} + c_{2} l_{1} m_{2} \cos{\left(q_{2} \right)}\\I_{2} + c_{2} l_{1} m_{2} \cos{\left(q_{2} \right)}&I_{2}\end{array}\right]\]
Kinetic energy
simplify(kinetic_energy(x))\[\begin{equation*}\frac{I_{1} v_{1}^{2}}{2} + \frac{I_{2} v_{1}^{2}}{2} + I_{2} v_{1} v_{2} + \frac{I_{2} v_{2}^{2}}{2} + c_{2} l_{1} m_{2} v_{1}^{2} \cos{\left(q_{2} \right)} + c_{2} l_{1} m_{2} v_{1} v_{2} \cos{\left(q_{2} \right)} + \frac{l_{1}^{2} m_{2} v_{1}^{2}}{2}\end{equation*}\]
Potential energy
simplify(gravitational_potential_energy(x))\[\begin{equation*}- g \left(c_{1} m_{1} \cos{\left(q_{1} \right)} + c_{2} m_{2} \cos{\left(q_{1} + q_{2} \right)} + l_{1} m_{2} \cos{\left(q_{1} \right)}\right)\end{equation*}\]
This page was generated using Literate.jl.