3D Pendulum

3 rods linked by spherical joints

Posted by Mellean on February 25, 2016

Recently by the same author:


Typical Application

Typical Applications and problems

You may find interesting:


Jupyter

Install Jupyter with a MATLAB kernel


3D Slider-crank

A toy system


Workflow Overview

graph TB node1(World parameters ) click node1 "#1" node1(World parameters ) --> node2(Multibody system configuration ) click node2 "#2" node2(Multibody system configuration ) --> node3(System dynamic constrains ) click node3 "#3" node3(System dynamic constrains ) --> node4(Mass matrix assembly ) click node4 "#4" node4(Mass matrix assembly ) --> node5(Start simulation ) click node5 "#5" node5(Start simulation ) --> node6(Output ) click node6 "#6"
%-------------------------------------------------------------------------%
%------------------------------Multibody Dynamic--------------------------%
%------------------------------A toy system-------------------------------%
% Problem: 3 rods linked using two spherical joints 3D

 

% Author: Mellean
% Data: 25Fev16
% Version: 1.0
%-------------------------------------------------------------------------%
clc
clear all
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Global variables used to
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
addpath('../dynamic')

global World % used to describe the world
global BodyList % List with body identifiers
global JointList % List with dynamic constrains identifiers
global Bodies % Structure with every rigid bodies in the system
global Joints % Structure with dynamics constrains
global Simulation
global Motors
global Motor

global TT Err

World parameters

World.gravity=[0;0;-0.00981]; % force to be applied on each body
World.ElasticNet = false;  % force are generated using and elastic network
World.Regularistion = true;
World.RFactor = 1e-15;     % regularization factor
World.FMNcontact = false;
World.FMNdensity = false;

% Baumgarte Method
World.alpha=5.0;
World.beta=5.0;

% Debugging information

World.C1=[];
World.Err=[];

% Flexible Multibody system
World.Flexible=false;

Multibody system configuration

BodyList={'Ground','C1','C2','C3'}; % list of system bodies
JointList={'Fix','J1','J2','J3'}; % list of dynamic constrains
Motors={};

%Ground: body C1
%Geometry

Bodies.Ground.geo.m=1; % massa
Bodies.Ground.flexible=false;


Bodies.Ground.geo.JP=diag([1,1,1]); % Moment of inertia

% Points in body Ground
Bodies.Ground.PointsList={'P1'};
Bodies.Ground.Points.P1.sPp=[0,0.5,0]'; % local frame coordinates

% Vectors in body Ground
Bodies.Ground.VectorsList={};

% Body initial values
Bodies.Ground.r=[0,0.0,0]'; % Body initial position in global coordinates
Bodies.Ground.r_d=[0,0,0]';  % initial velocity
Bodies.Ground.r_dd=[0,0,0]';  % initial acceleration
Bodies.Ground.p=[1,0,0,0]';  % initial Euler parameters
Bodies.Ground.p_d=[0,0,0,0]';% Euler parameters derivative
Bodies.Ground.w=[0,0,0]';    % initial angular velocity
Bodies.Ground.wp=[0,0,0]';  % initial angular acceleration
Bodies.Ground.np=[0,0,0]';   % initial moment
Bodies.Ground.exists=true;

%Body C1 a Rod
%%Geometry
Bodies.C1.geo.m=1; % rod mass
Bodies.C1.geo.h=1; % rod length
Bodies.C1.geo.r=1; % rod radius
Bodies.C1.flexible=false;

% Inertia tensor for body C1
Bodies.C1.geo.JP=diag([1/12*(Bodies.C1.geo.m*(3*Bodies.C1.geo.r^2+Bodies.C1.geo.h^2)),1/2*(Bodies.C1.geo.m*Bodies.C1.geo.r^2),...
     1/12*(Bodies.C1.geo.m*(3*Bodies.C1.geo.r^2+Bodies.C1.geo.h^2))]);

%List of points in body C1
Bodies.C1.PointsList={'P1','P2'};

Bodies.C1.Points.P1.sPp=[0,-0.5,0]';
Bodies.C1.Points.P2.sPp=[0,0.5,0]';

%List of vectors in body C1
Bodies.C1.VectorsList={};

% Body initial values
Bodies.C1.r=[0,1,0]';
Bodies.C1.r_d=[0,0,0]';
Bodies.C1.r_dd=[0,0,0]';
Bodies.C1.p=[1,0,0,0]';
Bodies.C1.p_d=[0,0,0,0]';
Bodies.C1.w=[0,0,0]';
Bodies.C1.wp=[0,0,0]';
Bodies.C1.np=[0,0,0]';
Bodies.C1.exists=true;

%Body C2 a Rod
%%Geometry
Bodies.C2.geo.m=1; % rod mass
Bodies.C2.geo.h=1; % rod length
Bodies.C2.geo.r=1; % rod radius
Bodies.C2.flexible=false;

% Inertia tensor for body C2
Bodies.C2.geo.JP=diag([1/12*(Bodies.C2.geo.m*(3*Bodies.C2.geo.r^2+Bodies.C2.geo.h^2)),1/2*(Bodies.C2.geo.m*Bodies.C2.geo.r^2),...
     1/12*(Bodies.C2.geo.m*(3*Bodies.C2.geo.r^2+Bodies.C2.geo.h^2))]);

%List of points in body C2
Bodies.C2.PointsList={'P2','P3'};

Bodies.C2.Points.P2.sPp=[0,-0.5,0]';
Bodies.C2.Points.P3.sPp=[0,0.5,0]';

%List of vectors in body C2
Bodies.C2.VectorsList={};

% Body initial values
Bodies.C2.r=[0,2,0]';
Bodies.C2.r_d=[0,0,0]';
Bodies.C2.r_dd=[0,0,0]';
Bodies.C2.p=[1,0,0,0]';
Bodies.C2.p_d=[0,0,0,0]';
Bodies.C2.w=[0,0,0]';
Bodies.C2.wp=[0,0,0]';
Bodies.C2.np=[0,0,0]';
Bodies.C2.exists=true;

%Body C3 a Rod
%%Geometry
Bodies.C3.geo.m=1; % rod mass
Bodies.C3.geo.h=1; % rod length
Bodies.C3.geo.r=1; % rod radius
Bodies.C3.flexible=false;

% Inertia tensor for body C3
Bodies.C3.geo.JP=diag([1/12*(Bodies.C3.geo.m*(3*Bodies.C3.geo.r^2+Bodies.C3.geo.h^2)),1/2*(Bodies.C3.geo.m*Bodies.C3.geo.r^2),...
     1/12*(Bodies.C3.geo.m*(3*Bodies.C3.geo.r^2+Bodies.C3.geo.h^2))]);

%List of points in body C3
Bodies.C3.PointsList={'P3','P4'};

Bodies.C3.Points.P3.sPp=[0,-0.5,0]';
Bodies.C3.Points.P4.sPp=[0,0.5,0]';
%List of vectors in body C3
Bodies.C3.VectorsList={};

% Body initial values
Bodies.C3.r=[0,3,0]';
Bodies.C3.r_d=[0,0,0]';
Bodies.C3.r_dd=[0,0,0]';
Bodies.C3.p=[1,0,0,0]';
Bodies.C3.p_d=[0,0,0,0]';
Bodies.C3.w=[0,0,0]';
Bodies.C3.wp=[0,0,0]';
Bodies.C3.np=[0,0,0]';
Bodies.C3.exists=true;

System dynamic constrains

%Ground joint

Joints.Fix.type='Fix';  % fix body in the space
Joints.Fix.body_1='Ground'; % body identifier

%Sherical joint linking body Ground and body C1
Joints.J1.type='She';  % spherical joint between body_1 and body_2
Joints.J1.body_1='Ground'; % body_1 identifier
Joints.J1.body_2='C1'; % body_2 identifier
Joints.J1.point='P1';  % point identifier

% Sherical joint linking body C1 and body C2
Joints.J2.type='She';  % revolute joint between body_1 and body_2
Joints.J2.body_1='C1'; % body_1 identifier
Joints.J2.body_2='C2'; % body_2 identifier
Joints.J2.point='P2';  % point identifier

% Sherical joint linking body C2 and body C3
Joints.J3.type='She';  % revolute joint between body_1 and body_2
Joints.J3.body_1='C2'; % body_1 identifier
Joints.J3.body_2='C3'; % body_2 identifier
Joints.J3.point='P3';  % point identifier

% Transport Multibody system information

World.nbodies = length(BodyList);  % number of bodies in the system
World.njoints = length(JointList); % number of joints in the system
World.nmotors = length(Motors); % number of joints in the system
World.NNodes  = 0 ;            % count number of nodes in the system
World.Msize   = World.NNodes*6+World.nbodies*6; % mass matrix size


Mass matrix assembly

y_d=[];

nbodies=length(BodyList);
World.M=zeros(nbodies*6);

for indexE=1:nbodies
    BodyName=BodyList{indexE};
    Bodies.(BodyName).g=World.gravity;
    O=zeros(3,3);
    index=(indexE-1)*6+1;

    Bodies.(BodyName).index=index; % body index in the mass matrix
    Bodies.(BodyName).forca=[];
    % recursive definition for the initial force
    y_d=[y_d; Bodies.(BodyName).r;Bodies.(BodyName).p;Bodies.(BodyName).r_d;Bodies.(BodyName).w];
end

Start simulation

% set integration parameters
t0=0;    % Initial time
t=100.00; % Final time
step=0.001; % Time-step


tspan = [t0:step:t];

% Set integrator and its parameters

fprintf('\n\n ODE45\n\n')
tol=1e-5;
options=odeset('RelTol',tol,'Stats','on','OutputFcn',@odeOUT);

tic
[T, yT]= ode45(@updateaccel, tspan, y_d, options);
timeode45=toc

 ODE45

878 successful steps
2 failed attempts
5281 function evaluations

timeode45 =

   14.1549

Output

Output: systems c-of-m yz-projection

fig=figure;
for index=1:nbodies
    BodyName=BodyList{index};
    plot(yT(:,(index-1)*13+2), yT(:,(index-1)*13+3))

    hold on
end
xlabel('y'),ylabel('z')
% print(fig,'Positionyz','-dpng')

hold off

Output: systems c-of-m xz-projection

fig=figure;
for index=1:nbodies
    BodyName=BodyList{index};
    plot(yT(:,(index-1)*13+1), yT(:,(index-1)*13+3))
    hold on
end
xlabel('x'),ylabel('z')
% print(fig,'Positionxz','-dpng')
hold off

Output: Velocidades**2

fig=figure;
for indexE=1:nbodies
    L=yT(:,(indexE-1)*13+8:(indexE-1)*13+10);
    v=[];
    for i=1:length(L)
        v=[v L(i,:)*L(i,:)'];
    end
    plot(T, v)
    hold on
end
xlabel('T'),ylabel('v^2[m/s]')
%print(fig,'velocity','-dpng')
hold off

Output: Error on the system constrains

fig=figure;
plot( Err)
xlabel('iteration'),ylabel('Error')