YARP  2.3.70.1
Yet Another Robot Platform
How to add a device to YARP
Author
Paul Fitzpatrick

In YARP, a device driver is a class that implements one or more interfaces.

If you're interested in learning how to use device drivers, see Getting Started with YARP Devices, Device invocation examples, and yarpdev: the standard YARP device utility. If you're read all that before and are interested in learning how to create devices, then read on...

What is a device driver in YARP?

A device driver should derive from the abstract class yarp::dev::DeviceDriver. This interface contains methods common to all device drivers, such as open and close.

Additionally a device driver should implement a selection of other interfaces that capture what it shares with other families of devices. For example a camera might implement yarp:dev::IFrameGrabber (a "raw" interface to the raw data) and/or yarp::dev::IFrameGrabberImage (a higher-level source of images). For example, the yarp::dev::DragonflyDeviceDriver class implements a few of these interfaces. Interfaces are abstract classes, the idea is that from outside the user can access a device by using a pointer to the interface he/she needs, if that interface is supported by the device. This is quite similar to the way COM works (in a simplified way).

In practice to implement a new device you create a new class which derives from DeviceDriver and from the interfacees you want to support, and you implement them. The interfaces are documented in the code, using the doxygen standard. See Getting Started with YARP Devices for an example.

Step by step instructions

So you want to add a device to YARP?

  • Place your device in a subdirectory of $YARP_ROOT/src/devices. This isn't actually a requirement, but it is the easiest way to start. Let us say you pick the directory foo.
  • Get an example that uses your device compiling with CMake in your directory.
  • Split your example into a library part, with contains the device code, and an executable, which exercises the device. The library part should include at least one class that inherits from yarp::dev::DeviceDriver. Let's suppose that class is called FooDriver, and is defined in FooDriver.h
  • Just to review, your foo/CMakeLists.txt file might look something like this:
    find_package(YARP REQUIRED)
    # ... find and use other needed libraries ...
    add_library(foodev FooDriver.cpp FooDriver.h)
    target_link_libraries(foodev ${YARP_LIBRARIES})
    add_executable(example FooExample.cpp)
    target_link_libraries(example foodev)
  • Got all that working? Good. When your device gets bundled up with others, YARP will define the CMake COMPILE_DEVICE_LIBRARY variable. So please modify your CMakeLists.txt so that if this variable is set, all it does is add your device library, and skips any testing you might do.
    find_package(YARP REQUIRED)
    # ... find and use other needed libraries ...
    add_library(foodev FooDriver.cpp FooDriver.h)
    target_link_libraries(foodev ${YARP_LIBRARIES})
    if(NOT COMPILE_DEVICE_LIBRARY)
    add_executable(example FooExample.cpp)
    target_link_libraries(example foodev)
    endif()
  • One more thing: YARP needs to keep track of a global list of devices, their names, and other details. To do this, add in some code like this at the very beginning of your CMakeLists.txt
    if(COMPILE_DEVICE_LIBRARY)
    yarp_prepare_plugin(foo
    TYPE FooDriver
    INCLUDE FooDriver.h
    CATEGORY device)
    endif()
  • It is good to add this before searching for any libraries or files, so that you can suppress such searches if the device is not needed by the eventual user. In that case, the SKIP_foo variable will be set, so you can do:
    if(COMPILE_DEVICE_LIBRARY)
    yarp_prepare_plugin(foo
    TYPE FooDriver
    INCLUDE FooDriver.h
    CATEGORY device)
    endif()
    if(NOT SKIP_foo)
    find_package(YARP REQUIRED)
    # ... find and use other needed libraries ...
    yarp_add_plugin(foodev FooDriver.cpp FooDriver.h)
    target_link_libraries(foodev ${YARP_LIBRARIES})
    if(NOT COMPILE_DEVICE_LIBRARY)
    add_executable(example FooExample.cpp)
    target_link_libraries(example foodev)
    endif()
    endif()
  • To actually try compiling your device, edit $YARP_ROOT/src/devices/CMakeLists.txt and add in where all the similar lines are:
    add_subdirectory(foo)
  • (Alternatively, you can copy $YARP_ROOT/src/devices/CMakeLists.txt to some other directory, remove all the other add_subdirectory lines and just leave your own)
  • Now rebuild the YARP library. You should now be able to configure it to link your device.