Title: Overview of SPEEDES
1Overview of SPEEDES
- Dr. Ronald Van Iwaarden
- Metron Inc.
- April 17, 2003
2What is SPEEDES?
- Synchronous Parallel Environment for Emulation
and Discrete-Event Simulation - Software Framework/Toolbox for building parallel
C simulations - Distributes simulation over multiple CPUs
- Coordinates simulation activities between CPUs
- Based on NASA-patented algorithms
- More than twenty publications (three award
winning) - Object-oriented (C)
- Multiple time management algorithms (BTW,
Conservative) - Scalable internals with low overheads
- Supported by Metron
3Parallel Simulation
- Divide Simulation Work Among Multiple CPUs
- Reduce time needed to perform simulation
- Perfect Speedup N CPUs do the work N times as
fast - Ideal, but usually not attainable
- Goal is to get the maximum speedup possible (e.g.
8 CPUs performing simulation 5 times as fast as 1
CPU) - Speedup is limited by amount of parallelism
inherent in a simulation - Some simulations have lots of things that can be
done concurrently - Others are mostly sequential little inherent
parallelism
4Discrete Event Simulation (DES)
- Consists of Objects and Events
- Simulation Objects model the entities to be
simulated - Example military simulation might have Ship,
Aircraft, and Tank objects - Events model interactions between entities
- Example military simulation might have event
modeling Aircraft dropping bomb on a Ship - Events are instantaneous
- Events act on exactly one object
- DES versus Timestep Simulation
- Timestep simulation driven by clock repeatedly
incremented by ?t - DES just skips ahead to the next generated event
regardless how big a jump it is
5DES Event Ordering Easy On One CPU
Increasing Timestamp
Event Queue
Process Earliest Event
Generate New Event And Insert in Queue
Simulation Objects
6Parallel Discrete Event Simulation (PDES)
- Discrete Event Simulation distributed over two or
more nodes (usually CPUs) - Events can still be processed in order, but
requires centralized control and communications
overhead - Called Conservative Time Management conservative
in the sense that it will not process an event
unless it knows the event can be processed
without being in error - Optimistic Time Management
- Allow event to be processed even if we dont know
its next in line - Straggler event an event whose timestamp is
earlier than one (or more) that has already been
processed
7Optimistic PDES
- Dealing with straggler event
- Must revert simulation state back to what it was
at timestamp of straggler - Roll back processed events whose timestamp
exceeds stragglers timestamp - Undo state changes caused by rolled back events
- Cancel all events generated by rolled back events
- Cancel all events generated by above events, etc.
- Can cause massive cascade of rollbacks
- Need to limit optimistic processing so that cost
of rollbacks doesnt outweigh the benefits of
optimistic time management - SPEEDES has input parameters for controlling the
amount of optimistic processing - Stop node from going too far into the future
since this is likely to generate cascade of
rollbacks
8SPEEDES PDES
- Framework for implementing PDES
- Summary of how SPEEDES works
- User defines C simulation classes that inherit
from SPEEDES SpSimObj class - User defines events that act upon the simulation
objects - Usually just a C method in a simulation class
- Events act on exactly one object change object
state and/or generate other events - SPEEDES distributes objects among available CPUs,
manages event scheduling, and coordinates events
9SPEEDES Simulation Execution
- SPEEDES Nodes start up
- Each Node creates its subset of simulation
objects - -User can designate which objects go on which
nodes (Object Decomposition) - After all objects created, SPEEDES calls virtual
Init() method on each - Initializes objects and schedules first round of
events - First round of events schedules more events,
which schedule more events, etc. - Generated events processed until simulation end
time reached (tend parameter in speedes.par input
file)
10Ping Pong Simulation Example
- ifndef S_PlayerGate
- define S_PlayerGate
- include "SpDefineSimObj.H"
- include "SpDefineEvent.H"
- class S_Player public SpSimObj
- public
- S_Player()
- virtual void Init()
- void PingEvent(int n)
- void PongEvent(int n)
-
- DEFINE_SIMOBJ(S_Player, 2, SCATTER)
- DEFINE_SIMOBJ_EVENT_1_ARG(PingEvent, S_Player,
PingEvent, int) - DEFINE_SIMOBJ_EVENT_1_ARG(PongEvent, S_Player,
- PongEvent, int)
- endif
S_Player.H File
11Ping Pong Simulation, cont
- include "S_Player.H"
- include "RB_ostream.H"
- S_PlayerS_Player()
- void S_PlayerInit()
- if (SpGetSimObjKindId() 0)
- SCHEDULE_PingEvent(0,SpGetObjHandle(),0)
-
-
- void S_PlayerPingEvent(int n)
- RB_cout ltlt n ltlt " Ping" ltlt endl
- SCHEDULE_PongEvent(SpGetTime()1,
- SpGetObjHandle("S_Player_MGR",1),n1)
-
- void S_PlayerPongEvent(int n)
- RB_cout ltlt " ltlt n ltlt " Pong" ltlt endl
S_Player.C File
12Ping Pong Simulation, cont
- include "SpMainPlugIn.H"
- include "S_Player.H"
- int main (int argc, char argv)
- PLUG_IN_SIMOBJ(S_Player)
- PLUG_IN_EVENT(PingEvent)
- PLUG_IN_EVENT(PongEvent)
- ExecuteSpeedes(argc, argv)
- return 0
Main.C File
parameters float tend 10.0 //simulation end
time
speedes.par File
13Ping Pong Simulation, cont
- 0 Ping
- 1 Pong
- 2 Ping
- 3 Pong
- 4 Ping
- 5 Pong
- 6 Ping
- 7 Pong
- 8 Ping
- 9 Pong
- 10 Ping
Simulation Output
14SPEEDES Simulation Objects
- Model real-world entities of interest
- All Simulation state contained in simulation
objects - Defining Simulation Object Classes
- Inherit from SPEEDES SpSimObj class
- Invoke DEFINE_SIMOBJ macro
- Insert PLUG_IN_SIMOBJ macro call into main()
15DEFINE_SIMOBJ Macro Call
- DEFINE_SIMOBJ(SimObjClassName, NumObjs,
DecompositionType) - SimObjClassName is the C class name
- NumObjs is the number of instances to create
- DecompositionType is an enum specifying how
objects should be distributed across SPEEDES
nodes BLOCK, SCATTER, FILE_BLOCK, or
FILE_SCATTER - Creates type name SimObjClassName_MGR
- Creates int type ID SimObjClassName_MGR_ID
- Example DEFINE_SIMOBJ(S_Truck, 12, SCATTER)
- Creates 12 S_Truck objects card-deals across
nodes - Creates type name S_Truck_MGR
- Creates int type ID S_Truck_MGR_ID
16SpSimObj Class
- Init() virtual method
- Called by SPEEDES during simulation
initialization - Used to initialize objects and begin event
scheduling - Do not rely on constructor, this serves that
functionality - Terminate() virtual method
- Called by SPEEDES just before ending simulation
execution - Used for final output, clean up, etc.
17SpSimObj Class Identifiers
- IDs needed to specify object on which event will
occur - Global ID
- Unique integer assigned to every object in the
simulation - int SpSimObjGetSimObjGlobalId()
- Local ID
- Unique integer assigned to every object of a
given class, on a given node - If there are 8 S_Ship objects on node5, they are
assigned local IDs 0, 1, 2, , 7 - int SpSimObjGetSimObjLocalId()
- Kind ID
- Unique integer assigned to every object of a
given class, over all nodes - If there are 25 S_Ship objects in the entire
simulation, they are assigned kind IDs 0, 1, 2,
, 24 - int SpSimObjGetSimObjKindId()
18SpSimObj Class Identifiers, cont
- Object Name
- SPEEDES assigns unique default name of form
- ltclassnamegt_MGR ltkind IDgt
- Example S_Jet with kind ID of 7 gets name
S_Jet_MGR 7 - char SpSimObjGetName()
- Use SpSimObjSetName(char name) to assign name
(should be unique) - Manager ID
- Integer ID of the object manager for this class
of object - Can be thought of as the object class ID
- Each object class has a unique integer ID
- int SpSimObjGetSimObjMgrId()
- Node ID
- Integer ID of SPEEDES node object is on
- int SpSimObjGetNodeId()
19Simulation Object Handles
- SpObjHandle Class
- Contains the following triple to uniquely
identify objects - (NodeID ObjMgrID LocalID)
- Object Handles used by SCHEDULE functions to
uniquely specify which object event will act on
20Object Handle Lookup
- SpObjHdl SpSimObjGetObjHandle()
- Get objects own handle
- SpObjHdl SpSimObjGetObjHandle(int kindId)
- Get handle of object with given kind ID and of
same class as this object - SpObjHdl SpSimObjGetObjHandle(int mgrId, int
kindId) - Get handle of object with given type ID and kind
ID - SpObjHdl SpSimObjGetObjHandle(int mgrId, char
name) - Get handle of object with given type ID and name
- Assumes unique names within a given type ID
21Object Handle Lookup, cont
- SpObjHdl SpSimObjGetObjHandle(char mgrName,
int kindId) - Get handle of object with given type name and
kind ID - SpObjHdl SpSimObjGetObjHandle(char mgrName,
char name) - Get handle of object with given type name and
object name
22Global Functions
- SpGlobalFunctions.H contains functions that
duplicate much of this functionality - Several functions apply to the current simulation
object - int SpGetSimObjKindId()
- int SpGetSimObjLocalId()
- int SpGetSimObjGlobalId()
- int SpGetSimObjHandle()
- int SpGetNumNodes()
- int SpGetSimObjName()
- SpSimObj SpGetSimObj()
- int SpGetSimObjNodeId()
- int SpGetSimObjMgrId()
23Global Functions, cont
- SpGlobalFunctions.H functions
- Global functions to lookup other objects handles
- SpObjHandle SpGetObjHandle(int kindId)
- SpObjHandle SpGetObjHandle(int mgrId, int kindId)
- SpObjHandle(SpGetObjHandle(int mgrId, char
objName) - SpObjHandle SpGetObjHandle(char mgrType, int
kindId) - SpObjHandle SpGetObjHandle(char mgrType, char
objName)
24Making Simulation Objects Rollbackable
25Motivation Straggler Event
ObjX
ObjY
Schedule event at t80.0
- Event on ObjX processing at t50.0Schedules
event on ObjY for t80.0
- Last event on ObjY was at t100.0Need to revert
ObjY state back to t80.0 state
Node 0
Node 1
26Rolling Back To t80.0
- Un-process all events on ObjY after t80.0
- Cancel all events generated by these events
- Revert state of ObjY to what it was at t80.0
- SPEEDES does event cancellation automatically
- User must make state of ObjY rollbackable
- Use SPEEDES rollback types RB_int, RB_double,
etc. to make state of object - Rollback types automatically revert to correct
state when necessary - Behave like normal int, double, etc.
- Rule Any part of object state that can be
changed by an event must be made rollbackable
27Rollback Classes
- RB_int rollbackable int
- RB_double rollbackable double
- RB_SpBool rollbackable boolean
- RB_voidPtr rollbackable void
- RB_ostream rollbackable ostream
- RB_exostream rollbackable ostream to external
module - RB_SpList rollbackable list
- RB_SpBinaryTree rollbackable binary tree
- RB_SpHashTree rollbackable hash tree
- RB_SpPriorityTree rollbackable priority tree
28RB_int Class
- Behaves like int in expressions
- RB_int k
- k int m 2 k k 4m 12 k2m etc.
- How it works
- Assume RB_int k is 0 and event does k 15
- Assignment operator is overloaded to do the
following - Store current value of k (0) in an item that has
a pointer back to k - Increment k by 15
- If event gets rolled back, item is used to
restore previous value of k
29Warehouse Simulation Example
- One Warehouse and one parts distributor
- Warehouse is manufacturing widgets
- Needs one part to make one widget
- Can make one widget per hour, if parts available
- At start of each day, parts inventory is checked
- If no parts, need to shut down Warehouse
- Otherwise, compute number of widgets to be made
that day - At end of each day, print total number of widgets
produced thus far and status of Warehouse
(Running or Shut down) - Distributor delivers parts to Warehouse before
start of day 3 - If ReceiveParts event is straggler, Warehouse
goes into shutdown mode, etc. which will need to
be rolled back - Note how RB types are used to make Warehouse
state rollbackable - Code is all in one file, Warehouse.C
30Warehouse.C File
- include "SpMainPlugIn.H"
- include "SpDefineSimObj.H"
- include "SpDefineEvent.H"
- include "SpSchedule.H"
- include "RB_ostream.H"
- enum ShutDown,Running
- class S_Warehouse public SpSimObj
- // Rollbackable state of S_Warehouse
- RB_int PartsInventory, RunMode
- RB_double TotalWidgets
- public
- virtual void Init()
- void StartDay()
- void ReceiveParts(int num_parts)
- PartsInventory num_parts
-
- void EndDay()
- char rmode "Running"
31Warehouse.C File, cont
- DEFINE_SIMOBJ(S_Warehouse, 1, BLOCK)
- DEFINE_SIMOBJ_EVENT_0_ARG(StartDay, S_Warehouse,
StartDay) - DEFINE_SIMOBJ_EVENT_1_ARG(ReceiveParts,
S_Warehouse, ReceiveParts, int) - DEFINE_SIMOBJ_EVENT_0_ARG(EndDay, S_Warehouse,
EndDay)
32Warehouse.C File, cont
- void S_WarehouseInit()
- PartsInventory 20
- RunMode Running
- SpSimTime day1at8am 86060
- SCHEDULE_StartDay(day1at8am, SpGetObjHandle())
-
- void S_WarehouseStartDay()
- int parts_used_today 8
- if (PartsInventory lt parts_used_today)
- parts_used_today PartsInventory
- if (parts_used_today 0)
- RunMode ShutDown
- // Schedule special shut down events
- else
- PartsInventory - parts_used_today
- RunMode Running
-
- // It takes 1 part to make 1 widget.
33Warehouse.C File, cont
- class S_Distributor public SpSimObj
- public
- virtual void Init()
- SpSimTime day3at7am 3246060 76060
- int num_parts 40
- SCHEDULE_ReceiveParts(day3at7am,
- SpGetObjHandle(S_Wareh
ouse_MGR_ID, 0), - num_parts)
-
-
- DEFINE_SIMOBJ(S_Distributor, 1, BLOCK)
34Warehouse.C File, cont
- int main (int argc, char argv)
- PLUG_IN_SIMOBJ(S_Warehouse)
- PLUG_IN_SIMOBJ(S_Distributor)
- PLUG_IN_EVENT(StartDay)
- PLUG_IN_EVENT(EndDay)
- PLUG_IN_EVENT(ReceiveParts)
- ExecuteSpeedes(argc, argv)
-
speedes.par File
- parameters
- float tend 1000000 // End time for
simulation -
35Warehouse Simulation Output
- At 57600, Total widgets ever produced 8, Status
is Running - At 144000, Total widgets ever produced 16,
Status is Running - At 230400, Total widgets ever produced 20,
Status is Running - At 316800, Total widgets ever produced 28,
Status is Running - At 403200, Total widgets ever produced 36,
Status is Running - At 489600, Total widgets ever produced 44,
Status is Running - At 576000, Total widgets ever produced 52,
Status is Running - At 662400, Total widgets ever produced 60,
Status is Running - At 748800, Total widgets ever produced 60,
Status is Shut Down - At 835200, Total widgets ever produced 60,
Status is Shut Down - At 921600, Total widgets ever produced 60,
Status is Shut Down
36Rollbackable Allocation/Deallocation
- Memory management must be as well in addition to
pointers - RB_NEW functions
- Allocate storage in an event if event is rolled
back, automatically delete the storage - Examples
- char RB_NEW_char(void)
- char RB_NEW_ARRAY_char(int size)
- RB_DELETE functions
- Note storage is to be deleted, but dont actually
delete it - If event is committed, delete the storage
- Examples
- void RB_DELETE_char(char buff)
- void RB_DELETE_ARRAY_char(char buff)
37Creating RB_NEW and RB_DELETE
- include RB_SpDefineClass.H
- class Student
- public
- char Name
- int Age
-
- // Following macro creates functions
- // Student RB_NEW_Student()
- // Student RB_NEW_ARRAY_Student(int size)
- // void RB_DELETE_Student(Student st)
- // void RB_DELETE_ARRAY_Student(Student st)
- RB_DEFINE_CLASS(Student)
38Using RB_NEW and RB_DELETE
- include RB_SpDefineClass.H
- include RB_voidPtr.H
- RB_DEFINE_CLASS(char)
- class S_Ship public SpSimObj
- private
- RB_voidPtr currName
- public
- char GetCurrentName()return (char)currName
- void SetName(char newName)
- if (currName)
- RB_DELETE_ARRAY_char((char)currName)
-
- currName RB_NEW_ARRAY_char(strlen(newName)1
) - strcpy((char)currName, newName)
-
-
39SPEEDES EVENTS
40Point-to-Point Events
- Event on one object schedules event on another
- Creating Point-to-Point Event
- Define method in simulation object
- This code will be executed when event is
processed - Up to 8 parameters
- No pointers or reference arguments
- Parameters must have a copy constructor (no
arrays) - Call appropriate DEFINE_SIMOBJ_EVENT macro
- Discussed below
- Call PLUG_IN_EVENT(eventName) prior to
ExecuteSpeedes() - Registers event with given name in SPEEDES
framework
41DEFINE_SIMOBJ_EVENT Macro
- DEFINE_SIMOBJ_EVENT_ltnumParamsgt_ARG(eventName,
- className, methodName, paramTypeList)
- ltnumParamsgt is 0, 1, 2, , 7 or 8
- eventName is user-selected name for event
- className is the name of the object class
- methodName is the event method name
- paramTypeList is a comma-separated list of
parameter types - Example for method double Funk(int i, double x,
int j), paramTypeList is int, double, int
42Point-to-Point Event Example
- include "SpMainPlugIn.H"
- include "SpSimObj.H"
- include "SpDefineSimObj.H"
- include "SpDefineEvent.H"
- include "Blob.H" // Class Blob header
- class S_MySimObj public SpSimObj
- public
- void Funk(Blob b, int i, double x) //event
method -
- // Define 1 S_MySimObj simulation object
- DEFINE_SIMOBJ(S_MySimObj, 1, SCATTER)
- // Define event FunkEvent create
SCHEDULE_FunkEvent function - DEFINE_SIMOBJ_EVENT_3_ARG(FunkEvent, S_MySimObj,
Funk, - Blob, int, double)
- void PlugInMySimObj()
- PLUG_IN_EVENT(FunkEvent)
- PLUG_IN_SIMOBJ(S_MySimObj)
43Point-to-Point Event Example, cont
- Above example creates a global function that can
be used to schedule FunkEvent on any instance of
S_MySimObj - SpCancelHandle
- SCHEDULE_FunkEvent(const SpSimTime eventTime,
- const SpObjHandle recipientObj,
- Blob b, int i, double x,
- const char dataBuff NULL, int dataBytes
0) - eventTime is the time at which to process event
- recipientObj is a handle specifying object on
which to process event - Blob b, int i, double x arguments needed to
call Funk - dataBuff is a buffer of data to send to event
(optional) - dataBytes is the number of bytes in dataBuff
(optional)
44Event Data Buffer
- Besides event arguments, can send raw buffer of
data to event - Use last two (optional) SCHEDULE arguments
- Good for sending variable-length array of data to
events - Example variable-length array of location
objects (lat, lon, alt) defines a path object
can move on - Event code uses global functions to retrieve data
buffer - char SpGetMsgData()
- int SpGetMsgDataBytes()
45Process Model
- An ordinary point-to-point event takes place
instantaneously, whereas a process takes place
over a non-zero time interval - Many algorithms are simplified when coded as a
positive duration process - Processes provide a framework that automatically
manages exiting and resuming at a later time. - Processes spend most of their time in an inactive
state, waiting between instantaneous actions. - Most simulations can make use of the process
model. - A process is defined and implemented as in
ordinary point-to-point events.
46Common Macros
- P_VAR starts the process model. After this call
to P_VAR the user declares local state variables.
(variables whose values need to be saved should
the process model exit and then be reentered) by
calling P_LV. - P_LV - defines process model local variables.
- P_BEGIN - marks the beginning of process model
user code algorithm. - P_END - marks the end of process model user code
algorithm. - WAIT - instructs SPEEDES to sleep for a certain
amount of time, during which time it will save
the state of local variables. - WAIT_FOR - Like WAIT, but sleep until a specific
semaphore (declared as either as either type
'SpLogicalSem' (logical-valued) or 'SpCounterSem'
(integer-valued) takes on a specified value. - WAIT_FOR_RESOURCE - Similar to WAIT_FOR, except
that the semaphore, a special 'resource
semaphore' (SpResourceSemaphore) is associated.
The process sleeps until a specified amount of
resource becomes available. - ASK - queries a user-defined method on a SimObj.
47Simple Counter Simulation
include "SpMainPlugIn.H" include
"SpSimObj.H" include "SpDefineSimObj.H" include
"SpDefineEvent.H" include "SpGlobalFunctions.H"
include "SpProc.H" include "RB_ostream.H" class
S_Object public SpSimObj public S_Object()
virtual void Init() void
IncrementProcess() DEFINE_SIMOBJ(S_Object, 1,
SCATTER) DEFINE_SIMOBJ_EVENT_0_ARG(IncrementProce
ss, S_Object,
IncrementProcess) void S_ObjectInit()
SCHEDULE_IncrementProcess(0.0, SpGetObjHandle())
48Counter, cont
- void S_ObjectIncrementProcess()
- P_VAR
- P_LV(int, counter)
- P_BEGIN(1)
- counter 0
- while(1)
- RB_cout ltlt "t" ltlt SpGetTime().GetTime()
- ltlt " " ltlt "counter " ltlt counter
- counter counter 2
- RB_cout ltlt ", Incrementing it to " ltlt counter
ltlt endl - WAIT(1, 2.0) // Wait 2 seconds
-
- P_END
-
- int main (int argc, char argv)
- PLUG_IN_SIMOBJ(S_Object)
- PLUG_IN_EVENT(IncrementProcess)
- ExecuteSpeedes(argc, argv)
49Notes
- IncrementProcess implements the periodic action
of counter incrementation. - P_VAR starts the process model.
- P_LV(int, counter) declares local state variable
'counter' to be integer. - P_BEGIN(1) indicates where the process model user
code starts. The integer argument 1 specifies the
number of subsequent process model macros used
(e.g. WAIT, WAIT_FOR, ASK, etc.). - WAIT(1, 2.0) sets that particular reentry point
to have a label of 1, saves off the value of the
local variable counter, and causes the event to
exit and reenter 2.0 seconds later.. - P_END closes the code for the P_BEGIN(1) call.
50Warehouse.C File
- void S_WarehouseInit()
- PartsInventory 20
- RunMode Running
- SpSimTime day1at8am 86060
- SCHEDULE_CreateWigits(day1at8am,
SpGetObjHandle()) -
- void S_WarehouseCreateWigits()
- P_LV
- int parts_used_today 8
- P_BEGIN(2)
- while(1)
- if (PartsInventory lt parts_used_today)
- parts_used_today PartsInventory
- if (parts_used_today 0)
- RunMode ShutDown
- // Schedule special shut down events
- else
- PartsInventory - parts_used_today
51Object Proxies
52Public Objects
- Public Objects
- Part of object state is made publicly readable to
interested objects (called subscribers) - SPEEDES allows objects to be made public
- Attributes readable part of public object
- Publish act of making attributes readable to
subscribers - Subscribers
- Subscriber of ClassX is notified of existence of
all ClassX objects - Subscriber discovers ClassX objects
- Subscriber of ClassX is notified of changes to
attributes of ClassX objects - Subscriber reflects ClassX object changes
53Object Proxies
- Object Proxy
- SPEEDES object that represents a public object
- Contains copies of the published attributes of
the object - Subscribers receive an object proxy when they
discover objects - Can examine current state of published attributes
in object proxy - Subscribers get updated proxy whenever attributes
are changed - Automatically delivered by reflect event
- Who can subscribe?
- Simulation objects
- External modules
54Object Proxies Implementation
- Simulation object inherits from S_SpHLA (child of
SpSimObj) - Attributes are defined in the input file
Objects.par - Attributes from Objects.par are then mapped to
attributes of simulation object - Subscribers are declared in Objects.par
- Event handlers are registered for attribute
reflected - Any changes to exported attributes are
automatically reflected to subscribers - Changes are rollbackable as well
55Object Proxies Attributes
- INT_ATTRIBUTE exportable integer
- DOUBLE_ATTRIBUTE exportable floating point
- LOGICAL_ATTRIBUTE exportable boolean
- STRING_ATTRIBUTE exportable strings
- POSITION_ATTRIBUTE exportable fixed position
- DYNAMIC_POSITION_ATTRIBUTE exportable position
function
56Object Proxies Objects.par
- MySimObj
- define string publisherName
- define float health
- define int status
-
- Warehouse
- reference INHERIT MySimObj
- define int inventory
- define position Position
-
- Factory
- reference INHERIT MySimObj
- define int inventory
- define position Position
- reference SUBSCRIBE Warehouse
- reference SUBSCRIBE Factory
57Object Proxies Simulation Objects
- include S_SpHLA.H
- include S_SpExportAttribute.H
- class MySimObj public S_SpHLA
- private
- STRING_ATTRIBUTE name
- DOUBLE_ATTRIBUTE health
- INT_ATTRIBUTE status
- public
- MySimObj(char objName MySimObj)
S_SpHLA(objName) - DEFINE_ATTRIBUTE(name, publisherName)
- DEFINE_ATTRIBUTE(health, health)
- DEFINE_ATTRIBUTE(status, status)
-
-
- class Warehouse public MySimObj
- private
- INT_ATTRIBUTE inventory
58Object Proxies FreeObjectProxy
- Can define special proxies with type specific
methods - Implemented internally using free lists to
minimize execution time
- include SpFreeObjproxy.H
- include SpObjProxy.H
- class WarehouseProxy public SpObjProxy
- public
- void getInventory()
- static int statusRef GetReference(inventory
, Warehouse) - return GetInt(statusRef)
-
- FREE_DEFINE_CLASS(WharehouseProxy_GlobalCtorDtor,
ShipProxy) - SpFreeObjProxySpFreeObjProxy(int n)
- set_ntypes(n)
- set_type(Warehouse", Warehouse_PROXY_ID,
WarehouseProxy_GlobalCtorDtor, - sizeof(WarehouseProxy), 100)
-
59Object Proxies Reflected Attributes
- include S_SpHLA.H
- include SpDefineHandler.H
- include F_SpProxyItem.H
- include FactoryProxy.H
- class Warehouse public S_SpHLA.H
- //
- public
- void DiscoverObject()
- Warehouse()
- void Init()
-
- DEFINE_SIMOBJ_HANDLER(DiscoverObject, Warehouse,
DiscoverObject) - void WarehouseInit()
- AddHandler(DiscoverObject_HDR_ID(), Discover
Object) -
- void WarehouseDiscoverObject()
60Interfacing With SPEEDES Simulations
61SPEEDES External Modules
SpeedesServer
External Module
Simulation
62External Module
- External program connected to SPEEDES simulation
- Controls time advance of simulation
- Receives information about simulation state
(object proxies and messages) - Can invoke events in the simulation
- Can be used to display what simulation is doing
- Can take user input (e.g. GUI, mouse, keyboard)
to control simulation - Control time advance
- Insert events into simulation
63External Module State Manager
- SpStateMgr Class
- Main tool for building external modules
- Provides methods for advancing simulation time
(e.g. GoToTime(t) ) - Has mechanisms for discovering/reflecting
simulation objects - Keeps list of object proxies
- Actually is a small conservative discrete event
simulation attached to SPEEDES simulation - Has special state manager events
- Maintains own simulation time
- Can send/receive messages to/from simulation
- External module can invoke event in simulation
- Simulation can invoke event in external module
64SpStateMgr Subscripton Methods
- SubscribeAll() subscribe to all objects in
simulation (receive proxies and updates for all
objects) - SubscribeType(char type, ...) subscribe to one
or more simulation object classes - SubscribeObject(char objectName, ...) subscribe
to one or more specific simulation objects - SubscribeData(char name, char type) send
request to all objects of class type name
parameter tells objects what kind of message
subscription is requested - Used to receive general data messages from
simulation
65Creating State Manager Events
- Step 1 Define class inheriting from
SpStateMgrEvent - Define virtual Process() method this is the code
that will be executed when event is called
class MyReflect public SpStateMgrEvent
public MyReflect() void Process()
cout ltlt "MyReflectProcess" ltlt endl
66Creating State Manager Events
- Step 2 Define allocator function that returns
block of new events - Needed by state manager for free lists
void NewMyReflect(int n) return new
MyReflectn
67Creating State Manager Events
- Step 3 Register event with state manager
stateManager.DefineNumberOfEvents(1) stateManager
.DefineEvent( "REFLECT_ATTRIBUTES", //
Event name 0, // Unique
integer NewMyReflect, // Allocator
Function sizeof(MyReflect), // Size of
event class 100) // Initial number of
items to allocate // in free list
68Built-in State Manager Event Names
- "DISCOVER_OBJECT
- For discovering simulation objects and receiving
initial proxy - "REFLECT_ATTRIBUTES
- For receiving attribute updates of subscribed
objects
69Receiving Non-Proxy Messages
- Define state manager event that will be called
when message arrives from simulation - Message will be in data buffer accessed with
GetData() call in events Process method - Register event with SpStateMgrDefineEvent
- Send request into simulation with
SpStateMgrSubscribeData - Simulation object can check for subscribers using
SpSimObjCheckSubscription(char subscribeName) - Simulation object can send message to external
module using global function RBSendSubscribedData - When message arrives at external module, the new
state manager event will be executed
70RBSendSubscribedData
void RBSendSubscribedData( SpSimTime time, char
name, char data, int
bytes, int globalId, SpHostUser
hostUser ) Notes time simulation time to send
data name subscribed data name data buffer
containing message bytes number of bytes in
data buffer globalId sender simulation object
global ID Sent with message so external module
can identify sender object hostUser global
object that manages external module
comms SpGetHostUser() returns this object
71Sending Message To External Module
if (CheckSubscription("SubscribedInfo"))
SpSimTime sendTime SpGetTime() 7 char
dataMsg "No aircraft have been detected"
int dataBytes strlen(dataMsg)1
RBSendSubscribedData(sendTime,
"SubscribedInfo", dataMsg,
dataBytes, SpGetSimObjGlobalId(),
SpGetHostUser())
72Controlling Simulation Time Advance
- GoToTime(SpSimTime t)
- Blocking call that doesn't return until
simulation has advanced GVT gt ttimeLag - While call is blocked, state manager receives
messages from simulation, which cause state
manager events to execute.
stateManager.GoToTime(0.0) while
(stateManager.SpeedesExecuting() 1)
stateManager.GoToTime(stateManager.GetCurrentTime(
) 100.0)
73Accessing Proxies In State Manager
- State Manager object keeps list of object proxies
- Iterating through all proxies
- SpObjProxy GetFirstProxy(void)
- SpObjProxy GetNextProxy(void)
- Iterating through proxies by type
- SpObjProxy GetFirstProxy(char type)
- SpObjProxy GetNextProxy(void)
- GetNextProxy() iterates by type when called after
GetFirstProxy(type) - Get Proxy by object name
- SpObjProxy GetProxy(char objectName)
- Get Number of proxies
- int GetNproxies(void)
74Invoking simulation event fromexternal module
with SendCommand
- SpStateMgrSendCommand
- Two versions one takes GlobalID, other takes
object name - Schedules event at GVT can cause rollbacks
- Obviously, there must be a simulation event
defined (with correct name) to be invoked from
external module
int SendCommand(char eventName,
int simObjGlobalId, char
message, int bytes) eventName
name of event to call simObjGlobalId global
ID of simulation object message data to be
sent to event (0-arg event!) bytes number of
bytes in message buffer.
75SendCommand Example
// In SpStateMgrEvent Process method int
globalId GetSimObjGlobalId() int acknowledge
GOT_LAST_MSG char msg (char )
acknowledge int msgLen sizeof(acknowledge) Se
ndCommand("GetExtMessage", globalId, msg,
msgLen)
76Invoking simulation event fromexternal module
with ScheduleEvent
- SpEmHostUserScheduleEvent
- Two versions one takes GlobalID, other takes
object name - Schedules event at specified time (must be gt
GVT) - Less likely to cause rollbacks if scheduled well
ahead of GVT - SpEmHostUser is comms interface class used by
SpStateMgr - SpEmHostUser SpStateMgrGetEmHostUser(void)
- Obviously, there must be a simulation event
defined (with correct name) to be invoked from
external module
77ScheduleEvent
SCHEDULE_EVENT_REPLY_MESSAGE ScheduleEvent(
SpSimTime time, // event time int
globalId, // global ID of simulation
object char eventName, // event name
char msg, // obsolete param
int msgBytes, // bytes in msg
sizeof(SpMsg) char data, //
data sent to event int dataBytes,
// bytes in data buffer TimeMode
tmMode IF_IN_PAST_IGNORE, int
cancelHandleReq 1) Notes tmMode tells
SPEEDES what to do if event time is befor GVT
choices are enum TimeMode
IF_IN_PAST_SCHEDULE_AT_GVT,
IF_IN_PAST_IGNORE cancelHandleReq If
equal to 1, a cancel handle is returned
otherwise, NULL is returned.
78ScheduleEvent Example
SpMsg obsolete char obsoleteArg (char
)obsolete int globalId 24 SpSimTime
evtTime(stateManager-gtGetCurrentTime()
17.0) // Get host user obj from state
manager SpEmHostUser hostUser
stateManager.GetEmHostUser() // Data message
used by event char dataBuff "Attack at
dawn!" int dataBytes strlen(dataBuff)1 hostU
ser-gtScheduleEvent(evtTime, globalId,
"SubAttack", // event name
obsoleteArg, sizeof(SpMsg),
dataBuff, dataBytes,
IF_IN_PAST_SCHEDULE_AT_GVT)
79Graphical Interfaces
- Because each Speedes simulation has its own
domain and object model, it is not possible to
have a meaningful general-purpose Speedes GUI. - As a result, any graphical interface needs to be
designed with a specific Speedes simulation in
mind. - The State Manager has the necessary tools for an
application to interface with Speedes during a
simulation run. - Such an application would have to be written in
C or some other language that is capable of
calling C functions. - Developing GUIs in C can be cumbersome and
time-consuming, depending on the graphics
libraries available.
80Graphical Interfaces (Java State Mgr)
- The Java State Manager is a wrapper around the
State Mgr that allows a Java application to
interact with a Speedes simulation via the Java
Native Interface (JNI). - Provides access to part of the functionality of
the State Mgr. - For a Java application using the Java State Mgr,
retrieving data from Speedes can be as simple as
calling a function. - Java has powerful built-in graphics packages that
can be used to quickly develop GUIs. - By utilizing third-party Java extensions such as
the Joint Mapping Toolkit (JMTK), highly detailed
GUIs can be developed in shorter time frames.
81Java Graphical Interface
Speedes Server
Speedes Simulation
Simulation Objects w/ Current Positions
Current Simulation Time
82Web Interfaces
- The Java State Manager cannot be used to create
Speedes applets (web-based Java applications). - Security concerns prohibit Java applets from
invoking native (i.e. non-Java) code. - Thus, any web-based Speedes interface must rely
on more conventional tools, such as scripts that
invoke other applications and display the
results. - An all Java application could be written which
interprets the SpStateMgr TCP/IP stream.
83Future Collaboration
- Metron Support
- Metron can provide expert assistance in
designing, coding, testing, porting and debugging
SPEEDES simulations - Cost Effective
- Especially when first learning SPEEDES, it is
faster and cheaper to have support than to go it
alone - Metron can also provide general
mathematical/analytical expertise for modeling,
problem-solving, etc. - Metron can develop extensions to the current
SPEEDES framework as needed/desired.