-
Notifications
You must be signed in to change notification settings - Fork 8
Seer
The Seer system is meant to extend the simulator itself by providing means to extract information and visualization from simulations. It is more a pluging manager than anything else.
The image below summarizes the Seer architecture and how it integrates with the simulator. Seer is added as a DES system, much like any other, and executes at certain intervals (the events indicated with 'S' in the event queue of the image). At each Seer event, the system scans the Position and Skeleton components to create a snapshot of the simulation in that point in time.
Once the snapshot is created it is passed to the seer consumers. A seer consumer is a function that will process the message somehow. For example, saving it to a different file, printing it to the terminal, etc. One particular usecase is to provide visualization for the simulation. That has been achieved using Firebase real-time database and the Seer plugin to parse messages in the browser.
On initialization of the Seer system you can pass a list of consumer functions. A Consumer function receives 2 arguments: the message (format detailed below) and the message index. If your seer consumer needs some cleanup after the simulation exits, it will have to be passed to the Simulator as part of the cleanup routine. The consumers execute in a separate thread from the processor.
ℹ️
Seer consumers are supposed to be stateless.
Also during initialization of the system a scan_interval
parameter is passed, which defined the frequency at which Seer will produce messages, in simulation seconds.
All messages are passed as a python dictionary object.
The first message passed to seer consumers contains information about the simulation, as shown below. timestamp will be included in every message and corresponds to the simulation time that the message was generated. window_name
is the name of the scenario (defined in the map). dimentions
is a tuple with the width and height of the scene.
{
"timestamp": -1,
"window_name": simulation_skeleton.id,
"dimensions": size
}
The subsequent messages always have these fields:
- timestamp - Simulation time when message was generated
- deleted - List of IDs (map ids) of entities that were removed from the simulation since the last message
Plus, for every entity (read callout) in the simulation the message will contain a key with the map ID of that entity (e.g. the ID of the entity on the map or defined in its Entitydefinition) and a dictionary as value with the data shown below.
{
'value': skeleton.value, // text of entity on the map
'x': position.x,
'y': position.y,
'width': position.w,
'height': position.h,
'style': skeleton.style // JGraph style string
}
⚠️
To reduce snapshot size only entities that had some change since the last snapshot are included in the message.
In the second message, all entities in the simulation are included.
The last message is always {"theEnd": True}
.
A Seer consumer can be any function that accepts 2 parameters: a message (formatted as shown above) and a message index, and returns nothing. Then you simply have to pass the function in the seer initialiation as one of the seer consumers.