
Space engineering
Simulation modelling platform
Foreword
This Standard is one of the series of ECSS Standards intended to be applied together for the management, engineering and product assurance in space projects and applications. ECSS is a cooperative effort of the European Space Agency, national space agencies and European industry associations for the purpose of developing and maintaining common standards. Requirements in this Standard are defined in terms of what shall be accomplished, rather than in terms of how to organize and perform the necessary work. This allows existing organizational structures and methods to be applied where they are effective, and for the structures and methods to evolve as necessary without rewriting the standards.
This Standard has been prepared by the ECSS-E-ST-40-07C Working Group, reviewed by the ECSS Executive Secretariat and approved by the ECSS Technical Authority.
Disclaimer
ECSS does not provide any warranty whatsoever, whether expressed, implied, or statutory, including, but not limited to, any warranty of merchantability or fitness for a particular purpose or any warranty that the contents of the item are error-free. In no respect shall ECSS incur any liability for any damages, including, but not limited to, direct, indirect, special, or consequential damages arising out of, resulting from, or in any way connected to the use of this Standard, whether or not based upon warranty, business agreement, tort, or otherwise; whether or not injury was sustained by persons or property or otherwise; and whether or not loss was sustained from, or arose out of, the results of, the item, or any services that may be provided by ECSS.
Published by: ESA Requirements and Standards Division ESTEC, P.O. Box 299, 2200 AG Noordwijk The NetherlandsCopyright: 2020© by the European Space Agency for the members of ECSS## Change log
|
ECSS-E-ST-40-07C
|
First issue
|
Introduction
Space programmes have developed simulation software for a number of years, which are used for a variety of applications including analysis, engineering operations preparation and training. Typically, different departments perform developments of these simulators, running on several different platforms and using different computer languages. A variety of subcontractors are involved in these projects and as a result a wide range of simulation software are often developed. This standard addresses the issues related to portability and reuse of simulation models. It is based on the work performed by ESA in the development of the Simulator Model Portability Standards SMP1 and SMP2 starting from the mid-end of the nineties.
This standard integrates the ECSS-E-ST-40 with additional requirements which are specific to the development of simulation software. The formulation of this standard takes into account:
The existing ISO 9000 family of documents, and
The Simulation Model Portability specification version 1.2.
The intended readership of this standard is the simulator software customer and supplier.
Scope
ECSS-E-ST-40-07 is a standard based on ECSS-E-ST-40 for the engineering of simulation software.
ECSS-E-ST-40-07 complements ECSS-E-ST-40 in being more specific to simulation software. Simulation software include both Simulation environments and simulation models. The standard enables the effective reuse of simulation models within and between space projects and their stakeholders. In particular, the standard supports model reuse across different simulation environments and exchange between different organizations and missions.
This standard can be used as an additional standard to ECSS-E-ST-40 providing the additional requirements which are specific to simulation software.
This standard may be tailored for the specific characteristic and constrains of a space project in conformance with ECSS-S-ST-00.
Applicability
This standard lays down requirements for simulation software including both Simulation environments and simulation models. The requirements cover simulation models’ interfaces and simulation environment interfaces for the purpose of model re-use and exchange to allow simulation models to be run in any conformant simulation environment.
A consequence of being compliant to this standard for a model is the possibility of being reused in several simulation facilities or even in several projects. However, adherence to this standard does not imply or guarantees model reusability, it is only a precondition. Other characteristics of the model, to be defined outside this standard, such as its functional interfaces and behaviour, its configuration data as well as quality, suitability and performance, etc. are also heavily affecting the potential for a model to be reused. In addition, agreements need to be reached on simulation environments compatibility, model validation status as well as legal issues and export control restrictions.
Therefore, this standard enables but does not mandate, impose nor guarantee successful model re-use and exchange.
Model reuse in this standard is meant both at source-code and binary level, with the latter restricted to a fixed platform.
Normative references
The following normative documents contain provisions which, through reference in this text, constitute provisions of this ECSS Standard. For dated references, subsequent amendments to, or revision of any of these publications do not apply. However, parties to agreements based on this ECSS Standard are encouraged to investigate the possibility of applying the more recent editions of the normative documents indicated below. For undated references, the latest edition of the publication referred to applies.
|
ECSS-S-ST-00-01
|
ECSS system - Glossary of terms
|
|
ECSS-E-ST-40
|
Space engineering - Software general requirements
|
|
[SMP_FILES]
|
ECSS_SMP_Issue1(2March2020).zip – SMP C++ Header files, SMP XML schemas and SMP Catalogue. (Available from ECSS website)
|
|
https://www.w3.org/TR/xmlschema11-2/
|
XML schema specification
|
|
http://www.opengroup.org
|
The UUID specification from Open Group.
|
|
https://www.osgi.org/developer/specifications/
|
OSGi Specifications
|
Terms, definitions and abbreviated terms
Terms from other standards
For the purpose of this Standard, the terms and definitions from ECSS-S-ST-00-01 and ECSS-E-ST-40 apply.
For the purpose of this Standard, the terms and definitions from ECSS‐E‐ST‐70 apply, in particular the following term:
mission
Terms specific to the present standard
In the following list of terms, underlined words are further defined in the same list.
aggregate
relationship between two components implemented by storing their references
Each component in such a relationship keeps its own lifecycle and it does not dependent on that of other components.
association
relationship between two instances of any data-type, where each instance has its own lifecycle and there is no owner
breakpoint
unambiguous state of a simulation
component
building block of a simulation that can be instantiated and that has a well-defined contract to its environment
composite
component implementing composition
composition
hierarchical relationship where child component is destroyed if the parent component is destroyed
configuration
specification of values for fields of components
constructor
specific operation of a component, bearing the same name of the component, whose purpose is to allocate and build an instance of said component
consumer
component that can receive data in one of its input fields from an output field of another component
container
typed collection of child components
contract
set of interfaces, operations, fields, entry points, event sinks, event sources and all the associated constraints, used to interact with a component
data transfer
copy of value from an output field to an input field
entry point
operation without parameters that does not return a value, which can be added to the scheduler or event manager service
epoch time
absolute time of the simulation
event
see “simulation event”
event manager
component that implements the IEventManager interface
The IEventManager interface is specified in clause 5.3.4.
event sink
receiver of specific notifications, owned by a component and subscribed via a subscription mechanism
event source
emitter of specific notifications, owned by a component and offering a subscription mechanism
exception
non-recoverable error that can occur when calling into an operation or property
field
feature characterised by a value type and holding a value
input field
field explicitly marked for receiving values as a result of a data transfer
interface
named set of properties and operations
logger
component that implements the ILogger interface
The ILogger interface is specified in clause 5.3.1.
mission time
relative time measuring elapsed time from a mission specific point in time
model
component that implements the IModel interface
The IModel interface is specified in clause 5.2.3.2.
model implementation
executable code implementing a model
model instance
occurrence of a model implementation
output field
field explicitly marked for being the source of a value in a data transfer
operation
declaration of a behavioural feature of a component or an interface with the option to define parameters, return value and raised exceptions
package
collection of types, where each one is either a value type or a component
platform
set of subsystems/technologies that provide a coherent set of functionality through APIs and specified usage patterns
primitive type
type that can no longer be de-composed and that is pre-defined by the standard
The available primitive types are listed in Table 51: Primitive Types.
property
typed feature of a class, an interface or a component that can be accessed by two operations, the setter and the getter, not necessarily both present
provider
component that can send data of one of its output fields to an input field of another component
reference
pointer to a component
When dealing with the C++ mapping, the term reference has a meaning specific to that language, whereas in the rest of this standard it means point to a component (but it cannot for instance be a pointer to a class).
resolver
component that implements the IResolver interface
The IResolver interface is specified in clause 5.3.5.
schedule
planned time ordered execution of entry points
scheduler
component that implements the IScheduler interface
The IScheduler interface is specified in clause 5.3.3.
service
component that implements the IService interface
The IService interface is specified in clause 5.2.3.3.
simple field
field of a type that maps directly to a primitive type
simulation environment
platform implementing the standard E-40-07 services (event manager, link registry, logger, resolver, scheduler and time keeper) and the ISimulator interface
simulation event
call to an entry point by either scheduler or event manager
The term “event” is synonymous.
simulation time
relative time since start of simulation
simulator
collection of services and hierarchy of model instances together with a simulation environment
simulation
single execution of a simulator
simulation service
service instance resolvable by name in the global scope of the simulation environment
source
component that owns one or more references, one or more event links, or one or more output fields
The term “source component” is synonymous.
source component
See source
target
component that implements one or more interfaces, provides one or more event sinks, or one or more input fields
The term “target component” is synonymous.
target component
see “target”
time keeper
component that implements the ITimeKeeper interface
The ITimeKeeper interface is specified in clause 5.3.2.
value
state of a value type
value type
set of values which a variable can possess
Zulu time
the computer clock time, also called wall clock time
Abbreviated terms
For the purpose of this Standard, the abbreviated terms and symbols from ECSS-S-ST-00-01 and the following apply:
|
Abbreviation
|
Meaning
|
|
DES
|
Discrete-Event Simulation
|
|
SMDL
|
Simulation Model Definition Language
|
|
SMP
|
Simulation Modelling Platform
|
|
URI
|
Uniform Resource Identifier
|
|
URL
|
Uniform Resource Locator
|
|
UUID
|
Universally Unique IDentifier
|
Nomenclature
The following nomenclature applies throughout this document:
The word “shall” is used in this Standard to express requirements. All the requirements are expressed with the word “shall”.
The word “should” is used in this Standard to express recommendations. All the recommendations are expressed with the word “should”.
It is expected that, during tailoring, recommendations in this document are either converted into requirements or tailored out.
The words “may” and “need not” are used in this Standard to express positive and negative permissions, respectively. All the positive permissions are expressed with the word “may”. All the negative permissions are expressed with the words “need not”.
The word “can” is used in this Standard to express capabilities or possibilities, and therefore, if not accompanied by one of the previous words, it implies descriptive text.
In ECSS “may” and “can” have completely different meanings: “may” is normative (permission), and “can” is descriptive.
The present and past tenses are used in this Standard to express statements of fact, and therefore they imply descriptive text.
Principles
Objectives
The main objective of this standard is to enable the effective reuse of simulation models and applications within and between space projects and their stakeholders. In particular, the standard supports model reuse across different simulation environments and exchange between different organizations and missions.
The portability of models between different simulation environments is supported by defining a standard interface between the simulation environment and the models. Models can therefore be plugged into a different simulation environment without requiring any modification to the model source code.
The portability of models between different operating systems and hardware takes into consideration dependencies such as avoiding calls to operating specific APIs or use of hardware specific features. The guidelines to the model developer, on how to avoid developing models with such dependencies, is outside the scope of this standard.
Common Concepts and common types
The main purpose of SMP is to promote platform independence, interoperability and reuse of simulation models. This is done by defining;
Common Concepts: All SMP models fulfil common high-level concepts addressing fundamental modelling issues. This enables the development of models on an abstract level, which is essential for independence from simulation environments and reuse of models;
Common Type System: All SMP models are built upon a common type system. This enables different models to have a common understanding of the syntax and semantics of basic types, which is essential for interoperability between different models.
In other words, models are using common concepts and a common type system to become interoperable. Thus, models ‘live’ in between these two common layers as shown in Figure 41.
Figure 41: Common Concepts and Type System
Architecture
The SMP architecture covers two types of components;
Simulation Models provide application specific behaviour;
Simulation Environments provide Simulation Services.
This architecture is depicted in Figure 42.
Figure 42: SMP Architecture
An SMP compliant simulation environment provides the following six simulation services:
Logger: Allows logging messages (see clause 5.3.1);
Time Keeper: Provides the four different SMP time kinds (see clause 4.4 and 5.3.2);
Scheduler: Allows calls of entry points based on timed or cyclic events (see clause 5.3.3);
Event Manager: Provides mechanisms for global asynchronous events (see clause 5.3.4);
Resolver: Provides the ability to get a reference to any model within a simulation (see clause 5.3.5);
Link Registry: Maintains a list of the links between model instances (see clause 5.3.6).
In addition, it supports other concepts laid out in this standard via some dedicated interfaces:
Simulation state machine controlling interface (see clause 4.5 and 5.3.7);
Interfaces allowing Self-persistence as described in clause 4.8 (see also IStorageReader in clause 5.3.8.1 and IStorageWriter in clause 5.3.8.2);
Publication: A set of interfaces allowing models to publish their state to the simulation environment (see clause 5.3.9);
Type registry: A registry allowing components to register types that later can be used for publication (see clause 5.3.10);
Component Factory: Ability to create components via a factory (see clause 5.3.11).
The arrows in Figure 42 indicate interaction between components. In SMP, communication is performed via interfaces. Two different types of interfaces can be identified in this architecture:
Interfaces between components and the Simulation Environment, and
Inter-component communication interfaces.
Time handling principle
SMP defines four different time scales, referred to as time kinds (see clause 5.1.2 for exact specification):
Simulation Time: Relative time since start of simulation, starting at 0 when the simulation is setup.
Zulu Time: Zulu Time is the computer clock time, also called wall clock time.
Epoch Time: The absolute time of the simulation.
Mission Time: Mission time is a relative time, i.e. it measures elapsed time from a mission specific point in time.
SMP defines both Epoch and Mission Time as a fixed offset from Simulation Time. The Offset is set via calls to the SMP time keeper service and the two time kinds progress linearly with Simulation time. SMP does not define how Simulation time progress with respect to Zulu time. Typical examples of such a correlation is:
Real‐Time: The simulation time progresses with real-time, where real‐time is typically defined by the computer clock.
Accelerated: The simulation time progresses relative to real‐time using a constant acceleration factor. This factor can be larger than 1.0, which relates to ʺfaster than real‐timeʺ, smaller than 1.0, which means ʺslower than real‐timeʺ, or 1.0, which coincides with real‐time.
Free Running: The simulation time progresses as fast as possible, and is not related to real‐time. Typically, the speed is coordinated with the timed events of the scheduler, which underlines the close relationship between these two services (Time Keeper and Scheduler).
SMP does not mandate which of these modes a simulation environment supports.
Simulation lifecycle
Any SMP simulation goes via a lifecycle as defined in Figure 43. The simulation environment is responsible to ensure that this state diagram is followed. It is controlled via the ISimulator interface (see clause 5.3.7).
Figure 43: SMP State machine
Each state in Figure 43 has its own purpose and behaviour as explained in Table 41. Notice that some state transitions are automatically performed by the Simulation Environment as indicated in Figure 43, while others need explicit calls to the ISimulator interface.
Table 41: Overview of simulation states
|
Name
|
Description
|
|
Building
|
In Building state, the model hierarchy is created. In this state, Publish() and Configure() can be called any time to call the corresponding Publish() and Configure() operations of each component.
|
|
Connecting
|
In Connecting state, the simulation environment traverses the model hierarchy and calls the Connect() method of each component.
|
|
Initialising
|
In Initialising state, the simulation environment executes all initialization entry points in the order they have been added to the simulator using the ISimulator AddInitEntryPoint() method (see 5.3.7).
|
|
Standby
|
The simulation environment does not progress simulation time. Only entry points registered relative to Zulu time are executed.
|
|
Executing
|
The simulation environment does progress simulation time. Entry points registered with any of the available time kinds are executed.
|
|
Storing
|
In Storing state, the simulation environment first stores the values of all fields published with the State attribute to storage (typically a file). Afterwards, the Store() method of all components (Models and Services) implementing the optional IPersist interface is called, to allow custom storing of additional information.
|
|
Restoring
|
In Restoring state, the simulation environment first restores the values of all fields published with the State attribute from storage. Afterwards, the Restore() method of all components implementing the optional IPersist interface is called, to allow custom restoring of additional information.
|
|
Reconnecting
|
In Reconnecting state, the simulation environment makes sure that models that have been added to the simulator after leaving the Building state are properly published, configured and connected.
|
|
Exiting
|
In Exiting state, the simulation environment is properly terminating a running simulation.
|
|
Aborting
|
In this state, the simulation environment attempts a simulation shut-down, whereby the simulation can stop executing as the users expect, without guaranties for actual release of resources.
|
Simulation method
Discrete-event simulation (DES)
SMP is built on discrete-event simulation (DES) theory where the behaviour of a system is modelled as a discrete sequence of events in time. Each event that marks a change in the state of the systems occurs at a particular instant in time. The simulation can jump in time from one event to the next since no change in the system occurs between consecutive events.
The main elements in SMP that support this approach are:
The simulation components schedule EntryPoints (see clause 5.2.7.1) on the SMP scheduler (see clause 5.3.3) for execution of events.
The Simulation state is captured in the persisted data.
Parallelization and distribution
SMP assumes a single scheduler executing its events in sequence. All components are loaded inside the same address space allowing direct communication between them. The standard however does not prevent parallelization or distribution to be built into layers on top of the standard.
Inter component communication
Overview
SMP supports the following main method of communication between components:
Direct interface based communication
Data flow based communication
Event based communication
Interface based communication
An interface‐based design adds interfaces as the standard mechanisms for inter-model communication. This isolates the definition of an interface (the “contract”) from its implementation. In an interface‐based design, a model provides any number of interfaces. An Interface defines a contract between models. Every model implementing the interface provides all the functionality of the interface, so that every model, which consumes this interface can rely on the interface implementation. As interfaces are a mechanism to de‐couple models, they do not give access to fields, but only to operations. With special operations (i.e. use of Properties. See definition 3.2.33 "property") that read or write a single value, access to fields can be added.
Data flow based communication
Overview
In a data flow based communication, two components exchange the value of a field. The Provider component transfers an Output field value into an Input field of the Consumer component. The Output field is said to be connected to the Input field through a Dataflow connection.
The dataflow communication can be automatic, i.e. whenever the Output field is updated by its owning component, the value is immediately propagated to the connected Input field. The output fields which take part in an automatic dataflow based communication implement IDataflowField (see 5.2.11.7).
The dataflow communication can be scheduled, i.e. when the Output field is updated by its owning component, the value is not automatically propagated to the connected Input field. The transfer is only performed on request, e.g. cyclically by the Simulation Environment.
It is neither mandated when an Output field pushes its value into connected Input fields, nor whether an Input field performs any specific action after it has been updated. An Input field can be implemented in a way that it notifies its containing model about a change, which can be used to trigger certain behaviour in the Consumer component.
Data types consideration
When two fields are involved in a dataflow connection, compatibility of the field types ensures correct transfer of data between the provider model and the consumer model.
Two levels of type compatibility are specified for the fields:
Strict compatibility: both fields are typed by the same type as identified by their type UUID published in the Type Registry. In this case, it is obvious that the fields can be connected via a dataflow connection.
Equivalence: the types are equivalent as per their semantics or physical representation. For example, when type 1 is a user-defined type Voltage mapped on a Smp::Float64 and type 2 is an user-defined type Tension mapped on Smp::Float64. As both type 1 and type 2 are Smp::Float64, they are said “equivalent”. Dataflow connection is allowed as there is no issue to transfer information between type 1 and type 2.
Event Based communication
For an event‐based design the components are modelled using Event Sinks (see 5.2.6.1) and Event Sources (see 5.2.6.2). Events issued by the source are received by all sinks subscribed to receive the corresponding event.
Models, Services and Components
Objects
An object is the base class for all SMP elements. It provides the basic features of a name, description and parent to all SMP elements. This implies that all SMP elements are organized in a hierarchical structure and always able to traverse upwards towards its root. The elements inheriting directly from Object are:
Entry Points (IEntryPoint) as void operations that can be called by the scheduler and event manager services;
Entry Point Publisher (IEntryPointPublisher) for publishing of entry points;
Event Sinks (IEventSink) and Event Sources (IEventSource) for event based communication between objects;
Composites (IComposite) and Containers (IContainer) to build the object hierarchy;
Collection (ICollect) allowing to collect SMP elements in a collection;
References (IReference) allowing objects reference other components;
Components (IComponent) implementing the simulation behaviour;
Types (IType) to be used for the definition of fields;
Factory (IFactory) that creates components;
Persistent Objects (IPersist) that can store and restore their state. IPersist is the basis for the following important elements:
Fields (IField) to hold the simulation state and data;
Failures (IFailure) to allow objects to represent a failure in a system.
Figure 44: Object mechanisms
Components
Figure 45: Overview of components hierarchy
The functionality of an SMP based simulator is implemented in elements that implement the IComponent (see 5.2.3.1) interface. A component represents an implementation of a self-contained feature with well-defined interfaces to other components. At initialization time, a simulation is built by assembling a set of instances of components. In addition, to implementing the IComponent interface, a number of additional optional component mechanisms are specified (see Figure 46):
Component aggregation (IAggregate),
Inter-component events (IEventProvider and IEventConsumer),
Dynamic invocation (IDynamicInvocation),
Link management features (ILinkingComponent),
See clause 5.2 for details on Component Mechanisms.
The Simulator itself is an object, in particular a composite. All its direct children are components, namely models and services.
Figure 46: Component Mechanisms
All SMP components goes via a lifecycle as defined in Figure 47. Each component is responsible to ensure that this state diagram is followed. It is controlled via the IComponent interface (see clause 5.2.3.1).
Figure 47: Component State machine
Each state in Figure 47 has its own purpose and behaviour as explained in Table 52.
Factories
A Factory is an Object that creates Components. The type of the Component instantiated by the Factory is identified by a Universally Unique Identifier (UUID). The UUID is a 128-bit number which for practical purposes is unique, without depending for uniqueness on a central registration authority or coordination between the parties generating them. The purpose of the Factory is to hide the implementation details of how a Component is instantiated. For example, the base class of the Component implementation is hidden by the Factory.
A Factory is an Object that implements the IFactory interface. The Factory is registered with the simulator by calling the ISimulator::RegisterFactory method. Instances of the Component identified by the Component’s UUID can then be created by calling the ISimulator::CreateInstance method which uses the registered Factory to instantiate the Component.
Models and Services
Two main flavours of components are specified by SMP: Models and Services. The main differences are:
Models implement the IModel interface while Services implement the IServices interface. Both interfaces are empty and do not add any additional capabilities, but the difference allows to efficiently differentiate models and services.
Models are added to the simulation in a hierarchical tree, while services live in the global scope of the simulation.
The Models can be fallible by implementing the IFallibleModel interface but Services are not.
Models are added to the Simulations via the ISimulator AddModel method, while Services are added via the AddService method.
It is possible to get a reference to a service from the ISimulator interface via the GetService method by its name. This implies that all components in a simulation can easily obtain a reference to a service.
Services can only be added to the simulation during the first startup in building phase, while models can be dynamically added also later in stand-by state.
The mandatory features of an SMP runtime environment are specified as services. See clause 5.3 and Figure 45.
Publication and Persistence
SMP components publish their state information to the simulation environment to:
Allow visualization of the simulation state.
Allow the simulation environment to interact with the state of the component.
Allow the simulation environment to store and restore the state of the component via the SMP persistence mechanism.
All published fields are annotated with a set of attributes provided by the SMP component to the Simulation Environment:
A View Kind attribute indicating which kind of user this information is intended for. The values and intended interpretation of these values by the Simulation Environment is given in Table 42.
If the field is part of the breakpoint or not (State attribute of field).
If it is an Input, or an Output, or an Input/Output field (Input and Output attributes of field).
Additional meta information can also be provided via the SMP Catalogue (see 5.4.1).
Table 42: ViewKind values
|
Name
|
Intended interpretation
|
|
VK_None
|
The element is not made visible to the user.
|
|
VK_Debug
|
The element is made visible for debugging purposes. The element is not visible to end users. If the simulation environment supports the selection of different user roles, then the element is intended to be visible to ʺDebugʺ users only.
|
|
VK_Expert
|
The element is made visible for expert users.
|
|
VK_All
|
The element is made visible to all users. (this is the default)
|
From the list of published fields, the simulation environment is able to determine the state of a simulation and store it into a breakpoint (or to restore it when needed). This is called persistence. Persistence of SMP components can be handled in one of two ways:
External Persistence: The simulation environment stores and restores the model’s state by directly accessing the fields that are published to the simulation environment, i.e. via the IPublication (See 5.3.9.1) interface.
Self‐Persistence: The component can implement the IPersist (See 5.2.9) interface, which allows it to perform special operations during store and restore in addition to external persistence. Typically, self-persistence allows the persistence of dynamic data structure (e.g. events on the simulation schedule). Two approaches exist in this case for models to store their data:
Its state or parts of it can be stored/restored in the storage that is provided by the simulation environment via the IStorageReader (see 5.3.8.1) and IStorageWriter (see 5.3.8.2) interfaces provided by the simulation environment.
The component can query the filename and location of the storage file from the environment via the IStorageReader (see 5.3.8.1) and IStorageWriter (see 5.3.8.2) interfaces and store additional files in the same location. This mechanism is usually only needed by specialised models, for example embedded models that need to load on‐board software from a specific file.
SMP Runtime Environments supports both External and Self-Persistence. For models and components, only external persistence (via the Store() and Restore() methods of the ISimulator interface) is a mandatory feature, while self-persistence is an additional optional mechanism.
Dynamic invocation
SMP supports dynamic invocation allowing interaction between simulation environments and simulation models. This is typically used during execution allowing to control a simulation via scripting. It is a mechanism that makes the operations of a component available via a standardised interface.
In order to allow calling a named method with any number of parameters, a request object is created which contains all information for the method invocation. This request object is also used to transfer back a return value. The dynamic invocation concept standardises the request objects (IRequest interface, see 5.2.8.2). In addition, two methods are provided as part of IDynamicInvocation to create and delete request objects. However, it is not mandatory to use these methods, as request objects can as well be created and deleted using another implementation. A reason for doing this could be to minimise the number of round‐trips between a client (that calls a method) and a component that implements IDynamicInvocation. The sequence diagram in Figure 48 shows all steps involved when using the CreateRequest() and DeleteRequest() methods.
Figure 48: Sequence of calls for dynamic invocation
The sequence diagram in Figure 48, using a Client component and a Model implementing IDynamicInvocation, contains the following steps:
The client calls the CreateRequest() operation of the component to create a request object for the operation, passing it the name of the operation.
The component creates a request object for the operation, using the default values of all parameters.
The component returns the Request object via its IRequest interface to the client.
The client calls the SetParameterValue() operation of the Request object to set parameters to non‐default values.
The client calls the Invoke() operation of the component to invoke the corresponding operation.
The component calls the GetParameterValue() operation of the Request object to get parameters.
The component calls its internal operation that corresponds to the invoked operation.
The component calls the SetReturnValue() operation of the Request object to set the return value.
The component returns control to the client.
The client calls the GetReturnValue() operation of the Request object to get the return value.
The client calls the DeleteRequest() operation of the component to delete the Request object.
The component destroys the request object.
The component returns control to the client.
Components meta data
Catalogue
Meta data for SMP objects are stored in XML documents called the Catalogue. Having the SMP objects described in XML catalogues allows taking benefit from the XML language, for example:
Generation of the catalogues from UML diagrams
Generation of models documentation from the catalogue
Generation of models skeleton code from the catalogue (See clause 6.1).
The content of a catalogue is hierarchically ordered in namespaces that may be nested. Inside each namespace many uniquely named instance of the following SMP features can be found:
Types definitions including:
Constants, Fields and Properties
Exceptions
Data Types
Interfaces specifications
Component and model specifications including:
Event Sinks and sources
Fields and properties
Entry Points
Operations
Containment and inheritance
Interfaces, associations and references
Attributes that can be attached to elements:
Fallible and Forcible
Min and Max limits for types
View/ViewKind information determines the visibility of the element
For all the elements above, meta data can be added like the description of each element or the engineering unit for type definitions. From this, it can be seen that the Catalogue definition provides a rich capability to describe the complete external interface of all SMP components. In fact, the interfaces as described in the SMP standard can as well be expressed in a catalogue. (See ecss.smp.smpcat as referenced in clause 5.4.1.2.1a).
Package
A package describes how implementations of types defined in catalogues are packaged. This includes not only models, which may have different implementations in different packages, but as well all other user‐defined types.
Configuration
A configuration document allows specifying arbitrary field values of component instances in the simulation hierarchy. This can be used to initialise or reinitialise the simulation.
Model exchanges considerations
Overview
One of the primary goal of SMP is to allow model exchanges based on the Package concept.
Model source code exchange are considered easier than binary exchange as some considerations are important to be taken into account when exchanging binary models.
The mapping of a Package to C++ defines which symbols a static or dynamic library of SMP has to expose. This enables binary distribution of models, where only the catalogues and/or header files (for the compiler) and the libraries (for the linker) are provided, but no implementation source code. Nevertheless, binary compatibility depends on a number of other constraints, which may even vary between operating systems and compilers.
SMP Bundle
For distribution of a binary package SMP bundles are used. A SMP Bundle is an archive (e.g. a tar file on Linux, or a zip file on Windows) which provides the following elements:
One or more SMDL packages.
One or more package dynamic libraries, directly related to the SMDL packages.
One or more package static libraries, directly related to the SMDL packages.
All the SMP catalogues related to the SMDL packages.
Optionally include other artefacts (SMDL configurations) and/or the related source code for all or parts of the included SMDL packages.
The related structure of folders and files within the bundle, and the names of folders and files are not standardised.
The added value of a Bundle is the additional SMP.MF Bundle Manifest file.
This Manifest is an ASCII file (aligned with the OSGi bundle manifest format) which contains key-value pairs with important meta data for the bundle.
Interface requirements
Common
Primitive Types specification
All SMP fields, parameters, constants and properties shall be of either a Primitive Type as per PrimitiveTypes.h in [SMP_FILES], or a User Defined Type published to the Type Library.
This specification is compliant with the types specified in Table 51.
Mapping between SMP types, XML types and ISO/ANSI C++ types shall be as per Table 51.
C++ mapping for primitive types is provided by PrimitiveTypes.h in [SMP_FILES].
Table 51: Primitive Types
|
SMP Type
|
XML mapping
|
C++ mapping
|
Description
|
|
Char8
|
xsd:string
|
char
|
8 bit character type to represent textual characters
|
|
String8
|
xsd:string
|
const char*
|
8-bit character strings based on UTF-8 encoding, which is commonly used in XML
|
|
Bool
|
xsd:boolean
|
bool
|
Bool is a binary logical type with values true or false
|
|
Int8
|
xsd:byte
|
int8_t
|
8 bit signed integer
|
|
UInt8
|
xsd:unsignedByte
|
uint8_t
|
8 bit unsigned integer
|
|
Int16
|
xsd:short
|
int16_t
|
16 bit signed integer
|
|
UInt16
|
xsd:unsignedShort
|
uint16_t
|
16 bit unsigned integer
|
|
Int32
|
xsd:int
|
int32_t
|
32 bit signed integer
|
|
UInt32
|
xsd:unsignedInt
|
uint32_t
|
32 bit unsigned integer
|
|
Int64
|
xsd:long
|
int64_t
|
64 bit signed integer
|
|
UInt64
|
xsd:unsignedLong
|
uint64_t
|
64 bit unsigned integer
|
|
Float32
|
xsd:float
|
float
|
IEEE 754 single-precision floating-point type with a length of 32 bits.
|
|
Float64
|
xsd:double
|
double
|
IEEE 754 double-precision floating-point type with a length of 64 bits.
|
|
Duration
|
xsd:duration
|
int64_t
|
Duration in nanoseconds.
|
|
DateTime
|
xsd:dateTime
|
int64_t
|
Absolute time in nanoseconds.
|
The Duration type as per Table 51 shall be used for specifying a duration, as follows:
- It is expressed in nanoseconds;
- It is stored in a signed 64 bit integer;
- Positive values correspond to positive durations;
- Negative values correspond to negative durations.
- 1 Nanoseconds is the lowest level of granularity supported for time in SMP.
- 2 The duration type allows specifying values roughly between ‐290 years and 290 years.
- 3 The duration type allows expression of relative time, hence “negative duration” implies a relative time in the past.
The DateTime type as per Table 51 shall be used for absolute time values, as follows: - It is expressed in nanoseconds, relative to the reference time of 01.01.2000, 12:00, Modified Julian Date (MJD) 2000+0.5;
- It is stored in a signed 64 bit integer;
- Positive values correspond to times after the reference time;
- Negative values correspond to time values before the reference time.
- 1 Nanoseconds is the lowest level of granularity supported for time in SMP.
- 2 DateTime allows specifying time values roughly between 1710 and 2290.
A SMP Simple Field shall be of a type that maps directly to a Primitive Type.
The AnySimple type shall hold a Primitive Type as per AnySimple.h in [SMP_FILES].
The AnySimpleArray type shall be an array of AnySimples as per AnySimpleArray.h in [SMP_FILES].
Time Kinds
Simulation time shall be used for keeping the progress of time with respect to the start of the simulation, with the following properties:
- Simulation time is a non-negative Duration type;
- Simulation time is initialised to 0 at the beginning of the Building state as per Table 41;
- Simulation time changes only when:
- The simulation is progressing in the Executing state;
- As a result of a restore of a breakpoint in restoring state;
- As a result of ITimeKeeper SetSimulationTime.
- It is not specified how quickly simulation time is progressed when the simulator is in Executing state;
- Simulation time is stored and restored in the storing and restoring states; Mission time shall be used for keeping the progress of relative time with respect to a Mission Start time, with the following properties:
- Mission time is initialised to 0 at the beginning of the Building state as per Table 41;
- Mission Time is calculated as a fixed offset between the current Epoch time and the given Mission start time according to the following formula: MissionTime = EpochTime – MissionStartTime;
- The Mission time progresses with Epoch time, which progresses with Simulation time, and is hence affected by the ITimeKeeper SetEpochTime method.
- The Mission time offset from Epoch time, the Mission start time changes by calls to:
- the ITimeKeeper SetMissionTime method;
- the ITimeKeeper SetMissionStartTime method.
- Mission time only progresses when the simulation environment is in Executing state;
- Mission time is stored and restored in the storing and restoring states;
- Mission time is stored as a Duration type. Zulu time shall be time dependent on the system clock of the host machine or an external clock source expressed using the DateTime type.
High Real Time systems sometimes uses an external clock source instead of the local system clock of host machine.
Epoch time shall be time dependent on the Simulation time with a fixed offset using the DateTime type.
- 1 Epoch time progresses with Simulation time.
- 2 Epoch time is changed with the ITimeKeeper SetEpochTime (See 5.3.2).
Path string
An SMP path string shall be a representation of a valid route from an SMP object in the hierarchy to another SMP object.
- 1 Examples of valid path strings:
- /Satellite/Receivers/Receiver1
- /Logger
- /Logger/
- ../../Transmitters/Transmitter4
- ./Satellite/../Satellite//Receivers/
- 2 Examples of invalid path strings:
- “/..”, parent of root object do not exist
- “…”, meaning of triple dots not defined.
Both Absolute and Relative path strings shall be supported and distinguished as follows: - Paths starting with a delimiter are absolute paths from the simulation root object.
- Paths not starting with a delimiter are relative paths from the current object.
The delimiter between component names in the path string shall be ”/”.
The delimiters between components and its children objects that are not components shall be either “/” or “.”.
This allows “Component.Operation()” to be used as path.
Trailing delimiters shall be allowed in path strings.
It shall be possible to reference the parent object by the “..” string.
It shall be possible to reference the current object by:
- the “.” string
- an empty string “”
This allows the following to be used as path to operations of current object:
- .Operation()
- ./Operation()
The path string shall allow an element in an array to be identified by “[n]” trailing the array name where “n” is the zero based element index, with no delimiter.
This allows the following to be used for addressing element 2 of an array “MyArray” in MyModel:
- MyModel/MyArray[2]
- MyModel.MyArray[2]
Universally Unique Identifiers (UUID)
All SMP types shall have a unique UUID as per Uuid.h in [SMP_FILES].
- 1 The UUID follows the specification from Open Group (http://pubs.opengroup.org/onlinepubs/9629399/apdxa.htm)
- 2 The UUID is a 128 bit long unique identifier.
- 3 The UUID allows for example to:
- Uniquely identify types defined in catalogues so that can be bound with implementations defined within packages.
- Uniquely identify linked elements within a Catalogue.
Exception specification
All SMP exceptions shall inherit from the Exception class as per Exception.h in [SMP_FILES] providing the following information:
- The description of the exception;
- The name of the exception;
- The exception message;
- The sender of the exception when the exception originates from an SMP Object.
This covers both exceptions defined in this standard and user defined exceptions.
Components and Objects interfaces
Object Specification (IObject)
All SMP objects shall provide the following features as per IObject.h in [SMP_FILES]:
- If the object is not an array element, a name of the object as follows:
- Not be empty;
- Start with a letter;
- Contain only letters, digits, and underscore (ʺ_ʺ);
- Not be an ISO/ANSI C++ keyword.
- If the object is an array element, the name shall be the array name appended by “[i]“ where “i” is a zero based element index;
- A description of the object;
- The parent object as follows:
- An IObject pointer to the parent if the object has a parent;
- A nullptr if the object does not have a parent.
- 1 The Object description may be empty.
- 2 All SMP elements inherit from the IObject interface including:
- Entry Points
- Event Sinks and Sources
- Fields
- Containers
- References
- Failures
- Components
- Composites
- Collections
- Factories
- Types
- 3 to item 5.2.1a.1(d): See ISO/IEC 9899:2011 [C11 Standard] and ISO/IEC 14882:2011 [C++11 Standard] for the actual list of keywords.
All SMP objects with the same parent that are to be resolved by the Resolver shall have a unique name.
Containers and References cannot be resolved via the resolver, hence they do not need a unique name.
The validity of the SMP name shall be checked when an SMP object is created, with the following behaviour:
- If an object with an invalid name is created, it throws a InvalidObjectName exception as per InvalidObjectName.h in [SMP_FILES].
Collection Specification (ICollection)
All SMP Collections of SMP elements shall implement the ICollection interface as per ICollection.h in [SMP_FILES].
The ICollection at method shall return the element with the given position or name, with the following behaviour:
- If no element exists with the given position or name, it returns nullptr. The ICollection size method shall return the number of elements in the collection.
Component Specification
Component (IComponent)
All SMP Components shall implement the IComponent interface as per IComponent.h in [SMP_FILES].
The IComponent GetState method shall return the current state of the component as per ComponentStateKind.h in [SMP_FILES], specified in Table 52.
Table 52: Component states
|
Name
|
Description
|
|
CSK_Created
|
The Created state is the initial state of a component. Component creation is done by an external mechanism, e.g. by factories.
|
|
CSK_Publishing
|
In Publishing state, the component is allowed to publish features. This includes publication of fields, operations and properties. In addition, the component is allowed to create other components.
|
|
CSK_Configured
|
In Configured state, the component has performed initial configuration. This configuration can be done by external components, or internally by the component itself, e.g. by reading data from an external source.
|
|
CSK_Connected
|
In Connected state, the component is connected to the simulator. In this state, neither publication nor creation of other components is allowed anymore. Configuration performed via loading of SMDL configuration file and/or calling of initialisation entry point are performed in this state.
|
|
CSK_Disconnected
|
In Disconnected state, the component is disconnected from the simulator, and all references to it are deleted, so that it can be deleted.
|
The IComponent Publish method shall be used by components to publish all publishable fields, properties and operations, with the following argument and behaviour:
- Argument:
- “receiver” giving a pointer to the IPublication instance for the component.
- Behaviour:
- If the component is not in Created state, then it throws an InvalidComponentState exception as per InvalidComponentState.h in [SMP_FILES];
- If the component is in Created state, then it enters the Publishing state;
- After entering Publishing state, it publishes its fields, properties and operations using the provided receiver argument;
- While in publishing state, it can create new components;
- 1 Components can override the implementation of operations and properties from their parents, hence it is possible that the same property and operation are published multiple times. In this case, the last call to published overrides the previous calls.
- 2 Newly created components are in Created state. The simulator is responsible for the triggering of state transitions of new components.
The IComponent Configure method shall be used to perform initial configuration of the component, with the following arguments and behaviour: - Arguments:
- “logger” giving a pointer to the ILogger instance for the component, to provide the possibility to log messages during its configuration;
- “linkRegistry” giving a pointer the ILinkRegistry instance for the component, to provide the possibility to register links.
- Behaviour:
- If the component is not in Publishing state, it throws an InvalidComponentState exception as per InvalidComponentState.h in [SMP_FILES];
- If the component is in Publishing state, it creates and configures other features and even other components using the field values of its published fields as sole source of configuration information for the creation of such components;
- After completing the configuration actions, the component enters Configured state.
The IComponent Connect method shall allow the components to connect to the simulator environment and other components, with the following argument and behaviour:
- Argument:
- “simulator” giving a pointer to the ISimulator interface as per ISimlator.h in [SMP_FILES] to access services from the simulation environment.
- Behaviour:
- If the Component is not in Configured state, it throws an InvalidComponentState exception as per InvalidComponentState.h in [SMP_FILES];
- If called in Configured state, the component enters Connected state;
- After entering Connected state, it connects to simulation services used by the component, if any.
It is guaranteed that all models have been created, published and configured before the Connect method of any component is called.
The IComponent Disconnect method shall disconnect the component from the simulation environment and any other components, with the following behaviour:
- If the Component is not in Connected state, it throws an InvalidComponentState exception as per InvalidComponentState.h in [SMP_FILES];
- If called in Connected state, the component enters Disconnected state;
- After entering Disconnected state, the component disconnects from simulation services by deleting all references of these services to the component. The IComponent GetField method shall provide access to the IField interface for fields of the component, taking the following argument and behaviour:
- Argument:
- “fullName” giving the path of the field for whom it returns the IField interface.
- Behaviour:
- If the passed fullName does not exist, it throws an InvalidFieldName exception as per InvalidFieldName.h in [SMP_FILES];
- If the passed field name exists and it is a field of simple type it returns its ISimpleField interface;
- If the passed field name exists and it is an array field it returns its IArrayField or ISimpleArrayField interface;
- If the passed field name exists and it is a structure field it returns its IStructureField interface.
This includes fields of structures and items of arrays.
The IComponent GetFields method shall return a collection of the component fields as per FieldCollection in IField.h in [SMP_FILES].
The IComponent GetUuid method shall return a reference to the Uuid of the component, as per Uuid.h in [SMP_FILES].
Model (IModel)
All SMP Components which contain the implementation of the simulations functional behaviour shall implement the IModel interface as per IModel.h in [SMP_FILES].
Service (IService)
All SMP components which implement a service to be used by other SMP models shall implement the IService interface as per IService.h in [SMP_FILES].
This includes both standard services specified in this standard and user defined services.
All SMP components which implement the IService interface shall ensure their state is fully persisted in a simulation breakpoint and restored on Restore.
Linking Component (ILinkingComponent)
All SMP Components which require dynamic removal of links at runtime shall implement the ILinkingComponent interface as per ILinkingComponent.h in [SMP_FILES].
The ILinkingComponent RemoveLinks method shall remove all links to the passed component stored in the LinkingComponent itself, taking the following argument:
- “target” giving the reference to the linked component.
The result of this removal is that the LinkingComponent can no longer access the target component removed.
Aggregation
Aggregation interface (IAggregate)
All SMP Components which are referencing other components shall implement the IAggregate interface as per IAggregate.h in [SMP_FILES].
The IReference interface is the referencing mechanism used by the aggregation interface.
The IAggregate GetReference method shall return the reference matching the given name, with the following argument and behaviour:
- Argument:
- “name” giving name identifying the reference.
- Behaviour:
- If no reference matching the given name is found, it returns a nullptr reference.
The IAggregate GetReferences method shall return an ordered collection of all references, with the following behaviour:
- If no reference matching the given name is found, it returns a nullptr reference.
- If the aggregation does not hold any reference, it returns an empty collection;
- If at least one reference is contained, it returns a collection ordered according to the order in which the references have been added to the aggregate.
Reference Interface (IReference)
All references returned by an aggregate shall implement the IReference interface as per IReference.h in [SMP_FILES].
A reference is a named object.
The IReference GetComponent method shall return a reference to the component matching the given name with the following argument and behaviour:
- Argument:
- “name” giving the name of the referenced component to be returned.
- Behaviour:
- If no component matching the given name argument is found, it returns a nullptr reference;
- If multiple components matching the given name argument are found, it returns one of the references.
Multiple components with the same name, but with a different parent (and hence path) can end up in a single reference. In this case, retrieving a component by name is not safe, as any of the components that match the name can be returned.
The IReference GetComponents method shall return an ordered collection of all the referenced components with the following behaviour:
- If no component is referenced, it returns an empty collection;
- If at least one component is contained, it returns a collection ordered according to the order in which the components have been added using the AddComponent method. The IReference AddComponent method shall add a component to the collection of referenced components, with the following argument and behaviour:
- Argument:
- “component” giving a reference to the component to be added.
- Behaviour:
- If the maximum supported number of referenced components is reached, it throws a ReferenceFull exception as per ReferenceFull.h in [SMP_FILES];
- If the reference interface implementation is expecting the given component to inherit from another type it throws an InvalidObjectType exception as per InvalidObjectType.h in [ZIPFLE].
A (typed) reference can attempt to type-cast a component to a specific type, to ensure that all components within the reference inherit from this common base type.
The IReference RemoveComponent method shall remove a component from the collection of referenced components, with the following argument and behaviour:
- Argument:
- “component” giving a reference to the component to be removed.
- Behaviour:
- If the minimum number of component(s) referenced by this object is reached, it throws a CannotRemove exception as per CannotRemove.h in [SMP_FILES];
- If the component to remove is not referenced, it throws a NotReferenced exception as per NotReferenced.h in [SMP_FILES].
RemoveComponent ensures that the right component is identified also if several components with the same name exist in the reference, as it takes a reference to the component as argument, and not the name.
The IReference GetCount method shall return the number of components in the collection of referenced components.
The IReference GetUpper method shall return the upper limit, with the following behaviour:
- If a maximum number has been defined, it returns the maximum number;
- If no maximum number has been defined, it returns -1.
The usage of -1 is consistent with the use of upper bounds in UML, where a value of -1 represents no limit (typically shown as *)
The IReference GetLower method shall return the minimum number of components in the collection or 0 when not defined.
The lower bound can be used to validate a model hierarchy. If a collection specifies a Lower value above its current Count, then it is not properly configured. An external component can use this information to validate the configuration before executing it.
Composition
Composition interface (IComposite)
All SMP Objects which contain Components shall implement the IComposite interface as per IComposite.h in [SMP_FILES].
- 1 The IContainer interface (see 5.2.5.1c.2) is the component container used by the composition interface.
- 2 Composition is the counter part of the IObject GetParent() method and allows traversing the tree of components from parent to child components.
The IComposite GetContainer method shall return the container matching the given name with the following argument and behaviour: - Argument:
- “name” giving the name of the container to be returned.
- Behaviour:
- If no container matching the given argument name is found, it returns a nullptr reference.
The IComposite GetContainers method shall return an ordered collection of all the containers with the following behaviour:
- If no container matching the given argument name is found, it returns a nullptr reference.
- If the composite does not hold any container, it returns an empty collection.
- If at least one container is contained, it returns a collection ordered according to the order in which the containers have been added to the composite.
Container interface (IContainer)
All SMP Objects which represent a composition of child Components shall implement the IContainer interface as per IContainer.h in [SMP_FILES].
- 1 The container components life-cycle coincides with its parent one.
- 2 The container is a named Object as per 5.2.1.
- 3 The container allows adding children to a parent object.
- 4 Each container holds objects of only one type.
The IContainer GetComponent method shall return the component matching the given name, with the following argument and behaviour: - Argument:
- “name” giving the name of the component to be returned.
- Behaviour:
- If no component matching the given name is found, it returns nullptr.
As the container does not support component name duplication, it is not possible to get naming conflict when performing query.
The IContainer GetComponents method shall return an ordered collection of all the contained components with the following behaviour:
- If no component is contained, it returns an empty collection;
- If at least one component is contained, it returns a collection ordered according to the order in which the components have been added using the AddComponent method. The IContainer AddComponent method shall add a component to the collection of contained components, with the following argument and behaviour:
- Argument:
- “component” giving the component to be added.
- Behaviour:
- If the maximum supported number of components is reached, it throws a ContainerFull exception as per ContainerFull.h in [SMP_FILES];
- If a component with the same name and parent already exists, it throws a DuplicateName exception as per DuplicateName.h in [SMP_FILES];
- If the container interface implementation is expecting the given component to inherit from another type, it throws an InvalidObjectType exception as per InvalidObjectType.h in [SMP_FILES].
A (typed) container can attempt to type-cast a component to a specific type, to ensure that all components within the container inherit from this common base type.
The IContainer GetCount method shall return the number of components contained in the collection.
The IContainer GetUpper method shall return the maximum number of components in the collection, with the following behaviour:
- If the maximum number of elements for the collection has been defined, it returns the maximum number;
- If the maximum number of elements for the collection has not been defined, it returns -1.
The usage of -1 is consistent with the use of upper bounds in UML, where a value of -1 represents no limit (typically shown as *).
The IContainer GetLower method shall return the minimum number of components in the collection or 0 when not defined.
The lower bound can be used to validate a model hierarchy. If a collection specifies a Lower value above its current Count, then it is not properly configured. An external component can use this information to validate the configuration before executing it.
The IContainer DeleteComponent method shall delete a component from the collection of contained components, with the following argument and behaviour:
- Argument:
- "component" giving a reference to the component to be deleted.
- Behaviour:
- If the minimum number of component(s) contained by this object is reached, it throws a CannotDelete expection as per CannotDelete.h in [SMP_FILES];
- If the component to delete is not contained, it throws a NotContained exception as per NotContained.h in [SMP_FILES];
- If the component to delete is included, and the minimum number is not reached, then the component is removed from the collection, and its destructor is called.
Events
Sink of events interface (IEventSink)
All SMP Objects which receive event notifications shall implement the IEventSink interface as per IEventSink.h in [SMP_FILES].
The specification of event sinks ensures that notifications from the event sources they are subscribed to can be managed.
The IEventSink GetEventArgType method shall provide the primitive type kind of the argument expected by the event sink when it is notified about a given event, with the following behaviour:
- If no argument is expected, it returns PTK_None.
- 1 See 5.2.6.1c for the specification of how event sinks are notified.
- 2 This operation allows for type checking when subscribing (see 5.2.6.2b) event sinks to event sources.
The IEventSink Notify method shall inform the object about the event, with the following arguments: - “sender” giving the reference to the event source calling the method;
- “arg” giving context data together with the event notification.
See 5.2.6.2d for the specification of how event sources call this method.
Source of events interface (IEventSource)
All SMP Objects which represent the source of event notifications shall implement the IEventSource interface as per IEventSource.h in [SMP_FILES].
The specification of event sources ensures that event sinks (see 5.2.6.1) that wish to receive their notifications can subscribe to them.
The IEventSource Subscribe method shall add the given event sink to the list of subscribed event sinks, with the following argument and behaviour:
- Argument:
- “eventSink” giving the reference to the event.
- Behaviour:
- If the given event sink is already subscribed to the event source, it throws an EventSinkAlreadySubscribed exception as per EventSinkAlreadySubscribed.h in [SMP_FILES];
- If the primitive type kind of the argument expected by the event sink is not semantically equivalent to the one of the event source as per Table 53, it throws an InvalidEventSink exception as per InvalidEventSink.h in [SMP_FILES].
Any event sink can only be subscribed once to each event source.
The IEventSource Unsubscribe method shall remove the given event sink from the list of subscribed event sinks, with the following argument and behaviour:
- Argument:
- “eventSink” giving the event to be unsubscribed.
- Behaviour:
- If the given event sink is not subscribed to the event source, it throws an EventSinkNotSubscribed exception as per EventSinkNotSubscribed.h in [SMP_FILES].
Any event sink can only be unsubscribed if it has been subscribed before.
When the event source emits the event, it shall call the Notify method of all the subscribed event sinks in the same order as the sinks have been subscribed.
See 5.2.6.1 for specification of the event sinks interface.
Consumer of events interface (IEventConsumer)
All SMP Components which hold event sinks and want to allow external access to them shall implement the IEventConsumer interface as per IEventConsumer.h in [SMP_FILES].
The publication of event sinks ensures that they can subscribe to other component’s event sources.
The IEventConsumer GetEventSinks method shall return a collection of all the contained event sinks, with the following behaviour:
- If no event sink is contained, it returns an empty collection. The IEventConsumer GetEventSink method shall return the component’s event sink corresponding to the given name, with the following argument and behaviour:
- Argument:
- “name” giving the name of the Event Sink.
- Behaviour:
- If no event sink with the given name exists, it returns nullptr.
Provider of events interface (IEventProvider)
All SMP Components which hold event sources and want to allow external access to them shall implement the IEventProvider interface as per IEventProvider.h in [SMP_FILES].
The publication of event sources ensures that other component’s event sinks can subscribe to them.
The IEventProvider GetEventSources method shall return a collection of all the contained event sources, with the following behaviour:
- If no event source is contained, it returns an empty collection. The IEventProvider GetEventSource method shall return the component’s event source corresponding to the given name, with the following argument and behaviour:
- Argument:
- “name” giving the name of event source to be returned
- Behaviour:
- If no event source with the given name exists, it returns nullptr.
Entry points
Entry points calling interface (IEntryPoint)
All SMP Objects which represent a schedulable entry point shall implement the IEntryPoint interface as per IEntryPoint.h in [SMP_FILES].
The specification of entry points ensures that the scheduler or the event manager can trigger them when the relevant events are emitted.
The IEntryPoint Execute method shall be called when the triggering event is emitted.
Entry Points publisher interface (IEntryPointPublisher)
All SMP components which hold entry points and want to allow external access to them shall implement the IEntryPointPublisher interface as per IEntryPointPublisher.h in [SMP_FILES].
The IEntryPointPublisher GetEntryPoints method shall return a collection of all the contained entry points, with the following behaviour:
- If no entry point is contained, it returns an empty collection. The IEntryPointPublisher GetEntryPoint method shall return the component’s entry point corresponding to the given name, with the following argument and behaviour:
- Argument:
- “name” giving the name of the EntryPoint to be returned.
- Behaviour:
- If no entry point with the given name exists, it returns nullptr.
The “name” always identifies a unique EntryPoint, as a component cannot have several EntryPoints with same name.
Dynamic Invocation
Dynamic invocation interface (IDynamicInvocation)
All SMP Components which allow the simulation environment to invoke operations on them shall implement the IDynamicInvocation interface as per IDynamicInvocation.h in [SMP_FILES].
All operations of simulation components callable through dynamic invocation shall be registered by the component using the IPublication interface.
See 5.2.12.2d for specification of the IPublication PublishOperation method to be used. Parameters of operations need to be of types registered in the type registry, which excludes operations with parameters of other types from dynamic invocation.
The IDynamicInvocation CreateRequest method shall return an instance of a request class for identifying the given operation, with the following argument and behaviour:
- Argument
- “operationName” giving the name of the callable method.
- Behaviour:
- If the operation with the given name is not callable through dynamic invocation, it returns nullptr;
- If the operation with the given name is callable through dynamic invocation, a fully populated request object with all parameters of the operation shall be created and returned.
- 1 The behaviour of this mechanism in the context of operation overloading is not specified.
- 2 The calling object is responsible for memory management of the request object, and for its deletion via DeleteRequest.
The IDynamicInvocation Invoke method shall invoke the method referenced, with the following argument and behaviour: - Argument:
- “request” giving the identification of the callable method, as a fully populated request object implementing IRequest (see 5.2.8.2).
- Behaviour:
- If the operation specified by the request parameter is not callable through dynamic invocation, it throws an InvalidOperationName exception as per InvalidOperationName.h in [SMP_FILES];
- If the number of arguments specified by the request object does not match the number of parameters of the callable operation, it throws an InvalidParameterCount exception as per InvalidParameterCount.h in [SMP_FILES];
- If the types of the arguments specified by the request object do not match the types of parameters of the callable operation, it throws an InvalidParameterType exception as per InvalidParameterType.h in [SMP_FILES];
- If called with a valid request object, it calls the operation identified in the request, passing the parameters provided in the request which are of parameter direction In or InOut;
- After invoking the request, it stores the parameter values of parameters with parameter direction InOut, Out or Return into the requests object.
The Invoke operation is a void operation as the result of the invocation is stored in the IRequest object (see 5.2.8.2.
The IDynamicInvocation DeleteRequest method shall release all resources associated to the given request instance.
All requests created with IDynamicInvocation CreateRequest shall be deleted with a call to IDynamicInvocation DeleteRequest.
The IDynamicInvocation GetProperties method shall return a collection of the invokable properties of the component as per PropertyCollection in IProperty.h in [SMP_FILES].
The IDynamicInvocation GetOperations method shall return a collection of the invokable operations of the component as per OperationCollection in IOperation.h in [SMP_FILES].
IRequest
All SMP Request objects which are used in dynamic invocation shall implement the IRequest interface as per IRequest.h in [SMP_FILES].
The IRequest GetOperationName method shall return the name of the callable operation represented by the request object.
Requests are usually created by calling the CreateRequest method of Dynamic Invocation (see 5.2.8.1) so the name returned is the string given to the CreateRequest method.
The IRequest GetParameterCount method shall return the number of parameters of the request object.
This operation only considers parameters of direction in, out or in/out, but not of type return.
The IRequest GetParameterIndex method shall return the index of a specified parameter, with the following argument and behaviour:
- Argument:
- “name” giving the name of the parameter for which the index is returned.
- Behaviour:
- If the name corresponds to the name of a parameter in the parameter collection, it returns the 0-based index of the parameter in this collection;
- If no parameter with the given name exists, it returns -1.
This operation only considers parameters of direction in, out or in/out, but not of type return.
The IRequest SetParameterValue method shall store the value for a parameter, with the following arguments and behaviour:
- Arguments:
- “index” giving the location of the parameter to be set;
- “value” giving the new value of the parameter.
- Behaviour:
- If the index is less than zero, it throws an InvalidParameterIndex exception as per InvalidParameterIndex in [SMP_FILES];
- If the index is greater than or equal to the number of parameters of the request object, it throws an InvalidParameterIndex exception as per InvalidParameterIndex in [SMP_FILES];
- If the type of the given value is different than the type of the parameter at the given index, it throws an InvalidParameterValue exception as per InvalidParameterValue.h in [SMP_FILES];
- If both index and value are valid, it stores the new value into the parameter with the given index, so that its new value can be returned with future calls to GetParameterValue.
This operation only considers parameters of direction in, out or in/out, but not of type return.
The IRequest GetParameterValue method shall return the value stored at the given index in the parameters collection, with the following argument and behaviour:
- Argument:
- “index” of the parameter for which the value is returned.
- Behaviour:
- If the given index is less than zero, it throws an InvalidParameterIndex exception as per InvalidParameterIndex.h in [SMP_FILES];
- If the index is greater than or equal to the number of parameters of the request object, it throws an InvalidParameterIndex exception as per InvalidParameterIndex.h in [SMP_FILES];
- If the index is valid, it returns the current value of the parameter.
- 1 The current value is either the initial value from creation of the request object, or the value provided to the last successful call of the SetParameterValue method for the same index.
- 2 This operation only considers parameters of direction in, out or in/out, but not of type return.
The IRequest SetReturnValue method shall allow to set a return value in the request with the following argument and behaviour: - Argument:
- “value” giving the new value to be set for the return parameter.
- Behaviour:
- If the operation does not return a value, it throws a VoidOperation exception as per VoidOperation.h in [SMP_FILES];
- If the type of the provided value does not match the type of the return value of the operation, it throws an InvalidReturnValue exception as per InvalidReturnValue.h in [SMP_FILES];
- If the operation does return a value of the given type, the return value is stored into the request object, so that it can be retrieved with later calls to GetReturnValue.
The IRequest GetReturnValue method shall return the return value of the callable operation in the request, with the following behaviour:
- If the operation does not return a value, it throws a VoidOperation exception as per VoidOperation.h in [SMP_FILES];
- If the operation does return a value, it returns the current value of the return parameter.
The current value is either the initial value from creation of the request object, or the value provided to the last successful SetReturnValue call.
Persistence (IPersist)
All SMP Objects which need self-persistence of data shall implement the IPersist interface as per IPersist.h in [SMP_FILES].
Self-persistence is an optional interface as external persistence by the simulation environment is sufficient for most components.
All Simulation objects which implement self-persistence shall read from the IStorageReader interface exactly the same amount of data and in the same order as it writes it to the IStorageWriter interface.
The IPersist Restore method shall read persisted data from storage through the IStorageReader interface with the following argument and behaviour:
- Argument:
- “reader” giving a pointer to a IStorageReader interface where data can be read from.
- Behaviour:
- The operation restores exactly the same amount of data from the reader that was stored by the writer on Store;
- If the operation cannot restore the data, it throws a CannotRestore exception as per CannotRestore.h in [SMP_FILES].
The IPersist Store method shall write persisted data to the storage through the IStorageWriter interface with the following argument and behaviour:
- Argument:
- “writer” giving a pointer to a IStorageWriter interface where data can be written to.
- Behaviour:
- The operation stores exactly the amount of data to the writer than what it restores from a reader on Restore;
- If the operation cannot store the data, it throws a CannotStore exception as per CannotStore.h in [SMP_FILES].
Failures
Failure interface (IFailure)
All SMP Objects which represent a failure shall implement the IFailure interface as per IFailure.h in [SMP_FILES].
The IFailure Fail method shall set the state of the failure to “failed”.
The IFailure Unfail method shall set the state of the failure to “not failed”.
The IFailure IsFailed method shall return the failure state of the failure with the following behaviour:
- If the state is “failed”, it returns true;
- If the state is not “failed”, it returns false.
Model failure state interface (IFallibleModel)
All Simulation models which can be failed through a list of possible failures shall implement the IFallibleModel interface as per IFallibleModel.h in [SMP_FILES].
- 1 This is an optional interface.
- 2 The simulation environment does not automatically persist the state of each failure, as it is the responsibility of the models to store the failure state in persisted data.
The IFallibleModel GetFailures method shall return the list of possible failures for this simulation model.
The IFallibleModel GetFailure method shall return a failure instance from the list of possible failures, with the following argument and behaviour: - Argument:
- “name” giving the name of the failure.
- Behaviour:
- If none of the failures in the list of possible failures matches the given name, it returns nullptr.
- If a failure matching the given name exists, it returns the pointer to the IFailure instance.
The IFallibleModel IsFailed method shall return the failure state of the model, with the following behaviour:
- If at least one of the failures returns true for its IFailure::IsFailed among the list of possible failures for this simulation model, it returns true;
- If none of the failures returns true for its IFailure::IsFailed among the list of possible failures for this simulation model, it returns false.
Field interfaces
ISimpleField
All SMP Fields which represent a primitive type shall implement the ISimpleField interface as per ISimpleField.h in [SMP_FILES].
The ISimpleField GetValue method shall return the field value stored in an AnySimple as per AnySimple.h in [SMP_FILES].
The ISimpleField SetValue method shall store the value in the field with the following argument and behaviour:
- Argument:
- “value” giving the new value to the field as an AnySimple as per AnySimple.h in [SMP_FILES].
- Behaviour:
- If the given value simple type kind does not match the simple type kind of the field, then it throws the InvalidFieldValue exception as per InvalidFieldValue.h in [SMP_FILES];
- If the given value simple type kind does match the simple type kind of the field, then it changes the field value to the given value.
The ISimpleField GetPrimitiveTypeKind method shall return the primitive type kind of the field.
IStructureField
All SMP Fields which represent a structured data shall implement the IStructureField interface as per IStructureField.h in [SMP_FILES].
The IStructureField GetField shall return the field as an IField, with the following argument and behaviour:
- Argument:
- “name” given the field name for which the IField interface is returned.
- Behaviour:
- If the field name is unknown to the structure, it returns nullptr.
The IStructureField GetFields shall return the list of fields of the structure as per FieldCollection in IField.h in [SMP_FILES].
- If the field name is unknown to the structure, it returns nullptr.
IArrayField
All SMP fields which represent an array where each array item is to be retrieved individually as a Field shall implement the IArrayField interface as per IArrayField.h in [SMP_FILES].
The IArrayField GetField shall return the array item as an IField as per IField.h in [SMP_FILES] with the following argument and behaviour:
- Argument:
- “index” giving the location of the item for which the IField pointer is returned.
- Behaviour:
- If the given index is outside the array size, it throws an InvalidArrayIndex as per InvalidArrayIndex.h in [SMP_FILES].
- Otherwise, return the array item at the given index as an IField
The IArrayField GetSize method shall return the number of array items.
ISimpleArrayField
All SMP fields which represent an array of simple type items where individual array items are not to be retrieved as Field shall implement the ISimpleArrayField interface as per ISimpleArrayField.h in [SMP_FILES].
This enables an efficient implementation especially of large arrays as a single object, rather than having each array item represented by an individual object. The implications are that such array items cannot be retrieved as Object or Field, e.g. via GetField(), and are hence not available in operations that require individual objects or fields.
The ISimpleArrayField GetSize method shall return the number of array items.
The ISimpleArrayField GetValue shall return the corresponding array item value stored in an AnySimple as per AnySimple.h in [SMP_FILES] with the following argument and behaviour:
- Argument:
- “index” giving the location of the item for witch the value is returned.
- Behaviour:
- If the given index is outside the array size, it throws an InvalidArrayIndex as per InvalidArrayIndex.h in [SMP_FILES].
- Otherwise, return the item value corresponding to the given index as an AnySimple.
The ISimpleArrayField SetValue shall set the corresponding array item value stored with the following arguments and behaviour:
- Arguments:
- “index” giving the location of the item for witch the value is set;
- “value” giving the new value for the array item.
- Behaviour:
- If the given index is outside the array size, it throws an InvalidArrayIndex as per InvalidArrayIndex.h in [SMP_FILES].
- If the given value simple type kind does not match the simple type kind of the corresponding array item, then it throws an InvalidFieldValue as per InvalidFieldValue.h in [SMP_FILES].
- If the given value simple type kind does match the simple type kind of the corresponding array item, then it stores the given AnySimple value into the item value corresponding to the given index.
The ISimpleArrayField GetValues method shall return all the array item values stored in an AnySimpleArray as per AnySimpleArray.h in [SMP_FILES] with the following arguments and behaviour:
- Arguments:
- “length” giving the length of the return array for values;
- “values” giving an array of allocated storage for which the return values are put.
- Behaviour:
- If the given value array size does not match the ArrayField size, it throws an InvalidArraySize as per InvalidArraySize.h in [SMP_FILES].
- Otherwise, copy all the item values into the given AnySimpleArray.
The ISimpleArrayField SetValues method shall allow setting all values of an array with the following arguments and behaviour:
- Arguments:
- “length” giving the length of the array with values to be set;
- “values” giving an array of values to be set in the array.
- Behaviour:
- If the given length does not match the ArrayField length, it throws a InvalidArraySize as per InvalidArraySize.h in [SMP_FILES];
- If any of the given values simple type kind does not match the array item simple type kind, then it throws an InvalidFieldValue as per InvalidFieldValue.h in [SMP_FILES].
- If any of the given values simple type kind does match the array item simple type kind, then it stores the given values into the corresponding array item values.
IField
All SMP fields shall implement the IField interface as per IField.h in [SMP_FILES].
The IField GetView method shall return the View Kind for the field.
See Table 42 for specification of View Kind.
The IField IsState method shall return true if the field State property is true, false otherwise.
The IField IsInput method shall return true if the field is an Input field, false otherwise.
The IField IsOutput method shall return true if the field is an Output field, false otherwise.
The IField GetType shall return the associated field type or nullptr if the field type has not been published in the Type Registry.
IForcibleField
All SMP simple fields which allow forcing of the field value shall implement the IForcibleField interface as per IForcibleField.h in [SMP_FILES].
The IForcibleField Force method shall force the field value so that it does not change until Unforce is called with the following argument and behaviour:
- Argument:
- “value” giving the forced value to be returned by GetValue until Unforce is called.
- Behaviour:
- If the given value simple kind does not match the field simple type kind, then it throws an InvalidFieldValue as per InvalidFieldValue.h in [SMP_FILES];
- If the given value simple kind does match the field simple type kind, then it stores the given value as the value to return by GetValue.
The handling of the forced field value within a model is undefined.
The IForcibleField Unforce method shall remove the forcing or freezing condition on the field so that GetValue called on the field returns the current field value.
The handling of the forced field value within a model is undefined.
The IForcibleField Freeze method shall force the field to its current field value so that it no longer changes until Unforce is called.
The IForcibleField IsForced shall return true if field is forced or freezed, otherwise it returns false.
IDataflowField
All SMP fields which support actively pushing their values to connected fields shall implement the IDataflowField interface as per IDataflowField.h in [SMP_FILES].
Dataflow connections are allowed for array items, structure fields and any sub-field of complex type fields.
The IDataflowField Connect method shall connect the field to an input field to create a dataflow connection between the two fields giving the following argument and behaviour:
- Argument:
- “target” giving the input field this output data flow field is connected to.
- Behaviour:
- If the target is already connected to this output field, it throws a FieldAlreadyConnected exception as per FieldAlreadyConnected.h in [SMP_FILES];
- If Connect is called several times for an output field, it connect the output field to a list of input fields allowing the same output to push values to several input fields;
- If the input and output field have the same type UUID, then the connection is considered to be strict compatible and it connects successfully;
- If the input and output field are of semantically equivalent types as per Table 53, then the connection is considered to be of equivalent types and it connects successfully;
- If the input and output are of non-equivalent and non-strict compatible types, it throws an InvalidTarget exception as per InvalidTarget.h in [SMP_FILES];
- If connection is successful, it invokes the Push methods immediately, triggering an update of the connected input field with the current value of the output field.
- 1 The specification of semantically equivalent type ensures that no information can be lost in transfer of data from output to input.
- 2 The input field is a passive part of the transfer since the output is pushing the values to the input.
- 3 The input field can be connected to several output fields.
- 4 The call of the Push allows to synchronise the Input value with the Output value immediately after the connection is established.
- 5 For arrays and structs, each array and struct element can implement IDataFlowField. In this case, each element can be connected with its own Connect call.
The IDataflowField Push method shall push the field value to all connected input fields. - 1 This is also called propagation of the value to all the connected consumer models.
- 2 Since the responsibility of calling the Push operation is delegated to the component owning the field, the propagation happens “automatic” as seen from the viewpoint of the simulation environment, hence this interaction method is called “automatic data propagation”.
Table 53: Semantically equivalent types for connections
|
Type
|
Semantically equivalent types
|
|
Char8
|
Char8
|
|
String
|
String of same length
|
|
Bool
|
Bool
|
|
Signed integers
|
Signed integer with same size
|
|
Unsigned integers
|
Unsigned integer with same size
|
|
Float
|
Float with same size
|
|
Array
|
Array with same length and each element are of semantically equivalent types.
|
|
Struct
|
Struct with:
|
|
Duration
|
Duration
|
|
DateTime
|
DateTime
|
|
Enumeration
|
Same enumeration type definition
|
Requirements on utilization of Simulation Environments interfaces by components
ILogger interface utilization
LogMessageKind type as per Services/LogMessageKind.h in [SMP_FILES] shall be used to store the Log Message Kind as returned from the results of ILogger::QueryLogMessageKind
The LogMessageKind returned is guaranteed to be always the same, even after a simulation state save or restore.
All SMP models and services shall use the predefined LogMessageKinds as defined in Table 54 for messages of message type Information, Event, Warning, Error or Debug .
IPublication interface
All Arrays published as a single array via the IPublication PublishArray method shall be without any padding.
This implies that array element with index i (0-based) is assumed to be stored at address of index 0 + i*sizeof(primitiveType).
When publishing arrays via the IPublication PublishArray method that require each element to be published individually, the following steps shall be followed:
- Call the IPublication PublishArray method giving the following arguments:
- Name of array
- Description of Array
- The PublishArray method returns a pointer to a IPublication interface
- Use the returned IPublication interface to publish each of the elements of the array.
In case of a multi-dimensional array, step 1-3 in 5.2.12.2b can be repeated iteratively.
When publishing a structure via the IPublication PublishStructure method, the following steps shall be followed:
- Call the IPublication PublishStructure method giving the following arguments:
- Name of Structure
- Description of Structure
- The PublishStructure method returns a pointer to a IPublication interface
- Use the returned IPublication interface to publish each of the elements of the structure.
In case of nested structures, steps 1-3 above can be repeated iteratively.
The IPublication PublishOperation method shall allow publishing an operation as per following procedure:
- Call the IPublication PublishOperation method giving the following arguments:
- Name of Operation
- Description of Operation
- Its view state
- The IPublication PublishOperation method returns a pointer to a IPublicationOperation interface
- Use the returned IPublicationOperation interface to publish each of the parameters and the return value of the operation.
See clause 5.3.9.2 for specification of the IPublicationOperation interface
ISimulator interface
All user defined services shall be added to the simulation using the ISimulator AddService method.
Simulation Environment interfaces
Logger (ILogger interface)
The Simulation Environment shall provide a component implementing the ILogger interfaces as per Services/ILogger.h in [SMP_FILES].
The component implementing the ILogger interface shall maintain a list mapping the defined Log Message Kinds names and IDs, including and eventually extending Table 54.
The ILogger QueryLogMessageKind method shall translate from the name of the message kind to the identifier of the message kind, with the following argument and behaviour:
- Argument:
- “messageKindName” giving a case sensitive string containing the name of the log message kind.
- Behaviour:
- If the given name matches one of the predefined LogMessageKind as specified in Table 54, it returns the corresponding LogMessageKind ID as per Table 54;
- If the given name does not match any LogMessageKind in Table 54 nor any of the log message kinds in the maintained mapping, it returns a new LogMessageKind ID as a unique identifier matching the given name;
- If the given name does not match any LogMessageKind in Table 54 but it matches one of the entries in the maintained mapping of log message kinds, it returns the corresponding LogMessageKind ID from the mapping.
Table 54: Default Log Message Kinds
|
Name
|
ID
|
Description
|
|
Debug
|
4
|
To be used for messages that can help during investigations of anomalous behaviours, but that regular users in nominal situations are not interested in seeing.
|
|
Error
|
3
|
To be used for error messages that the simulation or the model developer thinks are to be conveyed to the user when anomalous situations happen, that almost surely can lead to an anomalous simulation.
|
|
Warning
|
2
|
To be used for messages that the simulation or the model developer thinks are to be conveyed to the user when anomalous situations happen, that deserves users’ attention, but that non necessarily lead to an anomalous simulation.
|
|
Event
|
1
|
To be used for log messages that the simulation or the model developer thinks are to be conveyed to the user upon certain events (the definition of ’event’ is open and simulation or model developer driven).
|
|
Information
|
0
|
The message contains general information.
|
The list mapping the defined log message kinds to the defined LogMessageKind IDs shall be part of persisted data and saved/restored to/from breakpoints.
The list of log message kinds mapping shall be restored upon breakpoint restoring.
This implies that the list of log message kinds and associated names are part of the breakpoints and that models can store log message kinds they need and not continuously ask which LogMessageKind corresponds to a given LogMessageKind name. This leads to more efficient implementations.
The ILogger Log method shall log a message, with the following arguments:
- “sender” giving the originator of the message;
- “message” giving the text to be logged;
- “kind” giving the registered log message kind for this message as returned from ILogger::QueryLogMessageKind method.
- If the LogMessageKind ID was not previously registered by using ILogger::QueryLogMessageKind, then it registers the passed LogMessageKind with text set to the passed number, followed by the sender’s Name and the string “undefined log message kind”.
This implicit registration of a new LogMessageKind ID allows to quickly identify models in a simulation that are logging using custom unregistered LogMessageKinds.
Time Keeper (ITimeKeeper)
The simulation environment shall provide a component implementing the ITimeKeeper interface as per ITimeKeeper.h in [SMP_FILES].
- 1 The ITimeKeeper gives access to the Time Keeper Service.
- 2 The ITimeKeeper is used to maintain all the simulation times.
The ITimeKeeper SetEpochTime method shall set the simulation Epoch Time, with the following argument and behaviour: - Argument:
- “epochTime” giving the new epoch time;
- Behaviour:
- After setting the EpochTime, it emits a SMP_EpochTimeChanged global SMP event.
- 1 See Table 55 for details on EpochTimeChanged global Event.
- 2 This method changes the offset between the Simulation time and the Epoch time.
The ITimeKeeper SetMissionStartTime method shall set a new start time for Mission time, with the following argument and behaviour: - Argument:
- “missionStart” giving the new Epoch time for which the Mission time is zero.
- Behaviour:
- After changing the MissionStartTime, it emits the SMP_MissionTimeChanged global SMP Event.
This method changes the offset between the Epoch time and the Mission time.
The ITimeKeeper SetMissionTime method shall set the Mission time, with the following argument and behaviour:
- Argument:
- “MissionTime” giving the new Mission time at the current Epoch time.
- Behaviour:
- After changing the MissionTime, it emits the SMP_MissionTimeChanged global SMP Event.
This method changes the offset between the Epoch time and the Mission time.
The ITimeKeeper SetSimulationTime method shall advance the Simulation time, the following argument and behaviour:
- Argument:
- “SimulationTime” giving the new simulation time
- Behaviour:
- If SetSimulationTime method is called outside a PreSimTimeChange as per Table 55, then the method returns without updating the Simulation Time;
- If the given simulation time is less than the current simulation time, it throws an InvalidSimulationTime as per Services/InvalidSimulationTime.h in [SMP_FILES] and the Simulation Time is not updated;
- If the new simulation time is larger than the time of the next event on the scheduler, it throws an InvalidSimulationTime as per Services/InvalidSimulationTime.h in [SMP_FILES] and the Simulation Time is not updated;
- If SetSimulationTime method is called inside a PreSimTimeChange event as per Table 55, then the simulation time is updated to the given simulation time.
- 1 SetSimulationTime method should only called during a PreSimTimeChange global event as per Table 55.
- 2 SetSimulationTime method does not result in emissions of PreSimTimeChange and PostSimTimeChange global events as per Table 55.
When the Time Keeper updates the Simulation time in response to the Scheduler executing a new event, the update shall be performed as per the following procedure: - First the PreSimTimeChange event is emitted;
- If applicable, the simulation environment performs any activities related to maintain synchronization with Zulu time;
- Then the Simulation time is changed to the time of the Event that is about to be executed;
- Finally, the PostSimTimeChange event is emitted.
- 1 Depending on the timing constraints of the simulation, the Simulation Environment may perform actions (like delays) to keep the desired correlation between simulation time and Zulu time after the PreSimTimeChange event and the update of the Simulation Time for next event. How this synchronization is performed is outside the scope of this standard.
- 2 This method only sets the Simulation time between the current time and the time that is about to be set by the procedure described above.
The ITimeKeeper GetSimulationTime method shall return the Simulation time.
The ITimeKeeper GetEpochTime method shall return the current Epoch time.
The ITimeKeeper GetMissionTime method shall return the Mission time.
The TimeKeeper GetMissionStartTime method shall return the Mission Start Time.
The ITimeKeeper GetZuluTime method shall return the Zulu time.
Scheduler (IScheduler)
The simulation environment shall provide a Scheduler implementing the IScheduler in Services/IScheduler.h in [SMP_FILES].
The Scheduler shall allow Events to be added to the scheduler with a repeat count with the following behaviour:
- An Event with repeat=0 is non-cyclic and executes only once;
- An Event with repeat=0 is removed automatically after its triggering;
- An Event with repeat>0 is cyclic, and repeats ‘repeat’ times;
- An Event with repeat>0 is removed automatically after it has been triggered ‘repeat+1’ times;
- An Event with repeat<0 is cyclic forever;
- An Event with repeat<0 is never removed from the scheduler unless explicitly requested using the RemoveEvent() method. The Scheduler shall allow to specify the cycle time between each call for cyclic Events with the following behaviour:
- For non-cyclic Events, the cycle time parameter is stored, but not used;
- For cyclic Events, the cycle time is a positive duration;
- For cyclic Events, an InvalidCylceTime exception as per Services/InvalidCycleTime.h in [SMP_FILES] is thrown if the cycle time is negative or zero.
The cycle time can become relevant if a subsequent call to SetEventCount is received before the Event is removed from the scheduler.
Events added to the scheduler by AddSimulationTimeEvent, AddMissionTimeEvent, AddEpochTimeEvent and AddZuluTimeEvent shall be executed according to a “first posted, first executed” strategy where the posting order of Events are determined based on the order of the Add call.
This implies that the posting order is not affected by a change in Epoch time or Mission Time.
The IScheduler AddSimulationTimeEvent method shall add an Event to the scheduler, with the following arguments and behaviour:
- Arguments:
- “entryPoint” giving the Entry Point to be called when the Event is executed;
- “simulationTime” giving the relative time from now until the first call of the Entry Point;
- “cycleTime“ giving the cycle time of the Event as specified in 5.3.3c;
- “repeat“ giving the Event repetition count as specified in 5.3.3b.
- Behaviour:
- If the Simulation Time is less than zero, it throws an InvalidEventTime exception as per Services/InvalidEventTime.h in [SMP_FILES], the Event is not added to the scheduler and never executed.
- If Repeat is not zero and CycleTime is not positive, it throws an InvalidCycleTme exception as per Services/InvalidCycleTime.h in [SMP_FILES], the Event is not added to the scheduler and never executed;
- After adding the new Event to the scheduler, it returns the EventId as per Services/EventId.h in [SMP_FILES] identifying the added Event.
The execution order follows the general priority rules given in requirement 5.3.3d.
The IScheduler AddMissionTimeEvent method shall add an Event to the scheduler with the following arguments and behaviour:
- Arguments:
- “entryPoint“ giving the Entry Point to be called when the Event is executed;
- “missionTime“ giving the mission time of the first call of the Entry Point;
- “cycleTime“ giving the cycle time of the Event as specified in 5.3.3c;
- “repeat“ giving the Event repetition count as specified in 5.3.3b.
- Behaviour:
- If the Mission Time is less than the current mission time, it throws an InvalidEventTime exception as per Servives/InvalidEventTime.h in [SMP_FILES], the Event is not added to the scheduler and never executed;
- If Repeat is not zero and CycleTime is not positive, it throws an InvalidCycleTime exception as per Services/InvalidCycleTime.h in [SMP_FILES], the Event is not added to the scheduler and never executed;
- After adding the new Event to the scheduler, it returns the EventId as per Services/EventId.h in [SMP_FILES] identifying the added Event.
The execution order follows the general priority rules given in requirement 5.3.3d.
The IScheduler AddEpochTimeEvent method shall add an Event to the scheduler, with the following arguments and behaviour:
- Arguments:
- “entryPoint“ giving the Entry Point to be called when the Event is executed;
- “epochTime“ giving the epoch time of the first call of the Entry Point;
- “cycleTime“ giving the cycle time of the Event as specified in 5.3.3c;
- “repeat“ giving the Event repetition count as specified in 5.3.3b.
- Behaviour:
- If the Epoch Time is less than the current epoch time it throws an InvalidEventTime exception as per Services/InvalidEventTime.h in [SMP_FILES], the Event is not added to the scheduler and never executed;
- If Repeat is not zero and CycleTime is not positive, it throws an InvalidCycleTime exception as per Services/InvalidCycleTime.h in [SMP_FILES], the Event is not added to the scheduler and never executed;
- After adding the new Event to the scheduler, it returns the EventId as per Services/EventId.h in [SMP_FILES] identifying the added Event.
The execution order follows the general priority rules given in requirement 5.3.3d.
The IScheduler AddZuluTimeEvent method shall add an Event to the scheduler, with the following arguments and behaviour:
- Arguments:
- “entryPoint“ giving the Entry Point to be called when the Event is executed;
- “zuluTime“ giving the Zulu time of the first call of the Entry Point;
- “cycleTime“ giving the cycle time of the Event as specified in 5.3.3c;
- “repeat“ giving the Event repetition count as specified in 5.3.3b.
- Behaviour:
- If the given Zulu Time is less than the current Zulu time, it throws an InvalidEventTime exception as per Services/InvalidEventTime.h in [SMP_FILES], the Event is not added to the scheduler and never executed;
- If Repeat is not zero and CycleTime is not positive, it throws an InvalidCycleTime exception as per Services/InvalidCycleTime.h in [SMP_FILES], the Event is not added to the scheduler and never executed;
- After adding the new Event to the scheduler, it returns the EventId as per Services/EventId.h in [SMP_FILES] identifying the added Event.
The execution order follows the general priority rules given in requirement 5.3.3d.
The IScheduler AddImmediateEvent method shall add an immediate simulation time event to the scheduler with the current simulation time as execution time returning an EventId as per Services/EventId.h in [SMP_FILES], with the following argument and behaviour:
- Argument:
- “entryPoint” giving the Entry Point to be called when the Event is executed.
- Behaviour:
- The scheduled event is inserted at the front of the list of events scheduled for the current simulation time making it the next event to be executed;
- After adding the new Event to the scheduler, it returns the EventId identifying the added Event.
- 1 Calls to AddImmediateEvent differs to calls to AddSimulationTimeEvent method with repeat=0, cycleTime=0 and simulationTime=0 since the event is scheduled at the font instead of the end of the list of scheduled events for the current simulation time.
- 2 It cannot be assumed that Events added via AddImmediateEvent are the next Event executed, as other Events can be scheduled with AddImmediateEvent prior to its execution, hence executed first.
- 3 To execute an entry point immediately without going through the scheduler, the Execute() method of the EntryPoint can be called directly.
The EventId returned when adding an event shall be unique throughout the entire duration of the simulation implying that EventIds cannot be reused after the Event has been executed.
The EventId must only be unique within the Scheduler context; the Event Manager service uses the same EventId type, but uniqueness across services is not required.
The IScheduler RemoveEvent method shall remove an already scheduled Event from the Scheduler, with the following argument and behaviour:
- Argument:
- “eventId” giving the unique identifier of the Event.
- Behaviour:
- If the given EventId does not identify an even currently in the Scheduler, it throws an InvalidEventId exception as per InvalidEventId.h in [SMP_FILES];
- If the EventId is identical to the current executing Event in the schedule, then the call is functionally equivalent to setting the repeat count to 0 via the SetEventCount.
Setting the repeat count to 0 implies that the Event is removed from the scheduler immediately after it is executed.
The IScheduler SetEventSimulationTime method shall update the Simulation time of the next execution of an Event with the following arguments and behaviour:
- Arguments:
- “eventId” giving the unique identifier of the Event;
- “simulationTime” giving the relative time from now until the next execution of the Event.
- Behaviour:
- If the Simulation Time is negative, the Event is never executed but instead removed immediately from the scheduler;
- If the given EventId is not currently on the scheduler, it throws an InvalidEventId exception as per InvalidEventId.h in [SMP_FILES];
- If the Event identified by the given EventId is not scheduled on Simulation time, it throws an InvalidEventId exception as per InvalidEventId.h in [SMP_FILES];
- When the Simulation time of the next execution of an Event is updated, it takes effect on all future repeats of this Event as per the remaining “repeat” count and respecting the given cycle-time between each repeat.
Events scheduled with AddImmediateEvent are also considered to be scheduled based on Simulation Time.
The IScheduler SetEventMissionTime method shall update the Mission time of the next execution of an Event with the following arguments and behaviour:
- Arguments:
- “eventId” giving the unique identifier of the Event;
- “missionTime” giving the time of the next execution of the Event.
- Behaviour:
- If the given EventId is not currently on the scheduler, it throws an InvalidEventId exception as per InvalidEventId.h in [SMP_FILES];
- If the Event identified by the given EventId is not scheduled on Mission time, it throws an InvalidEventId exception as per InvalidEventId.h in [SMP_FILES];
- If the mission time is before the current mission time, the Event is never executed but instead removed immediately from the scheduler;
- When the Mission time of the next execution of an Event is updated, it takes effect on all future repeats of this Event as per the remaining “repeat” count and respecting the given cycle-time between each repeat.
The IScheduler SetEventEpochTime method shall update the Epoch time of the next execution of an Event, with the following arguments and behaviour:
- Arguments:
- “eventId” giving the unique identifier of the Event;
- “epochTime” giving the time of the next execution of the Event.
- Behaviour:
- If the given EventId is not currently on the scheduler, it throws an InvalidEventId exception as per Services/InvalidEventId.h in [SMP_FILES];
- If the Event identified by the given EventId is not scheduled on Epoch time, it throws an InvalidEventId exception as per Services/InvalidEventId.h in [SMP_FILES];
- If the epoch time is before the current epoch time, the Event is never executed but instead removed immediately from the scheduler;
- When the Epoch time of the next execution of an Event is updated, it takes effect on all future repeats of this Event as per the remaining “repeat” count and respecting the given cycle-time between each repeat.
The IScheduler SetEventZuluTime method shall update the Zulu time of the next execution of an Event, with the following arguments and behaviour:
- Arguments:
- “eventId” giving the unique identifier of the Event;
- “zuluTime” giving the time of the next execution of the Event.
- Behaviour:
- If the given EventId is not currently on the scheduler, it throws an InvalidEventId exception as per Services/InvalidEventId.h in [SMP_FILES];
- If the Event identified by the given EventId is not scheduled on Zulu time, it throws an InvalidEventId exception as per Services/InvalidEventId.h in [SMP_FILES];
- If the Zulu time is before the current Zulu time, the Event is never executed but instead removed immediately from the scheduler;
- When the Zulu time of the next execution of an Event is updated, it takes effect on all future repeats of this Event as per the remaining “repeat” count and respecting the given cycle-time between each repeat.
The IScheduler SetEventCycleTime method shall allow to update the cycle time of an already scheduled Event, with the following arguments and behaviour:
- Arguments:
- “eventId” giving the unique identifier of the Event;
- “cycleTime” giving the new cycle time of the Event as specified in 5.3.3c;
- Behaviour:
- If the given EventId is not currently on the scheduler, it throws an InvalidEventId exception as per Services/InvalidEventId.h in [SMP_FILES];
- If the Repeat count of the Event is not zero and CycleTime is not positive, it throws an InvalidCycleTime exception as per Services/InvalidCycleTime.h in [SMP_FILES] and the CycleTime is not updated.
The CycleTime can be set also for immediate events and events with repeat count equal to 0, as the repeat can be updated with SetEventCount afterwards.
The IScheduler SetEventCount method shall allow to update the repeat count of an Event already scheduled with the following arguments and behaviour:
- Arguments:
- “eventId” as a unique identifier of the Event;
- “count” giving the number of the Event repetitions as specified in 5.3.3b.
- Behaviour:
- If the given EventId that is not currently on the scheduler, it throws an InvalidEventId exception as per Services/InvalidEventId.h in [SMP_FILES];
- If Count is not zero and CycleTime of the Event is zero, it throws an InvalidCycleTime exception as per Services/InvalidCycleTime.h in [SMP_FILES] and the Count is not updated;
- If the given Count is greater than 0 and the given EventId is identical to the one currently executing, then the scheduler executes the Event for the given Count, excluding the current execution;
- If the given Count is 0, the Event is removed immediately after its execution is finished.
The IScheduler GetCurrentEventId method shall return an EventId as per Services/EventId.h in [SMP_FILES], with the following behaviour:
- If an Event is currently executing, it returns the EventId of the currently executing Event;
- If no scheduled Event is currently executing, it returns -1.
A scheduled Event may not be executing if the GetCurrentEventId is called as part of the SMP global events (See clause 5.3.4)
The IScheduler GetNextScheduledEventTime method shall return the Simulation Time of the execution of the next scheduled Simulation Time, Epoch Time or Mission Time Event.
- 1 Events scheduled in Zulu Time are not considered, as these Events do not have a fixed defined Simulation Time.
- 2 In case of Zulu Events executed, other Events may schedule Events prior to the time returned, hence the Scheduler does not guarantee that no other Events may be executed prior to the time returned from GetNextScheduledEvent().
The complete state of the Scheduler, with the exception of Events scheduled using ZuluTime, shall be part of persisted data and saved/restored to/from breakpoints.
When the SMP_EpochTimeChanged global SMP event is emitted, the events already scheduled with Epoch time shall behave as follows:- Non-cyclic events with Epoch Time equal to or in the future of the new Epoch Time, are executed according to the Epoch Time they were originally scheduled;
- Non-cyclic events with Epoch Time prior the new Epoch Time, are removed from the scheduler and not executed;
- For Cyclic Events, any repeat that falls prior the new Epoch Time is not executed and any positive repeat count is reduced according to the number of skipped executions;
- For Cyclic Events, any repeat that are equal or after the new Epoch Time is executed according to the original Epoch Time of the repeats.
When the SMP_MissionTimeChanged global SMP event is emitted, the events already scheduled with Mission time shall behave as follows: - Non-cyclic events with Mission time equal to or in the future of the new Mission Time, are executed according to the Mission Time they were originally scheduled;
- Non-cyclic events with Mission time prior the new Mission Time, are removed from the scheduler and not executed;
- For Cyclic Events, any repeat that falls prior the new Epoch Time is not executed and any positive repeat count is reduced according to the number of skipped executions;
- For Cyclic Events, any repeat that are equal or after the new Mission Time is executed according to the original Mission Time of the repeats.
When the simulator is in Standby state, the scheduler shall behave as follows:
- Events scheduled on simulation time including immediate Events, epoch and mission time are not processed;
- Events scheduled on Zulu time are executed.
Event Manager (IEventManager)
The simulation environment shall provide an Event Manager implementing the IEventManager interface as Services/IEventManager.h in [SMP_FILES].
The IEventManager QueryEventId method shall return the Event identifier for an Event, with the following argument and behaviour:
- Argument:
- “eventName” giving the name of the Event.
- Behaviour:
- If called with an empty name, it throws an InvalidEventName exception as per Services/InvalidEventName.h in [SMP_FILES];
- If called with the name of one of the pre-defined Event types as in Table 55 , it returns the corresponding EventId as in Table 55;
- If called with a non-empty event name different from all pre-defined event types as in Table 55, it returns an event identifier different from all pre-defined event identifiers in Table 55;
- If called with the same name again in the context of a restored simulation, it returns always the same event identifier.
This implies that the EventManager maintains a global list of events that is persisted in the breakpoint and restored when needed.
The Event Manager shall maintain a list of pairs of unique event identifiers and entry points.
The event identifier must only be unique within the Event Manager context; the Scheduler service uses the same EventId type, but uniqueness across services is not required.
The Event Manager shall initialise the list of pairs to be empty at creation time.
The IEventManager Subscribe method shall allow to subscribe an entry point to a global event identifier, with the following arguments and behaviour:
- Arguments:
- “event” giving the ID of the event to be subscribed;
- “entryPoint” giving a pointer to the entry point to be called when the event is emitted.
- Behaviour:
- If called with a pair of event identifier and entry point that is not currently in the internal list, it adds this pair to the internal list;
- If called with a pair of event identifier and entry point that is already in the internal list, it throws an EntryPointAlreadySubscribed exception as per Services/EntryPointAlreadySubscribed.h in [SMP_FILES];
- If called with an event ID that does not exist, it throws an InvalidEventId exception as per Services/InvalidEventId.h in [SMP_FILES].
The IEventManager Unsubscribe method shall remove a pair from the list, with the following arguments and behaviour:
- Arguments:
- “event” giving the ID of the event to be unsubscribed;
- “entryPoint” giving a pointer to the entry point to be unsubscribed.
- Behaviour:
- If called with a pair of event identifier and entry point that is currently in the internal list, it removes this pair to the internal list;
- If called with a pair of event identifier and entry point that is not in the internal list, it throws an EntryPointNotSubscribed exception as per Services/EntryPointNotSubscribed.h in [SMP_FILES];
- If called with an invalid event id, it throws an InvalidEventId exception as per Services/InvalidEventId.h in [SMP_FILES].
The IEventManager Emit method shall emit a specific global event to all the subscribed entry points, with the following arguments and behaviour:
- Arguments:
- “eventId” giving the ID of the event to be emitted;
- “synchronous” giving if the event is emitted synchronous to all subscribed entry points.
- Behaviour:
- If called with an event identifier for which pairs with entry points exist in the list, then these entry points are called;
- If more than one entry point is called, then the order of the calls are not guaranteed;
- If called with the synchronous flag set to false, the calls to the entry points are asynchronous, such that the call to the Emit method is not blocked from returning while waiting for calls to subscribed entry points to return;
- If called with the synchronous flag set to true, the calls to the entry points are synchronous, such that the call to the Emit method is blocked from returning until the calls to all subscribed entry points return.
The SMP predefined global events shall only be emitted in the conditions outlined in Table 55 and only by the Simulation Environment.
The SMP predefined global events shall be emitted with the synchronous flag set as per Table 55.
Table 55: Condition for emitting predefined global events
|
Name
|
EventId
|
Condition for emitting
|
Synchronous flag
|
|
SMP_LeaveConnecting
|
1
|
When leaving the Connecting state with an automatic state transition to Initializing state
|
True
|
|
SMP_EnterInitialising
|
2
|
When entering the Initialising state with an automatic state transition from Connecting state, or with the Initialise() state transition.
|
True
|
|
SMP_LeaveInitialising
|
3
|
When leaving the Initialising state with an automatic state transition to Standby state.
|
True
|
|
SMP_EnterStandby
|
4
|
When entering the Standby state with:
|
True
|
|
SMP_LeaveStandby
|
5
|
When leaving the Standby state with:
|
True
|
|
SMP_EnterExecuting
|
6
|
When entering the Executing state with the Run() state transition command from Standby state
|
True
|
|
SMP_LeaveExecuting
|
7
|
When leaving the Executing state with the Hold() state transition command to Standby state.
|
True
|
|
SMP_EnterStoring
|
8
|
When entering the Storing state with the Store() state transition command from Standby state
|
True
|
|
SMP_LeaveStoring
|
9
|
When leaving the Storing state with an automatic state transition to Standby state
|
True
|
|
SMP_EnterRestoring
|
10
|
When entering the Restoring state with the Restore() state transition command from Standby state
|
True
|
|
SMP_LeaveRestoring
|
11
|
When leaving the Restoring state with an automatic state transition to Standby state
|
True
|
|
SMP_EnterExiting
|
12
|
When entering the Exiting state with the Exit() state transition command from Standby state
|
True
|
|
SMP_EnterAborting
|
13
|
When entering the Aborting state with the Abort() state transition command from any other state
|
True
|
|
SMP_EpochTimeChanged
|
14
|
When changing the epoch time with the SetEpochTime() method of the time keeper service
|
True
|
|
SMP_MissionTimeChanged
|
15
|
When changing the mission time with one of the SetMissionTime() and SetMissionStartTime() methods of the time keeper service.
|
True
|
|
SMP_EnterReconnecting
|
16
|
When entering the Reconnecting state with the Reconnect() state transition from Standby state
|
True
|
|
SMP_LeaveReconnecting
|
17
|
When leaving the Reconnecting state with an automatic state transition to Standby state.
|
True
|
|
SMP_PreSimTimeChange
|
18
|
When all events have been executed by the Scheduler for a specific Simulation Time, but before the TimeKeeper changes the Simulation time to the time of next event.
|
False
|
|
SMP_PostSimTimeChange
|
19
|
When the simulation time has been changed by the Time Keeper, but before any events have been executed by the Scheduler.
|
False
|
Resolver (IResolver)
The simulation environment shall provide a component implementing the IResolver interface as Services/IResolver.h in [SMP_FILES].
The IResolver ResolveAbsolute method shall return a reference to a Component, Field, Failure, Container, Reference, Event Sink, Event Source or Entry Point object in the simulation, with the following argument and behaviour:
- Argument:
- “absolutePath” giving the absolute path string of the object.
- Behaviour:
- If the “absolutePath” does not give the path to an object, it returns nullptr;
- If no object with the given path can be found, it returns nullptr;
- If “absolutePath” resolves to an object, it returns the IObject reference to the object.
- 1 To allow keeping names as short as possible, and avoid dependency on the name of the simulator itself, absolute paths contain the name of either a top level Model or Service, but not the name of the simulator, although the simulator itself is the top-level object.
- 2 The specification of path string is given in clause 5.1.3.
The Resolver ResolveRelative method shall return a reference to an object in the simulation with the following arguments and behaviour: - Arguments:
- “relativePath” giving a path string representing the relative path to the object;
- “sender” giving the reference to the Component issuing the request.
- Behaviour:
- If “relativePath” does not resolve to any object, it returns nullptr;
- If “relativePath” resolves to an object, it returns an IObject reference to the object.
The specification of path string is given in clause 5.1.3.
Link Registry (ILinkRegistry)
The simulation environment shall provide a Link Registry service implementing the ILinkRegistry interface as Services/ILinkRegistry.h in [SMP_FILES].
- 1 The link registry maintains a global collection of links between components, supports adding, fetching and removing all links to a given target.
- 2 The links include Interface Links, Event Links and Field Links.
The ILinkRegistry AddLink method shall increment the link count between two components, with the following arguments and behaviour: - Arguments:
- “source” giving the source component;
- “target” giving the target component.
- Behaviour
- The link count between both components is incremented by one, taking note of a new link that has been created.
This method can be called several times with the same arguments, when a source component has several links to the same target component.
The ILinkRegistry GetLinkCount method shall return the link count between the given source and target, with the following arguments:
- “source” giving the source component;
- “target” giving the target component. The ILinkRegistry RemoveLink method shall decrement the link count between the two components, with the following arguments and behaviour:
- Arguments:
- “source” giving the source component;
- “target” giving the target component.
- Behaviour:
- If the link count between both components is positive, it is decremented by one, taking note that a link has been removed, and true is returned.
- If the link count between both components is 0, false is returned.
- 1 Existing links have been previously added to the service using the AddLink() method.
- 2 This method can be called several times with the same arguments, when several links from the source component to the same target component are removed.
The ILinkRegistry GetLinkSources method shall return the collection of source components for which a link to the given target component has been added to the registry.
The ILinkRegistry CanRemove method shall return whether all source components linking to the given target can be asked to remove their link(s), with the following argument and behaviour: - Argument:
- “target” giving the target component of the link.
- Behaviour:
- If all source components linking to the given target can be asked to remove their link(s), it returns true;
- If at least one of the source components linking to the given target cannot be asked to remove its link(s), it returns false.
Components can be asked to remove their links if they implement the optional ILinkingComponent interface.
The ILinkRegistry RemoveLinks method shall call the RemoveLinks method of all source components that implement the optional ILinkingComponent interface with the following argument:
- “target” giving the component from which all links to be removed.
Simulator (ISimulator)
The simulation environment shall provide a Simulator Object implementing the ISimulator interface as ISimulator.h in [SMP_FILES].
- 1 The ISimulator gives access to the simulation environment state and state transitions.
- 2 The ISimulator interface provides methods to add models and to add and retrieve simulation services.
The Simulator Object shall have two containers as follows: - One “Models” container that holds simulation models with no upper limit on the number of Models to hold;
- One “Services” container that holds simulation services with no upper limit on the number of Services to hold. The ISimulator interface shall be used to setup the simulation as per the following procedure:
- First the Publish method is called;
- After returning from the Publish call, the Configure method is called;
- After returning from the Configure method, the Connect method is called;
- After returning from the Connect method, the Initialise method is called. The ISimulator Publish method shall call the Publish() method of all service and model instances in the component hierarchy that are in Created state within the simulation as per following procedure:
- If the simulation is not in Building state, then it returns and no action is taken;
- If Publish method is called during the execution of the global event SMP_LeavingBuilding, then it returns and no action is taken;
- If the simulation is in Building state, it issues the global event “SMP_LeavingBuilding” via the Event Manager.
- After returning from the SMP_LeavingBuilding global event, it changes the simulation state to Publishing state.
- After entering Publishing state, it issues the global event “SMP_EnterPublishing” via the Event Manager.
- After returning from the “SMP_EnterPublishing” global event, it traverses through the "Service" container of the simulator, as follows:
- It calls the Publish() operation of each component in CSK_Created state;
- After calling Publish() on a service, it calls Publish() immediately on all its child components recursively.
- After completing the “Service” container, it traverses through the "Models" container of the simulator as follows:
- It calls the Publish() operation of each component in CSK_Created state;
- After calling Publish on a model, it calls Publish immediately on all its child components recursively.
- After all Publish() operations have been executed, it issues the global event “SMP_LeavingPublishing” via the Event Manager;
- After returning from the “SMP_LeavingPublishing” global event, it changes the simulation state to Building state;
- Finally, it issues the global event “SMP_EnteringBuilding” via the Event Manager. The ISimulator Configure method shall call the Configure() method of all service and model instances in the component hierarchy that are in Publishing state as per following procedure:
- If the simulation is not in Building state, then it returns and no action is taken;
- If Configure method is called during the execution of the global event SMP_LeavingBuilding, then it returns and no action is taken;
- If the simulation is in Building state, it issues the global event “SMP_LeavingBuilding” via the Event Manager;
- After returning from the SMP_LeavingBuilding global event, it changes the simulation state to “Configuring” state;
- After entering Configuring state, it issues the global event “SMP_EnterConfiguring” via the Event Manager;
- After returning from the “SMP_EnterConfiguring” global event, it traverses through the "Services" container of the simulator. For each component, it performs the following procedure:
- If the component is still in CSK_Created state, it first calls the Publish() operation;
- If the component is in CSK_Publishing state, it calls the Configure() operation;
- Then it immediately performs the same operation(s) recursively on all child components of the component.
- After configuring the Services, it traverses through the "Models" container of the simulator. For each component, it performs the following procedure:
- If the component is in CSK_Created state, it first calls the Publish() operation;
- If the component is in CSK_Publishing state, it calls the Configure() operation;
- Then it immediately performs the same operation(s) recursively on all child components of the component.
- After all Configure() operations have been executed, it issues the global event “SMP_LeavingConfiguring” via the Event Manager;
- After returning from the “SMP_LeavingConfiguring” global event, it changes the simulation state to Building state;
- Finally, it issues the global event “SMP_EnteringBuilding” via the Event Manager. The ISimulator Connect method shall call the Connect() method of all service and model instances in the component hierarchy that are in Configure state as per following procedure:
- If the simulation is not in Building state, then it returns and no action is taken;
- If Connect method is called during the execution of the global event SMP_LeavingBuilding, then it returns and no action is taken;
- If the simulation is in Building state, it issues the global event “SMP_LeavingBuilding” via the Event Manager;
- After returning from the SMP_LeavingBuilding global event, it changes the simulation state to Connecting state;
- After entering Connecting state, it issues the global event “SMP_EnterConnecting” via the Event Manager;
- After returning from the “SMP_EnterConnecting” global event, it traverses through the "Services" container of the simulator and performs the following actions:
- If the component is in CSK_Created state, it calls the Publish() operation;
- If the component is in CSK_Publishing state, it calls the Configure() operation;
- If the component is in CSK_Configure state, it calls the Connect() operation;
- Afterwards, it performs the same operation(s) recursively on all child components of the component.
- After connecting the services, the operation traverses through the "Models" container of the simulator performing the following actions:
- If the component is in CSK_Created state, it calls the Publish() operation;
- If the component is in CSK_Publishing state, it calls the Configure() operation;
- If the component is in CSK_Configure state, it calls the Connect() operation;
- Afterwards, it performs the same operation(s) recursively on all child components of the component.
- After all Connect() operations have been executed, it issues the global event “SMP_LeavingConnecting” via the Event Manager;
- After returning from the “SMP_LeavingConnecting” global event, it changes the simulation state to Initialising state;
- After entering Initialising state, it issues the global event “SMP_EnterInitialising” via the Event Manager;
- After returning from the “SMP_EnterInitialising” global event, it calls the initialising entry points for all models that has registered an initialising entry point via the ISimulator AddInitEntryPoint method in the order the entry points where added;
- After executing the entry points, it removes the entry points from the list so that in case Initialise is called again, the same Initialise entry point is not called twice;
- After calling all initialising entry points, it issues the global event “SMP_LeaveInitialising” via the Event Manager;
- After returning from the “SMP_LeaveInitialising” global event, it changes the simulation state to Standby state;
- Finally the global event “SMP_EnteringStandby” is issued via the Event Manager. The ISimulator Initialise method shall call all initialization entry points within the simulation as per the following procedure:
- If the simulation is not in Standby state, then it returns and no action is taken;
- If Initialise method is called during the execution of the global event SMP_LeavingStandby, then it returns and no action is taken;
- If the simulation is in Standby state, it issues the global event “SMP_LeavingStandby” via the Event Manager;
- After returning from the SMP_LeavingStandby global event, the simulator state changes to Initialising state;
- After entering Initializing state, it issues the global event “SMP_EnterInitialising” via the Event Manager;
- After returning from the SMP_EnterInitialising global event, it executes all entry points added via the ISimulator AddInitEntryPoint() method in the order they have been added by the AddInitEntryPoint() call;
- After executing the entry points, it removes the entry points from the list so that in case Initialise is called again, the same Initialise entry point is not called twice;
- After all entry points has been executed, it issues the global event “SMP_LeavingInitialising” via the Event Manager;
- After returning from the “SMP_LeavingInitialising” global event, it changes the simulation state to Standby state;
- Finally, it issues the global event “SMP_EnteringStandby” via the Event Manager. The ISimulator Run method shall change the state from Standby to Executing as per following procedure:
- If the simulation is not in Standby state, then it returns and no action is taken;
- If Run method is called during the execution of the global event SMP_LeavingStandby, then it returns and no action is taken;
- If Run method is called during the execution of the global event SMP_EnterStandby, then it returns and no action is taken;
- If the simulation is in Standby state, it issues the global event “SMP_LeavingStandby” via the Event Manager;
- After returning from the SMP_LeavingStandby global event, it changes the simulation state to “Executing” state;
- After entering Executing state, it issues the global event “SMP_EnterExecuting” via the Event Manager. The ISimulator Hold method shall change the state from Executing to Standby with the following argument and procedure:
- Argument:
- “hardHold” giving if the Simulation is halting immediately.
- Procedure:
- If the simulation is not in Executing state, then it returns and no action is taken;
- If called during the execution of the global event SMP_LeavingExecuting, then it returns and no action is taken;
- If called during the execution of the global event SMP_EnterExecuting, then it returns and no action is taken;
- If the simulation is in Executing state, it waits until the current executing event, if any, completes;
- After the current executing event is completed and if the hardHold argument is “false”, it executes all events scheduled for the current simulation time;
- After all events that needs executing is completed, it issues the global event “SMP_LeavingExecuting” via the Event Manager;
- After returning from the SMP_LeavingExecuting global event, it changes the simulation state to “Standby” state;
- After entering Standby state, it issues the global event “SMP_EnterStandby” via the Event Manager.
- 1 Halting the simulation with “hardHold” to “true” can cause the simulation to halt when some models have reached the current simulation time, but others not. This is useful for debugging purposes.
- 2 Halting the simulation with “hardHold” to “false” ensures that all simulation models have executed up until a consistent simulation time. This is useful for hardware in the loop simulations.
The ISimulator Store method shall store a breakpoint to file, with the following argument and procedure: - Argument:
- “filename” giving the name including the full path of the breakpoint file to be saved.
- Procedure:
- If the simulation is not in Standby state, then it returns and no action is taken;
- If Store method is called during the execution of the global event SMP_LeavingStandby, then it returns and no action is taken;
- If the simulation is in Standby state, it issues the global event “SMP_LeavingStandby” via the Event Manager;
- After returning from the SMP_LeavingStandby global event, it changes the simulation state to Storing state;
- After entering Storing state, it issues the global event “SMP_ EnterStoring” via the Event Manager;
- After returning from the “SMP_EnterStoring” event, it performs Self Persistence by calling the IPersist Store method on all simulation objects that implement the IPersist interface;
- After Self Persistence is completed, it performs External Persistence by storing the simulation state in the simulation breakpoint file given by the “filename” argument;
- After Store operation has been completed, it issues the global event “SMP_LeaveStoring” via the Event Manager;
- After returning from the “SMP_LeaveStoring” event, it changes the simulation state to Standby state;
- After entering Standby state, it issues the global event “SMP_EnterStandby” via the Event Manager.
Self-Persistence is performed prior to External Persistence during store as it allows models to update its published data prior to storing it.
The ISimulator Restore method shall restore a breakpoint from file, with the following argument and procedure:
- Argument:
- “filename” giving the name including the full path of the breakpoint file to restore.
- Procedure:
- If the simulation is not in Standby state, then it returns and no action is taken;
- If called during the execution of the global event SMP_LeavingStandby, then it returns and no action is taken;
- If the simulation is in Standby state, it issues the global event “SMP_LeavingStandby” via the Event Manager;
- After returning from the SMP_LeavingStandby global event, the simulation state is changed to Restoring state;
- After entering Restoring state, it issues the global event “SMP_EnterRestoring” via the Event Manager.
- After returning from the “SMP_EnterRestoring” event, it performs External Persistence by restoring the simulation state from a breakpoint file given by the “filename” argument;
- After completing External Persistence, it performs Self persistence by calling the IPersist Restore method of all simulation objects which implement the IPersist interface;
- After Restore operation has been completed, it issues the global event “SMP_LeavingRestoring” via the Event Manager;
- After returning from the “SMP_LeavingRestoring” event, the simulation state is changed to Standby;
- After entering Standby state, it issues the global event “SMP_EnterStandby” via the Event Manager.
Self-Persistence is performed after to External Persistence at restore as it allows models to use its published data during the self-persistence.
The ISimulator Reconnect method shall reconnect the component hierarchy starting at the root component given as parameter, with the following argument and procedure:
- Argument:
- “root” giving the component in the hierarchy for which the reconnect shall start from.
- Procedure:
- If the simulation is not in Standby state, then the method returns and no action is taken.
- If Reconnect method is called during the execution of the global event SMP_LeavingStandby, then the method returns and no action is taken.
- If the simulation is in Standby state, the global event “SMP_LeavingStandby” is issued via the Event Manager.
- After returning from the SMP_LeavingStandby global event, the simulation state is changed to “Reconnecting” state.
- The simulation environment ensures that all models under the given Root component parameter are published, configured and connected.
- After Reconnect operation has been completed, the simulation state is changed to Standby.
- After entering Standby state, the global event “SMP_EnterStandby” is issued via the Event Manager.
The ISimulator Exit method shall trigger a normal termination of a simulation, as per following procedure:
- If the simulation is not in Standby state, then it returns and no action is taken;
- If called during the execution of the global event SMP_LeavingStandby, then it returns and no action is taken;
- If the simulation is in Standby state, it issues the global event “SMP_LeavingStandby” via the Event Manager;
- After returning from the SMP_LeavingStandby global event, it changes the simulation state to “Exiting” state;
- After entering Exiting state, it issues the global event “SMP_EnterExiting” via the Event Manager;
- The Exit method triggers a normal termination of the simulation. The ISimulator Abort method shall trigger an abnormal termination of a simulation, as per following procedure:
- When called, it issues the global event “SMP_EnterAborting” via the Event Manager;
- After returning from the “SMP_EnterAborting” event, it changes the simulation state to Aborting state;
- After entering Aborting state, it triggers an abnormal termination of the simulation.
This method can be called from any other state.
The ISimulator GetState method shall return the current simulator state as per SimulatorStateKind in SimulatorStateKind.h in [SMP_FILES].
The ISimulator AddInitEntryPoint method shall add entry points to be executed in the Initialising state, as per following argument and behaviour:
- Argument:
- “entryPoint” giving a pointer to the entry point interface of the entry point to be added.
- Behaviour:
- If the simulation is not in Building, Connecting or Standby state, then it returns and no action is taken;
- If the simulation is in Building, Connecting or Standby state, it adds the entry point to the list of entry points to be executed once the simulation reaches Initialising state.
This allows components to subscribe to a callback during initialization phase since there are only explicit methods defined for Publish, Configure and Connect. This simplifies implementation for models that do not require initialization.
The ISimulator AddModel method shall add a model to the models collection of the simulator, with the following argument and behaviour:
- Argument:
- “model” giving the model to be added.
- Behaviour:
- If the Simulation is not in Standby, Building, Connecting or Initializing state, it throws an InvalidSimulatorState exception as per InvalidSimulatorState.h in [SMP_FILES];
- If the name of the new model conflicts with the name of an existing model already added via AddModel, it throws a DuplicateName exception as per DuplicateName.h in [SMP_FILES];
- If the name of the new model conflicts with the name of an existing service already added via AddService, it throws a DuplicateName exception as per DuplicateName.h in [SMP_FILES].
- 1 The container for the models has no upper limit and thus the ContainerFull exception will never be thrown.
- 2 The method will never throw the InvalidObjectType exception, as it gets a component implementing the IModel interface.
The ISimulator AddService method shall add a user-defined service to the services collection, with the following argument and behaviour: - Argument:
- “service” giving the service to be added.
- Behaviour:
- If the Simulation is not in Building state, it throws an InvalidSimulatorState exception as per InvalidSimulatorState.h in [SMP_FILES];
- If the name of the new service conflicts with the name of an existing model already added via AddModel, it throws a DuplicateName exception as per DuplicateName.h in [SMP_FILES];
- If the name of the new service conflicts with the name of an existing service already added via AddService, it throws a DuplicateName exception as per DuplicateName.h in [SMP_FILES].
- 1 The container for the services has no upper limit and thus the ContainerFull exception is never thrown.
- 2 The method never throw the InvalidObjectType exception, as it gets a component implementing the IService interface.
- 3 It is recommended that custom services include a project or company acronym as prefix in their name, to avoid collision of service names.
The ISimulator GetService method shall return the interface of a service with the following argument and behaviour: - Argument:
- “name” giving the name of the service.
- Behaviour:
- If no service with the given name , it returns nullptr;
- If a service with the given name is found, it returns a reference to that service.
The ISimulator GetLogger method shall return the interface of the mandatory logger service.
This is a type-safe convenience method, to avoid having to use the generic GetService() method. For the standardised services, it is recommended to use the convenience methods, which are guaranteed to return a valid reference.
The ISimulator GetTimeKeeper method shall return the interface to the mandatory time keeper service.
This is a type-safe convenience method, to avoid having to use the generic GetService() method. For the standardised services, it is recommended to use the convenience methods, which are guaranteed to return a valid reference.
The ISimulator GetScheduler method shall return the interface to the mandatory scheduler service.
This is a type-safe convenience method, to avoid having to use the generic GetService() method. For the standardised services, it is recommended to use the convenience methods, which are guaranteed to return a valid reference.
The ISimulator GetEventManager method shall return the interface to the mandatory event manager service.
This is a type-safe convenience method, to avoid having to use the generic GetService() method. For the standardised services, it is recommended to use the convenience methods, which are guaranteed to return a valid reference.
The ISimulator GetResolver method shall return the interface to the mandatory resolver service.
This is a type-safe convenience method, to avoid having to use the generic GetService() method. For the standardised services, it is recommended to use the convenience methods, which are guaranteed to return a valid reference.
The ISimulator GetLinkRegistry method shall return the interface to the mandatory link registry service.
This is a type-safe convenience method, to avoid having to use the generic GetService() method. For the standardised services, it is recommended to use the convenience methods, which are guaranteed to return a valid reference.
The ISimulator RegisterFactory method shall register a component factory, with the following argument and behaviour:
- Argument:
- “componentFactory” giving the factory to be registered.
- Behaviour:
- If another factory has been registered using the same implementation identifier already, it raises a DuplicateUuid exception as per DuplicateUuid.h in [SMP_FILES].
- 1 The simulator can use this factory to create component instances of the component implementation in its CreateInstance() method.
- 2 This method is typically called early in the Building state to register the available component before the hierarchy of model instances is created.
The ISimulator CreateInstance method shall create an instance of a component, with the following arguments and behaviour: - Arguments:
- “uuid” giving a unique identifier of the component implementation to create;
- “name” giving the name of the new instance;
- “description” giving the description of the new instance;
- “parent” giving the parent object of the new instance.
- Behaviour:
- If the uuid provided does not corresponds to a registered factory, it returns nullptr;
- If the name provided is not a valid object name, it raises an InvalidObjectName exception as per InvalidObjectName.h in [SMP_FILES];
- If the uuid provided corresponds to a registered model, and the name is a valid object name, it returns a reference to the newly created model with name, description and parent set as provided.
This method is typically called during Creating state when building the hierarchy of models.
The ISimulator GetFactory method shall return the factory of the component with the following argument and behaviour:
- Argument:
- “uuid” giving a unique identifier of the component implementation.
- Behaviour:
- If a factory has been registered with the given “uuid”, it returns a pointer to the registered factory;
- If no factory for the given “uuid” has been registered, it returns nullptr.
The ISimulator GetFactories method shall return a collection of all registered facories as per FactoryCollection in IFactory.h in [SMP_FILES].
The ISimulator GetTypeRegistry method shall return a reference to the Type Registry.
The ISimulator LoadLibrary method shall load a library for a Package, with the following argument and behaviour:
- Argument:
- "libraryPath" to the library to load.
- Behaviour:
- If called with an invalid libraryPath, it throws an LibraryNotFound exception as per LibraryNotFound.h in [SMP_FILES];
- If called with an libraryPath pointing to a library without initialise function, it throws and InvalidLibrary exception as per InvalidLibrary.h in [SMP_FILES];
- If called with the file name of a library, it loads this library into memory and calls the dynamic "Initialise()" function of this library;
- If called with the file name of a library, it calls the dynamic "Finalise()" function of this library when in Exiting or Aborting state.
The ISimulator GetContainers method shall return a ContainerCollection with two containers as follows:
- One container called “Models” with all the models added via ISimulator AddModel method;
- One container called “Services” with all the services added via the ISimulator AddService method. The ISimulator GetContainer method shall return the IContainer interface to the container, with the following argument and behaviour:
- Argument:
- “name” of the container to be returned.
- Behaviour:
- If called with “Models” as argument, it returns the container reference to the models container.
- If called with “Services” as argument, it returns the container reference to the Services container.
- If called with anything else than “Models” or “Services”, it returns nullptr.
The ISimulator GetParent shall return nullptr.
The Simulator is the root object in the simulator tree.
The ISimulator GetName shall return a valid name.
Persistence
Storage Reader Interface (IStorageReader)
The simulation environment shall provide a component implementing the IStorageReader interface as per IStorageReader.h in [SMP_FILES].
- 1 The IStoragerReader interface provides functionality to read data from storage.
- 2 The IStoragerReader interface allows objects implementing the IPersist interface to restore their state.
The IStorageReader Restore method shall restore data from storage, with the following arguments and behaviour: - Arguments:
- “address” giving the address of memory block;
- “size”, giving the size of the memory block.
- Behaviour:
- It reads from the breakpoint a memory block of the given size at the given address.
The IStorageReader GetStateVectorFileName method shall return the full name including the absolute path of the breakpoint file currently in use by the Storage Reader.
The IStorageReader GetStateVectorFilePath method shall return a full absolute path to the directory of the breakpoint file currently in use.
- It reads from the breakpoint a memory block of the given size at the given address.
The path can be used when reading additional files that correspond to the breakpoint file read.
Storage Writer Interface (IStorageWrite)
The simulation environment shall provide a component implementing the IStorageWriter interface as per IStorageWriter.h in [SMP_FILES].
- 1 The IStoragerWriter interface provides functionality to write data from storage.
- 2 The IStoragerWriter interface allows objects implementing the IPersist interface to store their state.
The IStorageWriter Store method shall store data to storage by writing a memory block of data to the breakpoint file with the following arguments: - “address” giving the address of memory block;
- “size” giving the size of the memory block.
The IStorageWriter GetStateVectorFileName method shall return the full name including the absolute path of the breakpoint file currently in use by the Storage Writer.
The IStorageWriter GetStateVectorFilePath method shall return a full absolute path to the directory of the breakpoint file currently in use.
The path can be used when writing additional files that correspond to the breakpoint file written.
Publication
IPublication
The simulation environment shall provide a component implementing the IPublication interface as per IPublication.h in [SMP_FILES].
The IPublication interface provides functionality to allow publishing simulation model members, including fields, properties and operations.
The IPublication GetTypeRegistry method shall return a reference to the Type Registry.
See clause 5.3.10 for details on the Type Registry.
The IPublication PublishField method shall allow publishing of a field, with the following arguments and behaviour:
- Arguments:
- “name” giving the field name;
- “description” giving the field description;
- “address” giving the pointer to the address where the value of the field is found supporting the following pointer types:
Char8, Bool, Int8, Int16, Int32, Int64, UInt8, UInt16, UInt32, UInt64, Float32, Float64. * “view” giving the fields view attribute as per ViewKind.h in [SMP_FILES]; - “state” given if the field is part of the simulation state when storing or restoring or not;
- “input” giving if the field is an input field or not;
- “output” giving if the field is an output field or not.
- Behaviour:
- If the name of the new field to be published is already used by another published field by the same Component, it throws DuplicateName as per DuplicateName.h in [SMP_FILES];
- If the name of the new field to be published is not a valid object name, it throws InvalidObjectName as per InvalidObjectName.h in [SMP_FILES].
- 1 The view kind attribute is specified in Table 42.
- 2 There is no publishing call for String8 as it relies on dynamically allocated memory areas, hence cannot be published like the other primitive types.
- 3 Duration and DateTime cannot be supported in the same way, as they are not strong types (they are defined to be identical to Int64, but with a different semantic). For publication of Duration and DateTime, PublishField with Uuid is used.
The IPublication PublishField method shall allow publishing a field, with the following arguments and behaviour: - Arguments:
- “name” giving the field name;
- “description” giving the field description;
- “address” giving the field memory address;
- “uuid” giving the field type;
- “view” giving the fields view attribute as per ViewKind.h in [SMP_FILES];
- “state” given if the field is part of the simulation state when storing or restoring or not;
- “input” giving if the field is an input field or not;
- “output” giving if the field is an output field or not.
- Behaviour:
- If the name of the new field to be published is already used by another published field by the same Component, it throws DuplicateName as per DuplicateName.h in [SMP_FILES];
- If the name of the new field to be published is not a valid object name, it throws InvalidObjectName as per InvalidObjectName.h in [SMP_FILES];
- If the given Uuid is not a valid Uuid of a registered type, it throws InvalidUuid as per InvalidUuid.h in [SMP_FILES].
The view kind attribute is specified in Table 42.
The IPublication PublishField method shall allow publishing a field, with the following argument and behaviour:
- Argument:
- “field” giving a pointer to the field IField interface.
- Behaviour:
- If the name of the new field to be published is already used by another published field by the same Component, it throws DuplicateName as per DuplicateName.h in [SMP_FILES].
All additional data defining the field is available via the operations supported by the IField interface.
The IPublication PublishArray method shall publish an array of simple types that can be mapped to a primitive type, with the following arguments and behaviour:
- Arguments:
- “name” giving the array name;
- “description” giving the array description;
- “count” giving the size of an array;
- “address” giving the array memory address of the first element;
- “type” giving the type of each array item;
- “view” giving the array view attribute as per ViewKind.h in [SMP_FILES];
- “state” given if the array is part of the simulation state when storing or restoring or not;
- “input” giving if the array is an input field or not;
- “output” giving if the array is an output field or not.
- Behaviour:
- If the name of the new Array to be published is already used by another published field by the same Component, it throws DuplicateName as per DuplicateName.h in [SMP_FILES];
- If the name of the new field to be published is not a valid object name, it throws InvalidObjectName as per InvalidObjectName.h in [SMP_FILES].
The IPublication PublishArray method shall allow to publish arrays of any type by allowing each element of the array to be published individually, with the following arguments and behaviour:
- Arguments:
- “name” giving the array name;
- “description” giving the array description.
- Behaviour:
- If the name of the new Array to be published already used by another published field by the same Component, it throws DuplicateName as per DuplicateName.h in [SMP_FILES];
- If the name of the new field to be published is not a valid object name, it throws InvalidObjectName as per InvalidObjectName.h in [SMP_FILES];
- A pointer to an IPublication object is returned.
- 1 The returned IPublication interface allows callers of PublishArray to publish each element of the array individually.
- 2 See clause 5.2.12.2 for details on how to public each element individually.
The IPublication PublishStructure method shall allow publishing a structure by allowing each child element to be published individually, with the following arguments and behaviour: - Arguments:
- “name” giving the struct name;
- “description” giving the struct description.
- Behaviour:
- If the name of the new Structure to be published is already used by another published field by the same Component, it throws DuplicateName as per DuplicateName.h in [SMP_FILES];
- If the name of the new Struct to be published is not a valid object name, it throws InvalidObjectName as per InvalidObjectName.h in [SMP_FILES];
- A pointer to an IPublication object is returned.
- 1 The returned IPublication interface allows callers of PublishStructure to publish each element of the struct individually.
- 2 See clause 5.2.12.2 for details on how to publish each element individually.
The IPublication PublishOperation method shall allow publishing of an operation, with the following arguments and behaviour: - Arguments:
- “name” giving the operation name;
- “description” giving the operation description;
- “view” giving the visibility of the operation
- Behaviour:
- If an Operation with the same Name is already published, it updates the “Description” and “View” of the previous publication and it returns the same IPublishOperation of the previously published Operation;
- If an Operation with the same Name is not published, it creates a new IPublishOperation instance and returns it.
- 1 The returned IPublishOperation interface allows callers of PublishOperation to publish parameters and return value of the operation.
- 2 See clause 5.2.12.2 for details on how to publish a complete operation including its parameters.
The IPublication PublishProperty method shall allow publishing a property, with the following arguments and behaviour: - Arguments:
- “name“ giving the property name;
- “description“ giving the property description.
- “uuid“ giving the property type.
- “accessKind“ giving the property access restrictions as per AccessKind.h in [SMP_FILES] allowing the following values:
Read and write;Read only;Write only. * “view“ giving its view kind attribute as per ViewKind.h in [SMP_FILES].
- Behaviour:
- If a Property with the same Name is already published, it updates the “description”, “uuid”, “accessKind” and “view” of the previous Property;
- If the given Uuid is not a valid Uuid of a registered type, it throws a TypeNotRegistered exception as per TypeNotRegistered.h in [SMP_FILES].
The IPublication GetField method shall return an interface to a field, with the following argument and behaviour:
- Argument:
- “fullName“ giving the path relative to the component.
- Behaviour:
- If no field exists with the given fully qualified name, it throws an InvalidFieldName exception as per InvalidFieldName.hin [SMP_FILES];
- If the field matching the given fully qualified name has a simple type, it returns an ISimpleField instance;
- If the field matching the given fully qualified name is an Array Field, it returns an IArrayField instance;
- If the field matching the given fully qualified name is a Structure Field, it returns an IStructureField instance.
The path relative to the component is constructed as per clause 5.1.3. Examples:
- MyStructuredField.InnerField
- MyArrayField[2]
- MyStructuredField.ArrayInnerField[2]
The IPublication GetFields method shall return a collection of published fields as per FieldCollection in IField.h in [SMP_FILES].
The IPublication GetProperties method shall return a collection of published properties as per PropertyCollection in Property.h in [SMP_FILES].
The IPublication GetOperations method shall return a collection of published operations as per OperationCollection in Operation.h in [SMP_FILES].
The IPublication CreateRequest method shall return a request object allowing dynamic invocation of a published operation with the following argument and behaviour: - Argument:
- “operationName” giving the name of operation.
- Behaviour:
- If no operation with the given name can be found, it returns nullptr.
- 1 See clause 5.2.8.2 for specification of the returned request object.
- 2 When the request object is no longer needed, destroyed with a call to IPublication DeleteRequest.
The IPublication DeleteRequest method shall delete request object that has been created with the CreateRequest() method, with the following argument: - “request” giving the object to be deleted.
The request object cannot be used anymore after DeleteRequest has been called for it.
The IPublication Unpublish method shall release all data published earlier via the Publish operations.
This is called prior to deleting the component that has called into a specific IPublication instance
IPublishOperation
The simulation environment shall provide a component implementing the IPublishOperation interface as per Publication/IPublishOperation.h in [SMP_FILES].
The IPublishOperation PublishParameter method shall allow publishing parameters of an operation, with the following arguments and behaviour:
- Arguments:
- “name” giving the parameter name;
- “description” giving the parameter description;
- “uuid” giving the parameter type identifier in the Type Registry;
- “direction” giving the parameter direction as per Publication/ParameterDirectionKind.h in [SMP_FILES] allowing the following values:
“In” for read only parameters that are not changed by the operation;“Out” for write only parameters where no initial value is specified but the operation provides an output value;“InOut” for both read and write parameters;“Return” for the operation return value.* Behaviour: - If the name of the new parameter to be published is already used by another published parameter by the same Operation, it throws DuplicateName as per DuplicateName.h in [SMP_FILES];
- If the given Uuid is not a valid Uuid of a registered type, it throws TypeNotRegistered as per TypeNotRegistered.h in [SMP_FILES];
- If the name of the new parameter to be published is not a valid object name, it throws InvalidObjectName as per InvalidObjectName.h in [SMP_FILES].
Type Registry
ITypeRegistry
The simulation environment shall provide, via the IPublication interface, a Type Registry publication implementing the ITypeRegistry interface as Publication/ITypeRegistry.h in [SMP_FILES].
This interface defines a registration mechanism for user defined types.
The Type Registry shall contain all pre-defined SMP value types with their pre-defined universally unique identifiers as per ecss.smp.smpcat in [SMP_FILES].
It is not mandatory for the models to make use of the Type Registry.
The ITypeRegistry GetType method shall return the interface to the requested primitive type, with the following argument:
- “type” giving a primitive type kind.
This method can be used to map primitive types to the IType interface to treat all types identically.
The ITypeRegistry GetType method shall return the interface to the requested type, with the following argument and behaviour:
- Argument:
- “typeUuid” giving the Uuid for which the type are returned.
- Behaviour:
- If no type with the registered Uuid are found, it returns nullptr.
This method can be used to find out whether a specific type has been registered before.
The ITypeRegistry AddFloatType method shall return the interface to a new Float type, with the following arguments and behaviour:
- Arguments:
- “name” giving the name of the registered type;
- “description” giving the description of the registered type;
- “uuid” giving the universally unique identifier of the registered type;
- “minimum” giving the minimum value for float;
- “maximum” giving the maximum value for float;
- “minIncluded” giving whether the minimum value is valid or not;
- “maxIncluded” giving whether the maximum value is valid or not;
- “unit” giving the unit of the type;
- “type” giving the primitive type to use for Float type.
- Behaviour:
- If the Primitive Type given is not a Float type, it throws an InvalidPrimitiveType exception as per InvalidPrimitiveType.h in [SMP_FILES];
- If another type with the same uuid already is registered, it throws a TypeAlreadyRegistered exception as per TypeAlreadyRegistered.h in [SMP_FILES].
- 1 IComponent and IDynamicInvocation support fields, parameters and operations of Float types via the PTK_Float32 and PTK_Float64 primitive type, as a Float is mapped either to Float32 or Float64.
- 2 In type registry, name duplication is possible as long as the uuid is unique.
The ITypeRegistry AddIntegerType method shall return the interface to a new Integer type, with the following arguments and behaviour: - Arguments:
- “name” giving the name of the registered type;
- “description” giving the description of the registered type;
- “uuid” giving the universally unique identifier of the registered type;
- “minimum” giving the minimum allowed value for integer;
- “maximum” giving the maximum allowed value for integer;
- “unit” giving the unit of the type;
- “primitiveType” giving the primitive type to use for Integer type.
- Behaviour:
- If the Primitive Type given is not an Integer type, it throws an InvalidPrimitiveType exception as per InvalidPrimitiveType.h in [SMP_FILES];
- If another type with the same uuid already is registered, it throws a TypeAlreadyRegistered exception as per TypeAlreadyRegistered.h in [SMP_FILES].
IComponent and IDynamicInvocation support fields, parameters and operations of Integer types via the PTK_Int primitive types, as an Integer is mapped to one of Int8 / Int16 / Int32 / Int64 / UInt8 / UInt16 / UInt32 / UInt64.
The ITypeRegistry AddEnumerationType method shall return the interface to a new Enumeration type, with the following arguments and behaviour:
- Arguments:
- “name” giving the name of the registered type;
- “description” giving the description of the registered type;
- “uuid” giving the universally unique identifier (UUID) of the registered type;
- “size” giving the size of an instance of this enumeration in bytes. Valid values are 1, 2, 4 and 8.
- Behaviour:
- If another type with the same uuid already is registered, it throws a TypeAlreadyRegistered exception as per TypeAlreadyRegistered.h in [SMP_FILES].
The ITypeRegistry AddArrayType method shall return the interface to a new Array type, with the following arguments and behaviour:
- If another type with the same uuid already is registered, it throws a TypeAlreadyRegistered exception as per TypeAlreadyRegistered.h in [SMP_FILES].
- Arguments:
- “name” giving the name of the registered type;
- “description” giving the description of the registered type;
- “typeUuid” giving the universally unique identifier of the registered type;
- “itemTypeUuid” giving the universally unique identifier of the Type of the array items;
- “itemSize” giving the size of an array item in bytes, taking possible padding into account, as it can be used by the simulation environment to calculate the memory offset between array items;
- “arrayCount” giving the number of elements in the array;
- “simpleArray” giving a flag whether a field of this array type is be implemented as ISimpleArrayField or as IArrayField.
- Behaviour:
- If another type with the same uuid already is registered, it throws a TypeAlreadyRegistered exception as per TypeAlreadyRegistered.h in [SMP_FILES].
The ITypeRegistry AddStringType method shall return the interface to a new String type, with the following arguments and behaviour:
- If another type with the same uuid already is registered, it throws a TypeAlreadyRegistered exception as per TypeAlreadyRegistered.h in [SMP_FILES].
- Arguments:
- “name” giving the name of the registered type;
- “description” giving the description of the registered type;
- “uuid” giving the universally unique identifier of the registered type;
- “length” giving the maximum length of the string.
- Behaviour:
- If another type with the same uuid already is registered, it throws a TypeAlreadyRegistered exception as per TypeAlreadyRegistered.h in [SMP_FILES].
The ITypeRegistry AddStructureType method shall return the interface to a new Structure type that allows adding fields, with the following arguments and behaviour:
- If another type with the same uuid already is registered, it throws a TypeAlreadyRegistered exception as per TypeAlreadyRegistered.h in [SMP_FILES].
- Arguments:
- “name” giving name of the registered type;
- “description” giving description of the registered type;
- “uuid” giving the universally unique identifier of the registered type.
- Behaviour:
- If another type with the same uuid already is registered, it throws a TypeAlreadyRegistered exception as per TypeAlreadyRegistered.h in [SMP_FILES].
The ITypeRegistry AddClassType method shall return the interface to a new Class type that allows adding fields, with the following arguments and behaviour:
- If another type with the same uuid already is registered, it throws a TypeAlreadyRegistered exception as per TypeAlreadyRegistered.h in [SMP_FILES].
- Arguments:
- “name” giving name of the registered type;
- “description” giving description of the registered type;
- “uuid” giving the universally unique identifier of the base class.
- Behaviour:
- If another type with the same uuid already is registered, it throws a TypeAlreadyRegistered exception as per TypeAlreadyRegistered.h in [SMP_FILES].
IType
The simulation environment shall provide a class implementing the IType interface as per Publication/IType.h in [SMP_FILES].
The IType GetPrimitiveTypeKind method shall return the primitive type kind as per PrimitiveTypes.h in [SMP_FILES] for types in the type registry as follows:
- If the type cannot be mapped to a primitive type kind, it returns PTK_None;
- If the type is registered as a derived type of one of the primitive types, it returns the Primitive type kind;
- If the type is one of the primitive types themselves, it returns the corresponding primitive type kind.
- 1 The primitive types are specified in Table 51.
- 2 Types that cannot be mapped to a primitive type include:
- Arrays registered via ITypeRegistry AddArrayType;
- Structures registered via ITypeRegistry AddStructureType.
- 3 Derived types include:
- Enumerations registered via ITypeRegistry AddEnumerationType;
- Strings registered via ITypeRegistry AddStringType;
- Integer types registered via the ITypeRegistry AddIntegerType;
- Float types registered via the ITypeRegistry AddFloatType.
The IType GetUuid method shall return the Universally Unique Identifier of the type.
The IType Publish method shall allow publishing a new field in a receiver, with the following arguments: - “receiver” giving the publishing interface to publish against;
- “name” giving the name of instance;
- “description” giving the description of instance;
- “address” giving the address of instance;
- “viewKind” giving the visibility of instance;
- “state” giving if the instance is part of the breakpoint or not;
- “input” giving if writing to the instance is allowed;
- “output” giving if reading from the instance is allowed.
Using the IType Publish method is an alternative method to publish a field than using the IPublication publishing methods.
IStructureType
The simulation environment shall provide a class implementing the IStructureType interface as per Publication/IStructureType.h in [SMP_FILES].
The IStructureType AddField method shall add a field to the structure, with the following arguments:
- “Name” giving the name of the field;
- “Description” giving the description of the field;
- “Uuid” giving the universally unique identifier of field Type, as a value type;
- “offset” giving the memory offset of field relative to Structure;
- “ViewKind” giving the visibility of instance;
- “state” giving if the instance is part of the breakpoint or not;
- “input” giving if writing to the instance is allowed;
- “output” giving if reading from the instance is allowed.
IClassType
The simulation environment shall provide a class implementing the IClassType interface as per Publication/IClassType.h in [SMP_FILES].
IArrayType
The simulation environment shall provide a class implementing the IArrayType interface as per Publication/IArrayType.h in [SMP_FILES].
The IArrayType GetSize method shall return the number of elements in the array.
The IArrayType GetItemType method shall return a pointer to the type that all array items have.
IEnumerationType
The simulation environment shall provide a class implementing the IEnumerationType interface as per Publication/IEnumerationType.h in [SMP_FILES].
The IStructureType AddLiteral method shall add a literal entry to the enumeration given the following input arguments and behaviour:
- Arguments:
- “name” giving the name of the literal;
- “description” giving the description of the field;
- “value” giving the “value” of the literal.
- Behaviour:
- If the given Name is already added as a literal to the enumeration, it throws a DuplicateName exception as per DuplicateName.h in [SMP_FILES];
- If the given Value is already added as a literal to the enumeration, it throws a DuplicateLiteral exception as per Publication/DuplicateLiteral.h in [SMP_FILES].
Component Factory (IFactory)
The simulation environment shall provide a class implementing the IFactory interface as per IFactory.h in [SMP_FILES].
The IFactory GetUuid method shall return the UUID of the component that will be created by this factory.
The IFactory CreateInstance method shall create an instance of the component with the following arguments:
- “name” giving the name of the instance to be created;
- “description” giving the description of the instance to be created;
- “parent” giving a pointer to the parent object of the instance to be created. The IFactory DeleteInstance method shall delete an existing component with the following argument:
- “instance” given the IComponent interface to the component to be deleted. The IFactory GetTypeName method shall return the fully qualified C++ type name of the component type.
The fully qualified type name contains all namespaces and the name of the type, separated by two colons ("::").
Meta data
Catalogue
File format specification
The Catalogue file shall be in conformance with thc Catalogue file DRD of Annex A.
Validation rules
General
All user defined catalogues shall link to the SMP catalogue in file XML/ecss.smp.smpcat in [SMP_FILES] for all standard SMP elements defined in this standard.
- 1 The ecss.smp.smpcat contains the complete meta data model for all elements of [SMP_FILES] expressed in an SMP catalogue.
- 2 The usage of a common standardized SMP catalogue ensures that common types and other elements have the same UUID across all platform, hence allows model integration.
No recursive Types shall be specified.
Models, interfaces, entry points, fields, etc… are Types in the catalogue, so these Types cannot be typed as, be derived from or use themselves at any level of their specification.
Types that are used in another Type shall be visible for that Type.
XLinks in documents shall not result in recursively linked documents.
The xlink:href attribute shall be a valid URI locator on the form "<Document>[#<Fragment>]", where <Document> is the linked XML file and <Fragment> is an optional named element defined in that file.
In case the named element is defined within the same file, i.e. the link is local to the file, the <Document> part of the locator can be omitted.
The xlink:title attribute shall always contain the Name of the referenced named element.
Types
The size of an array size shall be a positive number.
The PrimitiveType for a Float may only point to Float32 or Float64.
Float Minimum shall be less than Float Maximum if MinInclusive is false or MaxInclusive is false.
Float Minimum shall be less or equal to Float Maximum if MinInclusive is true and MaxInclusive is true.
The length of a string shall be larger or equal to zero.
The length of a String Value shall not exceed the size of the corresponding String type.
The PrimitiveType for an Integer shall point to Int8, Int16, Int32, Int64, UInt8, UInt16, UInt32 or UInt64.
For Integer types, the Minimum shall be less or equal to the Integer Maximum.
The type for an AttributeType shall point to a ValueType.
The Type link for an Attribute shall point to an AttributeType.
The default value of an AttributeType shall be not empty.
The Value of an Attribute shall not be empty.
Named Element
A Named Element Name shall be unique in its context.
A Named Element Id shall be unique in its Document.
A Named Element Id shall not be empty.
A Named Element Name shall not be an ISO/ANSI C++ keyword.
A Named Element Name shall only contain letters, digits, and the underscore, optionally followed by ‘[‘ and ‘]’ enclosing a number or a string.
Type UUID shall be unique.
Container and associations
Container lower bound shall be a positive number or 0.
Container lower bound shall be less or equal to the container upper bound, if present.
Container upper bound shall be ‐1 or larger or equal to the container lower bound.
The Type link of an Association shall point to a Model, Interface or Value Type.
The Type link of a Container shall point to a Reference Type.
The Type link of a Reference shall point to an Interface.
For a Reference, the Lower limit shall be less or equal to the Upper limit.
Enumeration
Enumeration Literal Names shall be unique within an Enumeration.
Enumeration Literal Values shall be unique within an Enumeration.
Entry Point
Entry Point Output fields shall be output type fields.
Entry Point Input fields shall be input type fields.
Entry Point Input and Output fields shall be located in the same Model or a base model.
Properties
Property Attached Field shall have the type of Property’s Type, or a type derived thereof.
Property Attached Field shall be located in the same Class or a base class.
The Type link of a Property shall point to a Value Type.
The Type of the AttachedField shall match the Type of the Property.
A Property of an Interface shall be public.
A Property of an Interface shall not be static.
References
Reference lower bound shall be larger than zero.
Reference lower bound shall be less or equal to Reference upper bound, if present.
Reference upper bound shall be ‐1, larger or equal to Reference lower bound.
Fields
The Field link shall point to a Field.
The Type link for a Field shall point to a ValueType.
The Field value shall not be empty.
A Field of a Structure shall be public.
The Type link of an Operation shall point to a ValueType.
Operations
An operation of an Interface shall be public.
An Operation of an Interface shall not be static.
The Type link of a Parameter of the Operation shall point to a Value Type.
A Parameter shall only have a default value if its type is Value Type.
The value of a parameter shall be inside the range defined for the corresponding type.
Each operation shall have only one parameter with the return type attribute set.
Constructors
Constructors shall not have any return parameters.
Constructors shall not have Const, Virtual or Static attributes.
Events
Events shall be typed by an EventType.
The EventArgs link for an EventType shall only point to a SimpleType.
The Type link of an EventSource shall point to an EventType.
The Type link of an EventSink shall point to an EventType.
An EventSource shall only be linked to an EventSink when both have the same EventType.
Requirements on utilization of Catalogue
The simulation Models design shall be defined via a catalogue, or a set of catalogues.
Catalogues shall not have circular dependencies.
Each Model in a simulation shall be defined in a catalogue.
Each user-defined Service in a simulator shall be defined in a catalogue.
Each Interface between components shall be defined in a catalogue.
Each Type used in an interface or component shall be defined in a catalogue.
Each Field of a model or service that is of a type defined in a catalogue shall be defined in a catalogue.
Each public Property of an interface, model or service shall be defined in a catalogue.
Each public Operation of an interface, model or service shall be defined in a catalogue.
Each Entry Point of a model or service shall be defined in a catalogue.
Each Event Source of a model or service shall be defined in a catalogue.
Each Event Sink of a model or service shall be defined in a catalogue.
Each Container of a model or service shall be defined in a catalogue.
Each Reference of a model or service shall be defined in a catalogue.
Package
File format specification
The Package file shall be in confromance with the Package file DRD of Annex B.
Validation rules
There shall be no clashes of Type names in packages.
For each Model implementation, a different Uuid shall be used.
Configuration data
File format
Files containing configuration data for published fields should be in conformance with the Configuration file DRD of Annex C.
The usage of the SMP Configuration file format is optional.
Validation rules
All path strings in configuration files shall be valid SMP path strings.
Valid SMP path strings are specified in clause 5.1.3
All field values set shall be valid values for the field type it refers to.
Implementation mapping
Catalogue to C++
Mapping templates
Syntax and expression rules used in the specification of C++ mapping templates:
Parts omitted to shorten the template and ease the reading are replaced by ‘…’.
Information from the catalogue to be mapped in the C++ code is specified by means of placeholders encased within dollar ‘Component.Name...Element[i]...Type$)’ expression. For example, for a given type ‘MyType’ defined within two levels of nested namespaces would refer to ‘::Namespace1::Namespace2::MyType’.
Optional code is specified encased within the square bracket ‘[‘ and ‘]’ symbols. For example, ‘[static]’ where the use of ‘static’ might be subject to some conditions. Exception is where ‘[...]’ is used for the elements in an array as per rule a.2. above.
Alternative code is specified by means of the ‘|’ separator symbol where exactly one of several options is required. For example, ‘A|B|C’ if either ‘A’, ‘B’ or ‘C’ is to be used in the code.
Table 61 and Table 62 contains the C++ declaration and defintition templates and are referred to from requirements of clause 6.1.
Table 61: C++ declaration templates
|
Template
|
C++ mapping
|
|
Constant
|
static constexpr TypeName($Constant.Type$) $Constant.Name$ = $Constant.Value$;
|
|
Field
|
[static ][mutable ]TypeName($Field.Type$) $Field.Name$;
|
|
Association
|
[const ][static ][mutable ]TypeName($Association.Type$)[*]$Association.Name$;
|
|
Parameter
|
[const ]TypeName($Parameter.Type$)[*|&]$Parameter.Name$[ = $Parameter.Default$]
|
|
Property Getter
|
[virtual ] [static ][const ]TypeName($Property.Type$)[*|&]get_$Property.Name$()[ const][ = 0];
|
|
Property Setter
|
[virtual ][static ]voidset_$Property.Name$([const ]TypeName($Property.Type$)[*|&] value)[ = 0];
|
|
Operation
|
[virtual ][static ]void|TypeName($Operation.Parameter[i].Type$)[*|&]$Operation.Name$(void|...)[ const][ = 0];
|
|
Operator
|
[virtual ][static ]void|TypeName($Operation.Parameter[i].Type$)[*|&] operator$Operation.Operator.OperatorKind$(void|...)[ const][ = 0];
|
|
Constructor
|
$Owner.Name$(void|...)[= delete];
|
|
Entry Point
|
Smp::IEntryPoint* $EntryPoint.Name$;
|
|
Event Sink
|
Smp::IEventSink* $EventSink.Name$;
|
|
Event Source
|
Smp::IEventSource* $EventSource.Name$
|
|
Container
|
Smp::IContainer* $Container.Name$;
|
|
Reference
|
Smp::IReference* $Reference.Name$;
|
|
Uuid
|
extern const Smp::Uuid Uuid_$Type.Name$;
|
|
Global Registry
|
[static] void _Register_$Type.Name$(Smp::Publication::ITypeRegistry* registry);
|
|
Scoped Registry
|
[static] void _Register(Smp::Publication::ITypeRegistry* registry);
|
|
Enumeration
|
enum class $Enumeration.Name$ : Smp::Int32 {...};
|
|
Literal
|
$Enumeration.Literal.Name$ = $Enumeration.Literal.Value$
|
|
Integer
|
typedef $Integer.PrimitiveType$|Smp::Int32 $Integer.Name$;
|
|
Float
|
typedef $Float.PrimitiveType$|Smp::Float64 $Float.Name$;
|
|
String
|
struct $String.Name$ {Smp::Char8 internalString[$String.Length$+1];};
|
|
Array
|
struct $Array.Name$ {TypeName($Array.ItemType$) internalArray[$Array.Size$];};
|
|
Structure
|
struct $Structure.Name$ {...};
|
|
Class
|
class $Class.Name$[ : public TypeName($Class.Base.Name$)] {...};
|
|
Exception
|
class $Exception.Name$ : public TypeName($Exception.Base.Name$)|Smp::Exception {...};
|
|
Interface
|
class $Interface.Name$[ : virtual public TypeName($Interface.Base[1].Name$), ..., TypeName($Interface.Base[N].Name$)] {...};
|
|
Model
|
class $Model.Name$ :[ public TypeName($Model.Base.Name$),][ virtual public TypeName($Model.Interface[1].Name$), ..., TypeName($Model.Interface[N].Name$),][ virtual public Smp::IEntryPointPublisher,][ virtual public Smp::IEventConsumer,][ virtual public Smp::IEventProvider,][ virtual public Smp::IComposite,][ virtual public Smp::IAggregate,]virtual public Smp::IModel {...};
|
|
Service
|
class $Service.Name$ :[ public TypeName($Service.Base.Name$),][ virtual public TypeName($Service.Interface[1].Name$), ..., TypeName($Service.Interface[N].Name$),][ virtual public Smp::IEntryPointPublisher,][ virtual public Smp::IEventConsumer,][ virtual public Smp::IEventProvider,]virtual public Smp::IService {...};
|
Table 62: C++ definition templates
|
Template
|
C++ mapping
|
|
Uuid
|
Smp::Uuid Uuid_$Type.Name$ = $Type.Uuid$;
|
|
Simple
|
TypeName($Variable.Type$) $Variable.Name$ = $Variable.Value.Value$|$Variable.Value.Literal$;
|
|
Array
|
TypeName($Variable.Type$) $Variable.Name$ = {{$Variable.ItemValue[1].Value$|$Variable.ItemValue[1].Literal$,...,$Variable.ItemValue[N].Value$|$Variable.ItemValue[N].Literal$}};
|
|
Structure
|
TypeName($Variable.Type$) $Variable.Name$ = {$Variable.FieldValue[1].Value$|$Variable.FieldValue[1].Literal$,...,$Variable.FieldValue[N].Value$|$Variable.FieldValue[N].Literal$};
|
|
Property Getter
|
return $Property.AttachedField.Name$;
|
|
Property Setter
|
$Property.AttachedField.Name$ = value;
|
Namespaces and files
All elements shall be declared within the exact same namespace as in the Catalogue.
Each type shall be declared in a dedicated header file as follows:
- The hierarchy of namespaces defines the file location with one directory level per namespace level in the hierarchy;
- The type name defines the file name.
Header files shall allow multiple inclusion by implementing ‘#include’ guards.
Header files shall avoid circular dependencies by using forward declaration.
Element and Type Visibility Kind
Visibility kind attributes shall be mapped to ISO/ANSI C++ member access specifiers as follows:
- If the attribute is explicitly defined, mapping is as per Table 63;
- If the attribute is undefined, the default “Private” visibility kind is used with mapping as per Table 63. Table 63: C++ mapping for the Visibility kind attribute
|
Visibility kind
|
Description
|
C++ mapping
|
|
Private
|
Local to the parent Type.
|
private
|
|
Protected
|
Local to the parent Type and derived Types thereof.
|
protected
|
|
Public
|
Global.
|
public
|
Mapping of elements
Value elements
Simple value elements shall be mapped to ISO/ANSI C++ variable’s values as follows:
- Syntax as per “Simple” template in Table 62;
- If the element value is of EnumerationValue type, mapping is done using the Literal attribute instead of the Value one. Array value elements shall be mapped to ISO/ANSI C++ variable’s values as follows:
- Syntax as per “Array” template in Table 62;
- If the element items are of EnumerationValue type, mapping is done using their Literal attribute instead of the Value one. Structure value elements shall be mapped to ISO/ANSI C++ variable’s values as follows:
- Syntax as per “Structure” template in Table 62;
- For the element fields of EnumerationValue type, mapping is done using the Literal attribute instead of the Value one.
Constant
Constant elements shall be mapped to ISO/ANSI C++ member variables as per “Constant” template in Table 61.
The value of the Constant member variable shall be defined as per mapping of the Value attribute.
See clause 6.1.4.1 for details on the mapping of Value attributes.
The access specifier of the Constant member variable shall be defined as follows:
- If the member variable belongs in a C++ structure, the member is public;
- If the member variable does not belong in a C++ structure, the mapping of the Visibility attribute is used.
- 1 See clause 6.1.3 for details on the mapping of Visibility attributes.
- 2 The access specifier applies to Classes, Models, Services and Interfaces.
Field
Field elements shall be mapped to ISO/ANSI C++ member variables as per “Field” template in Table 61.
The initial value of the Field member variable shall be defined as per mapping of the Default attribute.
See clause 6.1.4.1 for details on the mapping of Value attributes.
The access specifier of the Field member variable shall be defined as follows:
- If the member variable belongs in a C++ structure, the member is public;
- If the member variable does not belong in a C++ structure, the mapping of the Visibility attribute is used.
See clause 6.1.3 for details on the mapping of Visibility attributes.
The Static attribute as per ecss.smp.smpcat in [SMP_FILES] shall have the following effect for the Field C++ mapping:
- If set to “true”, then the C++ field includes the ‘static’ specifier as per “Field” template in Table 61;
- If not set, then it has no effect;
- If set to “false”, then it has no effect. The Mutable attribute as per ecss.smp.smpcat in [SMP_FILES] shall have the following effect for the Field C++ mapping:
- If set to “true”, then the C++ field includes the ‘mutable’ specifier as per “Field” template in Table 61;
- If not set, then it has no effect;
- If set to “false”, then it has no effect.
Association
Association elements shall be mapped to ISO/ANSI C++ member variables as per “Association” template in Table 61;
The access specifier of the Association member variable shall be defined by the mapping of the Visibility attribute.
See clause 6.1.3 for details on the mapping of Visibility attributes.
The ByPointer attribute as per ecss.smp.smpcat in [SMP_FILES] shall have the following effect for the Association C++ mapping:
- If set to “true”, then the C++ mapping of the type includes the ‘*’ specifier as per “Association” template in Table 61;
- If not set, then the C++ mapping of the type includes the specifier corresponding to the type referenced in the Type attribute as per Table 64;
- If set to “false”, then the C++ mapping of the type does not include the ‘*’ specifier. Table 64: C++ mapping of Association depending on ByPointer attribute
|
|
C++ mapping
| |||
|
Native Type
|
Value Type
|
Value Reference
|
Reference Type
| |
|
Specifier without ByPointer
|
|
|
|
*
|
|
Specifier with ByPointer=”true”
|
*
|
*
|
*
|
*
|
|
Specifier with ByPointer=”false”
|
|
|
|
|
The Const attribute as per ecss.smp.smpcat in [SMP_FILES] shall have the following effect for the Association C++ mapping:
- If set to “true”, then the C++ mapping includes the ‘const’ specifier as per “Association” template in Table 61;
- If not set, then it has no effect;
- If set to “false”, then it has no effect. The Static attribute as per ecss.smp.smpcat in [SMP_FILES] shall have the following effect for the Association C++ mapping:
- If set to “true”, then the C++ mapping includes the ‘static’ specifier as per “Association” template in Table 61;
- If not set, then it has no effect;
- If set to “false”, then it has no effect. The Mutable attribute as per ecss.smp.smpcat in [SMP_FILES] shall have the following effect for the Association C++ mapping:
- If set to “true”, then the C++ mapping includes the ‘mutable’ specifier as per “Association” template in Table 61;
- If not set, then it has no effect;
- If set to “false”, then it has no effect.
Parameter
Parameter elements shall be mapped to ISO/ANSI C++ as follows:
- If the Direction kind attribute is ‘return’, the parameter is the return type of a C++ member method;
- If the Direction kind attribute is not ‘return’, the parameter is an argument of a C++ member method with default value given by the Default attribute;
- Syntax is for arguments as per “Parameter” and for the return type as per “Operation” templates in Table 61;
- For the C++ type specifier the mapping of the Direction kind attribute corresponding to the type referenced in the Type attribute as per Table 65 is used. Table 65: C++ mapping for the Direction kind attribute
|
Direction kind
|
C++ mapping
| |||
|
Native Type
|
Value Type
|
Value Reference
|
Reference Type
| |
|
in
|
const
|
|
const
|
const &
|
|
out
|
*
|
*
|
|
*
|
|
inout
|
*
|
*
|
|
*
|
|
return
|
|
|
|
*
|
The ByReference attribute as per ecss.smp.smpcat in [SMP_FILES] shall have the following effect for the Parameter C++ mapping:
- If set to “true”, then the C++ mapping includes the ‘&’ specifier as per “Parameter” template in Table 61, irrespectively of Table 65;
- If not set, then the C++ mapping is done according to Table 65;
- If set to “false”, then the C++ mapping does not include the ‘&’ specifier, irrespectively of Table 65. The Const attribute as per ecss.smp.smpcat in [SMP_FILES] shall have the following effect for the Parameter C++ mapping:
- If set to “true”, then the C++ mapping includes the ‘const’ specifier as per “Parameter” template in Table 61, irrespectively of Table 65;
- If not set, then the C++ mapping is done according to Table 65;
- If set to “false”, then the C++ mapping does not include the ‘const’ specifier, irrespectively of Table 65. The ByPointer attribute as per ecss.smp.smpcat in [SMP_FILES] shall have the following effect for the Parameter C++ mapping:
- If set to “true”, then the C++ mapping includes the ‘*’ specifier as per “Parameter” template in Table 61, irrespectively of Table 65;
- If not set, then the C++ mapping is done according to Table 65;
- If set to “false”, then the C++ mapping does not include the ‘*’ specifier, irrespectively of Table 65.
It is invalid to have both the ByReference attribute and the ByPointer attribute set to ”true” for the same parameter.
Property
Property elements shall be mapped to ISO/ANSI C++ member methods as follows:
- If the Access attribute is not defined, or it is defined with value equal to ‘readWrite’ or ‘readOnly’, a getter member method is created with syntax as per “Property Getter” template in Table 61;
- If the Access attribute is not defined, or it is defined with value equal to ‘readWrite’ or ‘writeOnly’, a setter member method is created with syntax as per “Property Setter” template in Table 61; The access specifier of the Property member methods shall be defined as follows:
- If the Operation belongs in an Interface, the member is public;
- If the Operation does not belong in an Interface, the mapping of the Visibility attribute is used.
See clause 6.1.3 for details on the mapping of Visibility attributes.
If the AttachedField element is defined, the body of the Property getter and setter member methods shall be respectively mapped as per “Property Getter” and “Property Setter” templates in Table 62.
The ByReference attribute as per ecss.smp.smpcat in [SMP_FILES] shall have the following effect for the Property C++ mapping:
- If set to “true”, then the C++ mapping of the type includes the ‘&’ specifier;
- If not set, or if set to “false”, then the C++ mapping of the type does not include the ‘&’ specifier. The ByPointer attribute as per ecss.smp.smpcat in [SMP_FILES] shall have the following effect for the Property C++ mapping:
- If set to “true”, then the C++ mapping of the type includes the ‘*’ specifier;
- If not set, then the C++ mapping of the type includes the specifier corresponding to the type referenced in the Type attribute as per Table 66;
- If set to “false”, then the C++ mapping of the type does not include the ‘*’ specifier. Table 66: C++ mapping for Property depending on ByPointer attribute
|
|
C++ mapping
| |||
|
Native Type
|
Value Type
|
Value Reference
|
Reference Type
| |
|
specifier without ByPointer
|
|
|
|
*
|
|
Specifier with ByPointer=”true”
|
*
|
*
|
*
|
*
|
|
Specifier with ByPointer=”false”
|
|
|
|
|
The Static attribute as per ecss.smp.smpcat in [SMP_FILES] shall have the following effect for the Property C++ mapping:
- If set to “true”, then the C++ mapping includes the ‘static’ specifier as per “Property Getter” and “Property Setter” template in Table 61;
- If not set, then it has no effect;
- If set to “false”, then it has no effect. The Virtual attribute as per ecss.smp.smpcat in [SMP_FILES] shall have the following effect for the Property C++ mapping:
- If set to “true”, then the C++ mapping includes the ‘virtual’ specifier as per “Property Getter” and “Property Setter” template in Table 61;
- If not set, then the C++ mapping includes the ‘virtual’ specifier as per “Property Getter” and “Property Setter” template in Table 61 if the property belongs to an Interface, Model or Service;
- If set to “false”, then it has no effect. The Abstract attribute as per ecss.smp.smpcat in [SMP_FILES] shall have the following effect for the Property C++ mapping:
- If set to “true”, then the C++ mapping includes the ‘=0’ pure specifier as per “Property Getter” and “Property Setter” template in Table 61;
- If not set, then the C++ mapping includes the ‘=0’ pure specifier as per “Property Getter” and “Property Setter” template in Table 61 if the property belongs to an Interface;
- If set to “false”, then it has no effect. The ConstGetter attribute as per ecss.smp.smpcat in [SMP_FILES] shall have the following effect for the Property C++ mapping:
- If set to “true”, then the C++ mapping includes the ‘const’ specifier at the end, as per “Property Getter” template in Table 61;
- If not set, then it has no effect;
- If set to “false”, then it has no effect. The Const attribute as per ecss.smp.smpcat in [SMP_FILES] shall have the following effect for the Property C++ mapping:
- If set to “true”, then the C++ mapping includes the ‘const’ specifier at the beginning, as per “Property Getter” and "Property Setter" templates in Table 6-1;
-
- If not set, then it has no effect;
-
- If set to “false”, then it has no effect.
Operation
Operation elements shall be mapped to ISO/ANSI C++ member methods as follows:
- If neither the Operator nor the Constructor attribute is set, syntax is as per “Operation” template in Table 61.
- If the Operator attribute is set, syntax is as per “Operator” template in Table 61.
- If the Constructor attribute is set, syntax is as per “Constructor” template in Table 61.
- 1 Operator and Constructor attributes cannot be both set at the same time for a given Operation element as they are mutually exclusive.
- 2 Constructor methods inherit the name from the element the Operation is member of, therefore their own Name attribute is ignored.
Operation elements shall have at maximum one Parameter element, or none in case the Constructor attribute is set, with Direction attribute equal to ‘return’.
Parameter elements belonging to the Operation element shall be mapped as follows: - Syntax as per mapping of Parameter elements.
- If there is no Parameter element with Direction attribute equal to ‘return’, the return type of the Operation member method is ‘void’.
- If there is no Parameter element with Direction attribute different than ‘return’, the only argument of the Operation member method is ‘void’.
- If there is more than one Parameter element with Direction attribute different than ‘return’, they are mapped in sequence as comma-separated arguments for the Operation member method.
See clause 6.1.4.5 for details on the mapping of Parameter elements.
The access specifier of the Operation C++ member method shall be defined as follows:
- If the Operation belongs in an Interface, the member is public;
- If the Operation does not belong in an Interface, the mapping of the Visibility attribute is used.
See clause 6.1.3 for details on the mapping of Visibility attributes.
The Static attribute as per ecss.smp.smpcat in [SMP_FILES] shall have the following effect for the Operation C++ mapping:
- If set to “true”, then the C++ mapping includes the ‘static’ specifier as per “Operation” or “Operator” template in Table 61;
- If not set, then it has no effect;
- If set to “false”, then it has no effect.
Constructor methods are not affected by the Static attribute.
The Virtual attribute as per ecss.smp.smpcat in [SMP_FILES] shall have the following effect for the Operation C++ mapping:
- If set to “true”, then the C++ mapping includes the ‘virtual’ specifier as per “Operation” or “Operator” template in Table 61;
- If not set, then the C++ mapping includes the ‘virtual’ specifier as per “Operation” or “Operator” template in Table 61 if the Operation belongs to an Interface, Model or Service;
- If set to “false”, then it has no effect.
Constructor methods are not affected by the Virtual attribute.
The Abstract attribute as per ecss.smp.smpcat in [SMP_FILES] shall have the following effect for the Operation C++ mapping:
- If set to “true”, then the C++ mapping includes the ‘=0’ pure specifier as per “Operation” or “Operator” template in Table 61;
- If not set, then the C++ mapping includes the ‘=0’ pure specifier as per “Operation” or “Operator” template in Table 61 if the Operation belongs to an Interface;
- If set to “false”, then it has no effect.
Constructor methods are not affected by the Abstract attribute.
The Const attribute as per ecss.smp.smpcat in [SMP_FILES] shall have the following effect for the Operation C++ mapping:
- If set to “true”, then the C++ mapping includes the ‘const’ specifier as per “Operation” or “Operator” template in Table 61;
- If not set, then it has no effect;
- If set to “false”, then it has no effect.
Constructor methods are not affected by the Const attribute.
The Operator attribute as per ecss.smp.smpcat in [SMP_FILES] shall have the following effect for the Operation C++ mapping:
- If set, then the C++ mapping of the Operator kind referenced in the Operator attribute as per Table 67 is used.
- If not set, it has no effect. Table 67: C++ mapping for the Operator attribute kinds
|
Operator kind
|
Description
|
C++ mapping
|
|
None
|
Undefined.
|
|
|
Positive
|
Positive value of instance.
|
+x
|
|
Negative
|
Negative value of instance.
|
-x
|
|
Assign
|
Assigns new value to instance.
|
x = a
|
|
Add
|
Adds value to instance.
|
x += a
|
|
Subtract
|
Subtracts value to instance.
|
x -= a
|
|
Multiply
|
Multiplies instance with value.
|
x *= a
|
|
Divide
|
Divides instance by value.
|
x /= a
|
|
Remainder
|
Remainder of instance for value.
|
x %= a
|
|
Greater
|
Compares whether instance is greater than value.
|
x > a
|
|
Less
|
Compares whether instance is less than value.
|
x < a
|
|
Equal
|
Compares whether instance is equal to value.
|
x == a
|
|
NotGreater
|
Compares whether instance is not greater than value.
|
x <= a
|
|
NotLess
|
Compares whether instance is not less than value.
|
x >= a
|
|
NotEqual
|
Compares whether instance is not equal to value.
|
x != a
|
|
Indexer
|
Returns indexed value of instance.
|
x[a]
|
|
Sum
|
Returns sum of two values.
|
a + b
|
|
Difference
|
Returns difference of two values.
|
a - b
|
|
Product
|
Returns product of two values.
|
a * b
|
|
Quotient
|
Returns quotient of two values.
|
a / b
|
|
Module
|
Returns remainder of two values.
|
a % b
|
EntryPoint
EntryPoint elements shall be mapped to ISO/ANSI C++ member pointer variables as per “EntryPoint” template in Table 61.
The access specifier of the EntryPoint member variable shall be public.
The EntryPoint member variable shall point to an implementation of the Smp::IEntryPoint interface.
EventSink
EventSink elements shall be mapped to ISO/ANSI C++ member pointer variables as per “EventSink” template in Table 61.
The access specifier of the EventSink member variable shall be public.
The EventSink member variable shall point to an implementation of the Smp::IEventSink interface.
If the EventType of an EventSink has an EventArgs, the implementation of the Notify method of the Smp::IEventSink interface shall expect to receive an “arg” parameter of simple type as defined by the type of the EventArgs.
See clause 5.2.6.1 for the details of the Notify method of the Smp::IEventSink interface.
EventSource
EventSource elements shall be mapped to ISO/ANSI C++ member pointer variables as per “EventSource” template in Table 61.
The access specifier of the EventSource member variable shall be public.
The EventSource member variable shall point to an implementation of the Smp::IEventSource interface.
If the EventType of an EventSource has an EventArgs, the implementation of the Emit method of the Smp::IEventSource interface shall expect to pass an “arg” parameter of simple type as defined by the type of the EventArgs.
See clause 5.2.6.2 for the details of the Emit method of the Smp::IEventSource interface.
Container
Container elements shall be mapped to ISO/ANSI C++ member pointer variables as per “Container” template in Table 61.
The access specifier of the Container member variable shall be public.
The Container member variable shall point to an implementation of the Smp::IContainer interface.
If the Type element of the Container points to a reference type, then the implementation of the AddComponent method of the Smp::IContainer interface shall expect the component parameter to be derived from this Type.
See clause 5.2.5.2 for the details of the AddComponent method of the Smp::IContainer interface.
Reference
Reference elements shall be mapped to ISO/ANSI C++ member pointer variables as per “Reference” template in Table 61.
The access specifier of the Reference member variable shall be public.
The Reference member variable shall point to an implementation of the Smp::IReference interface.
If the Type element of the Reference points to a reference type, then the implementation of the AddComponent method of the Smp::IReference interface shall expect the component parameter to be derived from this Type.
See clause 5.2.4.2 for the details of the AddComponent method of the Smp::IReference interface.
Basic Value Types
Common specification
For each type, a universally unique identifier (UUID) variable shall be declared as per “Uuid” template in Table 61.
The value of the universally unique identifier (UUID) variable shall be defined as per “Uuid” template in Table 62.
For each type, a method to register the type in the registry shall be defined as per “Global Registry” template in Table 61.
If the type belongs to a Reference Type, the access specifier of the C++ member variables, types and methods related to the type shall be defined by the mapping of the Visibility attribute.
See clause 6.1.3 for details on the mapping of Visibility attributes.
Enumeration
Enumeration types shall be mapped to ISO/ANSI C++ enumerated types as per “Enumeration” template in Table 61.
Literal elements shall be mapped to ISO/ANSI C++ enumeration literals with value assignment as per “Literal” template in Table 61.
Literal elements shall be declared within the exact same Enumeration type as in the Catalogue.
Integer
Integer types shall be mapped to ISO/ANSI C++ type definitions as follows:
- Syntax is as per “Integer” template in Table 61;
- If it references a specific type, the same is used for the declaration;
- If it does not reference a type, the default Int32 primitive type as per Table 51 is used for the declaration.
Float
Float types shall be mapped to ISO/ANSI C++ type definitions as follows:
- Syntax is as per “Float” template in Table 61;
- If it references a specific type, the same is used for the declaration;
- If it does not reference a type, the default Float64 primitive type as per Table 51 is used for the declaration.
String
String types shall be mapped to ISO/ANSI C++ structures as per “String” template in Table 61.
- 1 Using a structure with a single internalString array field (rather than using an array) allows passing String types by value.
- 2 The extension of one extra character in length ensures that the terminating NULL character fits into the string.
Array
Array types shall be mapped to ISO/ANSI C++ structures as per “Array” template in Table 61.
Using a structure with a single internalArray array field (rather than using an array) allows passing Array types by value.
Compound Value Types
Common specification
For each type, a universally unique identifier (UUID) variable shall be declared as per “Uuid” template in Table 61.
The value of universally unique identifier (UUID) variables shall be defined as per “Uuid” template in Table 62.
For each type, a method to register the type in the registry shall be defined as follows:
- Syntax is as per “Scoped Registry” template in Table 61;
- Method is declared as member of the C++ structure or class the type is mapped to. Constant and Field elements belonging to the type shall be mapped within the exact same C++ structure or class the type is mapped to.
See clause 6.1.4.1c.2 for details on the mapping of Constant elements and clause 6.1.4.3 for details on the mapping of Field elements.
If the type belongs to a Reference Type, the access specifier of the C++ member variables, types and methods related to the type shall be defined by the mapping of the Visibility attribute.
See clause 6.1.3 for details on the mapping of Visibility attributes.
Structure
Structure types shall be mapped to ISO/ANSI C++ structures as per “Structure” template in Table 61.
Class
Class types shall be mapped to ISO/ANSI C++ classes as follows:
- Syntax as per “Class” template in Table 61;
- If the Base element is defined, the class inherits from the Base class. Class types shall have a default constructor whose access specifier is defined by the mapping of the Visibility attribute.
See clause 6.1.3 for details on the mapping of Visibility attributes.
Class types shall have a virtual destructor with the noexcept keyword whose access specifier is defined by the mapping of the Visibility attribute.
See clause 6.1.3 for details on the mapping of Visibility attributes.
If the Class type has the NoConstructor attribute as per ecss.smp.smpcat in [SMP_FILES] set to "true", the constructor shall be declared with the delete keyword.
If the Class type has the NoDestructor attribute as per ecss.smp.smpcat in [SMP_FILES] set to "true", the destructor shall be declared with the default keyword.
Association, Property and Operation elements belonging to the Class type shall be mapped within the exact same C++ class the type is mapped to.
See clause 6.1.4.4 for details on the mapping of Association elements, clause 6.1.4.6 for details on the mapping of Property elements and clause 6.1.4.7 for details on the mapping of Operation elements.
If the Class type has the Abstract attribute set to “true”, the destructor shall be declared as pure virtual.
The BaseClass attribute as per ecss.smp.smpcat in [SMP_FILES] shall have the following effect for the Class C++ mapping:
- If set, then the class includes an inheritance link to the base class that the attribute points to;
- If not set, then it has no effect.
Exception
Exception types shall be mapped to ISO/ANSI C++ classes as follows:
- Syntax as per “Exception” template in Table 61;
- If the Base element is defined, the class inherits from the Base class;
- If the Base element is not defined, the class inherits from the default Exception class. Exception classes shall have a default constructor whose access specifier is defined by the mapping of the Visibility attribute.
See clause 6.1.3 for details on the mapping of Visibility attributes.
Exception classes shall have a copy constructor whose access specifier is defined by the mapping of the Visibility attribute.
- 1 Copy constructors are required to be able to catch exceptions by value.
- 2 See clause 6.1.3 for details on the mapping of Visibility attributes.
Exception classes shall have a virtual destructor whose access specifier is defined by the mapping of the Visibility attribute.
See clause 6.1.3 for details on the mapping of Visibility attributes.
Association, Property and Operation elements belonging to the Exception type shall be mapped within the exact same C++ class the type is mapped to.
See clause 6.1.4.4 for details on the mapping of Association elements, clause 6.1.4.6 for details on the mapping of Property elements and clause 6.1.4.7 for details on the mapping of Operation elements.
If the Exception type has the Abstract attribute set to “true”, the destructor shall be declared as pure virtual.
The BaseClass attribute as per ecss.smp.smpcat in [SMP_FILES] shall have the following effect for the Exception C++ mapping:
- If set, then the Exception includes an inheritance link to the base class that the attribute points to;
- If not set, then it has no effect.
Reference Types
Common specification
For each type, a universally unique identifier (UUID) variable shall be declared as per “Uuid” template in Table 61.
The value of universally unique identifier (UUID) variables shall be defined as per “Uuid” template in Table 62.
Constant, Property and Operation elements belonging to the type shall be mapped within the exact same C++ class the type is mapped to.
See clause 6.1.4.2 for details on the mapping of Constant elements, clause 6.1.4.6 for details on the mapping of Property elements and clause 6.1.4.7 for details on the mapping of Operation elements.
The access specifier of class constructors and destructors within the C++ class a type is mapped to shall be defined by the mapping of the type Visibility attribute.
See clause 6.1.3 for details on the mapping of Visibility attributes.
Interface
Interface types shall be mapped to ISO/ANSI C++ abstract classes as follows:
- Syntax as per “Interface” template in Table 61;
- If Base elements are defined, the class inherits from the Base classes;
- All class member methods are declared as pure virtual. Interface classes shall have a virtual destructor with an empty implementation.
Model
Model types shall be mapped to ISO/ANSI C++ classes as follows:
- Syntax as per “Model” template in Table 61;
- If Base element is defined, the class inherits from the Base class;
- If Interface elements are defined, the class inherits from the Interface classes;
- If at least one EntryPoint is defined, the class inherits from the Smp::IEntryPointPublisher class;
- If at least one EventSink element is defined, the class inherits from the Smp::IEventConsumer class;
- If at least one EventSource element is defined, the class inherits from the Smp::IEventProvider class;
- If at least one Container element is defined, the class inherits from the Smp::IComposite class;
- If at least one Reference element is defined, the class inherits from the Smp::IAggregate class.
Model classes shall have a default constructor.
Model classes shall have a virtual destructor.
Field and Association elements belonging to the Model type shall be mapped within the exact same C++ class the Model type is mapped to.
See clause 6.1.4.3 for details on the mapping of Field elements and clause 6.1.4.4 for details on the mapping of Association elements.
EntryPoint, EventSink, EventSource, Container and Reference elements belonging to the Model type shall be mapped within the exact same C++ class the Model type is mapped to.
See clause 6.1.4.8 for details on the mapping of EntryPoint elements, clause 6.1.4.9 for details on the mapping of EventSink elements, clause 6.1.4.10 for details on the mapping of EventSource elements, clause 6.1.4.11 for details on the mapping of Container elements and clause 6.1.4.12 for details on the mapping of Reference elements.
The Fallible attribute as per ecss.smp.smpcat in [SMP_FILES] shall have the following effect:
- If set to “true”, then the C++ class implements the IFallibleModel interface;
- If not set, then it has no effect;
- If set to “false”, then it has no effect. The BaseClass attribute as per ecss.smp.smpcat in [SMP_FILES] shall have the following effect for the Model C++ mapping:
- If set, then the class includes an inheritance link to a base class that the attribute points to;
- If not set, then it has no effect.
Service
Service types shall be mapped to ISO/ANSI C++ classes as follows:
- Syntax as per “Service” template in Table 61;
- If Base element is defined, the class inherits from the Base class;
- If Interface elements are defined, the class inherits from the Interface classes.
- If at least one EntryPoint is defined, the class inherits from the Smp::IEntryPointPublisher class;
- If at least one EventSink element is defined, the class inherits from the Smp::IEventConsumer class;
- If at least one EventSource element is defined, the class inherits from the Smp::IEventProvider class;
Service classes shall have a default constructor.
Service classes shall have a virtual destructor.
Field and Association elements belonging to the Service type shall be mapped within the exact same C++ class the Service type is mapped to.
See clause 6.1.4.3 for details on the mapping of Field elements and clause 6.1.4.4 for details on the mapping of Association elements.
EntryPoint, EventSink and EventSource elements belonging to the Service type shall be mapped within the exact same C++ class the Service type is mapped to.
See clause 6.1.4.8 for details on the mapping of EntryPoint elements, clause 6.1.4.9 for details on the mapping of EventSink elements and clause 6.1.4.10 for details on the mapping of EventSource elements.
The BaseClass attribute as per ecss.smp.smpcat in [SMP_FILES] shall have the following effect for the Model C++ mapping:
- If set, then the class includes an inheritance link to a base class that the attribute points to;
- If not set, then it has no effect.
Package to library
Mapping templates
Syntax and expression rules used in the specification of C++ mapping templates:
Information from the package to be mapped in the C++ code is specified by means of placeholders encased within dollar ‘Package.Name$ for the value of the field ‘Name’ of some ‘Package’ referred in the context the template is applicable.
Table 68 contains the C++ declaration templates for packages and is referred to from requirements of clause 6.2.
Table 68: C++ declaration templates for packages
|
Template
|
C++ mapping
|
|
Static Initialise
|
extern “C” bool Initialise_$Package.Name$( Smp::ISimulator* simulator, Smp::Publication::ITypeRegistry* typeRegistry);
|
|
Static Finalise
|
extern “C” bool Finalise_$Package.Name$();
|
|
Dynamic Initialise
|
extern ʺCʺ bool Initialise( Smp::ISimulator* simulator, Smp::Publication::ITypeRegistry* typeRegistry);
|
|
Dynamic Finalise
|
extern ʺCʺ bool Finalise(Smp::ISimulator* simulator);
|
|
DLL Initialise
|
extern ʺCʺ DLL_EXPORT bool Initialise( Smp::ISimulator* simulator, Smp::Publication::ITypeRegistry* typeRegistry);
|
|
DLL Finalise
|
extern ʺCʺ DLL_EXPORT bool Finalise(Smp::ISimulator* simulator);
|
|
DLL_EXPORT
|
#ifdef WIN32 #define DLL_EXPORT declspec(dllexport)#else #define DLL_EXPORT#endif
|
Common to Unix and Windows
The SMDL Package Provider shall implement the Package as a Static or Dynamic Library file.
The Library file can be materialized differently on different Operating Systems.
The Library shall contain an Initialise function as per Initialise template in Table 68.
The Library shall contain a Finalise method as per Finalise template in Table 68.
The Finalise method function shall release memory allocated during Initialise method, unless ownership has been handed over.
The Initialise function shall register all user-defined Types in the library with the Type Registry using the provided Type Registry interface.
This is done by calling the global register function (for Enumeration, Integer, Float, Array, String) or method (Structure, Class, Exception) of the type.
The Initialise function shall register the class Factory of all implemented models in the library using the ISimulator RegisterFactory method.
The ownership of the class factory is handed over to the object implementing ISimulator.
The Initialise function shall register an instance of all Services in the library using the ISimulator AddService method.
The ownership of the service is handed over to the object implementing ISimulator.
Unix (Shared object)
The SMDL Package shall be implementation mapped on UNIX based Operation Systems using on the following two methods:
- As a Static Library file with extension “.a”;
- As a Dynamic Shared Object file with extension “.so”.
The Static Library shall contain an Initialise method as per the “Static Initialise” template in Table 68.
The Dynamic Shared Object shall contain an Initialise method as per the “Dynamic Initialise” template in Table 68.
The Static Library shall contain a Finalise method as per the Static Finalise template in Table 68.
The Dynamic Shared Object shall contain a Finalise method as per the “Dynamic Finalise” template in Table 68.
The Initialise function shall call the Initialise ( ) function.
The Finalise function shall call the Finalise ( ) function.
The Initialise function shall call the initialization functions of the Packages which are referenced as Dependencies of the Package. - 1 Dependency indicates that a type referenced from an implementation in the package needs a type implemented in the referenced package.
- 2 There are no rules on the order in which packages are initialised, as the type registration process via Universally Unique Identifiers (UUIDs) does not introduce dependencies on the order.
The Initialise and Finalise functions shall be implemented so that multiple calls are possible. - 1 The Initialise and Finalise functions may get called several times during initialization when a library is referenced from more than one package.
- 2 Ensuring that types are only registered once and memory is only allocated once allows multiple calls to Initialise.
Packages shall map to either static or dynamic libraries. - 1 Two dynamic library implementations are currently mapped
- Unix Shared Object (SO)
- Windows Dynamic Link Library (DLL)
- 2 The requirements for the static library are common to all the dynamic library implementations, therefore they are not repeated in the corresponding clauses. The clauses on the dynamic library implementations cover only the specific delta specifications applicable to the case at hand.
Addendum for Windows Dynamic Link Library (DLL)
A package shall be mapped to a single DLL file.
A single DLL file shall implement a single package.
All functions exported by a DLL file shall be exported with platform-specific decorations based on the calling convention.
This is typically achieved by using the ‘C’ linkage (extern “C”) along with the __declspec(dllexport) storage-class attributes.
A DLL file shall export the function Initialise() with the following “DLL Initialise” template in Table 68 where DLL_EXPORT is as per “DLL_EXPORT” template in Table 68.
A DLL file shall export the function Finalise() with the following DLL Finalise template in Table 68 where DLL_EXPORT is as per DLL_EXPORT template in Table 68.
SMP Bundle
A SMP bundle shall be composed by one or more SMDL packages.
A SMP bundle shall be composed by one or more package dynamic libraries, directly related to the SMDL packages.
A SMP bundle may be composed by one or more package static libraries, directly related to the SMDL packages.
A SMP bundle shall be composed by all the SMP catalogues related to the SMDL packages.
A SMP Bundle shall include a SMP manifest file in conformace with the Manifiest file DRD of Annex D.
ANNEX(normative)Catalogue file - DRD
Catalogue DRD
Requirement identification and source document
This DRD is called from ECSS-E-ST-40-07 requirement 5.4.1.1a.
Purpose and objective
The purpose of the Catalogue file is to hold the model meta data.
Expected response
Scope and content
The suffix for catalogue files shall be “smpcat”.
The document shall be compliant with the Catalogue XML XSD in XML/Smdl/Catalogue.xsd in [SMP_FILES] and the files referred from it:
- XML/Core/Types.xsd in [SMP_FILES]
- XML/Core/Elements.xsd in [SMP_FILES]
Special remarks
None.
ANNEX(normative)Package file - DRD
Package DRD
Requirement identification and source document
This DRD is called from ECSS-E-ST-40-07 requirement 5.4.2.1a.
Purpose and objective
The purpose of the Package file is to contain all metamodel elements that are needed in order to define how implementations of types defined in catalogues are packaged.
Expected response
Scope and content
The suffix for package files shall be “smppkg”.
The document shall be compliant with the Package XML XSD in xml/Smdl/Package.xsd in [SMP_FILES] and the files referred from it:
- xml/Smdl/Types.xsd in [SMP_FILES]
- xml/Smdl/Elements.xsd in [SMP_FILES]
Special remarks
None.
ANNEX(normative)Configuration file - DRD
Configuration DRD
Requirement identification and source document
This DRD is called from ECSS-E-ST-40-07 requirement 5.4.3.1a
Purpose and objective
The purpose of the Configuration file is to hold configuration data for a simulation.
Expected response
Scope and content
The suffix for configuration files shall be “smpcfg”.
The document shall be compliant with the Configuration XML XSD in xml/Smdl/Configuration.xsd in [SMP_FILES] and the files referred from it:
- xml/Smdl/Types.xsd in [SMP_FILES]
- xml/Smdl/Elements.xsd in [SMP_FILES]
Special remarks
None.
ANNEX(normative)Manifest file - DRD
Configuration DRD
Requirement identification and source document
This DRD is called from ECSS-E-ST-40-07 requirement 6.2.5e.
Purpose and objective
The purpose of the Manifest file is to hold meta data for a bundle.
Expected response
Scope and content
The SMP Manifest files name shall be “SMP.MF”.
The SMP Manifest file shall be an ASCII file which contains key-value pairs in the following format: “Key: Value”
In the SMP Manifest file the Key and Value shall be separated by a colon.
In the SMP Manifest file the, the Key shall only contain alpha-numerical characters, underscore (“_”) or dash (“-“).
In the SMP Manifest file the, the Value shall start at the first non-whitespace character after the colon (“:”), and is terminated by the end of line.
The SMP Manifest file shall contain the Mandatory Keys listed in Table D-1 as indicated in the Mandatory column.
The SMP Manifest file shall conform to the OSGi Core Release 6 Bundle Manifest file format.
Internet link to the OSGI Core manifest: https://osgi.org/download/r6/osgi.core-6.0.0.pdf
Table: SMP Manifest Key
|
Key
|
Meaning
|
Mandatory
|
|
Bundle-Copyright
|
Copyright statement for the bundle.
|
Yes
|
|
Bundle-ContactAddress
|
Full address of a person or company that can be contacted.
|
No
|
|
Bundle-DocURL
|
URL where documentation for the bundle can be retrieved from.
|
No
|
|
Bundle-Description
|
Textual description of the bundle and its content.
|
Yes
|
|
Bundle-ManifestVersion
|
A bundle manifest may express the version of the OSGi manifest header syntax in the Bundle-ManifestVersion header. If specified, the bundle manifest version must be ’2’.
|
Yes
|
|
Bundle-Name
|
The Bundle-Name header defines a readable name for this bundle. This should be a short, human-readable name that can contain spaces.
|
Yes
|
|
Bundle-SymbolicName
|
The Bundle-SymbolicName manifest header is a mandatory header. The bundle symbolic name and bundle version allow a bundle to be uniquely identified in the Framework. That is, a bundle with a given symbolic name and version is treated as equal to another bundle with the same (case sensitive) symbolic name and exact version.
|
Yes
|
|
Bundle-Vendor
|
The Bundle-Vendor header contains a human-readable description of the bundle vendor.
|
Yes
|
|
Bundle-Version
|
Bundle-Version is an optional header; the default value is 0.0.0.
|
Yes
|
|
Require-Bundle
|
The Require-Bundle header specifies the required exports from another bundle. This is a comma-separated list of required bundles, where each bundle is at least specified by its symbolic name, optionally followed by a specific version:
|
No
|
|
Compiler-Name
|
Name of the compiler that has been used to compile the source code.
|
No
|
|
Compiler-Version
|
Version of the compiler that has been used to compile the source code.
|
No
|
|
OS-Name
|
Name of the Operating System.
|
No
|
|
OS-Version
|
Version of the Operating System.
|
No
|
Special remarks
None.
Bibliography
|
ECSS-S-ST-00
|
ECSS system – Description, implementation and general requirements
|
|
ISO 9000 series
|
Quality management systems standardsInternational Organization for Standardization (ISO)http://www.iso.org
|
|
ISO/IEC 9899:2011
|
ISO/IEC 9899:2011 Information technology -- Programming languages -- C
|
|
ISO/IEC 14882:2011
|
ISO/IEC 14882:2011 Information technology -- Programming languages -- C++
|
|
Open Group UUID
|
Open Grouphttp://www.opengroup.org
|
|
OSGi Manifest
|
Open Services Gateway initiativehttp://www.osgi.org
|
|
SMP v1.2
|
Simulation Model PortabilitySpecification version 1.2
|
|
XML
|
Extensible Markup LanguageWorld Wide Web Consortium (W3C)http://www.w3.org/XM
|