Skip to content

VexOS Events

jmalins edited this page Dec 27, 2012 · 3 revisions

VexOS uses an internal event loop to sequence the behaviors and actions of a robot. The user never sees the event loop directly, but may register Event Handlers to receive a callback whenever a particular event occurs. For more on the overall VexOS processing architecture, see VexOS Execution Cycle.

Events represent a very flexible way for the Robot object, Subsystems, and Buttons to run actions at different times. In general, events should not be used from inside of Commands, as a given Command instance is not usually guaranteed to be running... if your design requires using events from inside of a Command class, there is probably a better way to design it.

Event Types

The events types supported by VexOS are defined in an enumeration suitable called EventType. The available event types (from VexOS.h) are:

typedef enum {
    EventType_Initialize,
    EventType_DisabledPeriodic,
    EventType_DisabledEnd,
    EventType_AutonomousStart,
    EventType_AutonomousPeriodic,
    EventType_OperatorStart,
    EventType_OperatorPeriodic,
    EventType_SystemError
} EventType;

The details of each event type are as follows:

  • Initialize - occurs during the initialize phase of robot startup. This happens after the robot initialize method is called.
  • DisabledPeriodic - occurs once per robot cycle while the robot is disabled.
  • DisabledEnd - occurs when the disabled period has ended and the robot is passing into either operator or autonomous control.
  • AutonomousStart - occurs at the start of autonomous control
  • AutonomousPeriodic - occurs once per robot cycle during autonomous control
  • OperatorStart - occurs at the start of operator control
  • OperatorPeriodic - occurs once per robot cycle during operator control
  • SystemError - occurs when an exception is raised from a VexOS system call. The robot is suspended after this event finishes, so you better do something important.

Registering Event Handlers

Events are registered using the following API (from VexOS.h):

typedef void (EventHandler)(EventType type, void* state);

bool VexOS_addEventHandler(EventType type, EventHandler* handler, void* state);
bool VexOS_removeEventHandler(EventType type, EventHandler* handler);
bool VexOS_hasEventHandler(EventType type, EventHandler* handler);

To use these methods you must first create an EventHandler function. This is a function (of any name) with a specific set of arguments. The first argument is an EventType value, while the second is an untyped void* pointer as a "state" value. A void* is like type Object in Java: any pointer you pass (such as one of type Command*) will automatically be converted to void*. You must then convert it back to you target pointer type, since void* cannot be used directly.

After the event handler method is defined, call VexOS_addEventHandler(type, handler, state) to register the method. When VexOS calls your event handler during the EventType event, the state pointer will be passed back to you.

In the example below, an event is registered in the robot initialize method to run a Command (such as an autonomous program) at the start of autonomous mode (note that there are better, built-in ways to run commands during autonomous), but this is a simple example:

static void myAutoStartHandler(EventType type, void* state) {
    Command* autoProg = (Command*) state;
    Command_start(autoProg);
}

// this the standard robot initialize() method //
static void initialize() {
    ...
    Command* autoProg = Command_new(&MySuperAuto);
    VexOS_addEventHandler(EventType_AutonomousStart, myAutoStartHandler, autoProg);
    ...
}

Then event type is passed to the callback function to allow registering the same callback for more than one event type. The callback could then use a switch statement to handle different events in different ways. It should be noted that C will automatically convert void* pointers to different types without using casts, but I prefer the explicit cast, since it is clearer to the reader.

The addEventHandler method will return true if the handler was successfully added, or false if it is already registered and therefore was not added.

Removing Event Handlers

To remove a previously registered event handler, the call is similar:

VexOS_removeEventHandler(EventType_AutonomousStart, myAutoStartHandler);

The call will return true if the handler was removed or false it was not previously registered and couldn't be removed.

Clone this wiki locally