What's New - Still a dummy text...?

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam iaculis adipiscing mi. Nulla vulputate mi at lorem. Fusce tincidunt dui non lectus euismod faucibus.

Learn more…

A Simple Distributed Application

August 3, 2010

Using the Flexible Robotics Framework, building distributed applications for various tasks becomes suprisingly easy. You don't not need to know anything about parallelization techniques, MPI-environments, cluster technology and so on - this is all handled by the FRF.

On this page, we examine the following code snippet (main.cpp) and explain the basic concepts briefly:

#include <frf.h>

int main(int argc, char **argv)
{
  /// Boot distributed environment
  frf::boot(argc, argv);

  /// Setup processing units
  frf::vision::camera::OpenCVCamera* cam = new frf::vision::camera::OpenCVCamera();
  frf::gui::GuiUnit* gui = new frf::gui::GuiUnit();

  /// Initialize the processing units
  frf::init();

  /// Connect the shared parameters
  unsigned int id;
  id = cam->share<frf::core::data::Image>(frf::vision::camera::OpenCVCamera::LIVE_IMAGE);
  gui->connectTo(id, "Live Images", new frf::gui::feedback::Image("USB Image"));

  /// Run distributed application
  return frf::run();
}

Step-by-Step Analysis

August 3, 2010

Let's analyze the above snippet and explain it step-by-step:

  1. Above our main() function we can include all the necessary FRF-headers with a single include:
    #include <frf.h>
  2. The first thing needed in a distributed application is booting the MPI-environment. This is done with a single call (that also passes additional command-line arguments to the runtime-configuration object):
    frf::core::boot(argc, argv);
  3. The application is then ready to initialize the processing units. A processing unit is the atomic entity for processing something. The FRF comes with numerous predefined processing units. If you decide to install the package from our download page, you have them all. If you decide to build the library yourself from scratch, you can enable / disable them manually in the build system.
    Here, you only need to know that there is a unit called OpenCVCamera calling some OpenCV-library functions to start a camera and a GuiUnit using some Qt4-library functions to create a display for viewing the live image.
    frf::vision::camera::OpenCVCamera* cam = new flexrf::vision::camera::OpenCVCamera();
    frf::gui::GuiUnit* gui = new flexrf::gui::GuiUnit();
  4. In the distributed system, each processing unit is bound to a processor, which itself is bound to a physical computer at runtime. It's essentially this binding, that is done within the next call:
    frf::init()
  5. An important step comes next: usually you would like the processing units to be able to exchange information amongst each other. For this purpose, the parameters of a processing unit (as designed by the developer) can be made available globally. The FRF therefore offers a templated share<T>() function to achieve this. After sharing a parameter, other units may connect to that parameter and all subsequent read / write access of both units affect the gobal, shared parameter value. Synchronization is entirely handled by the FRF across threads, processors and physical PCs.
    In our case, the camera unit shares the captured live image and the GUI connects to that parameter in order to show it.
    unsigned int id;
    id = cam->share<frf::core::data::Image>(
            frf::vision::camera::OpenCVCamera::LIVE_IMAGE);
    gui->connectTo(id, "Live Images", new frf::gui::feedback::Image("USB Image"));
    Without any further explanation, we just note here, that the gui->connectTo() call actually also creates a feedback widget "USB Image" for displaying the live image within a subwindow "Live Images" of the GUI.
  6. After sharing ("globalizing") desired parameters, the applications main event loop has to be executed in order to start capturing images from the camera and displaying them in the GUI. The run() automatically shuts down the distributed syste, once the GUI has been closed.
    frf:run();

A Handy Extension

August 3, 2010

Despite all automatic distribution logic, it is sometimes necessary to bind a processing unit to a certain physical PC. This is for example the case, if your camera is connected to specific PC and you want to run the image acquisition unit OpenCVCamera on that PC. FRF provides a simple mechanism to enforce binding of units to specific resources, you only need to substitute the line

frf::vision::camera::OpenCVCamera* cam = new flexrf::vision::camera::OpenCVCamera();

from the snippet above with these lines:

std::string localhost = "127.0.0.1";
frf::core::Processor* processor = frf::Environment::instance()->processorByIP(localhost);
frf::vision::camera::OpenCVCamera* cam = new frf::vision::camera::OpenCVCamera(processor);

Here, the system searches for a processor on the PC with the given IP-address. You can then manually bind the unit by passing the reference in the constructor. This mechanism works for all processing units by default.

What it Looks Like

August 4, 2010

After compiling the above source into an executable, on startup the GuiUnit should display a live video from the camera. Congratulations, your first distributed application using the Flexible Robotics Framework is done. Now it's time to get started with your very own project.