0

Rosanswers logo

I won't pretend to be a ROS Linux or coding expert, but I've been stuck on getting my catkin_make to compile using the MRAA library from Intel. I'm using Intel's Up Board as my robot central controller. It will be eventually be doing SLAM and taking simple orders through a ROS message from a central computer elsewhere. Pretty standard. There are a few peripherals I want to connect to the Up Board by serial communication (SPI, specifically). At compile time the system breaks down when it tries to link to the MRAA library. It doesn't understand the references. So the way I see it, it's either a problem with the way I installed the library, or my CMakeLists.txt or package.xml is setup wrong. I've been through a lot of documentation, but cannot determine how to get the proper setup to link to the library.

catkin_make output:

[100%] Built target floorbot_generate_messages
/home/floorbot/catkin_ws/src/floorbot/src/sojourner.cpp: In function ‘int main(int, char**)’:
/home/floorbot/catkin_ws/src/floorbot/src/sojourner.cpp:32:2: error: ‘mraa’ has not been declared
  mraa::Spi * spiCom;
  ^
/home/floorbot/catkin_ws/src/floorbot/src/sojourner.cpp:32:14: error: ‘spiCom’ was not declared in this scope
  mraa::Spi * spiCom;
              ^
/home/floorbot/catkin_ws/src/floorbot/src/sojourner.cpp:33:2: error: ‘mraa’ has not been declared
  mraa::Spi * tooth;
  ^
/home/floorbot/catkin_ws/src/floorbot/src/sojourner.cpp:33:14: error: ‘tooth’ was not declared in this scope
  mraa::Spi * tooth;
              ^
/home/floorbot/catkin_ws/src/floorbot/src/sojourner.cpp:35:15: error: expected type-specifier before ‘mraa’
  spiCom = new mraa::Spi(0); // <---- portal to arduino (CS0)
               ^
/home/floorbot/catkin_ws/src/floorbot/src/sojourner.cpp:35:15: error: expected ‘;’ before ‘mraa’
/home/floorbot/catkin_ws/src/floorbot/src/sojourner.cpp:36:14: error: expected type-specifier before ‘mraa’
  tooth = new mraa::Spi(1);  // <---- portal to bluetooth (CS1)
              ^
/home/floorbot/catkin_ws/src/floorbot/src/sojourner.cpp:36:14: error: expected ‘;’ before ‘mraa’
/home/floorbot/catkin_ws/src/floorbot/src/sojourner.cpp:54:50: error: ‘chatterCallback’ was not declared in this scope
  ros::Subscriber sub = n.subscribe("chat", 1000, chatterCallback);
                                                  ^
make[2]: *** [floorbot/CMakeFiles/sojourner.dir/src/sojourner.cpp.o] Error 1
make[1]: *** [floorbot/CMakeFiles/sojourner.dir/all] Error 2
make: *** [all] Error 2
Invoking "make -j4 -l4" failed
floorbot@floorbot:~/catkin_ws$ 

CMakeLists.txt:

cmake_minimum_required(VERSION 2.8.3)
project(floorbot)
find_package(catkin REQUIRED COMPONENTS
  roscpp std_msgs message_generation)
find_package(Boost REQUIRED COMPONENTS system)
#find_package(mraa REQUIRED)
add_message_files(FILES commands.msg)
generate_messages(DEPENDENCIES std_msgs)

catkin_package( ${catkin_CURRENT_SOURCE_DIR} INCLUDE_DIRS include LIBRARIES floorbot mraa CATKIN_DEPENDS roscpp mraa std_msgs message_runtime DEPENDS system_lib mraa)

include_directories(${catkin_INCLUDE_DIRS})

include_directories(/home/mraa)

include_directories(/usr/include/mraa)

add_subdirectory(mraa)

add_library(mraa floorbot.cpp)

add_executable(sojourner src/sojourner.cpp) add_dependencies(sojourner floorbot_generate_message_cpp ${catkin_EXPORTED_TARGETS})

target_link_libraries(mraa)

target_link_libraries(sojourner ${catkin_LIBRARIES})

package.xml:

<?xml version="1.0"?>
<package>
  <name>floorbot</name>
  <version>0.0.1</version>
  <description>The floorbot package</description>
  <maintainer email="floorbot@todo.todo">floorbot</maintainer>
  <license>TODO</license>
  <buildtool_depend>catkin</buildtool_depend>
  <build_depend>roscpp</build_depend>
  <build_depend>rospy</build_depend>
  <build_depend>std_msgs</build_depend>
  <build_depend>commands</build_depend>
  <build_depend>mraa</build_depend>
  <build_depend>message_generation</build_depend>
  <run_depend>roscpp</run_depend>
  <run_depend>rospy</run_depend>
  <run_depend>std_msgs</run_depend>
  <run_depend>commands</run_depend>
  <run_depend>mraa</run_depend>
  <run_depend>message_runtime</run_depend>

<export></export> </package>

Important code:

#include "robot.h"
#include "ros/ros.h"
#include "floorbot/commands.h"
#include "mraa.h"

void chatterCallBack(const floorbot::commands::ConstPtr& msg, Robot & robot) { robot.setCommand(msg->x_cmd, msg->y_cmd, msg->orientation); }

int main(int argc, char **argv) {

Robot robot;

// Check battery status
// setBatSat() // &lt;--- initialize battery status
// Check to see if robot is docked
// setDocked() // &lt;--- update docking status

// --- Stuff for SPI communicaion --- //
mraa::Spi * spiCom;
mraa::Spi * tooth;
unsigned int bufSize = 3;
spiCom = new mraa::Spi(0);  // &lt;---- portal to arduino (CS0)
tooth = new mraa::Spi(1);       // &lt;---- portal to bluetooth (CS1)

I've tried gvdhoorn's suggestions and I still can't get it past telling me that it cannot find 'mraa-config.cmake.' The file does not exist. I tried making one and it did not work either. I'm going to try Intel's formus too to make sure I have everything setup right with MRAA. One thing to note it that I have MRAA in the home directory (~/mraa). It seems that most libraries should be in ~/usr/include/. All the tutorials for MRAA show it being placed in the home folder and installing it from there.

Here's my attempt at making a mraa-config.cmake file:

# config for mraa library
# MRAA_INCLUDE_DIRS  - include directory for mraa
# MRAA_LIBRARIES     - libraries to link against

Compute paths

get_filename_component(MRAA_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) set(MRAA_INCLUDE_DIRS "@CONF_INCLUDE_DIRS@")

Library dependencies

if(NOT TARGET mraa AND NOT mraa_BINARY_DIR) include("${MRAA_CMAKE_DIR}/mraaTargets.cmake") endif()

Import targets

set(MRAA_LIBRARIES mraa)


Originally posted by titan vista on ROS Answers with karma: 18 on 2016-11-10

Post score: 0

1 Answers1

0

Rosanswers logo

target_link_libraries(sojourner ${catkin_LIBRARIES})

In your current CMakeLists.txt at least, you're only linking against whatever catkin_LIBRARIES contains, and don't have any of the MRAA paths added to the compiler's include path. catkin_LIBRARIES whill not contain the MRAA libraries (as they are not catkin packages), and without the MRAA headers on your include path, the compiler will not know about any MRAA datastructures, functions, etc, so that's where the undeclared X errors are coming from.

How to link to third party library ? and How do I link a library in cmake? (note that explicitly setting the linker path is discouraged) are related, but just to reiterate:

  1. install your dependency somewhere on your system. This could be in the 'normal' locations (ie: /usr/local/.., or perhaps even system wide, depending on whether you build this from source or install a package distributed via your system's package manager), your home directory or somewhere else.

  2. make your CMakeLists.txt able to find your dependencies: some distribution-provided packages (ie: .debs on Debian/Ubuntu) provide CMake compatible files that allow you to use find_package(PKG_NAME). If no CMake files are available, try PkgConfig. If none of this is available / works, you could hard-code the path to the include and library director(y)(ies), but that should really be used as a last resort only.

  3. finally, if you could use find_package(..), add the pkg_name_LIBRARIES and pkg_name_INCLUDE_DIRS variables to the relevant include_directories(..) and target_link_libraries(..) lines in your CMakeLists.txt. If you used PkgConfig, do the same, but the variable names might be slightly different. If you hard-coded things, I'd still recommend using variables with the same names that the find scripts would use, because that makes it easy to move to a find script in the future.

In your case, you'll want to make sure the directory containing the mraa.h file is on the include path, and that your sojourner binary is linked with the (I'm guessing here) mraa library. Note that the file will probably be called libmraa.so, but CMake expects only the proper name (ie: mraa).

Bonus points if, instead of hard-coding, you write a CMake find or config script for MRAA and use that.

PS: for some more information on the recommended ways for step 2, see How to do common tasks » Package format 2 (recommended) » C++ system library dependencies in the catkin documentation.


Edit:

I've tried gvdhoorn's suggestions and I still can't get it past [..]

For now, I wouldn't bother with doing things the 'proper' way. If all this is new to you, just do something like this in your CMakeLists.txt:

...

set (mraa_INCLUDE_DIRS "/path/to/where/mraa/headers/are") set (mraa_LIBRARIES "/full/path/to/libmraa.so")

...

include_directories(${catkin_INCLUDE_DIRS} ${mraa_INCLUDE_DIRS})

...

add_executable(sojourner src/sojourner.cpp) ... target_link_libraries(sojourner ${catkin_LIBRARIES} ${mraa_LIBRARIES})

...

I also wouldn't bother with adding anything to the catkin_package(..) statement for now. Get your binary to compile and link successfully. Afterwards, we can deal with the rest. Auto-detection was for bonus points :).

Your package.xml is also not important for now. You can't add the mraa stuff there anyway, as rosdep doesn't know about the MRAA at all (and CMakeLists.txt doesn't care about package.xml).

And btw: remember all of this is CMake. None of it is catkin specific.

That may sound pedantic and minor, but I'm just saying this because catkin is basically CMake, but with a bunch of extra convenience macros and functions (like catkin_package(..)). You'll probably have an easier time finding related questions (on StackExchange/Overflow fi) if you search for 'cmake' instead of 'catkin'.


Originally posted by gvdhoorn with karma: 86574 on 2016-11-11

This answer was ACCEPTED on the original site

Post score: 3


Original comments

Comment by titan vista on 2016-11-14:
Thanks gvdhroon! I added

find_package(PkgConfig REQUIRED)
pkg_check_modules(mraa REQUIRED mraa)
include_directories(${mraa_INCLUDE_DIRS})
catkin_package(... LIBRARIES ... mraa ... DEPENDS ... mraa)

It took more careful reading of your links.

Comment by gvdhoorn on 2016-11-15:
Good to hear you got it to work.

Is your comment cut-off, or have you forgotten to also target_link_libraries(..) with mraa?

Comment by titan vista on 2016-11-15:
I actually did not have that line. I tried it with ${mraa_LIBRARIES} in target_link_libraries and it make no difference with or without it. I still have plenty of errors, due to other things, but it ma crop up later when I get those bugs ironed out.

gvdhoorn-rse
  • 39,013
  • 1
  • 1
  • 4