UniversalRobots / Universal_Robots_Client_Library

A C++ library for accessing the UR interfaces that facilitate the use of UR robotic manipulators by external applications.
Apache License 2.0
117 stars 86 forks source link

Universal Robots Client Library

A C++ library for accessing Universal Robots interfaces. With this library C++-based drivers can be implemented in order to create external applications leveraging the versatility of Universal Robots robotic manipulators.

Requirements

Build instructions

See Build / installation

License

The majority of this library is licensed under the Apache-2.0 licensed. However, certain parts are licensed under different licenses:

While the main LICENSE file in this repository contains the Apache-2.0 license used for the majority of the work, the respective libraries of third-party components reside together with the code imported from those third parties.

Library contents

Currently, this library contains the following components:

Example driver

In the examples subfolder you will find a minimal example of a running driver. It starts an instance of the UrDriver class and prints the RTDE values read from the controller. To run it make sure to

Architecture

See Architecture documentation

A word on the primary / secondary interface

Currently, this library doesn't support the primary interface very well, as the Universal Robots ROS driver was built mainly upon the RTDE interface. Therefore, there is also no PrimaryClient for directly accessing the primary interface. This may change in future, though.

The comm::URStream class can be used to open a connection to the primary / secondary interface and send data to it. The producer/consumer pipeline structure can also be used together with the primary / secondary interface. However, package parsing isn't implemented for most packages currently. See the primary_pipeline example on details how to set this up. Note that when running this example, most packages will just be printed as their raw byte streams in a hex notation, as they aren't implemented in the library, yet.

A word on Real-Time scheduling

As mentioned above, for a clean operation it is quite critical that arriving RTDE messages are read before the next message arrives. Due to this, both, the RTDE receive thread and the thread calling getDataPackage() should be scheduled with real-time priority. See this guide for details on how to set this up.

The RTDE receive thread will be scheduled to real-time priority automatically, if applicable. If this doesn't work, an error is raised at startup. The main thread calling getDataPackage should be scheduled to real-time priority by the application. See the ur_robot_driver as an example.

Producer / Consumer architecture

Communication with the primary / secondary and RTDE interfaces is designed to use a consumer/producer pattern. The Producer reads data from the socket whenever it comes in, parses the contents and stores the parsed packages into a pipeline queue. You can write your own consumers that use the packages coming from the producer. See the comm::ShellConsumer as an example.

Logging configuration

As this library was originally designed to be included into a ROS driver but also to be used as a standalone library, it uses custom logging macros instead of direct printf or std::cout statements.

The macro based interface is by default using the DefaultLogHandler to print the logging messages as printf statements. It is possible to define your own log handler to change the behavior, see create new log handler on how to.

Change logging level

Make sure to set the logging level in your application, as by default only messages of level WARNING or higher will be printed. See below for an example:

#include "ur_client_library/log.h"

int main(int argc, char* argv[])
{
  urcl::setLogLevel(urcl::LogLevel::DEBUG);

  URCL_LOG_DEBUG("Logging debug message");
  return 0;
}

Create new log handler

The logger comes with an interface LogHandler, which can be used to implement your own log handler for messages logged with this library. This can be done by inheriting from the LogHandler class.

If you want to create a new log handler in your application, you can use below example as inspiration:

#include "ur_client_library/log.h"
#include <iostream>

class MyLogHandler : public urcl::LogHandler
{
public:
  MyLogHandler() = default;

  void log(const char* file, int line, urcl::LogLevel loglevel, const char* log) override
  {
    switch (loglevel)
    {
      case urcl::LogLevel::INFO:
        std::cout << "INFO " << file << " " << line << ": " << log << std::endl;
        break;
      case urcl::LogLevel::DEBUG:
        std::cout << "DEBUG " << file << " " << line << ": " << log << std::endl;
        break;
      case urcl::LogLevel::WARN:
        std::cout << "WARN " << file << " " << line << ": " << log << std::endl;
        break;
      case urcl::LogLevel::ERROR:
        std::cout << "ERROR " << file << " " << line << ": " << log << std::endl;
        break;
      case urcl::LogLevel::FATAL:
        std::cout << "ERROR " << file << " " << line << ": " << log << std::endl;
        break;
      default:
        break;
    }
  }
};

int main(int argc, char* argv[])
{
  urcl::setLogLevel(urcl::LogLevel::DEBUG);
  std::unique_ptr<MyLogHandler> log_handler(new MyLogHandler);
  urcl::registerLogHandler(std::move(log_handler));

  URCL_LOG_DEBUG("logging debug message");
  URCL_LOG_INFO("logging info message");
  return 0;
}

Contributor Guidelines

Acknowledgment

Many parts of this library are forked from the ur_modern_driver.

Developed in collaboration between:

Universal Robots A/S   and   FZI Research Center for Information Technology.

<img src="http://rosin-project.eu/wp-content/uploads/rosin_ack_logo_wide.png" alt="rosin_logo" height="60" >

Supported by ROSIN - ROS-Industrial Quality-Assured Robot Software Components. More information: rosin-project.eu

<img src="http://rosin-project.eu/wp-content/uploads/rosin_eu_flag.jpg" alt="eu_flag" height="45" align="left" >

This project has received funding from the European Union’s Horizon 2020 research and innovation programme under grant agreement no. 732287.