RoomsWorld is a simulated Soar Robot environment. It is composed of a set of connected rooms, some of which contain blocks. One of the rooms is designated the storage room. The agent's task is to collect the blocks and move them to the storage room. The agent can turn and move forward, and pick up and put down a block. The agent can only carry one block at a time. The agent's movement is continuous and takes time (it turns and moves at a fixed rate). The agent's perception is limited by a vision cone.

Environment Properties
  • Deterministic, dynamic with respect to the agent's actions, continuous
Download LinksAssociated Agents
  • The environment download contains agents. Which agent loads depends on the configuration file you choose.

Component Overview
  1. April
    • []
    • A major part of the project is the april libraries in the april.jar file. These contain all sorts of component and utility functions, including most of the simulator and 3D viewer code (Vis), and math routines and such.
    • Note that this is a fork of the official april code with heavy modifications. Acquiring the april code from the april folks will not work.
  2. libgrrc-java
    • This is a pure Java implementation of the libgrrc library used to communicate with a few of the robots such as Superdroid and the PackBot (Michigan GRRC interface). This allows the simulator code to interface directly with these robots.
  3. Soar
    • Soar SML 9.3.4 is used to interface the Simulator and Soar.
  4. soarrobot
    • The soarrobot project contains three Eclipse projects: SoarRobotServer for the main simulator components, SoarRobotTablet for a component that runs on the Android Galaxy tablet, and SoarRobotLibrary for shared code between the two.
Entry Point

The Application class (edu.umich.robot.Application) in the SoarRobotServer project serves as an entry point for the application. This program serves as a manager/container for most of the other components.
When the app is first run, the first thing it does is look at the configuration file supplied on the command line and determine if it is supposed to be in batch, or headless mode. More often it is not so it starts up an interactive GUI.
The headless/batch mode grabs configurations from a file (or multiple files) and runs them back to back to gather data over multiple runs.
The GUI uses a configuration file or prompts the user to find one. Defaults exist in config basic. 3x3.txt is a good one to start with.
Configuration Files

Configuration files are based on a configuration file utility in the april libraries. See april.config.Config and friends. ConfigUtil is used to load configuration files initially. Config files are key-value pairs with syntactic sugar to make things easy to read.

    splinters = seek;
        position = [2, -2];
        productions = "agents/robot3/clean-house-new.soar";
This snippet has exactly three key value pairs and can be rewritten to emphasize this:

    splinters = [seek];
    seek.position = [2.0,-2.0]; = "agents/robot3/clean-house-new.soar";
The pound sign comments out the rest of a line. Brackets form blocks that prepend the block name to each key in the block. Nested blocks are allowed, along with keys that share the names as block names:

    alpha = foo;
            bravo = bar;
        bravo = charlie;

    alpha = foo;
    alpha.bravo = charlie;
    alpha.bravo.bravo = bar;
All entries should end on a semicolon. All whitespace is ignored unless "it is in quotes like this." All values are actually stored as arrays and writing entries with only one value without array notation is optional. To encode multiple values, just add values in square brackets with commas separating things.

   encoding_a_single_value = foo;
   another_way = [foo];
   yet_another = [bar,];
   careful with spaces = becomes; # carefulwithspaces = becomes;
   values_too = "spaces must be in quotes";
   many = ["one", "two", "three"];
Everything is stored as a string. It is converted to a type when you read it. If you know that robot.pose is an array of floats, you'll call getDoubles(). If any fail to convert, you'll get an exception.

Configuration Content

Configuration files contain the following stuff:
  • splinters: an array of names of splinters
  • SPLINTER_NAME: a block for each splinter named in splinters with information about the splinter
    • position: location of the bot
    • productions: Soar productions to load
    • OTHER: There are a bunch more properties here controlled by guis
  • image_path: path to image file used for walls
  • image_origin: pixel marking the origin. The lower-left corner is used, I think
  • meters_per_pixel: pixel to meter unit conversion
  • metadata: block with information describing the metadata presented to Soar depending on where on the map it is in
    • INTEGER: starting at 0 and counting up, each room description in x, y, w, h pixels (relative to image).
    • doors: array indicating which rooms are doors
    • closed: array indicating which doors are closed
    • locked: array indicating which closed doors are locked, and with what key [door-id, key, door-id, key, ...etc...]
    • objects: block with object class/prototype descriptions with initial state
      • OBJECT_NAME: block with an object description
        • size: size of the object in meters: [width, height]
        • color: color from the set defined in java.awt.Color
        • ANY: any property with any value, shows up on input-link
      • placed: array with triples: object name, x, y where object name is a prototype defined in this block, and x, y where it is supposed to go. Example: [green_cube, -3.2, 4.1]
Configuration files are usually started by hand but then tweaked and written out by the app. There are a few GUIs that mess around with various configuration files stuff in the app, and then write it out in a flat format. Nothing here is finished, it is all tailored to some research done in December.

When the app writes out the config file, it does so in the flat format where everything is explitly key/value pairs with array values of strings.

GUI Applicaiton

Most of the time, the simulator is started in the GUI/interactive mode as opposed to the data-collecting, headless, batch mode.
A simple swing application is started with a 3D view in to the environment and a list of robots and associated controllers.

Right click the controller's list to associate a Soar agent.

Robot Controllers

Robot controllers are things that, well, control the robots. The gamepad is a simple robot controller. Another one could be the web interface that was never ported over from the old sproom code. The main robot controller is Soar.

Robots are initially created with no controller. If their configuration includes productions, a Soar agent and debugger is created. If the gamepad is connected and the 2 button pressed, it takes over for whatever controller is on. Pressing 2 again pops it off returning control. Great for overriding behavior.

The only gamepad currently supported is the Logitech Wireless.


Below the 3D scene is a feedback window with output sometimes useful for debugging agents.


The GUI creates the main program controller. Many of the GUI actions interact with this controller. The controller manages Soar and Soar agents, robots and their controllers, the simulator and other components.

Event System

Many of the messages passed from controller to controller are though events. There are three types of event managers and events:
  • The main program event manager that serves events extending AbstractProgramEvent. Things like simulation start, stop, robots getting added or removed, controller changes, and time scale change are all handled here. There is only one of these event managers and it is in the Controller.
  • Robot Controller event managers, one in each robot controller. Each Soar agent and the gamepad have one of these to dish out events extending AbstractControlEvent. These events include drive commands and environment manipulation.
  • Robot Feedback event managers, one in each robot interface implemenation. These events extend AbstractFeedbackEvent and include the status of drive and effector commands.
The event types are switched using classes. Registering for a parent class registers you for all derived class event types. Events fire with a new instance of the event class. Event parameters are passed in to the event object. Events are (should be) immutable.(Actually I think some aren't. Most are.)


A member of the Controller, the simulator is implemented in the april code and takes an initial configuration file to bootstrap.
The simulator takes the image, image origin, and meters per pixel and uses this data to generate simulated laser data and motion collision for the robots.
IO link Specification

Input Link

At the top level there are the following identifiers:
  • time: World clock
  • self: Information about the robot
  • configuration: Simulator and robot settings and configuration
  • waypoints: Navigation point data as set by the robot
  • received-messages: Messages received by the robot
  • area-description: Information about the map based on the robot's current location
  • objects: Information about objects detected by the simulated object sensor
  • lidar: Laser range finder data
  • seconds (int) (positive seconds): Use to measure elapsed time only.
  • microseconds (int) (microseconds 0 to 999999): Fraction of second, use to measure elapsed time only.
Use time.seconds and time.microseconds to measure elapsed time only--they are not related to any other notion of system or wall-clock time. Real current time is not implemented.

  • Reports all current settings of output-link.configure.
  • limits.velocity
    • linear
      • maximum Maximum linear velocity in configured units.
      • minimum Minimum linear velocity in configured units.
    • angular
      • maximum Maximum linear velocity in configured units.
      • minimum Minimum linear velocity in configured units.
  • geometry
    • length
    • width
    • height
    • wheelbase
  • range-count (int): Number of coarse LIDAR ranges.
  • field-of-view (angle-resolution type): Object sensor field of view.
  • manipulation-distance-min (float): Minimum allowable distance for get-object (and commands like it) to work, also distance that objects are dropped.
  • manipulation-distance-max (float): Maximum allowable distance for get-object (and commands like it) to work.
Current interface configuration, configurable using the output link configure command. WME formats are identical to the command parameters except that there is no status reported here.

Additionally, some non-configurable information is presented on the configuration input link.

  • name (string): Agent name.
  • area (int): Unique identifying number for area/room.
  • headlight (string) (on, off): Headlight state.
  • battery (float) (100.0-0.0): Percent battery life.
  • pose
    • x (float)
    • y (float)
    • z (float)
    • yaw (angle-resolution type) (-180 to 180, or -pi to pi)
    • x-velocity (float)
    • y-velocity (float)
    • z-velocity (float)
    • yaw-velocity (float) (positive for left turn, negative for right turn)
Self contains data about the robot itself.

self.pose gives information about the robot's position and velocity. This information is an aggregate of mapping and navigational subsystems (such as odometry or external localizers) between the interface and the simulation or hardware. The origin can be configured using the configure command.

  • waypoint: One for each registered and enabled waypoint.
    • id (any type): User-defined unique identifier in user-defined type.
    • x (float)
    • y (float)
    • z (float)
    • distance (float) (positive): Distance to point.
    • yaw (angle-resolution type) (-180 to 180, or -pi to pi): What absolute yaw to turn to to face the point.
    • relative-bearing (angle-resolution type) (-180 to 180, or -pi to pi): Which way to turn to face the point, positive means turn left. 0 means the point is straight ahead.
    • abs-relative-bearing (angle-resolution type) (0 to 180 or 0 to pi): Magnitude of relative bearing, represents how far to turn.
The Soar interface allows agents to define arbitrary points in space as named waypoints. Waypoints that are defined and enabled (they are enabled by default when defined) show up under the waypoints identifier. Distance to and useful angles are calculated to the waypoint.

Received Messages
  • message: One for each received message.
    • id (int): Unique identifying number for message.
    • from (string): Source of message (such as agent name).
    • first: Starts linked list.
      • word (string): The word data.
      • next (identifier or string "nil" to end): Under this identifier are more word and next WMEs, terminated when next is "nil".
The messaging system places messages to and from the agent under the received-messages identifier. Each message has a unique id number (used with the messaging commands) and a from field and a linked list of space-delimited words ended when next is set to a string instead of being an identifier pointing to the next word.
For example, matching on "go to waypoint alpha" from alice:

    (<s> ^io.input-link.received-messages.message <m>)
    (<m> ^id 1 ^from alice ^first <w1>)
    (<w1> ^word go ^next <w2>)
    (<w2> ^word to ^next <w3>)
    (<w3> ^word waypoint ^next <w4>)
    (<w4> ^word alpha ^next nil)
  • range: One per range to be measured (default is 5).
    • id (int): -nranges / 2 to nranges / 2, 0 is straight ahead (so, with 5, -2, -1, 0, 1, 2).
    • distance (float): Measured distance.
    • relative-bearing (angle-resolution type): Relative bearing to measured distance.
Area Description
  • id (int): Unique identifying number for area/room.
  • type (string) (door, room): Type of room.
  • light (string) (true, false): If the room is lit.
  • gateway (multi-valued): One for each exit from the room.
    • id (int): Unique identifying number for gateway.
    • direction (string) (north, east, south, west): Which wall the gateway is on.
    • to (int): Area id on this side of gateway.
    • to (int): Area id on other side of gateway.
    • door: Details about the door
      • id (int): Door id number.
      • state (string) (open, closed, locked): State of door.
    • x (float): To center of wall
    • y (float): To center of wall
    • z (float): To center of wall
    • distance (float): To center of wall
  • wall
    • direction (string) (north, east, south, west): Which wall it is.
    • open (string) (true, false): If the entire length of wall is virtual (part of a larger room).
    • to (int) (potentially multi-valued): One area id for each area connected on the other side of this wall, usually only one area. Does not include this area.
Area descriptions currently assume rectangular rooms with walls and gateways aligned with the x/y axes. The rooms may be comprised of multiple areas connected with virtual or "open" walls so that more complex (non-rectangular) rooms may be represented as compositions of rectangular rooms.

  • object: One for each detected object
    • type (string) (block, brick, ball, player): Type of object.
    • id (int): Unique identifying number for objects.
    • name (string): Unique agent name if other player.
    • x (float): To center of object
    • y (float): To center of object
    • z (float): To center of object
    • distance (float): To center of object
    • visible (string) (true, false): Object stays on input link briefly after it is not visible.
    • Optional properties (see below).
Objects in the world are sensed with some of these application-specific properties.
  • color (string)
  • height (string)
  • smell (string)
  • shape (string)
  • weight (float)
  • diffusible (string) (true, false): Object can be diffused.
  • diffuse-wire (string) (red, green, blue): Which wire diffuses it.
  • diffused (string) (true, false): Object (diffusible only) is diffused.
Output Link

A note about status error: most commands that return with status error will have an error message attached for debugging. Example parsing failure for set-velocity:

    (<s> ^io.output-link.set-velocity <sv>)
    (<sv> ^status error ^message |set-velocity: Unable to parse linear-velocity| )
Drive Commands

Only one of the drive commands can be issued at a time. If more than one command is issued, the system arbitrarily picks one unless one of them is estop, which overrides all other drive commands.
All parameters for the command must be on the same identifier of the command.
For example, all parameters for the command must be on the same identifier:

    (<s>  ^io.output-link <ol>)
    (<ol> ^set-velocity <sv>)
    (<sv> ^linear-velocity 1. ^angular velocity 1.) # Good
    (<ol>  ^set-velocity <sv1> ^set-velocity <sv2>)  # BAD: two separate commands
    (<sv1> ^linear-velocity 1.)    # BAD: missing angular velocity argument
    (<sv2> ^angular velocity 1.)   # BAD: missing linear velocity argument
For all drive commands:
  • throttle (float) A number from -1.0 to 1.0 representing percent throttle (or effort), negative is reverse.
  • linear velocity (float) Velocity, positive for forward or negative for reverse, in units defined by configuration. Subject to limitations defined in configuration.
  • angular velocity (float) Rotation, degrees or radians (as defined in configuration) per second, subject to limitations defined in configuration.Positive is left turn.
  • yaw (float or int) Absolute yaw. Ranges outside of normal limits (such as 720 degrees or -3*pi) are OK (and will be reduced internally to the usual ranges).
  • motor
    • left (float): Throttle, described above.
    • right (float): Throttle, described above.
    • status (string) (accepted, executing, complete, error)
  • set-velocity
    • linear-velocity
    • angular-velocity
    • status (string) (accepted, executing, complete, error)
  • set-linear-velocity
    • linear-velocity
    • status (string) (accepted, executing, complete, error)
  • set-angular-velocity
    • angular-velocity
    • status (string) (accepted, executing, complete, error)
  • set-heading
    • yaw (any number type)
    • status (string) (accepted, executing, interrupted, complete, error)
  • set-heading-linear
    • yaw (any number type)
    • linear-velocity (float)
    • status (string) (accepted, executing, interrupted, complete, error)
  • stop: Graceful stop.
    • status (string) (accepted, executing, interrupted, complete, error)
  • estop: Emergency/all stop.
    • status (string) (accepted, complete)
Effector and Robot State Commands
  • get-object: Pick up an object.
    • id (int): Target object id.
    • status (string) (accepted, complete, error)
  • drop-object: Drop a carried object.
    • id (int): Target object id.
    • status (string) (accepted, complete, error)
  • diffuse-object: Engage in a domain-specific diffuse task.
    • id (int): Target object id.
    • status (string) (accepted, complete, error)
  • diffuse-object-by-wire: Engage in a domain-specific diffuse task.
    • id (int): Target object id.
    • color (string) (red, green, blue): What wire to cut
    • status (string) (accepted, complete, error)
  • set-headlight: Turn headlight on/off.
    • setting (string) (on, off): Desired setting.
    • status (string) (accepted, complete, error)
  • set-room-light: Turn room light on/off.
    • setting (string) (on, off): Desired setting.
    • status (string) (accepted, complete, error)
  • open-door: Open a closed, unlocked door.
    • id (int): Target door id.
    • status (string) (accepted, complete, error)
  • close-door: Close an open door.
    • id (int): Target door id.
    • status (string) (accepted, complete, error)
  • lock-door: Lock a closed, unlocked door.
    • id (int): Target door id.
    • code (int): Passcode.
    • status (string) (accepted, complete, error)
  • unlock-door: Unlock a locked door.
    • id (int): Target door id.
    • code (int): Passcode.
    • status (string) (accepted, complete, error)
Waypoint Commands
  • add-waypoint: Enter a waypoint into the system, enabled.
    • id (any type): User-defined identifier string, type will be replicated on input-link.
    • x (float): Optional, default is 0.
    • y (float): Optional, default is 0.
    • z (float): Optional, default is 0.
    • status (string): (accepted, complete, error)
  • remove-waypoint: Remove the waypoint from the system.
    • id (any type)
    • status (string) (accepted, complete, error)
  • enable-waypoint: Enable a previously disabled waypoint.
    • id (any type)
    • status (string) (accepted, complete, error)
  • disable-waypoint: Disable an enabled waypoint.
    • id (any type)
    • status (string) (accepted, complete, error)
Communication Commands

Messages sent will appear on the input link after a one-decision-cycle delay.

The destination parameter for send-message is optional. If omitted, message will be broadcast to all listeners, including the sending agent (local echo).

The say destination is not currently implemented on windows platforms.

The remove-message command uses the message id number, available at
  • send-message
    • destination (string): Target of message or omit to broadcast to all available listeners.
    • first: See format and example under Self above.
    • status (string) (accepted, complete, error)
  • remove-message: Remove a specific message from the received-messages list.
    • id (int)
    • status (string) (accepted, complete, error)
  • clear-messages: Remove all messages from received-messages list.
    • status (string) (accepted, complete)
Configure Commands
  • length-units (string) (meters, feet): Units to use for length in I/O (globally).
  • angle-units (string) (radians, degrees): Units to use for angle measurement in I/O (globally).
  • angle-resolution (string) (int, float): Use integers or floating-point types for angle measurements in I/O (globally). Note that radians are always measured in floating-point.
  • linear-speed-units (string) (meters_per_sec, feet_per_sec, miles_per_hour): Units to use for linear speed measurement (globally).
  • angular-speed-units (string) (radians_per_sec, degrees_per_sec): Units to use for angular speed measurement (globally).
  • pose-translation: Translation to relocate origin of self.pose.
    • x (float)
    • y (float)
    • z (float)
  • pid-gains: Tune PID gains. Any parameters not given stay the same.
    • heading
      • p (float)
      • i (float)
      • d (float)
    • angular
      • p (float)
      • i (float)
      • d (float)
    • linear
      • p (float)
      • i (float)
      • d (float)
  • visible-time (float): Seconds objects stay on input-link after invisible.
  • status (string) (accepted, complete, error)
Configures the Soar interface. See the input link configuration identifier. Since there is only one status result, it is best to issue configure commands separately so that any errors will be easily traced.

Associated PublicationsDeveloper
  • Jon Voigt
  • Miller Tinkerhess
  • Various others (project previously known as Soar Robot World and Sproom)
Soar Versions
  • Soar 8, 9
  • C++