Introducing Interactive C Events

I have been playing around with Interactive C on the Handy Board. I have added the ability for event driven programs and the result is the Handy Board Interactive C Events (HB-ICE) source distribution. This post describes the overall design and code samples.

Event-driven programming enables you to focus on robotic behavior while the event infrastructure notifies you when something interesting happens. The event infrastructure is typically part of the operating system or application framework. In this case, HB-ICE provides the infrastructure. HB-ICE is just the minimum to monitor the Handy Board buttons and digital inputs. Other extensions will be added later.  I intend to use this to implement reactive behavior, hopefully with subsumption.

Button Events
Let’s start with an example. Here is the code that is notified when a button is released:

void handleButtonReleasedEvent(struct Event* event){
    int eventId = event->id;
    switch(eventId) {
        case EVENT_ID_START_BUTTON:
          start();
        break;
        case EVENT_ID_STOP_BUTTON:
          stop();
        break;
    }
}

When a button is released, a pointer to an event is passed to the function. The id of the event is used to determine what action to take.   Events are structures like this:

struct Event {
    int type;
    int id;
    int value;
    long timestamp;
};

The type field helps distinguish button events from digital or analog events. The id further distinguishes the event within the type. For example, a button released event needs to indicate if the start or stop button was released. The value field is a copy of the sensor, input or button state. The time stamp field is assigned to the event when it is signaled. I plan to use that for meta-sensing in the future.

In handleButtonReleasedEvent, the program either calls start() or stop(). This is used to start and stop the robot behaviors. So how does this all get started? Let’s look at the example program main() function and supporting functions:

void initialize(){
    initializeEventQueue();
    intializeDigitalEvents();
    initializeMotors();
    startMonitoringButtons();
}
void handleEvent(struct Event* event){
    int eventType = event->type;
    switch(eventType){
        case EVENT_TYPE_BUTTON_RELEASED:
          handleButtonReleasedEvent(event);
        break;
        case EVENT_TYPE_DIGITAL_CHANGED:
          handleDigitalChangedEvent(event);
        break;
    }
}
void main(){
    struct Event* event = NULL;
    initialize();
    printf("press start\n");
    while(looping){
        event = dequeue(eventQueue);
        if(event != NULL){
            handleEvent(event);
        }
    }
    printf("done\n");
}

The main function calls intialize() and then enters an infinite event loop.  The initialize function initializes the event queue, digital events, motors and then starts monitoring the buttons.  The buttons are monitored in a separate process.  When a state change in a button is detected and the button is released, an event is added to the event queue. The event queue is a classic first in, first out (FIFO) queue.  The event loop in the main function takes events off the queue and calls the handleEvent function.  This function routes the event to the appropriate handler based on the type of event.

The HB-ICE distribution also supports the digital inputs. I have been using this infrastructure for the Handy Bug exercises in Fred Martin’s book entitled Robot Explorations and it appears to work.

Source
The source is available as a zip file via MediaFire hosting or from the Source Code page.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s