How to Architect a CoreEngine Application

Lay out folders, wire models to drivers, and follow the Core Engine's architectural rules.

This guide walks you through structuring a CoreEngine project: organizing folders, separating generated code from developer code, wiring streams and drivers through configuration, and applying the engine's state-machine best practices.

For the broader system-engineering process this fits into, see How to Build an APIC System for Software Engineers.

1. Understand the Core Principles

Before laying out a project, follow these architectural rules:

This guide targets core engine developers and integrators. It assumes familiarity with C++, state-machine design, and real-time system constraints.

2. Create the Root Folder Structure

Set up your project root with the following top-level folders:

Root
 ├── DBSim
 ├── interfaces
 │   ├── Drivers
 │   └── Streams
 ├── Models
 ├── OGI
 ├── Setups
 └── config.json
FolderResponsibility
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
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
Each driver folder splits into a driver layer (talks to Streams) and an api/ subfolder — a separate shared library implementing the device-specific API. See Driver & Stream Folder Layout for the full breakdown.

3. Organize Models and States

Each Model represents a logical subsystem or functional domain. A model may own one or more state-machine controllers, and each controller holds one or more States. Give each model responsibility for:

Inside a model folder, create a states/ directory containing 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
A single state is the smallest logical execution unit. It should implement one clear, deterministic responsibility.

4. Wire Drivers and Streams Through Configuration

Drivers (under interfaces/Drivers/) implement the physical or protocol-level interface (bus, socket, file, or simulated I/O), split into a driver layer and a separate API shared library. Streams (under interfaces/Streams/) bind blocks or model endpoints to these drivers using configuration.

  1. Define streams in streams.json.
  2. Specify for each stream: source block or model output, target driver, direction and rate, and optional transformation/filtering.
Key Rule: No hard-coded connections between models and drivers are allowed. All bindings must be configuration-driven.

5. Configure the Setups Folder

The Setups/ folder defines how the engine is instantiated for a specific system or project.

FileDescription
LRU-<project>.jsonLRUs, blocks, elements, layout, and properties
systemconfig.jsonApplication-specific configuration
streams.jsonStream-to-driver bindings

Optionally add a tests/ folder under Setups containing CSV-based test vectors for unit tests, standard compliance tests, and ATP (Acceptance Test Procedures).

6. Build the OGI Layer

The OGI (Operator Graphical Interface) layer implements the operator-facing application. It should handle:

OGI must not implement business logic or state transitions. All logic belongs in models.

7. Understand the Runtime Sequences

Keep these three runtime flows in mind while integrating components:

States can perform transitions directly by return value in the execute function.

8. Apply Best Practices

Design Rule: If behavior changes between projects, it belongs in configuration. If behavior changes between modes, it belongs in states.