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:
- fmu2watertank.c --main libary file
- roswrapper.h -- c wrapper file .h file
- roswrapper.cpp -- c wrapper file .cpp file
- rosclass.h -- header file for class contaning ros code
- rosclass.cpp -- cpp file for class contaning ros code
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