C++ Interface

This collection of basic examples are provided to ease and aid the introduction to programming applications using RobWork.

Template CMake Project

This tutorial will demonstrate how to create a simple RobWork application using CMake. First create a directory for your project. Now add a SampleTest.cpp file and type in a small main application:

RobWork/example/consoleapp/SampleTest.cpp
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <rw/common/Log.hpp>
#include <rw/loaders/WorkCellLoader.hpp>
#include <rw/models/WorkCell.hpp>

using rw::common::Log;
using rw::loaders::WorkCellLoader;
using rw::models::WorkCell;

int main(int argc, char** argv)
{
    if (argc != 2) {
        Log::errorLog() << "Usage: " << argv[0] << " <workcell>" << std::endl;
        return 1;
    }

    const std::string file = argv[1];
    WorkCell::Ptr workcell = WorkCellLoader::Factory::load(file);
    if (workcell.isNull()) {
        Log::errorLog() << "WorkCell could not be loaded." << std::endl;
        return 1;
    }

    Log::infoLog() << "Workcell " << workcell->getName();
    Log::infoLog() << " successfully loaded." << std::endl;
    return 0;
}

This example loads a WorkCell based on the argument given to the program. In the first lines, the header files are included for the types we use in the program. With the using statements we can avoid typing the full name when we use the Log, WorkCellLoader and WorkCell types in the code. Alternatively, one would have to write rw::common::Log, rw::loaders::WorkCellLoader and rw::models::WorkCell respectively. If you use more than one class from the same namespace, you should instead write:

using namespace rw::common;
using namespace rw::loaders;
using namespace rw::models;

When many different namespaces and classes from RobWork are used, it can be somewhat tedious to write the using namespace and includes in every file. Instead a general header file rw/rw.hpp and a macro can be used to assemble all classes into one namespace. To include everything from RobWork We can instead write:

#include <rw/rw.hpp>
USE_ROBWORK_NAMESPACE
using namespace robwork;

Notice that including all headers from RobWork can be quite heavy for the C++ preprocessor. This might cause a penalty for the time used to compile the program. For small programs like this, it is acceptable to import all the headers. Always avoid importing rw/rw.hpp in header files. Especially when developing libraries, as the header file might be included in many files that will each be hit by a compilation time penalty.

Notice that using and using namespace must never be used in header files. Only if used inside functions.

In this example we write the output to Log::errorLog() and Log::infoLog(). For a console application like this, it makes little difference if you instead output directly to std::cout. It is good practice to use the Log facility anyways. If you later need to use a snippet of code or call a library function from a RobWorkStudio plugin, the output will be shown in the RobWorkStudio Log plugin instead of the terminal. In case RobWorkStudio is not launched from a terminal, this is very convenient. The output would otherwise be invisible to the user.

Now create a CMakeLists.txt file with the following content:

RobWork/example/consoleapp/CMakeLists.txt
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#####################################################
# Template for building RobWork dependent console application
#
# You should edit directly in this file to add extra source 
# files and when configuring your project.  
#####################################################

# Test CMake version
cmake_minimum_required(VERSION 3.5)

# The name of the project. (EDIT THIS)
project(ConsoleApp)

# Used to resolve absolute path names
set(ROOT ${CMAKE_CURRENT_SOURCE_DIR})

# Now set the RW/RWS root (edit this if necessary)
if(DEFINED ENV{RW_ROOT})
  file(TO_CMAKE_PATH "$ENV{RW_ROOT}" RW_ROOT)
else()
  set(RW_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../..")
endif()

set(ROOT ${CMAKE_CURRENT_SOURCE_DIR})

# optionally: point the find package in the direction of the robwork.
set(RobWork_DIR ${RW_ROOT}/cmake)
find_package(RobWork REQUIRED)

link_directories( ${ROBWORK_LIBRARY_DIRS} )

# Set the output dir for generated libraries and binaries
if(MSVC)
	SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${ROOT}/bin" CACHE PATH "Runtime directory" FORCE)
	SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${ROOT}/libs" CACHE PATH "Library directory" FORCE)
	SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${ROOT}/libs" CACHE PATH "Archive directory" FORCE)
else()
	SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${ROOT}/bin/${CMAKE_BUILD_TYPE}" CACHE PATH "Runtime directory" FORCE)
	SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${ROOT}/libs/${CMAKE_BUILD_TYPE}" CACHE PATH "Library directory" FORCE)
	SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${ROOT}/libs/${CMAKE_BUILD_TYPE}" CACHE PATH "Archive directory" FORCE)
endif()

# And now we add any targets that we want
add_executable(SampleTest SampleTest.cpp)
target_link_libraries(SampleTest PRIVATE ${ROBWORK_LIBRARIES})
target_include_directories(SampleTest PRIVATE ${ROBWORK_INCLUDE_DIRS} )

# if you have additional libraries or include dirs then add them here
set(USER_LIBRARIES )
target_link_libraries(SampleTest PRIVATE ${USER_LIBRARIES})
target_include_directories(SampleTest PRIVATE ${USER_LIBRARIES})
link_directories( )

Before running CMake, you should set the RW_ROOT environment variable to the path for RobWork. CMake will complain if it does not find RobWork.

Now make a build directory and from this directory run the command:

cmake -DCMAKE_BUILD_TYPE=Release path/to/project

On Windows you should also specify the generator based on your Visual Studio version:

cmake -DCMAKE_BUILD_TYPE=Release -G "Visual Studio 15 2017 Win64" path/to/project

You need to set the build type to the same build type that you used for compiling RobWork. Insert the correct path to the project code (the directory with the CMakeLists.txt file).

Build the project with make (on Linux):

make

In Windows, open the ConsoleApp solution in Visual Studio (solution was generated with CMake). Once the compilation succeeds, the executable will be put under the bin directory in the folder where CMakeLists.txt is located.

API documentation

The user is encouraged to use the C++ API documentation to look up functionality, classes and functions in RobWork. Please also consult the Manual for various examples of using the RobWork library.