Entities overview
This overview describes entities, the entity
data model's components, and how
Entity Manager supports distributed entity management.
An entity is an interoperable data structure that powers a common operational picture (COP). A COP provides human and machine consumers with a shared view of the current state of the modeled world, which enhances situational awareness and facilitates decision-making. In the COP, an entity represents any type of known object that can be referenced or commanded.
Entities can be tangible or intangible, such as:
- Physical objects, such as vessels or drones.
- Non-physical objects, such as signal detections.
- Visual concepts, such as bounding boxes or control zones.
Entity data model
The entity
data model is the canonical representation of all objects in your COP, providing a common language
to describe any object or concept that enhances situational awareness in Lattice. The data model is based on the
entity component system architecture and favors composition over inheritance.
An entity consists of components. The presence or absence of components, rather than a strict type hierarchy, determines what an entity is or how it should be interacted with. Think of an entity as a bag of components that can be mixed and matched as needed.
Entities might be incomplete at various points in time, reflecting the real-time state of the COP. Partial states are valuable for situational awareness, so your application should handle missing components robustly.
When producing an entity, only include components that are relevant to the entity you're modeling, along with the following required components:
Required component | Description |
---|---|
entity_id | Unique string identifier. Can be a Globally Unique Identifier (GUID). |
expiry_time | Expiration time that must be greater than the current time and less than 30 days in the future. The Entities API will reject any entity update with an expiry_time in the past. When the expiry_time has passed, the Entities API will delete the entity from the COP and send a DELETE event. |
is_live | Boolean that when true , creates or updates the entity. If false and the entity is still live, triggers a DELETE event. |
provenance.integration_name | String that uniquely identifies the integration responsible for publishing the entity. |
provenance.data_type | String that identifies the source data type for the entity. Multiple integrations can publish entities of the same data type. |
provenance.source_update_time | Last modification time of the entity's data at the original source, which determines the acceptance of updates to an entity. |
aliases.name | Human-readable string that represents the name of an entity. |
The entity
data model observes these principles:
- Components must not be duplicative. Avoid modeling the same underlying data on two different components.
- Components are non-hierarchical. The data model is composable and not an inheritance tree.
For more information, see the canonical
entity
data model in the Lattice API Reference.
Entity shapes
Although there is no strict type hierarchy, a user interface could group
entities according to its
ontology.template
component.
The three top-level groupings are track, asset, and geo-entity.
Track
A track represents any entity tracked by another asset or integration source.
Tracks are not directly under the control of friendly forces.
This includes aircraft tracks from radar or sensor hits, signal detections,
and vehicles, people, or animals detected through cameras.
A track must have one of the following ontology.template
component types:
TEMPLATE_TRACK
: Refers to any detected object.TEMPLATE_SENSOR_POINT_OF_INTEREST
: Refers to any sensors detected at a specific location.TEMPLATE_SIGNAL_OF_INTEREST
: Refers to a signal detection with characteristics such as emitter notation, frequency, or lines of bearing.
- Track
- Sensor point of interest (SPI)
- Signal of interest (SOI)
To create a track, such as an airplane or an animal, add the following components:
Airplane
{
"entityId": "UNIQUE_ENTITY_ID",
"description": "Airplane",
"isLive": true,
"createdTime": "2024-12-07T00:19:46.706195Z",
"expiryTime": "2024-12-07T00:24:46.706196Z",
"location": {
"position": {
"latitudeDegrees": 50.91402185768586,
"longitudeDegrees": 0.79203612077257,
"altitudeHaeMeters": 46.214997987295234
}
},
"aliases": {
"name": "Friendly Airplane"
},
"milView": {
"disposition": "DISPOSITION_FRIENDLY",
"environment": "ENVIRONMENT_AIR"
},
"ontology": {
"template": "TEMPLATE_TRACK",
"platform_type": "Airplane"
},
"provenance": {
"integrationName": "Your Integration",
"dataType": "Your Data Type",
"sourceUpdateTime": "2025-04-07T00:19:47.706196Z"
}
}
Bird
{
"entityId": "UNIQUE_ENTITY_ID",
"description": "Animal",
"isLive": true,
"createdTime": "2024-12-07T00:19:46.706195Z",
"expiryTime": "2024-12-07T00:24:46.706196Z",
"location": {
"position": {
"latitudeDegrees": 50.91402185768586,
"longitudeDegrees": 0.79203612077257,
"altitudeHaeMeters": 46.214997987295234
}
},
"aliases": {
"name": "Bird"
},
"milView": {
"disposition": "DISPOSITION_NEUTRAL",
"environment": "ENVIRONMENT_AIR"
},
"ontology": {
"template": "TEMPLATE_TRACK",
"platform_type": "Animal"
},
"provenance": {
"integrationName": "Your Integration",
"dataType": "Your Data Type",
"sourceUpdateTime": "2025-04-07T00:19:47.706196Z"
}
}
To create a sensor point of interest, add the following components:
- Add the required
location
field to the entity - Add the required
milView
field to the entity. - Optionally, add
sensors
to the entity to indicate more details about the sensor, including the sensor type and its operational state.
Sensor
{
"entityId": "UNIQUE_ENTITY_ID",
"description": "Sensor",
"isLive": true,
"createdTime": "2024-12-07T00:19:46.706195Z",
"expiryTime": "2024-12-07T00:24:46.706196Z",
"location": {
"position": {
"latitudeDegrees": 50.91402185768586,
"longitudeDegrees": 0.79203612077257,
"altitudeHaeMeters": 46.214997987295234
}
},
"aliases": {
"name": "SPI"
},
"milView": {
"disposition": "DISPOSITION_ASSUMED_FRIENDLY",
"environment": "ENVIRONMENT_SURFACE"
},
"ontology": {
"template": "TEMPLATE_SENSOR_POINT_OF_INTEREST",
"platform_type": "Radar"
},
"sensors": {
[
{
"operationalState": "OPERATIONAL_STATE_OPERATIONAL",
"sensorType": "SENSOR_TYPE_RADAR"
}
]
}
"provenance": {
"integrationName": "Your Integration",
"dataType": "Your Data Type",
"sourceUpdateTime": "2025-04-07T00:19:47.706196Z"
}
}
To create a signal of interest, add the following components:
- Add the required
signal
field to the entity. - Add the required
milView
field to the entity. - Add the
location
field ifsignal.fixed
is set.
Signal
{
"entityId": "UNIQUE_ENTITY_ID",
"description": "Signal",
"isLive": true,
"createdTime": "2024-12-07T00:19:46.706195Z",
"expiryTime": "2024-12-07T00:24:46.706196Z",
"location": {
"position": {
"latitudeDegrees": 50.91402185768586,
"longitudeDegrees": 0.79203612077257,
"altitudeHaeMeters": 46.214997987295234
}
},
"aliases": {
"name": "SOI"
},
"milView": {
"disposition": "DISPOSITION_SUSPICIOUS",
"environment": "ENVIRONMENT_SURFACE"
},
"ontology": {
"template": "TEMPLATE_SIGNAL_OF_INTEREST",
"platform_type": "Radar"
},
"provenance": {
"integrationName": "Your Integration",
"dataType": "YOUR_DATA_TYPE",
"sourceUpdateTime": "2025-04-07T00:19:47.706196Z"
}
}
Asset
An asset is an entity directly under your control that can accept tasks from an operator.
An asset must have the following ontology.template
component type:
TEMPLATE_ASSET
: Refers to a taskable entity under the control of friendly forces, such as a UAV, or a submarine.
To create a asset, add the following components:
Submarine
{
"entityId": "UNIQUE_ENTITY_ID",
"description": "Asset",
"isLive": true,
"createdTime": "2024-12-07T00:09:42.816877Z",
"expiryTime": "2024-12-17T00:09:42.816878Z",
"location": {
"position": {
"latitudeDegrees": 50.91402185768586,
"longitudeDegrees": 0.79203612077257,
"altitudeHaeMeters": 2994,
"altitudeAglMeters": 2972.8
}
},
"aliases": {
"name": "Dive"
},
"milView": {
"disposition": "DISPOSITION_FRIENDLY",
"environment": "ENVIRONMENT_SUB_SURFACE"
},
"ontology": {
"template": "TEMPLATE_ASSET",
"platform_type": "Submarine"
},
"provenance": {
"integrationName": "Your Integration",
"dataType": "YOUR_DATA_TYPE",
"sourceUpdateTime": "2025-04-07T00:19:47.706196Z"
}
}
Radar
{
"entityId": "UNIQUE_ENTITY_ID",
"description": "Asset",
"isLive": true,
"createdTime": "2024-12-07T00:09:42.816877Z",
"expiryTime": "2024-12-17T00:09:42.816878Z",
"location": {
"position": {
"latitudeDegrees": 50.91402185768586,
"longitudeDegrees": 0.79203612077257
}
},
"aliases": {
"name": "Tower"
},
"milView": {
"disposition": "DISPOSITION_FRIENDLY",
"environment": "ENVIRONMENT_SURFACE"
},
"ontology": {
"template": "TEMPLATE_ASSET",
"platform_type": "Radar"
},
"provenance": {
"integrationName": "Your Integration",
"dataType": "YOUR_DATA_TYPE",
"sourceUpdateTime": "2025-04-07T00:19:47.706196Z"
}
}
UAV
{
"entityId": "UNIQUE_ENTITY_ID",
"description": "Asset",
"isLive": true,
"createdTime": "2024-12-07T00:09:42.816877Z",
"expiryTime": "2024-12-17T00:09:42.816878Z",
"location": {
"position": {
"latitudeDegrees": 50.91402185768586,
"longitudeDegrees": 0.79203612077257,
"altitudeHaeMeters": 2994,
"altitudeAglMeters": 2972.8
}
},
"aliases": {
"name": "UAV"
},
"milView": {
"disposition": "DISPOSITION_FRIENDLY",
"environment": "ENVIRONMENT_AIR"
},
"ontology": {
"template": "TEMPLATE_ASSET",
"platform_type": "UAV"
},
"provenance": {
"integrationName": "Your Integration",
"dataType": "YOUR_DATA_TYPE",
"sourceUpdateTime": "2025-04-07T00:19:47.706196Z"
}
}
Geo-entity
A geo-entity is a shape, region, or point of interest drawn on the map, which may not physically exist. It could represent an airfield or a control zone for autonomous vehicle operations.
A geo-entity must have the following ontology.template
component type:
TEMPLATE_GEO
: Refers to any geo-entity shape.
To create a geo-entity, add the following components:
- Add the required
geo_shape
field to the entity - Add the required
geo_details
field to the entity. - Add the
location
field to the entity, yourgeo_shape
is anellipse
.
Point
{
"entityId": "UNIQUE_ENTITY_ID",
"description": "Geo point",
"isLive": true,
"createdTime": "2024-12-07T00:45:15.581592Z",
"expiryTime": "2024-12-07T00:50:15.581598Z",
"geoShape": {
"point": {
"position": {
"latitudeDegrees": 50.91402185768586,
"longitudeDegrees": 0.79203612077257,
"altitudeHaeMeters": 46.214997987295234,
"altitudeAglMeters": 0.5000067609670396
}
}
},
"geoDetails": {
"type": "GEO_TYPE_GENERAL"
},
"aliases": {
"name": "Point"
},
"ontology": {
"template": "TEMPLATE_GEO"
},
"provenance": {
"integrationName": "Your Integration",
"dataType": "Your Data Type",
"sourceUpdateTime": "2025-04-07T00:19:47.706196Z"
}
}
Polygon
{
"entityId": "UNIQUE_ENTITY_ID",
"description": "Geo polygon",
"isLive": true,
"createdTime": "2024-12-07T00:55:43.183738Z",
"expiryTime": "2024-12-07T01:00:43.183743Z",
"geoShape": {
"polygon": {
"rings": [
{
"positions": [
{
"position": {
"latitudeDegrees": 49.01611140463143,
"longitudeDegrees": 1.5746513124955297
}
},
{
"position": {
"latitudeDegrees": 49.01924140463143,
"longitudeDegrees": 2.882469645828863
}
},
{
"position": {
"latitudeDegrees": 48.4172380712981,
"longitudeDegrees": 2.9189863124955298
}
},
{
"position": {
"latitudeDegrees": 49.01611140463143,
"longitudeDegrees": 1.5746513124955297
}
}
]
}
]
}
},
"geoDetails": {
"type": "GEO_TYPE_GENERAL"
},
"aliases": {
"name": "Polygon"
},
"ontology": {
"template": "TEMPLATE_GEO"
},
"provenance": {
"integrationName": "Your Integration",
"dataType": "Your Data Type",
"sourceUpdateTime": "2025-04-07T00:19:47.706196Z"
}
}
Ellipse
{
"entityId": "UNIQUE_ENTITY_ID",
"description": "Geo ellipse",
"isLive": true,
"createdTime": "2024-12-07T01:06:32.834952Z",
"expiryTime": "2024-12-07T01:11:32.834954Z",
"location": {
"position": {
"latitudeDegrees": 51.46,
"longitudeDegrees": -0.16
}
},
"geoShape": {
"ellipse": {
"semiMajorAxisM": 20,
"semiMinorAxisM": 20,
"orientationD": 40
}
},
"geoDetails": {
"type": "GEO_TYPE_CONTROL_AREA"
},
"aliases": {
"name": "Ellipse"
},
"ontology": {
"template": "TEMPLATE_GEO"
},
"provenance": {
"integrationName": "Your Integration",
"dataType": "Your Data Type",
"sourceUpdateTime": "2025-04-07T00:19:47.706196Z"
}
}
Line
{
"entityId": "UNIQUE_ENTITY_ID",
"description": "Geo line",
"isLive": true,
"createdTime": "2024-12-07T01:08:39.079826Z",
"expiryTime": "2024-12-07T01:13:39.079828Z",
"geoShape": {
"line": {
"positions": [
{
"latitudeDegrees": 47.605,
"longitudeDegrees": -122.329
},
{
"latitudeDegrees": 47.61,
"longitudeDegrees": -122.33
}
]
}
},
"geoDetails": {
"type": "GEO_TYPE_GENERAL"
},
"aliases": {
"name": "Line"
},
"ontology": {
"template": "TEMPLATE_GEO"
},
"provenance": {
"integrationName": "Your Integration",
"dataType": "Your Data Type",
"sourceUpdateTime": "2025-04-07T00:19:47.706196Z"
}
}
Entity lifecycle management
Entities have a well-defined lifecycle of create, update, and delete.
On each lifecycle update, Entity Manager emits the state
change event to the COP using the StreamEntityComponents
call
(gRPC |
HTTP).
- Create: When an entity first appears or re-appears after expiring, the entity is created.
- Update: When data in the entity changes, Entity Manager emits the state
change as an update event. Note that, for performance reasons, Entity
Manager relies on changes to the
provenance.source_update_time
to trigger an update event. It does not perform a full proto diff to theprovenance.source_update_time
component to trigger an update event. - Delete: An entity is deleted when its
expiry_time
has passed or an update is sent with theis_live
component set tofalse
. You should handle a delete event by removing all references to it in memory or discarding it from your user interface.
Your application must implement a mechanism to control an entity's lifecycle by sending updates and setting expiry times as needed.
What's next
- To create entities in Lattice, see Publish entities to Lattice.
- Check out our sample apps in GitHub.