Robotics StackExchange | Archived questions

Problem building shared library using catkin for ros::init(...)

I am trying to build a shared c library that includes ros code. The intention is to build a Ros interface to the new co-simulation FMI standard. I have made c wrappers for the c++ code I intend to use and without the ros::init(...) function call it seems to work fine. I think my problem is the cmake file I have made since it seems to be missing ros::init()

So I have the following structure:

I use the following cmake file to compile the code:

cmake_minimum_required(VERSION 2.8.3)
project (ros_fmu_interface)

find_package(catkin REQUIRED COMPONENTS roscpp std_msgs rosgraph_msgs)

set(INCLUDE_DIR src src/include src/include/templates)
include_directories(include
    /usr/include
    ${INCLUDE_DIR} 
    ${catkin_INCLUDE_DIRS})

add_definitions(-DLIBXML_STATIC -DFMI_COSIMULATION -DMODEL_IDENTIFIER='tank' -DMODEL_GUID='"{8c4e810f-3df3-4a00-8276-176fa3c9f001}"')

SET(GCC_COVERAGE_COMPILE_FLAGS "-fmessage-length=0")
add_definitions(${GCC_COVERAGE_COMPILE_FLAGS})

add_library(tank SHARED src/fmu2watertank.c src/roswrapper.cpp src/rosclass.cpp)

add_dependencies(tank ${PROJECT_NAME} msgs_gencpp)

target_link_libraries(tank
   ${catkin_LIBRARIES}
 )

The code seems to compile fine :

-- Using CATKIN_DEVEL_PREFIX: /home/martin/ros_into/devel
-- Using CMAKE_PREFIX_PATH: /home/martin/ros_into/devel;/opt/ros/jade
-- This workspace overlays: /home/martin/ros_into/devel;/opt/ros/jade
-- Using PYTHON_EXECUTABLE: /usr/bin/python
-- Using Debian Python package layout
-- Using empy: /usr/bin/empy
-- Using CATKIN_ENABLE_TESTING: ON
-- Call enable_testing()
-- Using CATKIN_TEST_RESULTS_DIR: /home/martin/ros_into/build/test_results
-- Found gtest sources under '/usr/src/gtest': gtests will be built
-- Using Python nosetests: /usr/bin/nosetests-2.7
-- catkin 0.6.16
-- BUILD_SHARED_LIBS is on
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~  traversing 1 packages in topological order:
-- ~~  - ros_fmu_interface
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- +++ processing catkin package: 'ros_fmu_interface'
-- ==> add_subdirectory(agro_intelli/fmu_units/ros_fmu_interface)
-- Configuring done
-- Generating done
-- Build files have been written to: /home/martin/ros_into/build
####
#### Running command: "make -j8 -l8" in "/home/martin/ros_into/build"
####
Scanning dependencies of target tank
[ 66%] [ 66%] [100%] Building CXX object agro_intelli/fmu_units/ros_fmu_interface/CMakeFiles/tank.dir/src/rosclass.cpp.o
Building CXX object agro_intelli/fmu_units/ros_fmu_interface/CMakeFiles/tank.dir/src/roswrapper.cpp.o
Building C object agro_intelli/fmu_units/ros_fmu_interface/CMakeFiles/tank.dir/src/fmu2watertank.c.o
/home/martin/ros_into/src/agro_intelli/fmu_units/ros_fmu_interface/src/fmu2watertank.c:11:0: warning: "MODEL_IDENTIFIER" redefined [enabled by default]
 #define MODEL_IDENTIFIER tank
 ^
<command-line>:0:0: note: this is the location of the previous definition
/home/martin/ros_into/src/agro_intelli/fmu_units/ros_fmu_interface/src/fmu2watertank.c:12:0: warning: "MODEL_GUID" redefined [enabled by default]
 #define MODEL_GUID "{8c4e810f-3df3-4a00-8276-176fa3c9f001}"
 ^
<command-line>:0:0: note: this is the location of the previous definition
/home/martin/ros_into/src/agro_intelli/fmu_units/ros_fmu_interface/src/rosclass.cpp: In member function ‘void rosClass::setup()’:
/home/martin/ros_into/src/agro_intelli/fmu_units/ros_fmu_interface/src/rosclass.cpp:9:31: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
   char *argv[] = {"tank", NULL};
                               ^
Linking CXX shared library /home/martin/ros_into/devel/lib/libtank.so
[100%] Built target tank

But when I look into library file using nm I notice the following:

nm -D libtank.so

...
                 U _ZN3ros4initERiPPcRKSsj
0000000000005038 W _ZN5boost3argILi1EEC1Ev
0000000000005038 W _ZN5boost3argILi1EEC2Ev
0000000000005042 W _ZN5boost3argILi2EEC1Ev
0000000000005042 W _ZN5boost3argILi2EEC2Ev
...

I seems ros::init is undefined in the library. Making me think I need to fix something in my cmake file. I am unsure what I need to change for the includes or linking process and hope somebody can point me in the rigth direction!


For reference I have Included my c++ class and c wrapper.

rosclass.cpp:

#include "rosclass.h"
#include <ros/ros.h>
//#include "std_msgs/Float64.h"
//#include "std_msgs/Time.h"
//#include "rosgraph_msgs/Clock.h"

void rosClass::setup(){
  int argc = 1;
  char *argv[] = {"tank", NULL};
  ros::init(argc, argv, "fmu_interface");
  //info_pub = n.advertise<std_msgs::Float64>("info_data", 10);
  //time_pub = n.advertise<rosgraph_msgs::Clock>("/clock", 1);
}

/*
void rosClass::set_value(double f) {
    std_msgs::Float64 msg;
    msg.data = f;
    info_pub.publish(msg);
}

void rosClass::set_time(double t) {
    rosgraph_msgs::Clock clock;
    ros::Time time(t);
    clock.clock = time;
    time_pub.publish(clock);
}*/

rosclass.h :

#ifndef __ROSCLASS_H
#define __ROSCLASS_H

class rosClass {
        public:
                void setup();

                //void set_value(double f);

                //void set_time(double t);
};
#endif

roswrapper.cpp:

#include "rosclass.h"
#include "roswrapper.h"

extern "C" {
        rosClass* newRosClass() {
                return new rosClass();
        }

        void RosClass_setup(rosClass* v){
          v->setup();
        }

        void deleteRosClass(rosClass* v) {
            delete v;
        }
}

roswrapper.h

#ifndef __ROSWRAPPER_H
#define __ROSWRAPPER_H

#ifdef __cplusplus
extern "C" {
#endif

typedef struct rosClass rosClass;

rosClass* newRosClass();

void RosClass_setup(rosClass* v);

void deleteRosClass(rosClass* v);

#ifdef __cplusplus
}
#endif
#endif

Asked by mpc_agro on 2016-03-30 08:39:19 UTC

Comments

You write you "think my problem is the cmake file I have made since it seems to be missing ros::init()", but you don't tell us what issue you've observed. Do you get unresolved symbol errors at library load time?

Asked by gvdhoorn on 2016-03-30 09:01:48 UTC

When I load the library It cannot find _ZN3ros4initERiPPcRKSsj. Based on testing this problem relates to the line ros::init(argc, argv, "fmu_interface"); from above. I am just unsure what is missing or needs to be changed in my cmake file or if it is even possible to attempt what I am doing.

Asked by mpc_agro on 2016-03-30 09:30:56 UTC

Hi, Just curious if you got it to work - the link between FMI and ROS ... ?

Asked by avssrc01tamu on 2016-09-15 13:08:16 UTC

Answers