Three-dimensional visualization in simulators of rolling stock based on the OpenSceneGraph engine
A little less than a year ago, a publication was published, where we talked about the training and laboratory complex (ULK) of the EL1 Lastochka electric train, developed by our university. Then I promised that this would not be the last publication on this topic, in particular, I threatened to talk about the problems of creating three-dimensional visualization for simulators of this kind and to outline the main approaches to their solution.
The past year has pleased us with yet another release - ULK of high-speed electric train EVS2 “Sapsan”, which took place back in August last year. By itself, the educational and laboratory complex of this electric train deserves a separate story, but in the context of this publication we will discuss the painful problem of creating an adequate subsystem of three-dimensional visualization, which our team has approached from different sides for about two years. The release of the Sapsan simulator is significant (among other things) by the fact that it determined the vector of development of our developments in this area.
1. Briefly about ULC EVS2 “Sapsan”
I want to emphasize once again (which I do with enviable periodicity) that the training and laboratory complexes of rolling stock developed at our university are not intended to train locomotive brigades. As one of the commentators of the previous article rightly noted , our ULCs are not simulators, but simulators, where the main emphasis is placed on the competent implementation of the physics of train movement and modeling the operation of rolling stock subsystems ensuring its movement and stopping. The Sapsan simulator is not an exception, where the following tasks are solved: ')
Implemented a dynamic model of the mechanical part of the train, taking into account the longitudinal forces and the profile of the track
A detailed computer model of the operation of the key subsystems of an electric train has been built: a power electric circuit, a traction electric drive, pneumatic and electropneumatic brakes
Reproduced the main algorithms of the electric train control system at different levels
In addition, the educational and laboratory complex includes a full-size model of the electric train's cabin with the main controls and information display facilities. Unlike the Swallows simulator, this cabin was not made by us independently, but was acquired in 2015 from one of the well-known in our country offices engaged in the production of training simulators. Therefore, in the process of developing a simulator focused on creating software.
Cab photo
General view of the cabin interior
View through the windshield
Display of the integrated locomotive safety device (CLUB-U).The red “290” is the current speed limit received from the CLUB-U e-card.For the time being, the maximum speed achieved by the Sapsan on the Oktyabrskaya railway is adorning here.In the future, the electronic map will be implemented as it is done in life.
Main display "Human Machine Interface"
Display showing the state of the brake system of an electric train
Speed ​​adjuster and traction controller
Electric Train Brake Controller
Toggle switches for control of current collectors and protection devices (BV / GV) - black toggle switches near the speed limiter
Mileage counter.A funny story is connected with his appearance.When we handed over our first diesel locomotive simulator 2TE116, to our question when the certificate of completion would be signed, the customer’s representative joked: “Well, let's do it in life - when entering a new locomotive into operation, it must pass 5,000 km.That will pass ... ".The act of course was signed much earlier, but we, having assessed the humor of the situation, made a similar counter already on the Swallows simulator.The counter can be reset to “0” by entering the service password.
Right auxiliary panel with control gauges brake system and emergency brake valve.Not all the elements inherent in the present Sapsan are installed here - we received such a remote control from the supplier.
Therefore, some of the critical for us controls were implemented by software, in particular, the panel of bypass switches, controlled from the touch display
Software development of such a simulator simulator is a very broad question, and I will try (to the best of reason) to satisfy readers' interest in these issues in the future (if any), but for now, let us return to the main topic of the article - three-dimensional visualization of the train movement process.
2. Background and technology of the past
In the comments to the previous article , a question was asked which, I confess honestly, pretty much amused me. Yes, indeed, in many simulators still in operation today, the following approach is still used: video is shot on the real section of the railway and then scrolls on the simulator at a speed proportional to the speed of movement. They did this only because in those early times, when such simulators were created, the quality of three-dimensional graphics left much to be desired, and this applied to harsh graphic stations on commercial Unixes, and the PC was out of the question. Therefore, even manufacturers of computer games, for example , this one , did not disdain to use this approach.
Today it does not make sense, because:
Insufficient frame rate at low train speeds does not provide the desired smoothness of updating the picture. The cherished 25 fps we will have only at the speed at which the video from the driver’s cab was filmed. And this fatal flaw cannot be overcome - either by shooting with a high-speed camera (how much will the video shot at 120 frames per second weigh? That's the same ...), or by software generation of intermediate frames. The latter was undertaken by us using the OpenCV technology, but did not lead to normal results. This question was repeatedly worked out from all sides and as a result it was concluded that the costs of creating such a system far exceed the development of a similar system, but based on 3D graphics
Difficulties with smooth scrolling video back. And even considering that they will be overcome, then where the dogs running along the platform will run, can we even think about going backwards?
The lack of all "interactivity". How to deal with a change in the signal of a traffic light, with the movement of turnouts, the movement of oncoming and passing trains?
Therefore, all modern simulators and simulators are created using interactive 3D-graphics, the benefit today there are no obstacles either from a software or from a hardware point of view.
If from a hardware point of view, everything is extremely clear - a monitor installed instead of a windshield is connected to a PC with a normal video card (not even the top one), then from a software point of view it is a question of choosing a technology to implement the task.
3. Graphics engine versus game engine or why OpenSceneGraph was chosen
I can be mistaken, but I anticipate comments in advance, in which a completely logical question will be asked, why didn’t our choice analyze such mastodons like Unity or Unreal Engine 4 when analyzing existing technologies? I will answer this question, moreover, I substantiate my answer.
In short, neither Unity nor the Unreal Engine satisfies the requirements of the problem to be solved. A more detailed answer provides, first of all, the enumeration of the requirements in question. The TK compiled by us for the three-dimensional visualization subsystem includes (in decreasing order of importance) the following provisions:
The independence of the software development process of the visualization subsystem and the process of creating resources for it. Resources, in this case, include three-dimensional models, textures, as well as the so-called routes . A route is a set of configuration objects and resources that allow a video subsystem to display the desired section of the railway and provide a simulation of train movement on it. This also includes the possibility of changing the route without rebuilding the software part of the video subsystem.
Creating routes of unlimited length. I will make a reservation that unlimited length is in principle unattainable due to limited hardware resources. This requirement should be understood that the length of the route should be at least within one “shoulder”, that is, the section of the road between revolving points, and this, depending on various factors, is a sufficiently large distance, calculated by more than one hundred kilometers. This requirement imposes the need to provide dynamic loading / unloading of program resources with sufficient smoothness with reasonable memory consumption. And it is desirable that the engine contains such functionality "out of the box"
Convenient integration with used technology stack. Traditionally, due to objective reasons, our team uses C ++ language with Qt framework, IDT QtCreator, and Git as the version control system. As a system platform, ULK PS uses the OS based on the Linux kernel.
What is wrong with Unity and UE? What is the fact that the other engines are able to import resources of completely different formats. However, when assembling a project, they are irreversibly transformed into an internal binary format, which makes it impossible to add and change resources without re-assembling the project. Technologies like prefabs and asset bundles available in Unity do not solve the problem, as the engine editor is not the best place to create railway locations, which is why the need for an editor extension arises, which leads to the need to write “engine inside the engine”. In addition, the creation of prefabs and bundles is impossible without the use of the Unity editor, and this, as practice has shown, is not very convenient, especially for pure modelers and level designers. As for the UE, and in this and other resources for two years I asked enough questions about how to separate the project build process from the process of adding / changing the resources used by it, and I did not receive an adequate answer either in the documentation or from hardened "gamedevelopers. I would be very happy (without sarcasm) if I reasonably stumble with my nose into something that I missed.
As for the second requirement, both Unity and UE seem to provide the ability to create dynamically loaded locations, but the question remains: how can such locations be created independently of the editor without rebuilding the project? Only one way out - to write a “engine inside the engine”, which will load the “raw” (in any of the predefined export format from 3D editors) geometry and textures, apply all the necessary effects to them and position in space based on the data described in the external A format independent of the engine that needs to be further developed and taught the engine to interpret it.
In connection with the above, the question arises - if to solve the problem it is necessary to write a powerful software layer over the game engine, most of the functionality of which is simply not needed in the task in question, then why do we need a game engine?
Maybe enough graphics engine? I asked this question to the previous team, which took up the problem under discussion, relying on Unity (and naturally merged a bit later). In response, I received a counter question: “What do you propose?”, Answering which, in the spirit of the above text, received an opponent’s sarcastic smile.
If we do without sarcasm, then the presented task is a typical visualization task - here only a framework for working with graphics is required, since both physics and audio subsystem, based on physics, are implemented on the server side. My team and I came to understand this fact, moving by the inertia of previous developers, first towards Unity, through the UE and trying to fasten the graphics subsystem from the open railway simulators (OpenBVE, which by the way turned out, but became a temporary crutch)
OpenSceneGraph is by far the most advanced (open and free) graphics engine, focused on C ++ development. It is widely used abroad for technical three-dimensional visualization. This engine is not spared, and all sorts of simulator, the most famous of which - FlightGear . There was once a railway simulator based on this engine - Indra , from which, however, there were only dull screenshots of the above link and its further fate is unknown to me.
In the context of the problem being solved, the OSG graphics engine has the following positive qualities:
Cross-platform, which makes it possible to apply it in the GNU / Linux ecosystem
The C ++ / STL development language, which makes it easy and natural to integrate it into the development process established in our team;
The widest range of supported out of the box resource formats - 3D geometry and textures due to an advanced plugin system. A simple and intuitive interface for writing your own plug-ins to configure the resource manager for non-standard formats, which we used (I will write about this below);
A memory management system based on a proprietary model of smart pointers (the proprietary format of smart pointers has been used historically, due to the fact that there was no smart pointer in the C ++ standard at the beginning of the development of the engine);
Flexible modular architecture;
The scene object manager, which dynamically loads objects, provides for loading and drawing only those objects that fall within the clipping pyramid (due to the class osg :: PagedLOD)
Ability to integrate with the Qt framework. Thanks to the convenient “signals-slots” model provided by Qt, which significantly simplifies and accelerates development in C ++, we widely use this framework for developing software for training complexes. Accordingly, we have accumulated a significant code base reused in various projects, especially with regard to the interprocess communication library based on TCP sockets. Using Qt features in the video subsystem project seems to be a logical decision;
Quality of a picture, sufficient for the solved task.
It took about six months of intense study of the possibilities of OSG in order to thoroughly "test the ground" and find approaches to solving the problem with the help of this engine. What was born as a result deserves a separate discussion.
4. From architecture to working prototype
The video subsystem of the rolling stock simulators (HTSC) is a client application, commonly referred to as video3d-client, and performs the following functions:
A request to connect to the server part of the simulator, authorization on the server with a subsequent periodic request for the identifier of the loaded route, and then the current train position. When the connection is broken by the server, the transition to the standby mode, the possibility of reconnecting
Loading the selected route; organizing dynamic management of the contents of the rendered scene;
Actually rendering the scene in accordance with the current position of the train on the route
Not that this project was opensource, but it is quite possible to get acquainted with the code of a full-featured technology demo here . The project consists of the following modules:
filesystem - a library for working with the file system; it provides the generation of paths to configuration files and application resources
library - cross-platform implementation of a dynamic library loader. In general, a crutch written at a time when the possibilities of integration with Qt (where there is a QLibrary module ready for battle) were still vague
osgdb_dmd - plugin for loading models of a format specific for the DGLEngine engine version 1.1. What it took, I will explain below
route-loader is a library that provides an abstract interface to the route loader. The possibility of loading routes of arbitrary format is assumed.
tcp-connection - interprocess communication library via TCP sockets
viewer - the main executable module of the program
zds-route-loader - plugin for downloading ZDSimulator format routes
When designing VTPS, the question of choice arose: to develop the format of routes independently, or use the existing format of routes, as well as ready-made routes of domestic railways for the existing railway simulator. Fortunately, the decision turned up - a closed proprietary product ZDSimulator , which has the peculiarity that it is sharpened by domestic rolling stock and the specifics of the railway network. Despite the boast of the authors of the project, it has a lot of significant drawbacks, but it also has a simple and clear format of routes that are publicly available. At the first stage, it was a sin not to use the available opportunity, despite the fact that the graphic part of the simulator is based on the open engine DGLEngine. The trouble is that this engine is developing (though the current state of the project can be seen here ), but its current second version is incompatible with version 1.1, on which the ZDSimulator is based. The source code of version 1.1 has been lost, the links leading to them have long been rotten.
A thorough search in the web archive made it possible to find the lost and save by posting DGLEngine v1.1 on Gtihub. This engine uses its own specific format of 3D models. Having the source of the engine it was not difficult to write the appropriate plugin for OSG.
Thus, the task of creating the VTPS has been reduced to writing the program part on the OSG engine. In the future, it is planned to develop a proprietary route format, since the current format provides for movement only along the main routes and has several disadvantages that do not allow recreating a number of complex routes.
The hierarchy of the main classes of HTSC is presented in the following diagram.
The class hierarchy of route loader looks like this.
The loader of any other route format can be written as a plugin containing a class that inherits from the RouteLoader class. When the VTPS starts, it receives the path to the directory with the route, determines the format of the route, and dynamically loads the corresponding plug-in that performs the rest of the dirty work.
A fundamentally important nuance was the integration of the OSG engine and Qt. This integration exists and is called osgQt . This library is not used in this project for two reasons:
No need for window controls provided by Qt. OSG has its own fairly well-developed GUI window management system and it makes no sense to build a GUI on top of another GUI, since osgQt is intended primarily for integrating the OSG viewer into a GUI based on Qt
osgQt is bug-prone - incorrect work with the OpenGL context, which in some cases it cannot divide between OSG and QGLWidget, because of which the scene is displayed anywhere, just not on the Qt widget. Moreover, it has not been possible to find reasons yet, since on some systems this bug does not manifest itself.
There was an understanding that integration with Qt is necessary in terms of using the “signals-slots” concept to ensure interoperability with the tcp-connection network subsystem that uses Qt and is the de facto standard in our developments. I didn’t want to rely on the OSG messaging system and re-write a TCP client (and even a cross-platform one). There was an elegant solution based on the fact that if we want one object to send a signal that triggers a slot to activate from another object, we must fulfill three conditions:
Inherit QObject Interactive Classes
Arrange a signal processing loop
Create an instance of the QApplication class (or QCoreApplication) that exists in memory during the operation of the application
In this case, by no means should you make a call to QApplication :: exec (), which starts a regular signal processing cycle, it is enough to organize a cycle in which you simply process the signals with a call to QApplication :: processEvents (). In OSG, such a cycle exists (the cycle in which rendering is performed) and it is possible to create an event handler in which the event osgGA :: GUIEventAdapter :: FRAME is processed, which is generated by the engine when rendering the next frame. Thus, the whole integration has been reduced to code
#include"main.h"/*! * \fn * \brief Entry point *///------------------------------------------------------------------------------ // //------------------------------------------------------------------------------ int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); RouteViewer viewer(argc, argv); if (viewer.isReady()) return viewer.run(); return 0; }
after that, classes inherited from QObject and its derivatives can exchange signals before the loss of pulse.
All of the above allowed in two months to create the first working prototype of the VTTS. To demonstrate what happened in the end, I propose the following thread from experienced trips along real routes. I apologize in advance for the quality of the shooting - they did not get hold of a sensible technique.
Conclusion and conclusions
The main conclusion, at least for our team, was that the “seryabryannoy bullet” does not exist in the choice of technology for the implementation of the project. Game engines aggressively promoted to the market are not always suitable for solving specific tasks, such as the visualization of simulation results of technical systems. And if they are suitable, they are not optimal in terms of the effort spent on developing and supporting the project.
It's a shame that a very good, and most importantly free, OSG graphics engine in fact does not have a community in our country. In order to fix this problem, I write a series of articles here on the resource (there I collected all the links to more or less adequate sources of information, including in Russian). In addition, as a documentation describing the basic principles of OSG I can offer this blog as well . I hope that this information will be useful to someone.
As for the VTPS, the work in this direction continues. The next step is still a lot of important tasks to be solved in the near future.