Ask Your Question
1

Using roscpp in existing app on Android/iOS

asked 2019-11-21 12:29:55 -0500

peetonn gravatar image

updated 2019-11-21 12:36:26 -0500

Hi there. I have an existing app, or rather a shared library, that I compile for mobile platforms (currently Android, but iOS will come very soon too). It is a C++ library that have heavy dependencies (“heavy” in terms of cross-compiling and amount of code). Now, I need to publish (and consume) some ROS topics. I was looking at ROS client libraries page and it seems to me that I should use roscpp for my project. However, after following through all the android ndk tutorials I’m still confused on how I would incorporate roscpp into my existing code. I would expect to have a set of .so or .a libraries compiled for the target platform (btw, I use arm64 while docker container compiles for arm7) and a headers folder to include in my source code. My question is – how can I use roscpp in my existing C++ android library? I am not using Android studio, I use ndk-build directly. I noticed there’re Application.mk and Android.mk files in “roscpp_android_ndk” folder, is that shall be used ultimately?

edit retag flag offensive close merge delete

Comments

Could you elaborate a bit more on your hardware setup? Are you running ROS on a robot and you want to read /publish topics from it from Android/iOS? Or you want to actually run ROS nodes on Android/iOS?

lucascoelho gravatar image lucascoelho  ( 2019-11-21 15:29:19 -0500 )edit

ROS runs on multple OpenPTrack machines. My mobile client needs to publish specific topics that will be consumed by a ROS node. Mobile client will also need to subscribe for few topics. I have a c++ library that I NDK-compile and incorporate in mobile application in a third-party framework (not a Java/Swift app).

peetonn gravatar image peetonn  ( 2019-11-21 15:35:32 -0500 )edit

3 Answers

Sort by » oldest newest most voted
0

answered 2020-01-10 11:53:19 -0500

peetonn gravatar image

I was able to successfully compile roscpp for Android using this repo. It is a fork of the repo from the tutorial but most recent one (dated April 2019). Once libraries are compiled, I added this Android.mk to glue them into a static library and use it in my project:

LOCAL_PATH := $(call my-dir)

stlibs := xmlrpcpp Bullet3Geometry  boost_stacktrace_basic  diagnostic_aggregator  pcl_recognition  orocos-bfl  yaml-cpp  bz2  boost_math_tr1  charset  amcl_sensors  base_local_planner  theoraenc  vorbisfile  orocos-kdl  opencv_imgcodecs3  opencv_xobjdetect3  opencv_videoio3  SDLmain  tf2  boost_signals  image_publisher  SDL_image  image_proc  opencv_reg3  xml2  camera_calibration_parsers  move_base  boost_container  joint_state_listener  boost_context  bondcpp  boost_math_c99f  camera_info_manager  opencv_calib3d3  boost_math_c99l  navfn  tinyxml2  pcl_io_ply  boost_iostreams  opencv_xfeatures2d3  opencv_stereo3  urdfdom_world  boost_thread  eigen_conversions  boost_program_options  roslib  boost_coroutine  pcl_common  opencv_xphoto3  PocoNet  boost_timer  Bullet3Dynamics  opencv_ml3  boost_contract  ogg  opencv_plot3  collada-dom2.4-dp  tf  rosbag_storage  opencv_rgbd3  boost_type_erasure  interactive_markers  boost_log_setup  tinyxml  boost_atomic  flann_cpp_s-gd  pcl_search  laser_geometry  boost_random  pcl_ros_surface   boost_date_time  opencv_structured_light3  urdf  theora  opencv_optflow3  params  qhullcpp  uuid  pcl_surface  map_server_image_loader  rosconsole_backend_interface  urdfdom_model  LinearMath  tf2_ros  Bullet3OpenCL_clew  vorbisenc  pcl_features  pluginlib_tutorials  tf_conversions  opencv_fuzzy3  pcl_registration  opencv_saliency3  boost_test_exec_monitor  theoradec  boost_stacktrace_noop   opencv_img_hash3  opencv_ccalib3  boost_system  PocoUtild  opencv_tracking3  opencv_superres3  opencv_core3  lz4  opencv_surface_matching3  pointcloud_filters  roscpp_serialization  opencv_phase_unwrapping3  compressed_image_transport  compressed_depth_image_transport  move_slow_and_clear  PocoXML  assimp  pcl_kdtree  PocoJSON  opencv_aruco3  cpp_common console_bridge rosconsole_bridge pcl_ros_filters  opencv_ximgproc3  pcl_io  opencv_bgsegm3  boost_exception  pcl_sample_consensus  layers  Bullet3Collision  BulletCollision  robot_state_publisher_solver  opencv_imgproc3  depth_image_proc  rosbag  pcl_filters  stereo_image_proc  octomap  pcl_segmentation  opencv_video3  pcl_stereo  rosconsole_android  boost_math_c99  kdl_conversions  boost_prg_exec_monitor  opencv_dnn3  opencv_line_descriptor3  image_transport_plugins  amcl_map  opencv_objdetect3  pcl_octree  polled_camera  boost_math_tr1l  boost_math_tr1f  voxel_grid  flann_cpp_s  qhullstatic_r  actionlib  boost_wave  PocoUtil  opencv_bioinspired3  image_geometry  theora_image_transport  opencv_text3  kdl_parser  urdfdom_sensor  Bullet3Common  pcl_ros_tf  opencv_highgui3  costmap_2d  opencv_dpm3  Bullet2FileLoader  carrot_planner  nodeletlib  BulletSoftBody  pcl_keypoints  pcl_ros_segmentation  curl  opencv_features2d3  increment  mean  PocoXMLd  boost_log  cv_bridge  roscpp  rotate_recovery  opencv_photo3  SDL  pcl_ros_features  clear_costmap_recovery  opencv_datasets3  rospack  random_numbers  boost_graph  BulletDynamics  iconv  image_rotate  dynamic_reconfigure_config_init_mutex  image_transport  opencv_shape3  octomath  amcl_pf  opencv_flann3  nodelet_math  PocoJSONd  pcl_ros_io  median  rostime  boost_regex  trajectory_planner_ros  message_filters  opencv_videostab3  pcl_ml  PocoFoundationd  global_planner  roslz4  resource_retriever  boost_wserialization  rosconsole  pluginlib  boost_unit_test_framework  opencv_face3  octomap_ros  PocoFoundation  transfer_function  qhullstatic  laser_scan_filters  opencv_stitching3  class_loader  vorbis  urdfdom_model_state  boost_filesystem  geometric_shapes  boost_chrono  boost_serialization  PocoNetd  dwa_local_planner  topic_tools

define include_shlib
$(eval include $$(CLEAR_VARS))
$(eval LOCAL_MODULE := $(1))
$(eval LOCAL_SRC_FILES := $$(LOCAL_PATH)/../lib/lib$(1).so)
$(eval include $$(PREBUILT_SHARED_LIBRARY))
endef
define include_stlib
$(eval include $$(CLEAR_VARS))
$(eval LOCAL_MODULE := $(1))
$(eval LOCAL_SRC_FILES := ../lib/lib$(1).a)
$(eval include $$(PREBUILT_STATIC_LIBRARY))
endef

$(foreach stlib,$(stlibs),$(eval $(call include_stlib,$(stlib))))

include $(CLEAR_VARS)
LOCAL_MODULE    := roscpp_android_ndk
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../include
LOCAL_EXPORT_CPPFLAGS := -fexceptions -frtti
LOCAL_CPP_FEATURES := exceptions
LOCAL_EXPORT_LDLIBS := $(foreach l,$(stlibs),-l$(l)) -L$(LOCAL_PATH)/../lib
LOCAL_EXPORT_LDLIBS += -L$(LOCAL_PATH)/../share/OpenCV-3.3.1-dev/3rdparty/lib -ltegra_hal
LOCAL_STATIC_LIBRARIES := $(stlibs) c++_static

include $(BUILD_STATIC_LIBRARY)

More information can be found here.

edit flag offensive delete link more
1

answered 2019-11-21 16:40:36 -0500

duck-development gravatar image

you may use the http://wiki.ros.org/rosbridge_suite

and you have only json and some web sicket tcp oder udp connection und your done

edit flag offensive delete link more

Comments

is this the de-facto way to go in the cases like mine? we used ros bridge C# implementation in previous project for Unity app, this time wanted to go bare C++ with no WebSocket intermediary...

peetonn gravatar image peetonn  ( 2019-11-21 16:48:09 -0500 )edit

It is the easy way to get ros connection. With lowest dependecys. You can use a TCP connection without the websockets. Und you Code ist easy Portable from kinetic to melodic.

duck-development gravatar image duck-development  ( 2019-11-21 18:00:52 -0500 )edit
0

answered 2019-11-26 04:29:28 -0500

iliis gravatar image

You can use the rosjava API even with otherwise fully native code by using the JNI.

If you really don't want to use Java then I have some hints here (I hope I have time in the future to write that down properly). Be warned tough that it took me many weeks of fighting various build systems, fixing code and hunting down the right flags!

All you actually need to communicate is roscpp and its dependencies. Basically you start with rosinstall_generator roscpp --rosdistro melodic --deps and go from there. Throw out everything you don't really really need. Some libraries that ROS uses are cumbersome to cross-compile but easily stripped out by removing a few lines.

I had successs with Boost 1.69 using https://github.com/moritz-wundke/Boos... (1.70 didn't work) and a current cmake (3.15.5 for me).

I have a folder where I make install all third party dependencies into (like boost or eigen). Everything else is in a normal catkin workspace using the following config:

catkin config --install --cmake-args \
    -DCMAKE_BUILD_TYPE=RelWithDebInfo \
    -DANDROID_ABI=arm64-v8a \
    -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake \
    -DANDROID_TOOLCHAIN=clang \
    -DANDROID_NDK=$ANDROID_NDK_HOME \
    -DANDROID_NATIVE_API_LEVEL=26 \
    -DCMAKE_FIND_ROOT_PATH=<a whole bunch of paths here> \
    -DANDROID_STL=c++_shared \
    -DBoost_DEBUG=ON \
    -DBoost_COMPILER=-clang \
    -DBoost_ARCHITECTURE=-a64 \
    -DBUILD_SHARED_LIBS=ON \
    -DBoost_USE_STATIC_LIBS=ON

CMAKE_FIND_ROOT_PATH is a list of paths where all the third party libraries are installed to, as well as the catkin install folder. Every .so that's ever needed is in there basically so other packages can find it.

I spent a long time getting a working python 2 for Android. I got python itself running, but haven't managed to get pip and python libraries to cross-compile. You actually don't need any python just for roscpp tough ;)

I haven't gotten image_transport working, because that relies on some python modules. So I have to transmit uncompressed images which quickly saturates even a gigabit link!

Some ROS packages didn't compile out of the box and needed a few small fixes.


As for linking everything into our Android application: I'm using Android's cmake (with Android Studio 3.5.1 and NDK 20.0.5594570) which makes integration of a catkin package quite easy actually: If you've set your CMAKE_FIND_ROOT_PATH properly in the Android project you can just use find_package(roscpp). I don't have any experience using the old ndk-build based system and I warmly recommend cmake instead ;)

But basically: If you use an install layout in your catkin workspace (catkin config --install) you will get an install folder that contains all the .so and header files that you can just link to your code.


Another option might be to use Termux and compile everything you need on the device itself.

Good luck!

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

2 followers

Stats

Asked: 2019-11-21 12:29:55 -0500

Seen: 571 times

Last updated: Jan 10 '20