Open Digital Twin Interface

Version 1 - Connecting Digital Twin design and simulation applications

Exchanging data between design and simulation tools is not always easy. Even though we are in the times of Industrie4.0, the data exchange from the CAD system to different simulation tools is mostly based on Step. All additional information about kinematics (design structures are often not kinematic oriented), sensors and actuators are lost.

The idea of the Open Digital Twin Interface is to make it relatively easy for any external system to send extended data beyond the design to and from realvirtual.io. Other systems are also invited to use this open standard. The goal is that with some macro programming within the CAD system, an exporter can be easily created.

The data structure of the Open Digital Twin Interface consists of a relatively simple and readable JSON which transmits additional information to the 3D data. The 3D data can be designed as JT, Step, OBJ or FBX. An exporter from the CAD system is therefore relatively simple, since usually one of the formats can already be written by the CAD system. The data in the JSON references elements contained in the CAD data and thus supplements them with additional information on drives, kinematics and sensors.

If required, additional individual properties can be attached to the JSON objects, but their interpretation must then be implemented individually. Realvirtual.io Professional implements the standard described here.

The OpenDigitalTwin interface is a result of ITEA Project AITOC (https://aitoc.eu).

This is our example model from which the JSON data (see below) was generated:

Why not AutomationML or the Asset Administration Shell?

You may object that this is exactly what AutomationML or the Asset Administration Shell are for. From our point of view AutomationML is too complex to write an exporter from the CAD system. The XML structure is very difficult to understand, exporters are hardly available and even exporting Collada from the CAD system is an extremely high development effort.

The Asset Administration Shell, on the other hand, tries to describe all aspects of a digital twin in data terms, the kinematics, sensor and actuator side for simulation environments plays only a minor role. Also the format is relatively complex.

So we where looking for a simple solution that "everyone" can implement. Not something which covers everything, but something that is simple and offers the most important things.

Supported se cases

The Open Digital Twin Interface supports the following use cases

  • Offline (file-based) export of 3D and kinematic data from other systems, e.g. the design system

  • "Live-Link" with the CAD system, i.e. data is transmitted in the background, e.g. via TCP-IP, and is automatically updated in the scene

  • Creating signals in Unity Editor mode

  • Setting signals in simulation mode (like other realvirtual.io automation interfaces)

  • Reading signals in simulation mode

  • Connecting signals to components on objects (e.g. to connect a PLCOutputSignal to the Motors behavior model and its property DestinationSpeed)

  • Instantiating new objects in the digital twin model

  • Setting properties on components in the digital twin model

Optional properties

A lot of properties are optional and does not need to be transferred. E.g. if you would like to only read and write signal values from and to realvirtual.io you could create the OpenDigitalTwin class and inside this class you could only set the property Signals and the Signals array itself within the class signals.The rest of the OpenDigitalTwin class properties (parts, assembly, kinematicassembly and so on) stay null. Or you could only instantiate the class Parts if you only would like to transfer 3D Data and the Part hierarchy to realvirtual.io.

Basic concepts

Separated assembly and kinematic structure

CAD designs are mostly not kinematic structured. Therefore, the KinematicAssembly optionally builds a parallel kinematic structure. Each part in the design structure can be assigned to an element Kinematic in the KinematicAssembly. Drives and Sensors can be attached to the Assembly as well as to the Kinematic Structure.

Transforms (Positions and Rotations)

A transform contains the position and rotation, always in the global coordinate system related to the zero point of the Assembly and KinematicAssembly. Assembly and KinematicAssembly must have the same origin as the exported 3D data. Directions of drives and sensors are always referenced to the local coordinate system to which the drives or sensors are assigned.

Referencing 3D Data

Each part in the assembly structure can reference a construction element in the exported 3D data file (partfile and partcomponent). If partcomponent is empty or null, then the entire 3D data is assigned to the part in the assembly. So it is possible either to export all 3D data in one export, e.g. as Step, and then to reference them in the assembly structure or to export one 3D file (partfile) per assembly level.

Objects, Components and Properties

The entire digital twin is build by a hierarchy of objects. Each object can have multiple child objects. Each object only has one parent object. Objects including the hierarchy could be imported into the digital twin by importing Part Assemblies or Kinematic Assembly. So a Kinematic as well as a Part is an object in the hierarchy. Each Object itself can have different components on it. A component can be for example a drive, a sensor or a behavior model. The component (itself) has different properties which are defining the behavior of the component. A very special property of a component is a Signal. It is possible to connect signals in the signal list with the behavior behavior models (components) on the object.

Another way for creating Objects inside of the model is to instantiate new objects based on so called Prefabs. Prefabs are blueprints for simple or complex objects). With the Open Digital Twin Interface you could create new objects at certain positions and afterwards set properties of these components.

Licensing, Usage

We release the Open Digital Twin interface under MIT license. The import and export functions in realvirtual.io Professional itself are subject to the realvirtual.io license terms. Every user and CAD manufacturer is invited to use the Open Digital Twin Interface. If you want to become an official supporter, you will get a license realvirtual.io for testing and development purposes and support from our side for free. If you are interested, please send a mail to info@realvirtual.io.

Transport layers in realvirtual.io for the Open Digital Twin Interface

realvirtual.io is implementing three different transport layers for importing and exporting the OpenDigitalTwin data.

These layers are file based (JSON and CAD-Date), TCP-IP (realvirtual.io will be a TCP-IP server) and MQTT. All interfaces are going to run in Unity Editor mode as well as in playmode.

The interfaces are currently in development. More information will follow soon.

C# Classes

The following C# class structure can be used to serialize JSONS in the OpenDigitalTwin format or to get from a JSON back to the class structure. We have explained the most necessary in the source code, more explanations will follow here soon.

///  OpenDigitalTwin class definition version 1
///  Copyright (c) 2022 realvirtual.io - In2sight GmbH
//   MIT License
//   Permission is hereby granted, free of charge, to any person obtaining a copy of this source code, to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//   THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

namespace OpenDigitalTwin
{
    public class OpenDigitalTwin  // the frame classs, all components are optional, e.g. it is possible to import, read and write only signals without sending or receiving the other properties
    {
        public Header header;
        public Assembly assembly;
        public KinematicAssembly kinematicassembly;
        public Signals signals;
    }

    public class Assembly // The cad Assembly of parts - the structure the designer used in the cad system - very often not kinematic structured
    {
        public List<Part> parts;
    }
    
    public class Part // the part inside an Assembly which has a global position and rotation in relation to Assembly origin point, referencing to a part fild
    {
        public string id = "";
        public string partname="";
        public string occurenceid ="";
        public string partfile =""; // can be collada, jt, step, obj
        public string partcomponent =""; // can be a valid path /assembly1/subassembly/part if only a part of the partfile is a representation of the part (if just one file is exported) or keep it empty if the partfile ia a full representation of the part
        public string lastchange="";
        public string parentid="";
        public string kinematicreference=""; // optional -references this part into a structural level in the kinematics hierarchy, multiple parts can be assigned to the same kinematic reference (kinematic reference does not needs to be unique in the part structure)
        public List<string> materials; //optional - if not defined standard materials of partfile import are used
        public Transform transform;
        public Drive drive; //optional - Drive might be also attached in kinematic chain
        public Sensor sensor; //optional - Sensor might be also attached in  kinematic chain
        public string behaviormodel=""; // optional - might be used for attaching automatically for example FMUs
    }
    
    public class KinematicAssembly // a kinematic Assembly, parts can be linked to single compontents in kinematic chain
    {
        public List<Kinematic> kinematics;
    }

    public class Kinematic // a single kinematic component in the kinematic chain
    {
        public string id=""; // might be referenced by a part
        public string kinematicname = "kinematic"; // name of the structural component in the kinematic chain - is NOT unique and not referenced - just for information
        public string kinematicreference=""; // the kinematic referance of this kinematic component - needs to be unique in the kinematic chain 
        public string parentid=""; // the parent kinematic component
        public Transform transform;
        public Drive drive; // optional
        public Sensor sensor; // optional
    }

    public class Header // the header info for Assembly and kinematic Assembly  
    {
        public string reference = ""; // a reference for the digitaltwin interface 
        public int odtversion = 1; // version of odf file definition, currently 1
        public string lastchange=""; // optional
        public string cadystem=""; // optional 
        public string csys=""; // lefthanded / righthanded
    }

    public class Signals  // a list of all automation signals
    {
        public List<Signal> signals;
    }
    
    public class Transform // the global position and rotation in relation to Assembly origin point
    {
        public float posx;
        public float posy;
        public float posz;
        public float rotx;
        public float roty;
        public float rotz;
    }
    
    public class Drive // Drives can be connected to assemly hierarchy or kinematic hierarchy
    {
        public string type=""; // "linear, rotational,linearsurface,rotationsurface"
        public string direction="x"; // "x,y,z" in local coordinate system
        public float maxspeed=0; // optional
        public float maxacceleration=0; // optional
        public float lowerlimit=0; // optional
        public float upperlimit=0; // optional
        public string behaviormodel = ""; // optional e.g. for defining FMUs or realvirtual behavior models
    }
    
    public class Sensor  // a sensor which can be connected to assembly or kinematic hierarchy
    {
        public string direction = "x"; // "x,y,z" in local coordinate system
        public float length; // the length of detection, a sensor is a straight line (raycast) from the origin point of the part or kinematic transform
        public string behaviormodel = ""; // optional e.g. for defining FMUs or realvirtual behavior models
    }
    
    public class Signal  // a signal for reading and writing signals, if a signal list is send on edit mode the signals are created if not existing
    {
        public string signalname = "";   // signalname needs to be unique
        public string internalname = ""; // optional, if internalname empty than it equals signalname, for some interfaces (e.g. SiemensS7) internal name needs follow certain conditions to be a hardware adress
        public string folder = ""; // optional, if given certain hierarchy / folder path or organizing the signals
        public string direction = "input"; // input,output
        public string type = "bool";  //bool,int,float,text
        public string comment ="";
        public string value;
    }
}#

Example JSON

This is a part of the resulting JSON as an example.

The full json can be found here:

Change notes

16.10.2022 - added optional classes for connections (connecting signals to components), instantiations (creating prepared objects on certain positions) and opbject properties (reading and writing object values)

Last updated