Getting Started

The MBDyn solver takes as input a text-based description of the multibody dynamics problem which uses a custom input format. The MBDyn Toolbox can be used to generate these input files for MBDdyn using on normal Matlab code to more easily integrate MBDyn simulations into a Matlab program. The toolbox also has methods to then run the simulation, and load and post-process the results all from Matlab. In addition, co-simulation, where forces are sent to MBDyn from Matlab and motion data sent to Matlab from MBDyn on each time step is also possible.

Use of the toolbox requires an intermedate knowledge of Matlab. To understand in what knowledge is required, read Required Knowledge.

The MBDyn pre-processing tools which generate the files are based on an object oriented appoach, elements of the problem are represented as classes and a special system class acts as a container for the entire collection of input data, conceptually this is shown in Fig. 4.

_images/mbdyn_basic_object_diagram.png

Fig. 4 MBDyn Matlab Toolbox object model.

Problems

Although Fig. 4 shows multiple problem classes, there is currently only one type of problem available, the initial-value problem. This is a problem type for solving the motion of the multibody system over time.

Nodes

Nodes come in various types, the most commonly used being structural nodes which can have 6 degrees of freedom (position and orientation), and therefore describe the kinematics of rigid-body motion in space, or 3 degrees of freedom (position) and thus describe the kinematics of point mass motion in space. All the available node types in MBDyn are:

  • abstract

  • electric

  • hydraulic

  • parameter

  • structural

  • thermal

Not all of these node types are currently implemented in this toolbox. Those which are are represented as Matlab classes, all ultimately derived from the mbdyn.pre.node class.

Elements

Elements are things such as forces, couples, mechanical joints and bodies which are attached to structural nodes. However, there are also a wide range of other element types avaialable in MBDyn. The full list of elements available in MBDyn is shown below:

  • structural elements:
    • automatic structural

    • beam

    • body

    • couple

    • gravity

    • joint

    • joint regularization

    • plate

  • aerodynamic elements:
    • aerodynamic beam2

    • aerodynamic beam3

    • aerodynamic body

    • aeromodal

    • aircraft instruments

    • air properties

    • induced velocity

  • electric elements:
    • electric

  • hydraulic elements:
    • hydraulic

  • output elements:
    • RTAI output

    • stream output

    • stream motion output

  • generic elements:
    • bind

    • bulk

    • force

    • genel

    • loadable

    • user defined

  • miscellaneous element cards

Again, not every element is yet available in the Matlab toolbox. As with the nodes, those which are are represented as Matlab classes, all ultimately derived from the mbdyn.pre.element class.

Drivers

Drivers are special objects which can be required for certain configurations (see the MBDyn manual for more information). There is currently limited support for these drivers.

Control Data

Unlike the parts discussed above, control data does not refer to a class, instead this refers to general settings for the problem. These settings are accessed though properties and methods of the system class.

Example Matlab Script

The following example sets up and runs a simulation of a double pendulum. It also loads results from MBDyn output files, and plots some of them. The system to be simulated is shown in Fig. 5. This example does not demonstrate cosimulation, where forces are exchanged during simulation between Matlab and MBDyn. An example of this can be found later in this documentation.

my-picture1

Fig. 5 Double pendulum example geometry.

The pendulum consists of two bodies. One body is attached by a pin to a fixed location. The other body is attached to the first by a hinge. A script to describe and run the problem is shown in the heavily commented listing below.

  1% example_double_pendulum.m
  2%
  3% this is intended to replicate the MBDyn double pendulum example which can
  4% be found at:
  5%
  6% http://www.sky-engin.jp/en/MBDynTutorial/chap15/chap15.html
  7%
  8% It considers a double rigid pendulum composed of two links. This example
  9% uses the concept of 'references' which allow one to easily set the
 10% relative position of the links.
 11%
 12
 13% Let the angle between Link1 and the vertical line be theta1 and the angle
 14% between Link2 and Link1 be theta2, and set up some initial variables to
 15% hold data on the links.
 16
 17% initial angle between link 1 and the vertical axis
 18theta1 = -pi/5;
 19% initial angle between link 1 and link 2
 20theta2 = pi/5;
 21% length of the links
 22L = 1;
 23% Mass or the links
 24M = 1;
 25% inertia matrix for the links
 26inertiamat = diag ([0., M*L^2./12., M*L^2./12.]);
 27
 28% The reference class is used to assist with positioning things relative to
 29% known locations in the global frame. This can greatly ease the creation
 30% of 3D multibody models. They are also extremely useful for creating
 31% models in which components can be moved around while keeping the relative
 32% position of other components constant. 
 33
 34% Create a reference object to the global orientation/location frame.
 35gref = mbdyn.pre.globalref ();
 36
 37% Create a reference relative to the global frame, but with a different
 38% orientation, one rotated by theta1 radians about the y axis
 39ref_link1_angle = mbdyn.pre.reference ( ...
 40                [], ...
 41                mbdyn.pre.orientmat ('euler', [0, theta1, 0]), ...
 42                [], ...
 43                [], ...
 44                'Parent', gref, ...
 45                'Name', 'Ref_Link1_Angle' );
 46
 47
 48% Create a reference relative to ref_link1_angle for the location of Link
 49% 1's structural node. This one is at position [0.5*L; 0; 0], in the frame
 50% of the ref_link1_angle reference
 51ref_link1_node = mbdyn.pre.reference ( [0.5*L; 0; 0], ...
 52                                       [], ...
 53                                       [], ...
 54                                       [], ...
 55                                       'Parent', ref_link1_angle, ...
 56                                       'Name', 'Ref_Node_Link1' );
 57
 58% Now create a dynamic structural node for Link 1. The global position and
 59% orientation of the node are taken from the ref_link1_node reference which
 60% converts the relative location by which it was specified into the global
 61% frame. 
 62link1node = mbdyn.pre.structuralNode6dof ( ...
 63                        'dynamic', ...
 64                        'AbsolutePosition', ref_link1_node.pos, ...
 65                        'AbsoluteOrientation', ref_link1_node.orientm );
 66            
 67% Create a body representing link1 which is attached to the structural node
 68link1 = mbdyn.pre.body (M, [], inertiamat, link1node);
 69
 70% Create a reference in the frame of link 1 which points to the joint
 71% location between the two links
 72ref_link1_link2_joint = mbdyn.pre.reference ( ...
 73                   [L; 0; 0], ...
 74                   mbdyn.pre.orientmat ('euler', [0, theta2, 0]), [], ...
 75                   [], ...
 76                   'Parent', ref_link1_angle, ...
 77                   'Name', 'Ref_Link2');
 78
 79% From the joint location create a reference to the Link 2 node
 80ref_link2_node = mbdyn.pre.reference ( [0.5*L; 0; 0], ...
 81                                       mbdyn.pre.orientmat ('orientation', eye(3)), ...
 82                                       [], ...
 83                                       [], ...
 84                                       'Parent', ref_link1_link2_joint, ...
 85                                       'Name', 'Ref_Node_Link2');
 86
 87% Create structural node for link 2.
 88link2node = mbdyn.pre.structuralNode6dof (...
 89                          'dynamic', ...
 90                          'AbsolutePosition', ref_link2_node.pos, ...
 91                          'AbsoluteOrientation', ref_link2_node.orientm );
 92
 93% A body for link 2 attached to link2node
 94link2 = mbdyn.pre.body (M, [], inertiamat, link2node);
 95
 96% Next we are going to create the joints in the system, there are two
 97% joints, a revolute pin for link 1, and a revolute hinge between link 1
 98% and link 2. Both of these hinge types allow rotation around axis 3 in
 99% their local orientation. To get the hinges pointed in the right
100% direction, therefore, we have to create an orientation which will be
101% supplied to the hinges when they are created.
102
103% Orientations can be created using the mbdyn.pre.orientmat class. This is
104% essentially a wrapper for a 3x3 orientation matrix, but with various
105% ways of creating it and some other useful methods, including the ability
106% to draw the orientation in a figure (represented as 3 orthogonal axes).
107% Here we create an orientation using the '2vectors' method. This method
108% specifies an orientation by defining a plane using two non-parallel
109% vectors, see the help for mbdyn.pre.orientmat for more information on
110% this method. Here we create a orientatino with axis 3 pointing parallel
111% to the Y-axis of the global frame
112hinges_orientation = mbdyn.pre.orientmat ( ...
113    '2vectors', struct ('ia', 1, 'vecA', [1;0;0], 'ib', 3, 'vecB', [0;1;0]) );
114
115% Next create references for the location and orientation of the two
116% hinges, we can make them relative to previously create references for
117% convenience
118ref_pin = mbdyn.pre.reference ( [], hinges_orientation, [], [], ...
119                                'Parent', ref_link1_angle, ...
120                                'Name', 'Ref_pin' );
121                            
122ref_hinge = mbdyn.pre.reference ( [], hinges_orientation, [], [], ...
123                                  'Parent', ref_link1_link2_joint, ...
124                                  'Name', 'Ref_hinge' );
125
126% Create the two joint objects, first the pin joint
127pinjoint = mbdyn.pre.revolutePin ( ...
128                    link1node, ref_link1_angle.pos, ref_link1_angle.pos, ...
129                    'NodeRelativeOrientation', ref_pin.orientm, ...
130                    'PinOrientation', ref_pin.orientm );
131
132% Next create the hinge between the two links. The revoluteHinge requires
133% that you specify the location and orientation of the joint relative to
134% both nodes, and these locations must match up. Although by default the
135% reference frame of the location is that of the attached nodes, one can
136% also force an alternative reference frame. In this case we are not
137% meaning a mbdyn.pre.reference object, but rather a keyword specifying a
138% particular frame. The keyword can be 'node', 'local', 'other node',
139% 'other location' or 'global'. Below we explicitly specify 'node' and
140% 'other node' for the location reference, and both locations are specified
141% in the frame of the first structural node attached to the joint
142% (which is link1node).
143linkjoint = mbdyn.pre.revoluteHinge ( link1node, link2node, ...
144                                      [L/2;0;0], [L/2;0;0], ...
145                                      'Offset1Reference', 'node', ...
146                                      'Offset2Reference', 'other node', ...
147                                      'RelativeOrientation1', ref_hinge.orientm, ...
148                                      'Orientation1Reference', 'global', ...
149                                      'RelativeOrientation2', ref_hinge.orientm, ...
150                                      'Orientation2Reference', 'global' ...
151                                    );
152                                
153% Finally, create a gravity object. The default setting produce a uniform
154% gravitational field directed along the negative z asis. More advanced
155% forms of gravitational field are possible
156gravity = mbdyn.pre.gravity();
157
158% The double pendulum system is now fully described and we can set up the
159% problem settings
160prb = mbdyn.pre.initialValueProblem (0, 10, 1e-3, ...
161                                     'ResidualTolerance', 1e-9);
162
163
164% To solve the system, we create an mbdyn.pre.system object, into which we
165% put all the nodes and elements and the problem object. In this case we
166% also supply some references. This is optional and they are not used for
167% the solution of the problem. They are used only for visualisation
168% purposes (as will be be seen in the section below)
169mbsys = mbdyn.pre.system ( {prb}, ...
170                           'Nodes', {link1node, link2node}, ...
171                           'Elements', { link1, link2, pinjoint, ...
172                                         linkjoint, gravity }, ...
173                           'References', { ref_link1_angle, ...
174                                           ref_link1_node,  ...
175                                           ref_link1_link2_joint,  ...
176                                           ref_link2_node,  ...
177                                           ref_pin,  ...
178                                           ref_hinge }, ...
179                           'DefaultOrientation', 'orientation matrix');
180
181%% Visualisation of the system
182%
183% To assist with model development, various visualisation tools are
184% provided so one can check and debug the orientations and locations of
185% components
186%
187
188% Below we set the size of nodes and size and color of the bodies for
189% visualisation purposes. This has no effect on the simulation. By default
190% bodies are represented as simple box shapes. Below we are simply changing
191% the shape of these boxes. It is also possible to specify STL files for
192% bodies, in which case the STL mesh shape will insead be used in the
193% visualisation.
194%
195% Note that it is possible to do this *after* inserting them into the
196% system as they are derived from the Matlab handle class. This means
197% changes to these objects will be propogated to the copies in the system
198% (or elsewhere). This is something to bear in mind for all the mbdyn
199% classes, as nearly all are derived from the handle class.
200%
201mbsys.setStructuralNodeSize (L/10, L/10, L/10);
202link1.setSize (L, L/10, L/10);
203link2.setSize (L, L/10, L/10);
204link1.setColour ('r');
205link1.setColour ('b');
206% pinjoint.setSize (L/10, L/10, L/10);
207pinjoint.setColour ('k');
208% linkjoint.setSize (L/10, L/10, L/10);
209linkjoint.setColour ('g');
210
211% Draw the system to check it is set up correctly, we turn on plotting of
212% the supplied reference objects, as by default they are not plotted.
213mbsys.draw ( 'Mode', 'wireghost', ...
214             'References', true, ...
215             'ReferenceScale', 0.5, ...
216             'AxLims', [-2, 2; -2, 2; -2, 2;] );
217
218%% Run MBDyn For Problem
219%
220% Now we can actually generate the the input file for the MBDyn program,
221% and run it to solve the problem
222
223inputfile = 'example_double_pendulum.mbd';
224
225% Generate the input file for MBDyn in the specified location
226mbsys.generateMBDynInputFile (inputfile);
227
228% Start mbdyn with the generated input file using the start_mbdyn function
229% from the mbdyn.mint package. Note this is different from the mbdyn.pre
230% package all the previous classes were from. mint is short for
231% m-interface.
232mbdyn.mint.start_mbdyn (inputfile);
233
234%% Post-processing
235%
236% A class is also provided to post-process and visualise the results of an
237% MBDyn simulation
238
239% Load data into post-processing object, the ouput files are by default
240% created by MBDyn in the same location as the input files but with
241% alternative file extensions. We supply the input file, meaning the
242% postproc class looks for output files of the same name and location, but
243% with different file extensions
244mbdynpost = mbdyn.postproc (inputfile, mbsys);
245
246% Plot node trajectories
247mbdynpost.plotNodeTrajectories ();
248
249% Make a 2D plot of the node positions
250mbdynpost.plotNodePositions ();
251
252% Make a 2D plot of the node velocities
253mbdynpost.plotNodeVelocities ();
254
255% Make a 2D plot of the node angular velocities
256mbdynpost.plotNodeAngularVelocities ();
257
258% Plot a particular time step of interest
259mbdynpost.drawStep (500, ...
260    'AxLims', [-2, 2; -0.5, 0.5;  -2, 1]);
261
262% Animate the entire simulation, saving it in an avi file
263mbdynpost.animate ( 'PlotTrajectories', true, ...
264                    'DrawLabels', true, ...
265                    'Skip', 20, ...
266                    'DrawMode', 'solid', ...
267                    'Light', true, ...
268                    'AxLims', [-2, 2; -0.5, 0.5;  -2, 1], ...
269                    'VideoFile', 'example_double_pendulum.avi');
270                
271                

When run, the script ultimately produces six figures shown below. Fig. 6 shows the system with it’s initial setup, produced using the mbdyn.pre.system.draw () method. The remaining fgures, Fig. 7, Fig. 8, Fig. 9, Fig. 10, and Fig. 11 all show results from the simulation and produced using the mbdyn.postproc class.

_images/example_double_pendulum_1.png

Fig. 6 Double pendulum initial setup.

_images/example_double_pendulum_2.png

Fig. 7 Double pendulum result plot.

_images/example_double_pendulum_3.png

Fig. 8 Double pendulum result plot.

_images/example_double_pendulum_4.png

Fig. 9 Double pendulum result plot.

_images/example_double_pendulum_5.png

Fig. 10 Double pendulum result plot.

_images/example_double_pendulum_6.png

Fig. 11 Double pendulum result plot.

The final command in the example, i.e.

% Animate the entire simulation, saving it in an avi file
mbdynpost.animate ( 'PlotTrajectories', true, ...
                    'DrawLabels', true, ...
                    'Skip', 20, ...
                    'DrawMode', 'solid', ...
                    'Light', true, ...
                    'AxLims', [-2, 2; -0.5, 0.5;  -2, 1], ...
                    'VideoFile', 'example_double_pendulum.avi');
                
                

Animates the simulation in a figure and saves the animation to an avi file, the video can be seen below:

Getting Help

In general the mbdyn toolbox classes are documented (although this is an ongoing project), so to learn more about a class one can use the matlab built-in help and doc commands. e.g.:

help mbdyn.pre.reference

An API reference containing the same information (actually generated from the help for the classes) is provided with this docuement.