It is based around the concept of a âscene graphâ, providing an object- oriented ... display lists as part of the core scene graph. ..... source Scene Graph API.
The 1st Joint International Conference on Multibody System Dynamics May 25-27, 2010, Lappeenranta, Finland
Efficient implementation of 3D graphics in an MBS framework Alfonso Callejo, Santiago Tapia, Javier García de Jalón INSIA - University Institute for Automobile Research (UPM - Technical University of Madrid) Carretera de Valencia, km 7, 28031 Madrid, Spain Phone: +34 913365335 Email: {a.callejo, santiago.tapia, javier.garciadejalon}@upm.es
ABSTRACT This article presents a powerful implementation of an open source 3D graphics library into a mixed MATLAB/C++ MBS framework. Firstly, the authors make a summary of the framework. Its core is an efficient semi-recursive formulation which makes the most of the system topology and that is especially suitable for large and complex MBSs. It uses optimized math routines and C++ coding of the critical functions through MATLAB’s MEX-functions. Then, the main steps of the OpenSceneGraph scene creation are described, including the importation of the scenery and the CAD models and the generation of simple bodies like bars and rods. After that, the algebraic approach to manage the motion of the bodies is explained, as well as the function callbacks which apply the geometric transformations. One of the most critical parts is the bridge between the MBS model (MATLAB-based) and the 3D graphics function (C++ based). This is done by means of a MEX-function which sets up the 3D graphics viewer in a different thread, so that it does not interfere with the numerical integration, and creates a pipeline as the link between both programs. In order to assess the performance of the implementation, three MBS models are presented: a coach, a Formula SAE racing car and a semi-trailer truck. The time profiles show that despite being simpler, the MATLAB drawing functions are much slower than the realistic 3D graphics viewer. This effectiveness makes this approach suitable for real-time simulations and allows carrying out realistic visualizations of MBSs in a simple and versatile way. Keywords: multibody systems, 3D graphics viewer, MATLAB and C++, OpenSceneGraph toolkit. 1
INTRODUCTION
As in other areas of Computational Mechanics, like for example in the finite element method or in computational fluid dynamics, 3D graphics are quite essential in dynamics of multibody systems (MBS), specifically to make a straightforward definition of the topology and to display the results realistically. The authors present in this paper an approach to implement a 3D graphics viewer in a MBS framework. The main objective is to be able to display the results of the numerical integration, both while the integrator is working and at the end of the integration (as a post-process). Although the general ideas are valid for any type of framework, with the only requirement of having a C++ interface, the starting point of this approach is an optimized topological semi-recursive formulation (see References [1]-[2]) implemented in a mixed MATLAB/C++ environment. The formulation carries out two velocity transformations. First the closed-loops are opened and a velocity transformation that maps relative velocities onto Cartesian velocities is introduced symbolically. Then, a second velocity transformation applied numerically on a small system of equations leads to an even smaller system of equations in the independent relative accelerations. The final set of ODEs in the independent relative coordinates is shown in Equation (1). z R R z i RTz RTd M R d R z z i R Tz τ RTz R Td Q RTz RTd TT MT R z d d
(1)
where R d represents the first velocity transformation, R z the second velocity transformation, M the inertia matrix with the origin of coordinates as a reference point for bodies, M the matrix of accumulated inertias, Q the vector of accumulated external forces, τ the vector of joint forces, T the path matrix and z i the vector of independent coordinates. The mission of the numerical integrator is to compute the evolution of the system by solving the set of ODEs, i.e., to compute the different state vectors y T z iT zT over time, for which it needs to compute the state vector derivative y T z iT z T in every time step. The graphics viewer should be capable of displaying those state vectors efficiently over time. In this work, a fourth order Runge-Kutta scheme has been used as the numerical integrator. In order to assess the performance of the implementation, a 15-dof coach model, a 17-dof Formula SAE racing car model and a 41-dof semi-trailer truck model are presented. The latter is the largest of the three, since it consists of a tractor unit and a semi-trailer, 41 degrees of freedom, 81 bodies, 89 joints and 9 closed-loop constraints. The semi-trailer suspension, as well as the suspension of the rear part of the tractor unit, consists of air springs and dampers; and the suspension of the front part of the tractor unit consists of leaf springs and dampers. The tyre contact forces are modelled through Pacejka’s formulas. All models cover a slalom manoeuvre along a flat road and they have exact suspension geometry. Due to all these characteristics, they can be considered big and complex MBS models, and they are very suitable to test the presented implementation. 2
THE GRAPHICS TOOLKIT
The OpenSceneGraph (see References [3]-[4]) is an open-source, cross-platform graphics toolkit for the development of high-performance graphics applications such as flight simulators, games, virtual reality and scientific visualization. It is based around the concept of a “scene graph”, providing an objectoriented framework on top of OpenGL. This frees the developer from implementing and optimizing lowlevel graphics calls and provides many additional utilities for rapid development of graphics applications. It is written entirely in Standard C++ and OpenGL, and makes full use of the STL and design patterns. The key strengths of OpenSceneGraph are its performance, scalability, portability and the productivity gains associated to the use of a fully featured scene graph. In more detail: - Performance. Supports view-frustum culling, occlusion culling, small feature culling, Level Of Detail (LOD) nodes, OpenGL state sorting, vertex arrays, vertex buffer objects, OpenGL Shader Language and display lists as part of the core scene graph. These together make the OpenSceneGraph one of the highest performance graphics toolkit available. - Productivity. The core scene graph encapsulates the majority of OpenGL functionality including the latest extensions, provides rendering optimizations such as culling and sorting, and a whole set of add-on libraries which make it possible to develop high-performance graphics applications very rapidly. The application developer is made lighter to concentrate on content and how that content is controlled rather than on low level coding. - Database loaders. For reading and writing databases, the database library adds support for a wide variety of database formats via an extensible dynamic plugin mechanism. The distribution now includes 55 separate plugins for loading various 3D databases and image formats. - Node kits. The scene graph has also a set of node kits which are separate libraries that can be compiled in with the user’s applications or loaded in at runtime. - Portability. The core scene graph has been designed to have minimal dependency on any specific platform, requiring little more than Standard C++ and OpenGL. This has allowed the scene graph to be rapidly ported to a wide range of platforms. - Scalability. The scene graph will not only run on portables all the way up to high end multi-core, multiGPU systems and clusters.
3
IMPLEMENTATION
The viewer has been implemented in C++ as a library. It has to carry out three main tasks. Firstly, it creates or imports the 3D models that are going to be displayed. Then, it sets the function callbacks, which will be in charge of moving the objects along the scene as the integrator computes new positions. Finally, a communication between the MBS model and the graphics viewer must be set up, so that the data can pass from one to the other. In the rest of the article, the following ideas will be distinguished: - Multibody model: multibody system. - Body: rigid body which belongs to the multibody system and whose position over time is computed by the multibody formulation. - 3D model: three-dimensional geometry object independent from the graphics viewer program and which can have any of the typical 3D modelling file formats. - Node: 3D model which has been imported by the graphics environment and belongs to the scene graph. 3.1
Management of the 3D models
The management of 3D models revolves around a configuration file called Config.txt. In it, the user specifies, through their names, which bodies wants to display in the graphics viewer. If the name coincides with any of the MBS model bodies, the graphics viewer understands that the movement of the model specified in Config.txt must be in agreement with its MBS counterpart. If the name does not coincide with any of the MBS model bodies, the graphics viewer will keep that object static along the numerical integration. This is the case of, for example, some objects like the scenery or the road. SCENERY Model 3DLANDSCAPE.ive ROAD Model 3DROAD.ive CHASSIS Model 3DBUSCHASSIS.ive R_SUPPORT Generate - Blue R_L_STAB Generate - Green R_R_STAB Generate - Green R_L_WHEEL Model 3D_R_L_WHEEL.ive R_R_WHEEL Model 3D_R_R_WHEEL.ive L_CARRIER Generate - Blue R_CARRIER Generate - Blue L_S_TRIANG Generate - Yellow L_I_TRIANG Generate - Yellow R_S_TRIANG Generate - Yellow R_I_TRIANG Generate - Yellow F_L_STAB Generate - Green F_R_STAB Generate - Green L_STEER Generate - Red R_STEER Generate - Red F_L_WHEEL Model 3D_F_L_WHEEL.ive F_R_WHEEL Model 3D_F_R_WHEEL.ive ROD_L_DIFF Generate - Red ROD_R_DIFF Generate - Red ROD_R_L_STAB Generate - Red ROD_R_R_STAB Generate - Red ROD_R_L_LONG Generate - Red ROD_R_R_LONG Generate - Red ROD_F_L_STAB Generate - Red ROD_F_R_STAB Generate - Red ROD_L_STEER Generate - Red ROD_R_STEER Generate - Red ROD_C_STEER Generate - Red
-
-
Table 1. Configuration file of the coach model.
After the body name, the user must specify which type of display wants for that body, choosing among two options. If the user has a 3D model coming from a CAD environment or a 3D model library, the next configuration field should be the keyword Model and then the name of the 3D model (in any of the file formats that OpenSceneGraph supports, preferably *.ive, *.osg o *.3ds). This way the graphics program will directly look for the model and import it. On the other side, if the 3D model is not available, the user can set the option Generate and then specify a colour, and the program will generate a simplified model made of bars taking into account the local geometry of the body. Table 1 shows an example of configuration file. The first two objects, SCENERY and ROAD, will remain static along the integration, because those names do not belong to the MBS model. The objects CHASSIS, R_L_WHEEL, R_R_WHEEL, F_L_WHEEL and F_R_WHEEL will be imported, and the rest of the objects will be generated with tubes taking into account their local geometry. Figure 1 helps to understand the differences between a generated node and an imported one. For a rapid display of the MBS, or in the case that the bodies are simple (triangles, bars, rods, etc.), a generation of the bodies would be advisable, but if the 3D CAD models are available it is better to import them, because the display will be much more realistic. With respect to the hyphens, they are fill characters necessary for the parser to read the configuration file correctly.
Figure 1. Generated model of a carrier and imported model of a tyre. 3.2
Geometric transformations
The mission of the integrator is to solve the set of ODEs in the form yield by the semi-recursive formulation, i.e., to compute the different state vectors y T zT z iT over time. As far as the graphics viewer is concerned, it has to display, with the desired rate, what the integrator has computed. To do so, the integrator will call the graphics viewer in every integration step, just after calculating the new state vector, and will pass the new state vector as a set of positions and rotation matrices of the bodies. At that point, the graphics viewer has to be able to modify the position and rotation of all nodes as fast as it can. This is done through function callbacks that are permanently waiting for new positions. As soon as a new set of positions is received, each function callback applies to its node the new position and rotation. With respect to the way in which geometric transformations are applied to the nodes, let rref be the 3x1 position vector of any reference point of the body (as long as it is the same point during the entire simulation), rref ,0 the initial position of the reference point and A the absolute 3x3 rotation matrix. The position ri of a generic point i which belongs to the body can be computed as Equation (2) shows. ri rref A(ri ,0 rref ,0 )
(2)
In practice, both the translation and rotation are assembled in a unique 4x4 matrix M that is applied to the entire node geometry and that can be written as the product of three matrices: one containing a translation of rref ,0 , another with the current rotation A, and a third one with the new translation rref . Therefore the node is firstly moved to the origin, then it is rotated and finally it is again moved to the current position, as can be seen in Equation (3).
0 M T(rref ,0 )·R ( A)·T(rref ) T rref ,0
0 A 0 0 T 1 0 1 rref
0 1
(3)
OpenSceneGraph implements matrix M as a MatrixTransform object, which is a special node that contains the information of the geometric transformation. This node is part of the scene hierarchy, in a way that all nodes below it are affected by the transformation. Considering this way of integrating the transformations in the scene graph, there are two ways of organising the nodes in the scene, which also correspond to two different ways of computing the movements of the MBS. The first is a relative organization of the transformations, in which each transformation affects to all of its child nodes. This organization corresponds to a computation of the MBS position in relative coordinates, because the geometric transformation of each joint would affect to all the following bodies in the branch of the scene tree. This type of scene tree is depicted in Figure 2.
Figure 2. Piece of a sample scene tree with relative transformations. The second option, which is the one that has been chosen in this implementation, is to apply positions and rotation matrices in an absolute way and independently to each node. In this way, the scene tree is simpler and each node only depends on one transform node which contains the information about the absolute geometric transformation (see Figure 3). Scene
Transform node 1
Transform node 2
Transform node 3
Transform node i ...
Node 1 (wheel)
Node 2 (carrier)
Node 3 (chassis)
Node i (...)
Figure 3. Piece of a sample scene tree with absolute transformations. 3.3
Architecture
The last task to be done by the graphics program is to set the link between the MBS model (MATLABbased) and the graphics viewer itself (C++ based). This is carried out by means of a MEX-function, which basically is a C++ function that can be called from MATLAB. It has two main objectives:
- Launch the graphics viewer in a different thread of the operating system, so that it does not interfere with the numerical integration. This is done through the CreateThread function of Intel’s Threading Building Blocks library (TBB). From that moment, the graphics viewer begins performing several tasks on its own, like creating the scenery, setting the callbacks and showing the graphic window, and it waits for the results of the numerical integration. - Create a pipeline with a push-pop structure that makes the role of an intermediary between both programs. When the integrator wants to display a new system position, it introduces it into a stack of positions and rotation matrices. Meanwhile, the graphics viewer pulls positions and rotations from the other side. It is worth highlighting that each pair of positions and rotations has always an associated time which follows the integrator’s scale of times, and that the graphics viewer works at all times following the processor’s scale of times. Figure 4 shows a scheme of the architecture, with the most important functions that take part in the launching of the graphics viewer, in the generation of the models, in the creation and refreshing of the window and in the creation of the pipeline and the stack of positions.
Figure 4. Graphics viewer architecture. The left part, labelled as MBS model, corresponds to the integration loop of the multibody system. Every time a new set of positions newPositions is computed, the integrator calls the MEX-function animate3D. In the first call, this function will read the configuration file with the loadConfigFile function, it will create the pipeline with the init function, and it will launch the graphics viewer with the run function executed in a new thread created with the createThread function. The central part, labelled as pipeline, represents the pipeline, i.e., the interface between the MBS model and the graphics viewer. Specifically it consists on a series of positions and rotations associated to their integration time. The number of accumulated positions will depend on the rate with which the integrator pushes them and on the rate with which the graphics viewer pulls them. The right part, labelled as 3D graphics, refers to the graphics viewer, which, as it has been said, is executed through the run function. Its main tasks are to create the root scene with the CreateScene function, to read the configuration file, to create the nodes and to set up the function callbacks. The latter will be in charge of pulling positions from the pipeline through the function pull. Moreover, the graphics viewer defines the keyboard events so that the user can handle the visualization options and, finally, it goes into the render loop called refreshViewer, which, in every step and as fast as it can, displays the current frame.
4
EFFICIENCY
The efficiency of the graphics viewer is closely related with the three tasks described in the previous section: the 3D model management, the application of the geometric transformations and the program architecture. OpenSceneGraph handles its own native 3D file formats in a very efficient way, and among them, the ive format is the most efficient one. It optimizes the information for a rapid reading, compresses the textures and stores them with power-of-two sizes. Thank to all these attributes, the models are much more efficiently loaded and transformed than the models in osg format, which is the other OpenSceneGraph binary native file format. With respect to the function callbacks that apply the movements to the nodes, there are several concepts that are related: the function callbacks refresh rate, the render rate and the integrator computation rate. The most restrictive of them is the integrator computation rate, because it depends on lots of mathematical operations, on the CPU work load and on the specific MBS model. The other two rates will always be as big as the GPU allows, and in general they are not a cause of discontinuities in the display. Finally, it is crucial to execute the graphics viewer and the MBS integration loop in different threads of the operating system, so that they do not interfere between them. If they are executed in the same thread, the MBS model would sometimes have to wait for the graphics viewer to end a task, and other times the opposite thing would happen, which would be a lose of time for both programs. It is worth making a clarification about the efficiency of the graphics viewer. Although one of the main issues in the graphics viewer development has always been the efficiency, in order to allow real-time integrations for man-in-the-loop simulations or optimization tasks, the actual fact is that currently the main use of the graphics viewer in the authors’ research group is a post-processing use. Nevertheless, the results in Table 2 show that this implementation is perfectly suitable for real-time integrations. It is quite notorious that the 3D graphics function is much quicker than a display based on MATLAB’s line functions (see Table 2). A possible explanation for this is that the GPU manages much more efficiently the triangle coordinates of the 3D models than the lines defined in MATLAB’s plots, besides MATLAB loses a long time interpreting the code. Computation time (s) Model
Without graphics
MATLAB’s graphics
3D graphics viewer
15-dof Coach 17-dof Racing car 41-dof Truck
3.062 4.484 8.481
276.4 384.9 490.1
8.860 10.17 13.58
Table 2. Computation times according to the type of graphics viewer. Table 2 shows the time spent by the simulation program in a 5-second slalom manoeuvre with the three vehicles presented in the Introduction and with the three different ways of graphically displaying the results: without graphics, with MATLAB’s graphics and with the 3D graphics viewer described in this article. It is obvious that MATLAB’s graphics are a big load for the integration, while the increase of time with the 3D graphics viewer is very reasonable. 5
DESCRIPTION OF THE INTERFACE
The interface of the graphics viewer has a visual part and a textual part, as can be seen in Figure 5. In the visual part the bodies specified in the configuration file are rendered in three dimensions along the integration time. The first execution will correspond to the real-time display of the integration results. From the end of the integration onwards, everything shown in the graphic window is post-process. The textual part of the graphics viewer informs about the integration time according to the integrator time scale, about the real time since the beginning of the integration and about the vehicle velocity.
Figure 5. Screenshot of the graphics viewer during the integration.
Figure 6. Camera modes.
In addition to this, the graphics viewer has several functions to have a better spatial perception of the simulation: - Control of the simulation. Key “p” pauses the simulation, and when it is pressed again the simulation is resumed. Key “m” toggles to slow motion, which sometimes is very useful to perceive the details and which softens the rendering. Key “r” repeats the simulation from the beginning in post-process mode, that is to say, with the information that has been stored during the first integration. - Camera. Key “c” toggles between the following camera modes: oblique side view (default), side view, top view, front view, circular travelling and free mode. The latter allows handling the camera freely with the mouse: the left button changes the orientation, the right button changes the zoom and the center wheel translates the scenery. The camera modes are shown in Figure 6. - Fill mode. Key “f” toggles between the following ways of filling the chassis node: solid (default), transparent, invisible and wireframe. These modes are very useful to notice details of the suspension and to see how it works in certain manoeuvres. Figure 7 shows these modes. - Statistics. Key “s” shows several statistics of the rendering in the top part of the window, that can be useful to evaluate the efficiency of the graphics viewer. Specifically, it shows the frame rate (rendered frames per second), the threading model (number of cores used in the rendering), the time spent in the four traversals carried out in the scene (event, update, cull, draw) and the time spent by the GPU. All times are measured in milliseconds per frame. Figure 8 shows a screenshot of the statistics.
Figure 7. Fill modes of the chassis. 6
CONCLUSIONS
This approach has proved to be a very good way of implementing a 3D graphics viewer in a MBS framework, independently of the platform and with the only requirement of having a C++ interface. Specifically, the results show how the development of the viewer on a MATLAB-based MBS framework, besides improving the aesthetic and spatial perception, enhances the graphic display of results during the numerical integration and as a post-process, and benefits the efficiency of the global program against native MATLAB plotting functions. This effectiveness makes graphics viewer suitable for real-time simulations and allows carrying out realistic visualizations of MBSs in a simple and versatile way.
Figure 8. Rendering statistics. REFERENCES [1] GARCÍA DE JALÓN, J., ÁLVAREZ, E., DE RIBERA, F. A., RODRÍGUEZ, I., AND FUNES, F. J. A fast and simple semi-recursive dynamic formulation for multi-rigid-body systems. Advances in Computational Multibody Systems, Ed. by J. Ambrósio, Springer-Verlag (2005), 1-24. [2] GARCÍA DE JALÓN, J., HIDALGO, A. F., AND CALLEJO, A. MBS software development with Matlab for teaching and industrial usages. Proceedings of the ASME IDETC/CIE Conference, San Diego, 2009. [3] Introduction, OpenSceneGraph web page, http://www.openscenegraph.org/projects/osg/wiki/About/ Introduction, 30th of March, 2010. [4] MARTZ, P. OpenSceneGraph quick start guide - A quick introduction to the cross-platform Open source Scene Graph API. Skew Matrix Software LLC, 2007.