Home

Awesome

LibDS

Build Status

The DriverStation library allows you to connect and manage a robot easily by providing an abstraction layer between an application and the network comununications between the robot and the host computer.

The library is written in C, allowing it to be used in many platforms and/or programming languages (using wrappers).

Features

LibDS implements the following features:

You may find a lot of mistakes here, be it design choices or just stupid mistakes. If you spot something, I would be very grateful if you could tell me about it (or make a pull request).

Example Projects

Image

I have created two example projects to demonstrate the uses of LibDS:

You can browse the code of the examples here!

Quick Introduction

Initialization

The LibDS has its own event loop, which runs on a separate thread. To start the DS engine, you must call DS_Init(), which initializes all the modules of the LibDS (config, events, joysticks, etc).

You should initialize the DS before initalizing any of your application components that interact with the DS. Check this example:

#include <LibDS.h>

int main() {
   /* Initialize the DS */
   DS_Init();

   /* Now proceed to initializing your application */
   DeepMagic();
   VoodooInit();
   HeavyWizardry();
   
   /* Load the 2016 protocol, the protocol can be safely changed during runtime. 
    *
    * Also, the LibDS can operate safely without a loaded protocol, 
    * so there is no rush to call this function. 
    */
   DS_ConfigureProtocol (DS_GetProtocolFRC_2016());
}

Communication protocols

After initializing the DS, you must load a protocol, which instructs the LibDS on the following processes:

The LibDS has built-in support for the following protocols:

To load a protocol, use the DS_ConfigureProtocol() function. As a final note, you can also implement your own protocols and instruct the LibDS to use it.

Interacting with the DS events

The LibDS registers the different events in a FIFO (First In, First Out) queue, to access the events, use the DS_PollEvent() function in a while loop. Each event has a "type" code, which allows you to know what kind of event are you dealing with.

The easiest way to react to the DS events is the following (pseudo-code):

DS_Event event;
while (DS_PollEvent (event)) {
   switch (event.type) {
      case DS_EVENT_X:
         // react to x event
      case DS_EVENT_Y:
         // react to y event
   }
}

The code above must be called periodically. Here is a (functional) example:

#include <LibDS.h>
#include <stdio.h>

static void process_events();

int main() {
   DS_Init();
   DS_ConfigureProtocol (DS_GetProtocolFRC_2016());
   
   while (1) {
      process_events();
      DS_Sleep (10);
   }
   
   return EXIT_SUCCESS;
}

void process_events() {
   DS_Event event;
   while (DS_PollEvent (&event)) {
      switch (event.type) {
      case DS_ROBOT_ENABLED:
         printf ("Robot enabled\n");
         break;
      case DS_ROBOT_DISABLED:
         printf ("Robot disabled\n");
         break;
      case DS_ROBOT_CONNECTED:
         printf ("Connected to robot\n");
         break;
      case DS_ROBOT_DISCONNECTED:
         printf ("Disconnected to robot\n");
         break;
      case DS_ROBOT_VOLTAGE_CHANGED:
         printf ("Robot voltage set to: %f\n", event.robot.voltage);
         break;
      default:
         break;
      }
   }
}

Project Architecture

'Private' vs. 'Public' members

Protocols

Protocols are encapsulated structures. When a protocol is initialized, it defines its properties and its respective data functions. The different functions of the LibDS will then operate with the data and properties defined by the current protocol.

As with the original LibDS, protocols have access to the DS_Config to update the state of the LibDS.

The base protocol is implemented in the DS_Protocol structure.

Sockets

Instead of manually initializing a socket for each target, data direction and protocol type (UDP and TCP). The LibDS will use the DS_Socket object to define ports, protocol type and remote targets.

All the logic code is in socket.c, which will be in charge of managing the system sockets with the information given by a DS_Socket object.

Compilation instructions

To compile the project, navigate to the project root and run the following commands

If your project runs into runtime errors try running make staticlib instead of make

To install compiled library files, and headers to the correct locations in /usr/local, use this command