For running, DUECA uses two configuration files, which are actually scheme scripts. The first configuration file, named dueca.cnf, describes how a DUECA node is participating with other DUECA nodes in a DUECA process. Each of the DUECA nodes needs its own dueca.cnf.
The second configuration file describes the simulation or calculation process that will be run by DUECA. It is read when all the nodes have established communication with each other, and when they are roughly synchronised. Only one model file (dueca.mod) is needed. This file is read by DUECA node number 0, and its contents are transmitted to the other nodes in the DUECA process.
Note that the information on this page may be partially obsolete (sorry!). Many of the DUECA modules and of the core objects in DUECA are able to automatically generate documentation on the calls you can use in Scheme, see Configuring DUECA from Python or Scheme Calls from scheme.
Dueca.cnf
This is a sample dueca.cnf file
;;; parameter defining cooperation with other nodes
(define this-node-id 0) ; id of the current node
(define no-of-nodes 1) ; total number of nodes used
(define send-order 0) ; order/prio in send cycle
;;; parameter defining real-time behaviour
(define highest-manager 3) ; max priority of activities
(define run-in-multiple-threads? #t) ; #f has not been tested for long ...
(define rt-sync-mode 3) ; 0=sigwait, good for Linux master
; 1=select, portable
; 2=nanosleep, good for QNX slave
; 3=rtc, good for Linux slave
; 4=MsgReceive, good for QNX master
; 5=rt_sleep from RTAI
; 6=rt_sleep + slave the video sync
(define graphic-interface "gtk") ; selection of interface
; "gtk", "none" or "glut"
;;; parameters defining "size" of the time. Note that all nodes should have
;;; the same compatible-increment, and for all nodes
;;; tick-time-step/tick-base-increment should be the same
(define tick-base-increment 20) ; logical increment of time, each tick
(define tick-compatible-increment 20) ; same, but used at start-up
(define tick-time-step 0.01) ; time step for each tick
;;; parameter for communication using multicast
(define if-address "192.168.2.4") ; address of own ip interface
(define mc-address "224.0.0.1") ; multicast address
(define mc-port 7500) ; multicast port
(define packet-size 4096) ; size of packets
; or size of areas in scram comm
(define bulk-max-size (* 128 1024)) ; max size of bulk messages
(define comm-prio-level 2) ; priority communication process
(define unpack-prio-level 1) ; priority unpacking incoming data
(define bulk-unpack-prio-level 0) ; priority unpacking bulk data
;;; choice for the communication. Note that only one of the switches
;;; below may be true, and that they must be false when only one node is
;;; used
(define use-ip-comm? #f) ; if true, use ethernet
(define use-scram-comm? #f) ; if true, use scramnet
;;; -------------------------------------------------------------------
;;; 0 - A list to assemble references to dueca objects
(define (make-extender local-list)
(lambda (object)
(set! local-list (append local-list (list object)))))
(define dueca-list (make-extender (list )))
;;; 1 - ObjectManager. This enables named objects to be created,
;;; and allows query of the node id and number of nodes
(dueca-list
(make-object-manager 'node-id this-node-id
'no-of-nodes no-of-nodes))
;;; 2 - the environment. The environment will create the necessary
;;; number of activity managers, so activities may now be
;;; scheduled. From this point on it is also possible to create
;;; activities
(dueca-list
(make-environment 'multi-thread run-in-multiple-threads?
'highest-priority highest-manager
'graphic-interface graphic-interface)
)
;;; 2c - now priority specs can be made
(define comm-prio ; priority communication process
(make-priority-spec 'priority comm-prio-level
'order 0))
(define unpack-prio ; priority unpacking incoming data
(make-priority-spec 'priority unpack-prio-level
'order 0))
(define bulk-unpack-prio ; priority unpacking bulk data
(make-priority-spec 'priority bulk-unpack-prio-level
'order 0)) ;priority-specs
;;; 3 - Packers, and a packer manager. Packers are passive
;;; objects, accessed directly, and provide the configuration
;;; data for remote communication. The unpackers use an
;;; activity, and therefore must start after the environment
(if use-ip-comm?
(list
(define pkt (make-packer))
(define upkt (make-unpacker 'priority-spec unpack-prio))
(define fpkt (make-fill-packer 'buffer-size bulk-max-size))
(define fupkt (make-fill-unpacker 'priority-spec bulk-unpack-prio
'buffer-size bulk-max-size))
)
)
(if use-scram-comm?
(list
(define pkt
(make-reflective-packer 'buffer-size 1024))
(define upkt
(make-reflective-unpacker 'buffer-size 1024
'priority-spec unpack-prio))
(define fill-timing
(make-time-spec 'validity-start 0
'period tick-compatible-increment))
(define fpkt
(make-reflective-fill-packer 'buffer-size bulk-max-size
'packet-size 500
'set-timing fill-timing)) ) )
;;; the packer manager keeps an inventory of all packers for transport to
;;; other nodes. The three arguments are a fill (bulk) packer, a normal packer
;;; and (if possible) a high-priority packer
(if (> no-of-nodes 1)
(dueca-list (make-packer-manager
'add-set (make-packer-set fpkt pkt pkt)
'add-set (make-packer-set fpkt pkt pkt)
'add-set (make-packer-set fpkt pkt pkt)
'add-set (make-packer-set fpkt pkt pkt)
'add-set (make-packer-set fpkt pkt pkt)
'add-set (make-packer-set fpkt pkt pkt)
'add-set (make-packer-set fpkt pkt pkt)
'add-set (make-packer-set fpkt pkt pkt)
'add-set (make-packer-set fpkt pkt pkt)))
(dueca-list (make-packer-manager)) )
;;; 4 - The channel manager. From now on channel-using objects can
;;; be created.
(dueca-list (make-channel-manager))
;;; definition of the scramnet unpacker is delayed, because it will use a
;;; normal channel and needs the channel manager
(if use-scram-comm?
(define fupkt
(make-reflective-fill-unpacker 'buffer-size bulk-max-size)))
;;; 5 - The ticker. A channel-using object! From now on
;;; ticker-using objects can be created
(dueca-list (make-ticker 'base-increment tick-base-increment
'compatible-increment tick-compatible-increment
'time-step tick-time-step
'priority highest-manager
'sync-mode rt-sync-mode))
;;; 6 - communication hardware accessors. These may use the ticker
;;; or channels to trigger activity.
(if use-ip-comm?
(dueca-list (make-ip-multicast-accessor
pkt ; packer
upkt ; unpacker
packet-size 5 ; size of send buffer, no of buffers
packet-size 50 ; size of input buffer, no of buffers
mc-address mc-port ; multicast IP + base port
if-address ; interface to use for broadcast
50000 ; timeout in usec
no-of-nodes send-order ; no of parties, my send order
(make-time-spec 0 tick-compatible-increment)
; time specification,
comm-prio ; priority below stick
(make-transport-delay-estimator
50.1 1.1 ; initial estimate, 50us turnaround, 1us/byte
20.1 ; s.d. observation, 10 us
10.1 ; s.d. fixed delay
0.1 ; s.d. delay per byte
100.1)
fpkt ; filling packer
fupkt))) ; filling unpacker
(if use-scram-comm?
(dueca-list
(make-scramnet-accessor
no-of-nodes send-order ; no parties, my id
"scram" ; name for the area
(+ send-order 128) ; shmget key, not used here,
; except by QNX nodes for scramnet id
(* 256 1024) ; area size, in WORDS!
packet-size ; each block, also in words
pkt ; packer
upkt ; unpacker
(make-time-spec 0 tick-compatible-increment) ; time spec watchertail
(make-time-spec 0 tick-compatible-increment) ; time spec clock writer
comm-prio ; priority
fpkt fupkt ; fill packer, unpacker
)
)
)
;;; 7 - Pass control to the environment again.
;;; It will now invoke a completeCreation method
;;; from the previously created singletons (0, 1, 3, 4, 5, 6) to
;;; give these the opportunity to do additional initialisation
;;; Then it creates the EntityManager for this node
;; define Lisp mode for this file, for emacs
;; Local Variables: **
;; mode: lisp **
;; fill-column: 75 **
;; comment-column: 0 **
;; End:
This script first defines some scheme variables that will be used later in the creation of the DUECA objects. It is not strictly necessary to do this, but it makes the script easier to configure and read. Here are these variables, and a short explanation.
First the node that we live in, and the number of nodes this dueca process is made of:
(define this-node-id 0) ; id of the current node
(define no-of-nodes 1) ; total number of nodes used
(define send-order 0) ; order/prio in send cycle
If there are three nodes, these nodes must be named 0, 1, and 2. Node number 0 is special, in that it automatically takes the role of administrative node. Some central databases are located in this node, and the model script (dueca.mod) is read here. So it is not wise to use a computer with a highly critical real-time task for this node, or some embedded computer, where access to the script is difficult. In the example the computer with the experiment control station (where the experimenter is sitting), is used for node 0.
Another important item is the send-order. This defines the order in which IP messages are sent. The node with send-order 0 is also special, since this node is the reference to which all others sync for their timing. In this case you do want to choose a node with real-time behaviour. (send-order can also be the order of message blocks in case of SCRAMNet use).
Next some variables that define the type of real-time running are defined
(define highest-manager 3) ; max priority of activities
(define run-in-multiple-threads? #t) ; #f has not been tested for long ...
(define rt-sync-mode 3) ; 0=sigwait, good for Linux master
; 1=select, portable
; 2=nanosleep, good for QNX slave
; 3=rtc, good for Linux slave
; 4=MsgReceive, good for QNX master
; 5=rt_sleep from RTAI
; 6=rt_sleep + slave the video sync
The variable highest-manager refers to the highest ActivityManager in the DUECA node. Each ActivityManager in DUECA handles all activities for one priority. The ActivityManager number 0 handles administrative work (among other jobs, all token creation, activity and module creation). In this case, the highest-numbered manager is number 3, so there are activity managers for priority 0, 1, 2 and 3 in this node. If run-in-multiple-threads is true, each ActivityManager uses one thread (i.e. they can run concurrently). This can be set to false for debugging purposes, then the activity managers all share one thread, and the highest manager gets a first shot at doing all his work. The variable rt-sync-mode determines how the program syncs to the real-time clock in the computer.
Then some variables are defined that control the tick time in the node.
(define tick-base-increment 20) ; logical increment of time, each tick
(define tick-compatible-increment 20) ; same, but used at start-up
(define tick-time-step 0.01) ; time step for each tick
The base increment is the step size with which the Ticker increases the (integer) simulation time each time a time tick occurs. In this case the base increment is one. The time step is the time between ticks, 500 microseconds in the example. This means that every 500 microseconds, (i.e. 2000 times per second), the integer simulation time is incremented by 1. Per second, the integer simulation time increments with a value of 2000. Now this number must be the same for all nodes, otherwise they can never keep synchronised. For a node that runs at 50 Hz (time step of 20000 microseconds), the base increment should be 40.
The tick-compatible-increment is used before the nodes are connected. Ticking in this phase is slow, and nodes try to wait for messages from other nodes to come in. This value has to at least as high as the highest base increment used in the DUECA process. It will also be the rate at which the nodes communicate with each other.
The following section contains variables for the communication driver. In this case IP multicast is used.
(define if-address "192.168.2.4") ; address of own ip interface
(define mc-address "224.0.0.1") ; multicast address
(define mc-port 7500) ; multicast port
(define packet-size 4096) ; size of packets
if-address is the IP address of the interface used to communicate with the other DUECA nodes, mc-address is the broadcast address for the communication, mc-port is the port used and packet-size is the maximum size of the IP packets that can be sent over. The dueca-project script will try to guess the IP address for you, but it can guess wrong on computers with multiple network interfaces. So verify that you have got the right IP address here, otherwise messages don't arrive.
The dueca.cnf file is a scheme program, so it can contain programming statements. Many of these programming statements create objects and modules in DUECA that will later constitute the real-time program. To keep these together, a function "dueca-list" is created:
;;; 0 - A list to assemble references to dueca objects
(define (make-extender local-list)
(lambda (object)
(set! local-list (append local-list (list object)))))
(define dueca-list (make-extender (list )))
This function is needed to keep all the DUECA objects that are created in the script assembled in a list.
Explanation of the use of this function is deferred until later.
Then follow the main actions of the dueca.cnf script, which are calls to routines that are added to scheme from the C++ part of dueca. These calls have a C++ counterpart that is executed as they occur in scheme. Note that the order of this section is always the same, there are 7 steps in the creation of a DUECA node.
-
It starts with the object manager:
;;; 1 - ObjectManager. This enables named objects to be created,
;;; and allows query of the node id and number of nodes
(dueca-list
(make-object-manager 'node-id this-node-id
'no-of-nodes no-of-nodes))
You see that the object manager needs the node id and the total number of nodes. The ObjectManager is the DUECA object that issues all ID's to the objects in a DUECA node. It starts by issuing an ID to itself, and one to the only object that is not created by the scheme script, the scheme interpreter that reads this script.
-
The next object that is being created is the "Environment". This object controls the global flow of the DUECA program, and it also creates and controls the activity managers:
;;; 2 - the environment. The environment will create the necessary
;;; number of activity managers, so activities may now be
;;; scheduled. From this point on it is also possible to create
;;; activities
(dueca-list
(make-environment 'multi-thread run-in-multiple-threads?
'highest-priority highest-manager
'graphic-interface graphic-interface)
You see that it needs to know whether the node will use multiple threads, how many activity managers to make and what interfacing library to start.
-
At this point some priority specifications are created.
(define comm-prio ; priority communication process
(make-priority-spec 'priority comm-prio-level
'order 0))
(define unpack-prio ; priority unpacking incoming data
(make-priority-spec 'priority unpack-prio-level
'order 0))
(define bulk-unpack-prio ; priority unpacking bulk data
(make-priority-spec 'priority bulk-unpack-prio-level
'order 0)) ;priority-specs
-
The following step concerns the creation of packers, unpackers and the packer manager. Before a channel can send data to another node, it needs to know who will handle the data sending. Packers are objects that prepare data for sending to other nodes. They do not do the actual sending. Unpackers take data that comes in from another node, and distribute it over the channels.
;;; 3 - Packers, and a packer manager. Packers are passive
;;; objects, accessed directly, and provide the configuration
;;; data for remote communication. The unpackers use an
;;; activity, and therefore must start after the environment
(if use-ip-comm?
(list
(define pkt (make-packer))
(define upkt (make-unpacker 'priority-spec unpack-prio))
(define fpkt (make-fill-packer 'buffer-size bulk-max-size))
(define fupkt (make-fill-unpacker 'priority-spec bulk-unpack-prio
'buffer-size bulk-max-size))
)
)
(if use-scram-comm?
(list
(define pkt
(make-reflective-packer 'buffer-size 1024))
(define upkt
(make-reflective-unpacker 'buffer-size 1024
'priority-spec unpack-prio))
(define fill-timing
The packers and unpackers must be used as arguments for other scheme commands, and therefore they are "bound to" scheme variables. First a packer is made, with make-packer. The make-packer routine does not need any arguments. Then its corresponding unpacker is made, with make-unpacker. The unpacker needs one argument, and that is the priority specification (a PrioritySpec object in c++) for its activity. Here this activity has priority 1, order 0.
The following object that is made is a fill packer. A FillPacker is for BIG objects, that may take a while to transmit. The fill packer uses spare bandwith on the communication to send its message, the message may therefore arrive a bit late. The simulation itself does not use any such big objects, but logging of the activities (by DUECA) uses the fill packer. The fill packer takes the maximum size of packed obects as an argument, in this case 128 kB. Then the fill unpacker is made. This takes a priority as argument (the administrative priority in this case) and the maximum size of the objects.
The file has been laid out to also work on SCRAMNet set-ups. That is what the alternative configuration is for.
With the packers made, we now make a packer manager. This packer manager maintains an inventory of which packer to use for what destination. You may have several ways of transporting data to other nodes, but in this case it is pretty simple. All bulk data for other nodes is packed by the fill packer, and all normal and high-priority data is packed by the normal packer. The packer manager keeps an inventory of the packers for each destination:
(if (> no-of-nodes 1)
(dueca-list (make-packer-manager
'add-set (make-packer-set fpkt pkt pkt)
'add-set (make-packer-set fpkt pkt pkt)
'add-set (make-packer-set fpkt pkt pkt)
'add-set (make-packer-set fpkt pkt pkt)
'add-set (make-packer-set fpkt pkt pkt)
'add-set (make-packer-set fpkt pkt pkt)
'add-set (make-packer-set fpkt pkt pkt)
'add-set (make-packer-set fpkt pkt pkt)
'add-set (make-packer-set fpkt pkt pkt)))
(dueca-list (make-packer-manager)) )
You see that the make-packer-manager function repeatedly takes a packer set as its argument. These are constructed with the function make-packer-set, which takes three arguments, the bulk packer, the standard packer and the high-priority packer. The element of the vector that corresponds with the node itself (node 1, so the second element) is ignored, because data to the node itself need not be packed and sent. Note that it is OK to add a few extra packer sets. This set-up is valid for up to 8 nodes, if you use more add some more packer sets.
-
Next the channel manager is created. The channel manager does not need any arguments:
;;; 4 - The channel manager. From now on channel-using objects can
;;; be created.
(dueca-list (make-channel-manager))
-
When scramnet is being used, the fill unpacker can only be created after the ChannelManager has been created, since it will start to open a channel.
(if use-scram-comm?
(define fupkt
(make-reflective-fill-unpacker 'buffer-size bulk-max-size)))
-
Now the "clock" of the DUECA node is created, the ticker:
;;; 5 - The ticker. A channel-using object! From now on
;;; ticker-using objects can be created
(dueca-list (make-ticker 'base-increment tick-base-increment
'compatible-increment tick-compatible-increment
'time-step tick-time-step
'priority highest-manager
'sync-mode rt-sync-mode))
The make-ticker function needs the base increment, compatible increment and the time step as arguments. The Ticker uses an Activity, and it needs an ActivityManager for handling this activity. The argument highest-manager indicates that the highest activity manager is handling the Ticker activity.
-
The following step is the creation of the objects that do the communication to other DUECA nodes. Here there are two options, one with ethernet, the other with SCRAMNet
;;; 6 - communication hardware accessors. These may use the ticker
;;; or channels to trigger activity.
(if use-ip-comm?
(dueca-list (make-ip-multicast-accessor
pkt ; packer
upkt ; unpacker
packet-size 5 ; size of send buffer, no of buffers
packet-size 50 ; size of input buffer, no of buffers
mc-address mc-port ; multicast IP + base port
if-address ; interface to use for broadcast
50000 ; timeout in usec
no-of-nodes send-order ; no of parties, my send order
(make-time-spec 0 tick-compatible-increment)
; time specification,
comm-prio ; priority below stick
(make-transport-delay-estimator
50.1 1.1 ; initial estimate, 50us turnaround, 1us/byte
20.1 ; s.d. observation, 10 us
10.1 ; s.d. fixed delay
0.1 ; s.d. delay per byte
100.1)
fpkt ; filling packer
fupkt))) ; filling unpacker
(if use-scram-comm?
(dueca-list
(make-scramnet-accessor
no-of-nodes send-order ; no parties, my id
"scram" ; name for the area
(+ send-order 128) ; shmget key, not used here,
; except by QNX nodes for scramnet id
(* 256 1024) ; area size, in WORDS!
packet-size ; each block, also in words
pkt ; packer
upkt ; unpacker
(make-time-spec 0 tick-compatible-increment) ; time spec watchertail
(make-time-spec 0 tick-compatible-increment) ; time spec clock writer
comm-prio ; priority
fpkt fupkt ; fill packer, unpacker
Most arguments have comments explaining them.
-
Step 7 is not a really complicated step. In this step control is given to the Environment object, and DUECA starts running its c++ code.
;;; 7 - Pass control to the environment again.
;;; It will now invoke a completeCreation method
;;; from the previously created singletons (0, 1, 3, 4, 5, 6) to
;;; give these the opportunity to do additional initialisation
;;; Then it creates the EntityManager for this node
Details on the different classes and their Scheme interface can be found in the Scheme call reference
Dueca.mod
Here is the Dueca.mod file for the example:
;; document the set-up of the simulation
;; nodes
(define ecs-node 0) ; ecs, dutmms1, send order 1
(define cl-node 1) ; control loading dutmms4, send order 0
(define pfd-node 2) ; primary flight display dutmms2, send order 2
;; default priority set-up
(define admin-priority (make-priority-spec 0 0)) ; admin, interface, logging
(define sim-priority (make-priority-spec 1 0)) ; simulation, unpacking
;; difference; control loading
(if (equal? this-node-id cl-node)
(list
(define stick-priority (make-priority-spec 3 0)) ; cl simulation
)
)
;; timing parameters, basis is a granule size of 500 us
(define stick-timing (make-time-spec 0 1)) ; cl calculation, 2000 Hz
(define sim-timing (make-time-spec 0 40)) ; sim, 50 Hz
(define feedback-timing (make-time-spec 0 400)) ; eval feedback, 5 Hz
;;; the modules needed for dueca itself
;;; the modules needed for dueca itself
(dueca-list
(make-entity "dueca"
(if (equal? 0 this-node-id)
(list
(make-module 'dusime "" admin-priority 'min-interval 4000)
(make-module 'dueca-view "" admin-priority)
(make-module 'activity-view "" admin-priority)
(make-module 'timing-view "" admin-priority)
)
(list)
)))
;;; the spaceplane
(define spaceplane
(make-entity "spaceplane"
(if (equal? this-node-id ecs-node)
(list
(make-module 'space-plane "" sim-priority
'set-timing sim-timing 'set-stop-height 0.6)
(make-module 'numeric-plane-output "" sim-priority
'set-output-file "dump")
(make-module 'evaluator "" subsim-priority
'set-path "path1.txt"
'set-flare 7331 'set-final 3879
'set-path "path2.txt"
'set-flare 9280 'set-final 4673
'set-path "path3.txt"
'set-flare 11416 'set-final 5971
'set-feedback-timing feedback-timing
'set-stop-height 0.6)
(make-module 'spaceplane-control "" admin-priority)
)
)
(if (equal? this-node-id 1)
(list
(make-module 'mmslab-stick "stick" stick-priority
'set-timing stick-timing)
(make-module 'rate-reduction "" stick-priority
'set-timing sim-timing)
)
)
(if (equal? this-node-id 2)
(list
(make-module 'display-space "" admin-priority
'set-fullscreen #t)
)
)
(list) ; for nodes that get no modules, empty list
)) ; spaceplane-complete
;; define Lisp mode for this file, for emacs
;; Local Variables: **
;; mode: lisp **
;; fill-column: 75 **
;; comment-column: 0 **
;; End:
This file has already been discussed in the section on the model configuration file for the example. In short some guidelines:
-
Entities are created with the function make-entity. Assign the result of the make-entity function to a scheme variable, in the future it will be possible to use this scheme variable for re-configuration of the entity:
(define my-entity (make-entity "my-entity" ...
-
The make-entity function takes as its arguments the name of the entity that has to be created, and one or more lists of modules for this entity. Use the construction with the "if" function to create this list. When the test in the if statement returns true, the statement returns the list of your modules. In the other case it returns an emtpy list, '(list)', for example:
;;; the spaceplane
(define spaceplane
(make-entity "spaceplane"
(if (equal? this-node-id ecs-node)
(list
(make-module 'space-plane "" sim-priority
'set-timing sim-timing 'set-stop-height 0.6)
(make-module 'numeric-plane-output "" sim-priority
'set-output-file "dump")
(make-module 'evaluator "" subsim-priority
'set-path "path1.txt"
'set-flare 7331 'set-final 3879
'set-path "path2.txt"
'set-flare 9280 'set-final 4673
'set-path "path3.txt"
'set-flare 11416 'set-final 5971
'set-feedback-timing feedback-timing
'set-stop-height 0.6)
(make-module 'spaceplane-control "" admin-priority)
)
)
(if (equal? this-node-id 1)
(list
(make-module 'mmslab-stick "stick" stick-priority
'set-timing stick-timing)
(make-module 'rate-reduction "" stick-priority
'set-timing sim-timing)
)
)
(if (equal? this-node-id 2)
(list
(make-module 'display-space "" admin-priority
'set-fullscreen #t)
)
)
(list) ; for nodes that get no modules, empty list
)) ; spaceplane-complete
-
Each make-module call takes the name of the module as a scheme literal (i.e. after the quote '), the part name (as a string) and the priority specification as its minimum arguments. All additional arguments take the form of an argument name and the argument itself, these argument names are the same as those specified in the parameter table and of course the scheme parameters must be convertible to the parameters of the parameter table.
One set of models one will usually find in the configuration file are the dueca modules. These create a control window on the no 0 node, and give the user the opportunity to control the DUECA/DUSIME. The common format for these is:
(dueca-list
(make-entity "dueca"
(if (equal? 0 this-node-id)
(list
(make-module 'dusime "" admin-priority 'min-interval 4000)
(make-module 'dueca-view "" admin-priority)
(make-module 'activity-view "" admin-priority)
(make-module 'timing-view "" admin-priority)
)
(list)
)))
Note that these are normal modules. The dusime module provides the control logic for all modules that are derived from SimulationModule and HardwareModule. It coordinates state transitions between all these modules, collects reports about the transition and keeps these in a logic tree. The dueca-view module presents this tree, the control buttons for the DUECA part (which actually start and stop the module activities) and the control buttons for DUSIME, which control the mode the simulation is running in. It also presents an overview of the status of all nodes, and an overview of the status of all modules in DUECA.
Aside from this interface, there is another possibility to control the mode of the simulation. The DUSIME module opens a channel to which the application can send requests for simulation state changes. If you want to control these state changes, create a token to write to this channel. In your header file:
#include <dusime.h>
#include <SimStateRequest.hxx>
class MyClass: public SimulationModule
{
EventChannelWriteToken<SimStateRequest> requests;
Initialise the channel as follows:
requests(getId(), NameSet("dusime", "SimStateRequest", ""),
ChannelDistribution::NO_OPINION),
You can request for a transition to HoldCurrent, which will be granted if the system is in either the Advance or Replay mode. You can also request a transition to Advance, which will be granted if the system is in HoldCurrent. There is no confirmation on the request, other than the effects your module can detect (i.e. a different SimulationState when the transition is complete).
Some Advice
Making a dueca.cnf and a dueca.mod file for a DUECA application running on a single node is usually just a matter of some intelligent copying and pasting. Making a configuration for a full-blown simulation with multiple nodes can be a tricky job. I know, because it often takes me several passes to get the configuration right. Probably the best approach to this is to take things one step at a time. Start with the single node that runs your application as you developed it, add another node to it, but don't assign it any modules yet. If things start up all right, move the appropriate modules over. Then add another node, move the modules, and so on. If everything goes right, it only takes you 2n iterations. And if something does not work, you at least know which node is giving you problems.