Embedded Agents

For low-end devices such as the Mindstorm EV3, we would typically want (or need) to run the agent, the percept gathering and the robotic action implementation within a single process. The folder qulog/examples/ev3 contains support using the foreign function capabilities of Qu-Prolog and a very simple TeleoR program trev3.qlg that responds to being touched by backing away from the touch.

For embedded agents we need to define two system declared actions: poll_sensors and control_device.

In the program we have

poll_sensors(P) ::
P = [touched(Dir) :: Dir in [left,right] & is_touched(Dir)]
~> {}

rel is_touched(dir)
%% for the first argument 0 is left and 1 is right
is_touched(left) <= ev3_touch(0, 1)
is_touched(right) <= ev3_touch(1, 1)

control_device(OldActions, NewActions) ~>
forall L, R { move(L, R) in OldActions ~> ev3_stop() };
forall L, R { move(L, R) in NewActions ~>
ev3_run_forever(L, R) }

The responsibility of poll_sensors is to get the list of all the current sensor values as percepts. In this case we return touched percepts by using the foreign function interface to get the touch sensor values.

The responsibility of control_device is to stop the old actions and to start the new actions.

To start the agent we use start_embedded_agent passing in the time between polls of the sensors as, for example

act go()
go() ~>
ev3_init();
start_embedded_agent(0.1) ;
start_task(ev3, frighten())

This means that the agent will poll the sensors (by calling poll_sensors) every 0.1 seconds