Although probabilistic rules can represent a wide range of domain-specific knowledge and reasoning patterns, external modules remain of course necessary to interface the system with its environment -- for instance to perform tasks such as speech recognition, contextual awareness, and speech synthesis. This section explains how to implement such modules.
All OpenDial modules are required to implement the interface Module shown below:
/**
* Starts the module.
*
* @throws DialException if the initialisation fails
*/
public
void start()
throws
DialException;
/**
* Triggers the module after a state update
*
* @param state the dialogue state
* @param updatedVars the set of updated variables
*/
public
void trigger(DialogueState state,
Collection<String>
updatedVars);
/**
* Pauses the current module
*
* @param toPause whether to pause or resume the module
*/
public
void pause(boolean toPause);
/**
* Returns true if the module is running (i.e. started and
* not paused), and false otherwise
*
* @return whether the module is running or not
*/
public
boolean isRunning();
The start method corresponds to the initialisation of the module. The pause method is employed to temporarily interrupt the execution of the module. The isRunning method returns the current execution status of the module. Finally, the trigger method activates the module execution following a particular state update.
Some modules operate in synchronous mode. Synchronous modules are triggered upon each update of the dialogue state.
The core of a synchronous module is its implementation of the method trigger(...). Given the current dialogue state and a list of recently updated variables, the method is expected to trigger the module's internal processing, and possibly re-update the dialogue state via the method addContent(...) in DialogueSystem.
An basic example of synchronous module is shown in src/opendial/modules/examples/ModuleExample1.java. The module creates a small grid window with the location of the agent at its center. When applied together with the step-by-step example, the grid window is updated after each movement to reflect the new position.
Other modules run independently of the dialogue state. Such asynchronous modules typically relate to visual or speech perception tasks. Asynchronous modules update the dialogue state as soon as new observations are made available.
Asynchronous modules must run in a separate thread to avoid blocking the execution of other system components.
An basic example of asynchronous module is shown in src/opendial/modules/examples/ModuleExample2.java. This example is also intended to work in conjunction with the step-by-step example. The module creates a small grid window with four arrow buttons that can be clicked to instruct the agent to move in a particular direction. The method system.addContent(...) is employed to update the dialogue state with new information. The domain models and modules are then triggered after this operation.
Note that the trigger method is empty in this example, as the module runs independently of any state update.
Once it is implemented, a module can be attached to the dialogue system. This can be done in several ways:
The two first options will only work for modules that have a constructor that specifies the DialogueSystem instance as only argument (such as is the case for ModuleExample1 and ModuleExample2). The third option will work for module with arbitrary constructors.
Modules can require some specific settings to be specified before initialisation. Such settings can be directly encoded as new properties in the <settings> element of the dialogue domain specification.