Difference between revisions of "Cpp"

From RobotinoWiki
(Package links)
(Package links)
Line 10: Line 10:
 
[http://svn.openrobotino.org/trunk/openrobotino1/lib/rec/robotino/com Source code]
 
[http://svn.openrobotino.org/trunk/openrobotino1/lib/rec/robotino/com Source code]
  
[[downloads|openrobotino_api|Downloads]]
+
[[downloads#openrobotino_api|Downloads]]
 
|}
 
|}
  

Revision as of 14:39, 14 February 2011

Introduction

Robotino cpp icon 64.png The application programming interface (API) for Robotino(r) from Festo Didactic permits full access to Robotino's sensors and actors. Communication between the control program and Robotino is handled via TCP and UDP and is therefor fully network transparent. It does not matter whether the control program runs direcly on Robotino or on a remote system.

Package links

Code API

Source code

Downloads

Installation

Install the API either from binary or from source. The Windows binary installer will set the environment variable OPENROBOTINOAPI_DIR. With a deafult installation OPENROBOTINOAPI_DIR is "C:\{ProgramFiles}\REC GmbH\OpenRobotinoAPI".

To build your own program you need to

  1. add $(OPENROBOTINOAPI_DIR)/1/include to your compilers include search path
  2. if you want to use the convenience library rec_core_lt also add $(OPENROBOTINOAPI_DIR)/share/include to your compilers include search path
  3. use #include "rec/robotino/com/all.h" in your program to use the rec::robotino::com API
  4. add $(OPENROBOTINOAPI_DIR)/1/lib/win32 or $(OPENROBOTINOAPI_DIR)/1/lib/linux to your linkers library search path
  5. link against rec_robotino_com.lib on win32 and librec_robotino_com.so on linux systems
  6. for rec_core_lt link against rec_core_lt.lib on win32 and librec_core_lt.so on linux systems

If you are familiar with cmake you might prefer using $(OPENROBOTINOAPI_DIR)/1/tools/FindOpenRobotino1.cmake.

Usage

In the following you will find a simple example on how to drive Robotino on a circle.

Including headers

You need to include at least "rec/robotino/com/all.h". <cmath> is for cos and sin functions. <iostream> defines std::cout and std::cerr.

include "rec/robotino/com/all.h"
include "rec/core_lt/Timer.h"
include <cmath>
include <iostream>

Declarations

All classes of this API are in the namespace rec::robotino::com. To simplify usage we use this namespace as default. So we can write Com instead of rec::robotino::com::Com. We define all objects used at global scope. There is no need to do so but it makes life simple for this example.

using namespace rec::robotino::com;

class MyCom : public Com
{
  public:
    MyCom()
    {
    }

    void errorEvent( Error error, const char* errorString )
    {
      std::cerr << "Error: " << errorString << std::endl;
    }

    void connectedEvent()
    {
      std::cout << "Connected." << std::endl;
    }

    void connectionClosedEvent()
    {
      std::cout << "Connection closed." << std::endl;
    }
};

MyCom com;
OmniDrive omniDrive;

Notice the class MyCom which has rec::robotino::com::Com as base class. MyCom overwrites the three virtual funtions to handle different events.

Initialisation

In this function we register the handlers to the Com object. We have to tell the onmiDrive where it belongs to. This is done by setComId. Notice that this enables us to have multiple Com objects at the same time each of which connecting to a different Robotino.

void init()
{
  // Tell omniDrive which Robotino to drive
  // It is possible to have multiple Com objects and multiple OmniDrive objects.
  // By this you can drive multiple Robotinos from one program.
  omniDrive.setComId( com.id() );

  // Connect
  std::cout << "Connecting..." << std::endl;
  com.setAddress( "127.0.0.1" );
  com.connect();
  std::cout << std::endl << "Connected" << std::endl;
}

Driving Robotino

Driving Robotino is done by contiunously sending set point values for the motors to Robotino. The motors set point values are computed by omniDrive when calling its setVelocity function. Communication to Robotino is performed in a seperate thread. You can synchronize your thread with the communication thread by calling rec::robotino::Com::waitForUpdate. This function blocks until set values are trnasmitted to Robotino and sensor values are received.

void drive()
{
  rec::core_lt::Timer timer;
  timer.start();

  const float speed = 200.0f;
  const float rotationSpeed = 36.0f;

  while( com.isConnected() )
  {
    float rot = rotationSpeed * ( 2.0f * (float)M_PI / 360.0f ) * ( timer.msecsElapsed() / 1000.0f );

    omniDrive.setVelocity( cos(rot) * speed, sin(rot) * speed, 5.0f );

    com.waitForUpdate(); //wait until actor set values are transmitted and new sensor readings are available
  }
}

Closing communication

We do not really need a seperate function here. But it looks nice in the main function.

void destroy()
{
  com.disconnect();
}

The main program

This is pretty clear now, isn't it? Make sure to catch any exception which might be thrown from the functions within the try block.

int main()
{
  try
  {
    init();
    drive();
    destroy();
  }
  catch( const std::exception& e )
  {
    std::cerr << "Error: " << errorString << std::endl;
  }

  std::cout << "Press any key to exit..." << std::endl;
  rec::core_lt::waitForKey();
}