Overview
main() that calls
CSimSetups::Start(...)) — development means adding to or
modifying Models, States, Streams, and Drivers inside that existing
project, not writing a new entry point. For the separate, optional
DLL-based API used by external scripts to control an already-running
CoreEngine instance, see the
Scripts Interface reference instead.
The APIC Core Engine is a modular, state-driven simulation and execution framework designed to support complex system behavior, real-time data flows, and deterministic state machines. The engine separates generated ICD artifacts, developer-owned logic, configuration, and operator interfaces into well-defined layers.
Core Architecture
The engine is organized around the following principles:
- Strict separation between generated code and developer code
- Explicit state ownership inside models
- Configuration-driven wiring of streams and drivers
- Deterministic startup and runtime behavior
Root
├── DBSim
├── interfaces
│ ├── Drivers
│ └── Streams
├── Models
├── OGI
├── Setups
└── config.json
Folder Structure
| Folder | Responsibility |
|---|---|
DBSim/ |
Auto-generated ICD C++ sources and headers |
interfaces/ |
Container for the project's Drivers and Streams implementations |
interfaces/Drivers/ |
Project-specific hardware or protocol drivers, one subfolder per driver (see Driver folder layout) |
interfaces/Streams/ |
Logical data streams connecting blocks to drivers, one subfolder per stream |
Models/ |
Logical system models implementing behavior and states |
OGI/ |
Operator Graphical Interface logic and event handling |
Setups/ |
System configuration, layouts, streams, and test data |
interfaces/ folder. Stream implementations are unchanged — only their location moved. Drivers gained a new internal structure; see Driver folder layout.
Models & States Architecture
Each Model represents a logical subsystem or functional domain. A model may own one or more
state machines controller. A state controller holds one or more States.
The model responsible for:
- Internal state transitions in the states controllers
- Processing of incoming streams
- Generation and manipulating the LRUs blocks elements
States Organization
Within a model folder, a states/ directory may exist. This directory contains
state controllers, each grouping related states.
Models/
└── NavigationModel/
├── NavigationModel.cpp
├── NavigationModel.h
└── states/
├── Alignment/
│ ├── IdleState.cpp
│ ├── AligningState.cpp
│ └── AlignedState.cpp
└── FaultHandling/
├── FaultState.cpp
└── RecoveryState.cpp
Drivers & Streams
Drivers implement the physical or protocol-level interface (e.g., bus, socket, file, or simulated I/O). Streams bind blocks or model endpoints to these drivers using configuration.
Streams Configuration
Streams are defined in streams.json and specify:
- Source block or model output
- Target driver
- Direction and rate
- Optional transformation or filtering
Setups & Configuration
The Setups/ folder defines how the engine is instantiated for a specific system
or project.
| File | Description |
|---|---|
LRU-<project>.json |
LRUs, blocks, elements, layout, and properties |
systemconfig.json |
Application-specific configuration |
streams.json |
Stream-to-driver bindings |
Tests Folder
An optional tests/ folder may exist under setups, containing CSV-based test
vectors for:
- Unit tests
- Standard compliance tests
- ATP (Acceptance Test Procedures)
OGI (Operator Graphical Interface)
The OGI layer implements the operator-facing application. It handles:
- User interactions and commands
- Visualization of system state
- Translation of UI events into core engine actions
Sequence Diagrams
The following diagrams illustrate the runtime interaction between the Core Engine components. They focus on deterministic startup, stream execution, and state-machine behavior.
1. Application Startup Sequence
This diagram shows how the engine initializes configuration, models, drivers, and streams before entering real-time execution.
2. Stream Execution Sequence
Streams provide configuration-driven data flow between models and drivers. No direct coupling exists at code level.
3. State Lifecycle Sequence
Each state is a deterministic unit with a clear lifecycle. Transitions are explicit and controlled by the owning model.
Best Practices
- Keep generated code (
DBSim) read-only - One responsibility per state
- Explicit state transitions only
- Configuration over hard-coded behavior
- Fail fast on invalid configuration