Overview
As you have read in the Introduction, MIRA provides a middleware that handles the communication between the modules - or respectively the "units" as we call these modules from now on - and ties these units together to compose a complex application.
Beside this communication, the MIRA base and framework provide much more functionality that is realized using a couple of concepts and technologies, that are introduced on this page.
Technologies
In the following the core technologies are briefly described that are used to implement the concepts listed in the sections below. If you are new to MIRA and need a further overview, you can skip this section for the moment and continue reading the concepts starting with the next section.
- Class Factory: The class factory allows the construction of objects by their unique class identifier at runtime. This technique is the base for other techniques like serialization and the used plugin concepts. The class factory is aware of all classes that are specified in so called Manifest files that come with each Library.
- Serialization: Serialization allows the storage of data structures or objects in files or transmitting them to other computers. The used serialization and reflection technique allows to integrate the ability for serialization into any class or struct in a very easy way. Afterwards, every "reflectable" class can be configured via parameters, recorded as data into a tape file, transmitted to another computer, it can be easily registered as RPC service or used as parameters in remote procedures, and its values and properties can be changed live at runtime without any additional changes or additional techniques.
- Names: Names are used to identify Channels, Services, Authorities, and Units. For unique identification a hierarchical naming scheme with namespaces is used that is similar to URLs.
- Error Monitoring: In a complex and modular software architecture it can be difficult to identify problems. For this reason there are several classes for error monitoring and diagnostics help to identify and track problems.
Structural Level
The structure of MIRA can be visualized as follows:
The MIRA core is divided into the following software components:
- Base: The base is a core component that provides many commonly used classes, algorithms and helpers that are used by other components.
- Framework: The Framework is the second core component providing a middleware that implements the publisher/subscriber pattern to provide the functionality for different software modules to communicate with each other.
- GUI: The GUI component contains elements and classes for creating visualizations, widgets and tools that allow the user to visualize and manipulate data within the framework, units and other components of the robotic applications. It moreover contains the Rich Client Platform (RCP) which is the core of the modular GUI design.
Beside these core components, other elements like Plugins, Units, or Visualizations are located in Toolboxes and Domains.
- Toolboxes: Toolboxes contain algorithms and classes that are used directly by other components like domains, other toolboxes or stand alone applications and thereby allow code sharing (Tight Coupling). Dependency to the Framework should be avoided in toolboxes when possible but is allowed.
- Domains: Domains contain one or more units that may be used by other components like the application layer to build a complex application. Components of different domains may interact with each other (using the communication mechanisms) but must NOT use each other directly to avoid unwanted dependencies between domains (Loose Coupling).
All components within the Toolboxes and Domains are organized in Packages.
- Packages: Packages are collections of components (e.g. plugins, units, views, data files, etc.). Each package contains meta information describing its content and dependencies to other packages and components.
Component Level
Each component of an MIRA application that is written in C++ is compiled into a binary. In contrast, components that are written in a script language (e.g. Python) are interpreted directly from their source code. However, in both cases we can differentiate between components that are "Executables" and "Libraries".
- Executable: An executable is a file that can be executed by the processor or a script interpreter to perform indicated tasks according to encoded instructions. For execution of the encoded computer program a new process is instantiated.
- Shared Library: A library formally is a collection of functionalities that can be loaded by an executable. The executable is then able to access the functionalities within its process.
- Manifests: Manifests are files that are automatically generated with each shared library. They contain meta information on the library and the classes that are contained in the libraries. These manifest files are used by the class factory to keep track of all existing classes.
- Plugins: MIRA uses shared libraries to achieve a plugin mechanism, where each plugin is a shared library, that can be loaded dynamically at runtime. This is done by the class factory whenever a class is instantiated that is located in a library that is not yet loaded into the process of the current application.
Computation Graph Level
- Units / MicroUnits: Units are the modules of the modular application, that perform the actual tasks and computations. They implement the algorithms, e.g. for path planning or localization. Units are implemented as shared libraries. They are loaded and instantiated and finally executed when a configuration file is launched by the mira or miracenter tool.
- Channel: Channels provide an efficient way for units to communicate with each other. Each channel has a type and a unique name. A unit can publish data on a channel, while another unit can receive that data if it is subscribed to the channel. There can also be multiple publishers and subscribers for a channel. Channels automatically take care of thread synchronization and inter-process communication. Hence the communication is fully transparent for the units, no matter if they are located within the same or different process.
- Remote Procedure Calls / RPC: Remote Procedure calls are the second mechanism that can be used by Units to communicate with other components. They are suitable for "request - reply" interactions. A unit can be turned easily into an RPC service by offering its methods for remote calls using MIRA's reflect mechanism.
- Authorities: Authorities allow access to the above communication facilities of the framework. Each Authority has a unique name and may reside within a namespace. The aforementioned Units are Authorities themselves. However, using the Authorities directly, the features of the framework can also be used without Units. Additionally, each Authority provides its own thread for processing RPC calls and callbacks on subscribed channels.
- Transform: The transform framework manages all different coordinate frames of a robot and their relation to each other. Similar to a scene graph, the coordinate frames are stored in a tree-like structure. The transform framework allows to query the relative transformation between two arbitrary frames while taking the time stamps of the transforms into account.
Runtime Level
- Executable: An executable is a file that can be executed by the processor or a script interpreter to perform indicated tasks according to encoded instructions. For execution of the encoded computer program a new process is instantiated. The executables are build and linked by the compiler and can be found - after a successful build process - in the "bin" directory of your MIRA project.
- Shared Library: A library formally is a collection of functionalities that can be loaded by an executable. The executable is then able to access the functionalities within its process. The libraries are build and linked by the compiler and can be found - after a successful build process - in the "lib" directory of your MIRA project.
- Process: Each executable that is launched by the user is executed in its own process. All modules in a process can share memory and other resources while different processes do not share the same resources. A process has typically a main thread but there can be multiple threads in one process.
- Thread: A thread of execution is the smallest unit of processing that can be scheduled by an operating system. On most systems threads are contained in processes. Multiple threads in the same process can share resources. When using multiple threads one must regard the rules for multithreaded programming like protecting memory from concurrent access. However in MIRA we tried to free the normal user from this burden.
Filesystem Level
- Projects: A Project forms a collection of tools, Toolboxes and Domains that are somehow related (e.g. grouped by user/author, grouped by repository...) Each Project can be built separately and must be part of the MIRA_PATH environment.
- Directory Structure: MIRA is organized in Projects that contain Tools, Toolboxes and Domains. These Projects and its contained modules follow special directory structure guidelines.
- Packages: Packages are collections of components (e.g. plugins, units, views, data files, etc.). Each package contains meta information describing its content, dependencies to include paths, library paths and libraries as well as its dependencies to other packages.
- Toolboxes: Toolboxes contain algorithms and classes that are used directly by other components like domains, other toolboxes or stand alone applications and thereby allow code sharing (Tight Coupling). Dependency to the Framework should be avoided in toolboxes when possible but is allowed. Toolboxes are located in the "toolboxes" sub-directory of a Project.
- Domains: Domains contain one or more units that may be used by other components like the application layer to build a complex application. Components of different domains may interact with each other (using the communication mechanisms) but must NOT use each other directly to avoid unwanted dependencies between domains (Loose Coupling). Domains are located in the "domains" sub-directory of a Project.
Repository Level
- Repositories: Repositories are storage locations from where Packages can be installed e.g. by using mirapackage. Currently mirapackage supports SVN, FTP and local repositories (can be extended via plugins) for downloading either the source files or binary versions of packages.
- Source / Binary Distribution: Each package is available as binary format, as source files or both. Binary distributions are executables or libraries which are already built for a target operating system. Source distributions can be built by the user on supported target systems.
- Packages: Packages are collections of components (e.g. plugins, units, views, data files, etc.). Each package contains meta information describing its content, dependencies to include paths, library paths and libraries as well as its dependencies to other packages. Each package can be installed and updated separately and there can be multiple versions of the same Package.