How to configure the MRS
The
MRS consists, as stated on the "
What the MRS can do for you" page, of one or more ComponentRunners. Every ComponentRunner has a configuration file that configures the behavior of the ComponentRunner and the components that live inside it.
This document provides:
- A simple example
- A more complex example
- Usage of the ComponentRunner with the Eclipse Console
- Usage of the ComponentRunner without the Eclipse Console
- Usage of the ComponentRunner with Tomcat
A simple example
The following configuration file example configures a simple MRS which is not distributed. All components run on the same machine. We have the mandatory components, timer and server, a simulated world component, one micropsi agent and the Eclipse Console.
(You might have noticed: This is the default configuration of a toolkit installation.)
The full example configuration file is attached to this snip (example1.xml). Here's the explanation of what the sections in the file do:
<runner>
<components>
world,localserver,timer,micropsi,console
</components>
<threadpool>
<maxthreads> 10 </maxthreads>
<minthreads> 5 </minthreads>
<maxidletime> 5000 </maxidletime>
</threadpool>
<log>
<file> $MICROPSI_HOME/console.log </file>
<level> ALL </level>
</log>
</runner>The
runner part of the configuration file
must be provided. It contains the configuration for the ComponentRunner itself. All tags inside the runner tag are mandatory as well.
The
components tag contains a comma-separated list of components to be run by this runner. For every component, there must be a subsection later on in the file. The order in which the components are in this list is the order in which they will be instatiated and started by the ComponentRunner. Always start the world (or robot) before starting the server. Always start the server before starting the timer. Always start the timer before starting any other stuff. Start the other stuff in any order you like.
The
threadpool section configures the ComponentRunners thread pooling. Don't change the settings here.
The
log section configures ComponentRunner-wide logging. You can specify a file and a log level.
$MICROPSI_HOME is a variable. It's always defined. When you start the MRS with Eclipse Console, this variable will point to the directory in which the org.micropsi.runtime plugin lives. When starting the ComponentRunner alone (without Eclipse), $MICROPSI_HOME points to the current working directory. (The directory from which you started the ComponentRunner.)
Another variable, $WORKSPACE, is only defined when the MRS runs with the Eclipse Console. It points to the workspace of the running eclipse instance.
As log level, you may specify one of the following: ALL, DEBUG, INFO, WARN, ERROR, FATAL.
Ok, so this ComponentRunner is to run the components called "world", "localserver", "timer", "micropsi" (you guessed it: an agent), and "console".
Let's start with the definition of the "world" component.
<component id="world">
<class>
org.micropsi.comp.world.WorldComponent
</class>
<data>
<servers>
<server id="s1">
<type> 0 </type>
<name> worldserverserver </name>
</server>
</servers>
<clients>
</clients>
<worldfiledir> $MICROPSI_HOME/config/worldfiles </worldfiledir>
<worldfile> world.xml </worldfile>
<groundmapimagedir> $MICROPSI_HOME/config </groundmapimagedir>
<objecttypesconfigfile> $MICROPSI_HOME/config/worldobjecttypes.xml </objecttypesconfigfile>
</data>
</component>The first thing you need to know about component definitions is: They are generic. The ComponentRunner does not know what a "world" component is just by the name. (We could as well have named the component "wrdlbrmpfd".) So a component definition always defines:
- The class that implements the component
- channel servers and clients (see component to learn about channels)
- some information specific to this component implementation
In the case of the "world" component, the
class is the implementation of our simulated world, org.micropsi.comp.world.WorldComponent.
The
servers and
clients sections define the channel servers and clients. The world has one channel (to the server component), and it is the server of this channel. (Please excuse the confusion. There is a
component that plays the role of a server to agents and consoles, hence we decided to call the the component "server". A channelserver is the end of a channel that handles requests from channelclients. The servers/clients section of a component declaration talks about channelserver/channelclients.)
A channelserver's
id, an attribute of the
server tag, doesn't mean anything. The only thing to consider is that all channel servers should have different ids.
The channelserver
name for everything that plays the role of a world
must be worldserverserver. (Decode: "I am the world's channelserver for the server component").
The channelserver
type contains a code for the type of the channel. Currently, there are two supportet types: 0 (zero) for "in the same ComponentRunner" and 1 (one) for "XML-over-HTTP".
The other tags are specific to the world component and are described at the world component snip.
Now look at the definition for the server component:
<component id="localserver">
<class>
org.micropsi.comp.server.ServerComponent
</class>
<data>
<useworld> world </useworld>
<servers>
<server id="s1">
<type> 0 </type>
<name> serverconsoleserver </name>
</server>
<server id="s2">
<type> 0 </type>
<name> serveragentserver </name>
</server>
<server id="s3">
<type> 0 </type>
<name> servertimerserver </name>
</server>
<server id="s4">
<type> 1 </type>
<name> serveragentserver </name>
</server>
</servers>
<clients>
<client id="c1">
<type> 0 </type>
<name> serverworldclient </name>
<connect-to> worldserverserver </connect-to>
<usethreadpool> false </usethreadpool>
</client>
</clients>
</data>
</component>Of course, there's the
class tag that makes this component the server component. The server definitions should also be clear by now. There are four channelservers with four different ids. One for the timer (so it can tell us when to pass actions to the world). One for the Eclipse Console, so it can interact with the running MRS. One for the agent, so it can send actions and receive perception data. And another one for the agent, with the same name as the other (as it serves the same purpose, it's a channelserver, defined in the server component, for agents.), but a different type: A type-1-Server! This means that, if there is a servlet engine installed in the VM and a servlet is configured, agents will be able to connect through HTTP to this server.
The
clients section is new. A server component has a channelclient, so it can connect to the world component.
The
type says 0 (zero), so the client will try to find its server in the same ComponentRunner.
The
name just follows the conventions described above and on the
components page, but with a trailing "client" instead of "server". Decode: This is the server component's client for connecting to the world.
The
connect-to specifies the channelserver to connect to. In case of type-0-channels this is just the name of the channelserver. In case of a type-1-channel this would be the URL of the servlet where the channelserver listens for HTTP connections.
Ignore
usethreadpool and leave it at "false".
The other component's declarations are just as the ones given above. All tags without description on this page are specific to the component implementations and are described at the pages of the
components.
A more complex example
The second example defines an MRS with two ComponentRunners. The first one runs the world, server and timer components "headlessly". The second runs a console and and agent. This is a typical setup, of course, as the second ComponentRunner configuration could easily be started several times. With this setup, a constantly running ComponentRunner simulates a world where agents can join in via Internet.
The configuration files are attached as example2-server.xml and example2-client.xml.
With the information from the previous section, the files should be readable. The only interesting new thing is the $USERNAME variable: As this configuration is meant to be used multiple times in one MRS, the system should be able to distinguish the consoles, so $USERNAME will be replaced with a user tag to identify the console. The same thing could be done with the agent.
It is, however, not necessary to do so. If two components with the same ID show up in the system, one of them will be given a new ID.
Usage of the ComponentRunner with the Eclipse console
To use the ComponentRunner with the Eclipse console, you don't need to do anything. The Eclipse Console starts the MRS with the configuration file you specify in the preferences as soon as necessary. The only thing you need to look after is the "server to use" field - the entry must match the server name specified in the configuration file.
Usage of the ComponentRunner without the Eclipse console
The component runner can be used without the auto-start function the eclipse console implementation provides. All you need to do is to start the ComponentRunner directly:
java org.micropsi.comp.common.ComponentRunner CFG USERNAME
Replace CFG with the configfile and USERNAME with the value you want to put into the $USERNAME variable in the configfile. (You can also omit the username.)
Ensure that all binaries are in the classpath. You need at least the common.jar. Depending on what else you want to run, add world, server, timer, agentframework, net (the nodenets), robot and/or console.jar.
If you want to start the MRS programmatically from another Java application, call ComponentRunner.getInstance(CFG,...).
Usage of the ComponentRunner with Tomcat
The Eclipse Console automatically configures servlets for type-one channelservers. To enable type-one channelservers when running the MRS without the Eclipse Console, there must be a servlet container like
Tomcat. To start the MRS inside Tomcat or any other servlet container, configure it to start a servlet of type org.micropsi.comp.common.ComponentService for each channelserver:
web.xml
<servlet>
<servlet-name>servlet-serveragentserver</servlet-name>
<description>
The servlet for the serveragentserver of the "server" component
</description>
<servlet-class>org.micropsi.comp.common.ComponentService</servlet-class>
<init-param>
<param-name>configFile</param-name>
<param-value> CFG </param-value>
</init-param>
<init-param>
<param-name>component</param-name>
<param-value>server</param-value>
</init-param>
<init-param>
<param-name>channelserver</param-name>
<param-value>serveragentserver</param-value>
</init-param>
<load-on-startup>5</load-on-startup>
</servlet>(You can find a web.xml in the webapp directory of the toolkit's org.micropsi.runtime plugin).