External modules

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:

/** * Triggers the module after a state update * * @param state the dialogue state * @param updatedVars the set of updated variables */publicvoid trigger(DialogueState state, Collection<String>updatedVars);

/** * Returns true if the module is running (i.e. started and * not paused), and false otherwise * * @return whether the module is running or not */publicboolean 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.

Synchronous modules

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.

Asynchronous modules

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.

Attaching a module

Once it is implemented, a module can be attached to the dialogue system. This can be done in several ways:

You can specify the module's full classname (e.g. opendial.modules.ModuleExample1) in the <modules> property of the domain settings.

you can also directly include the module classname to the command line properties, with the flag -Dmodules=classname (notice the -D prefix). If the module requires additional parameters, you can add them as additional command line properties, e.g. -DparamName=paramValue.

Finally, you can also attach the module programmatically by creating the module instance and then calling the method attachModule(...) in the current DialogueSystem.

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.