Configuring A CAST System

Introduction

To run a CAST system you must provide the client with a description of the components you wish to run and the way that they are divided across subarchitectures. This configuration file is written in plain text and called a CAST file. For the sake of consistency we always give the config files a .cast suffix and store them in a /config directory. In a CAST config file you can describe anything from a single component, to a single subarchitecture (if you want to test it on its own) or to a full architecture with any number of subarchitectures. For each component you can specify the host it runs on and a list of command-line arguments which as passed into the component's configure method [c++|java].

Formatting

Comments

Comment lines start with #.

The HOST Line

If you want to specify a host machine to be used as the default for all subsequent components, you can specify it using the keyword HOST. E.g. The entry...

HOST dewey 

... will cause the configuration code to assign all subsequent components the hostname of dewey unless overridden.

The SUBARCHITECTURE Section

The majority of a config file will probably be made up of subarchitecture descriptions. A subarchitecture description is started with the following line

SUBARCHITECTURE <subarchName> <opt:subarchHost>

This states that the component descriptions following this line make up the subarchitecture, and run on the optionally specified host. E.g.

SUBARCHITECTURE vision.sa louie

Describes a subarchitecture vision.sa with its components to run by default on louie. The lines following this must describe a working memory component, and task manager component and zero or more processing components.

The Working Memory Line

You describe a subarchitecture working memory with the following line...

<opt:host> <lang> WM <class> <opt:command line>

Where <opt:host> is an optional name of the host to run the component on, <lang> specifies the language the working memory was written in and is either CPP or JAVA, WM states that this component is a working memory, <class> is the name of the component library (for C++) or is a fully qualified class name (for Java), and <opt:command line> is a list command parameters which are passed to the component's configure method. These are described in more detail here. E.g.

JAVA WM cast.architecture.SubarchitectureWorkingMemory --debug -v 2 -N

... specifies a java working memory component with some arguments, and

hewey C++ WM SubarchitectureWorkingMemory --log

... does the same for a C++ working memory (from libSubarchtectureWorkingMemory.so), but also specifies that it runs on a specific host.

The Task Manager Line

This is the same format as the working memory line, but with TM instead of WM. E.g.

hewey JAVA TM cast.architecture.AlwaysPositiveTaskManager 

Unmanaged Component lines

Unmanaged components [c++|java] are added to the subarchitecture using a line of the following format...

<opt:host> <lang> UM <id> <class> <opt:command line>

This is almost identical to preceding lines, with the addition of the <id> argument which specifies the unique identifier of the processing component (used to identify it at rutime). E.g.

CPP UM ernie.wise StraightMan --setup "what's brown and sticky"

Managed Component lines

Managed components [c++|java] are added in the same way as unmanaged components, but with MG instead of UM. E.g.

JAVA MG eric.morecambe comedyarch.FunnyMan --punchline "a stick" --log #--debug

Components

You can also add components a CAST system which are not part of a subarchitecture [c++|java].

This is done in a similar way to other components, but with a COMPONENT prefix...

COMPONENT <opt:host> <lang> <name> <class> <opt:command line>

e.g.

COMPONENT CPP eg ExampleComponent --log  #--debug

Would create an extra C++ component in the configuration.

"Command Line" Configuration

The command line-style arguments given to any process are parsed into string key-value pairs and are placed into the map given as input to the component's configure method [c++|java]. Any command line entry starting with - is treated as a key and then the subsequent string is treated as its associated value. Keys without attached values are given the value "true". Explicitly marked strings are not broken up. E.g.

--debug -v 2 -N -say "Hello World"

would result in the key-value pairs:

--debug = true
-v = 2 
-N  = true
-say = Hello World

Example Configuration

HOST localhost

SUBARCHITECTURE stage.subarch 
CPP WM SubarchitectureWorkingMemory  --log --debug
CPP TM AlwaysPositiveTaskManager #--log --debug
JAVA UM straight.man comedyarch.StraightMan -s "what's brown and sticky" --log --debug
CPP MG funny.man FunnyMan --punchline "a stick" --log --debug

SUBARCHITECTURE audience.subarch 
CPP WM SubarchitectureWorkingMemory  --log --debug
CPP TM AlwaysPositiveTaskManager #--log --debug
JAVA MG audience.member comedyarch.AudienceMember --reaction "YAY!" --log --debug


SUBARCHITECTURE director.subarch
#CPP WM SubarchitectureWorkingMemory  --log --debug
JAVA WM cast.architecture.SubarchitectureWorkingMemory  --log --debug
CPP TM AlwaysPositiveTaskManager #--log --debug
JAVA MG ass.director comedyarch.AssistantDirector --log #--debug
JAVA MG director comedyarch.Director --audience audience.subarch --log  #--debug

Including parts of configuration files

Configuration files may grow in a complex system. In this case one would split the configuration file in multiple parts and include the parts in the main file. This can be done with the INCLUDE statement:

# ----- file: main.cast -----
INCLUDE  stage_subarch.cast

# ----- file_ stage_subarch.cast
SUBARCHITECTURE stage.subarch 
CPP WM SubarchitectureWorkingMemory  --log --debug
CPP TM AlwaysPositiveTaskManager #--log --debug
JAVA UM straight.man comedyarch.StraightMan -s "what's brown and sticky" --log --debug
CPP MG funny.man FunnyMan --punchline "a stick" --log --debug

The INCLUDE statement accepts a file path that is relative to the directory in which the currently processed file resides.

Setting and using variables

(SETVAR, VARDEFAULT introduced in version 2.1.13)

Sometimes multiple components use the same setting which has to be entered in the arguments of every component. To simplify the modification of such arguments, variables can be used with the keywords SETVAR and VARDEFAULT. With SETVAR the value of a variable is changed unconditionally while VARDEFAULT sets the value of a variable only if the variable was not defined before.

SETVAR punchline="a brown stick"
VARDEFAULT punchline="a stick"
VARDEFAULT string="what's brown and sticky"

In this case the variable punchline has the value "a brown stick" and the value of string is "what's brown and sticky". Note that everything after = is part of the variables value, including the quotes.

The value of the variable can be used in the argument part of a configuration line with the variable expansion expression %(varname):

JAVA UM straight.man comedyarch.StraightMan -s %(string) --log --debug
CPP MG funny.man FunnyMan --punchline %(punchline) --log --debug

Variables can span multiple lines if the right-hand-side of the variable definition is <multiline>. The value of the variable spans until the line that contains only </multiline>:

SETVAR punchline=a brown stick
VARDEFAULT string=what's brown and sticky

SETVAR straight_params=<multiline>
   -s "%(string)"
   # --log --debug
</multiline>
JAVA UM straight.man comedyarch.StraightMan %(straight_params)

SETVAR funny_params=<multiline>
   --punchline "%(punchline)"
   --log --debug
</multiline>
CPP MG funny.man FunnyMan %(funny_params)

The lines that are inside the <multiline> section are concatenated with a single space except for the lines that start with # which are ignored.

This example also shows that the value of a variable can be used inside the right-hand-side of another variable.

Special variables

The configuration parser sets the following variables every time a new configuration file is included:

This variables can be used to reference extra files needed by some components with relative filenames:

SETVAR camera_config=%(CURRENT_DIR)/config/camera.ini

Distributed execution

(HOSTNAME introduced in version 2.1.13)

As stated above every component can be executed on a different host which can be set with the HOST statement or with the address of the host in a component definition command. Defining hosts in such a way is very non-portable.

To make the configuration files more portable, the command HOSTNAME can be used. The command must be placed in a configuration file before any other command except SETVAR, VARDEFAULT and INCLUDE (which can again include only the four commands mentioned here).

The defined host-name can be used in the form [host-name] anywhere a host address is recognized by the config parser, as described with each command above. A host name can additionally be used in a variable expansion expression as %(host:host-name).

In the following case the component laser.server is started on localhost (LaserHost -> Main -> localhost) while the component robot.server starts on the host PlayerHost (192.168.26.34). Both components connect to an instance of the Player server which is also running on the host PlayerHost.

HOSTNAME   Main        localhost
HOSTNAME   PlayerHost  192.168.26.34
HOSTNAME   LaserHost   [Main]

HOST       [Main]
COMPONENT  [LaserHost] CPP laser.server LaserServerPlayer --player-host %(host:PlayerHost)

COMPONENT  [PlayerHost] CPP robot.server RobotbaseServerPlayer --player-host %(host:PlayerHost)

Generated on Mon Jun 13 15:56:05 2011 for CoSy Architecture Schema Toolkit (CAST) by  doxygen 1.5.8