The control system first reads a user-supplied configuration file, then initializes components according to the specified settings. When initilization is successfully completed, the system enters the main event loop. In this loop, events are generated or captured, and dispatched to the handlers associated with the current behavior of the robot. When the main processing loop is finished, the system releases all components and exits.
The configuration information loaded at startup is stored in memory in a form that all components understand. Each component knows how to initialize and release itself as well as how to operate while the vehicle is in action. The propulsion system, DVL, DAC, altimeter, acoustics, cameras, pressure sensor, and dropper are each associated with a component object. With the exceptions of the DAC, pressure sensor, and dropper, each component begins its own thread of execution during initialization. The threads that handle the DVL, altimeter, acoustics and cameras are each responsible for continuously reading from those input sources and either updating global shared state (in the case of the DVL and altimeter) or generating events to be handled according to the current behavior (in the case of the acoustics and cameras). Thus, the system is highly concurrent, and a processing or I/O delay in one component typically will not affect the operations of other components. All concurrent access to shared data is protected with synchronization primitives implemented with the POSIX threading API.
Each component logs any pertinent information during runtime to its own log. All errors are written to a shared log, as well as to standard error. All log entries contain the exact execution and entry timestamps for debugging purposes. The configuration state of the vehicle (position, velocity, altitude, altitudinal velocity, heading, and angular velocity) are logged at each main processing loop pass, making replay of the mission possible from the logs. Any events, such as behavior changes and decisions, are also appended to a separate log. The logs are protected by synchronization primitives, so that multiple threads may safely write to the same log.