ros2-java / ros2_java

Java and Android bindings for ROS2
Apache License 2.0
165 stars 92 forks source link

Created a fresh app, upload libs and JNI files to compile but I am running into run time issues. #164

Open ahmadnav opened 3 years ago

ahmadnav commented 3 years ago

@esteve
Caused by: org.ros2.rcljava.exceptions.RCLException: Failed to init context options: failed to load shared library of rmw implementation. Exception: Cannot load library: dlopen failed: library "/storage/emulated/0/libs/librmw_fastrtps_cpp.so" not found, at /home/user/ros2_android_ws/src/ros2/rmw_implementation/rmw_implementation/src/functions.cpp:142, at /home/user/ros2_android_ws/src/ros2/rcl/rcl/src/rcl/init_options.c:55

Currently I am modying the functions.cpp file to point to the .so library which I have copied on to my phone. However, it still wont load it. I know the file exists and can be seen by the app as file.exist() returns true on the Java side. Any insight is greatly appreciated thanks!

ahmadnav commented 3 years ago
 Caused by: org.ros2.rcljava.exceptions.RCLException: Failed to init context options: failed to find shared library of rmw implementation. Searched rmw_fastrtps_cpp, at /home/loacaladmin/ros2_android_ws/src/ros2/rmw_implementation/rmw_implementation/src/functions.cpp:135, at /home/loacaladmin/ros2_android_ws/src/ros2/rcl/rcl/src/rcl/init_options.c:55

This is it running as default the std::string library_path = find_library_path(env_var); function in /src/ros2/rmw_implementation/rmw_implementation/src/functions.cpp cannot find the library. Is there any way to make this static? So we arn't looking for the lib at run time

fiaren commented 3 years ago

@ahmadnav I had the same problem when I created a test app in Dashing.

I don't know if this is the correct fix, as I haven't tested it, but I fixed the following, and it works now. Of course, since you have modified the source, you will have to build it again.

${ros2_android_ws}/src/ros2/rmw_implemenation/rmw_implementation/src/function.cpp:112   rerurn ""; ⇛ return filename; ${ros2_android_ws}/src/ros2/rosidl_typesupport/rosidl_typesupport_c/src/type_support_dispatch.cpp:60       rerurn ""; ⇛ return filename;  ${ros2_android_ws}/src/ros2/rosidl_typesupport/rosidl_typesupport_cpp/src/type_support_dispatch.cpp:60   rerurn ""; ⇛ return filename;

ahmadnav commented 3 years ago

@ahmadnav I had the same problem when I created a test app in Dashing.

I don't know if this is the correct fix, as I haven't tested it, but I fixed the following, and it works now. Of course, since you have modified the source, you will have to build it again.

${ros2_android_ws}/src/ros2/rmw_implemenation/rmw_implementation/src/function.cpp:112 rerurn ""; ⇛ return filename; ${ros2_android_ws}/src/ros2/rosidl_typesupport/rosidl_typesupport_c/src/type_support_dispatch.cpp:60
rerurn ""; ⇛ return filename; ${ros2_android_ws}/src/ros2/rosidl_typesupport/rosidl_typesupport_cpp/src/type_support_dispatch.cpp:60
rerurn ""; ⇛ return filename;

Now I get the error

Caused by: org.ros2.rcljava.exceptions.RCLException: Failed to init context options: failed to load shared library of rmw implementation. Exception: Cannot load library: dlopen failed: library "/home/${USER}/ros2_android_ws/install/rmw_fastrtps_cpp/lib/librmw_fastrtps_cpp.so" not found, at /home/loacaladmin/ros2_android_ws/src/ros2/rmw_implementation/rmw_implementation/src/functions.cpp:144, at /home/loacaladmin/ros2_android_ws/src/ros2/rcl/rcl/src/rcl/init_options.c:55 at org.ros2.rcljava.contexts.ContextImpl.nativeInit(Native Method)

The problem I think is the Poco shared lib is unable to access the lib as it stores the path to it as seen at compile time (On my computer) but that path is unavailable when it is running on an android to load the shared lib. One solution I think is if somehow we could package it as a static lib and use it as such than won't have to load it at run time on the android device.

esteve commented 3 years ago

@ahmadnav @fiaren a few things here:

Lastly, I've transferred this ticket to the ros2_java repo, please file tickets against the ros2_java repository, this issue is not related to the Android examples themselves, but to the core ros2_java code. Thanks.

ahmadnav commented 3 years ago

@esteve Thanks for the info! I am not compiling dashing, instead using the prebuilt release due to #158 . As for the functions.cpp I am using the dashing branch of ros2_android. P.S. When you said "colcon build --packages-ignore rmw_fastrtps_cpp") is this for compiling ros2_android_ws or for the ros2 itself?

fiaren commented 3 years ago

@esteve Thanks for the info. I did indeed build it using the Dashing branch.

(via colcon build --packages-ignore rmw_fastrtps_cpp)

It was very helpful.

ahmadnav commented 3 years ago

--- stderr: rmw_implementation
CMake Error at /home/loacaladmin/ros2_android_ws/install/rmw_implementation_cmake/share/rmw_implementation_cmake/cmake/get_default_rmw_implementation.cmake:62 (find_package): By not providing "Findrmw_fastrtps_cpp.cmake" in CMAKE_MODULE_PATH this project has asked CMake to find a package configuration file provided by "rmw_fastrtps_cpp", but CMake did not find one.

Could not find a package configuration file provided by "rmw_fastrtps_cpp" with any of the following names:

rmw_fastrtps_cppConfig.cmake
rmw_fastrtps_cpp-config.cmake

Add the installation prefix of "rmw_fastrtps_cpp" to CMAKE_PREFIX_PATH or set "rmw_fastrtps_cpp_DIR" to a directory containing one of the above files. If "rmw_fastrtps_cpp" provides a separate development package or SDK, be sure it has been installed. Call Stack (most recent call first): CMakeLists.txt:25 (get_default_rmw_implementation)


Failed <<< rmw_implementation [1.29s, exited with code 1]

I get this error if I build ros2_android_ws without rmw_fastrtps_cpp when --packages-ignore rmw_fastrtps_cpp is added to colcon build in ros_android_ws

esteve commented 3 years ago

@ahmadnav please give more context when you submit an issue, it's becoming hard to keep track of issues with just a dump of the logs.

The following command should force ROS2 to build with rmw_fastrtps_dynamic_cpp as the default rmw:

colcon build --packages-ignore rmw_fastrtps_cpp --cmake-args - DRMW_IMPLEMENTATION=rmw_fastrtps_dynamic_cpp - DRMW_IMPLEMENTATION_DISABLE_RUNTIME_SELECTION=ON

ahmadnav commented 3 years ago

@esteve I added some more context to my previous commentAdding --cmake-args - DRMW_IMPLEMENTATION=rmw_fastrtps_dynamic_cpp - DRMW_IMPLEMENTATION_DISABLE_RUNTIME_SELECTION=ON Resolves the runtime issue. Thanks!

However the app seems to hang at listenerNode = new ListenerNode("android_listener_node", "chatter", listenerView); I cannot see anything if I check for nodes on my laptop, and the app screen is black on the android. If I remove the above listenerNode declaration the app display works but it does not do much since the node isn't instantiated

esteve commented 3 years ago

@ahmadnav please post more details, is this one of the examples? Your own app? If so, can you put the code somewhere to have a look at?

ahmadnav commented 3 years ago

@ahmadnav please post more details, is this one of the examples? Your own app? If so, can you put the code somewhere to have a look at?

This is part of the examples.

esteve commented 3 years ago

@ahmadnav but the title of the ticket says that created a new app. So is this a new app or you built the examples? And if it's the latter, did you use colcon or Android Studio? Were you able to build the ros2_android package which contains ROS Activity?

ahmadnav commented 3 years ago

@ahmadnav but the title of the ticket says that created a new app. So is this a new app or you built the examples? And if it's the latter, did you use colcon or Android Studio? Were you able to build the ros2_android package which contains ROS Activity?

This is all done in Android studio, I did create a new app but the ros2_android_examples files are the same. I was having Sync issues with Gradle on the the original app. Essentially I added the .so files in /jniLibs/armebiav7-a and jars as dependencies, than ran the app on my phone. I just added the ROS2 Activity class to my project and built it there.

ahmadnav commented 3 years ago

I figured out the blank screen issue was due to not adding
uses-permission android:name="android.permission.INTERNET"

to the manifest. Interestingly nothing showed up on the log cat to indicate this it just hangs.

However now I am running into this issue; as it appears on log cat running the listener node.

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.ros2_android/com.example.ros2_android.ROS2ListenerActivity}: org.ros2.rcljava.exceptions.RCLException: Failed to create node: type support not from this implementation, at /home/loacaladmin/ros2_android_ws/src/ros2/rmw_fastrtps/rmw_fastrtps_dynamic_cpp/src/rmw_publisher.cpp:108, at /home/loacaladmin/ros2_android_ws/src/ros2/rcl/rcl/src/rcl/publisher.c:171

Luriwei commented 3 years ago

I figured out the blank screen issue was due to not adding to the manifest. Interestingly nothing showed up on the log cat to indicate this it just hangs.

However now I am running into this issue; as it appears on log cat running the listener node.

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.ros2_android/com.example.ros2_android.ROS2ListenerActivity}: org.ros2.rcljava.exceptions.RCLException: Failed to create node: type support not from this implementation, at /home/loacaladmin/ros2_android_ws/src/ros2/rmw_fastrtps/rmw_fastrtps_dynamic_cpp/src/rmw_publisher.cpp:108, at /home/loacaladmin/ros2_android_ws/src/ros2/rcl/rcl/src/rcl/publisher.c:171

Maybe you lost some .so files, i can create node after copy all the .so files, but the node can not be found by my computer.

ahmadnav commented 3 years ago

I figured out the blank screen issue was due to not adding to the manifest. Interestingly nothing showed up on the log cat to indicate this it just hangs. However now I am running into this issue; as it appears on log cat running the listener node. java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.ros2_android/com.example.ros2_android.ROS2ListenerActivity}: org.ros2.rcljava.exceptions.RCLException: Failed to create node: type support not from this implementation, at /home/loacaladmin/ros2_android_ws/src/ros2/rmw_fastrtps/rmw_fastrtps_dynamic_cpp/src/rmw_publisher.cpp:108, at /home/loacaladmin/ros2_android_ws/src/ros2/rcl/rcl/src/rcl/publisher.c:171

Maybe you lost some .so files, i can create node after copy all the .so files, but the node can not be found by my computer.

How do you know it's running?

Luriwei commented 3 years ago

I figured out the blank screen issue was due to not adding to the manifest. Interestingly nothing showed up on the log cat to indicate this it just hangs. However now I am running into this issue; as it appears on log cat running the listener node. java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.ros2_android/com.example.ros2_android.ROS2ListenerActivity}: org.ros2.rcljava.exceptions.RCLException: Failed to create node: type support not from this implementation, at /home/loacaladmin/ros2_android_ws/src/ros2/rmw_fastrtps/rmw_fastrtps_dynamic_cpp/src/rmw_publisher.cpp:108, at /home/loacaladmin/ros2_android_ws/src/ros2/rcl/rcl/src/rcl/publisher.c:171

Maybe you lost some .so files, i can create node after copy all the .so files, but the node can not be found by my computer.

How do you know it's running?

I create two app, one is talker and another is listener, when this two app run in one phone, the listener can receive message from the talker. But when this two app run in two separated phone, the listener can not receive any message from the talker.

ahmadnav commented 3 years ago

@Luriwei Thanks for the update! I still keep getting

Failed to create node: type support not from this implementation, at /home/loacaladmin/ros2_android_ws/src/ros2/rmw_fastrtps/rmw_fastrtps_dynamic_cpp/src/rmw_publisher.cpp:108,

error.

The build script I am using is export PYTHON3_EXEC="$( which python3 )" export PYTHON3_LIBRARY="$( ${PYTHON3_EXEC} -c 'import os.path; from distutils import sysconfig; print(os.path.realpath(os.path.join(sysconfig.get_config_var("LIBPL"), sysconfig.get_config_var("LDLIBRARY"))))' )" export PYTHON3_INCLUDE_DIR="$( ${PYTHON3_EXEC} -c 'from distutils import sysconfig; print(sysconfig.get_config_var("INCLUDEPY"))' )" export ANDROID_ABI=armeabi-v7a export ANDROID_NATIVE_API_LEVEL=android-21 export ANDROID_TOOLCHAIN_NAME=arm-linux-androideabi-clang

colcon build \ --packages-ignore cyclonedds rcl_logging_log4cxx rosidl_generator_py rmw_fastrtps_cpp \ --packages-up-to rcljava \ --cmake-args -DRMW_IMPLEMENTATION=rmw_fastrtps_dynamic_cpp -DRMW_IMPLEMENTATION_DISABLE_RUNTIME_SELECTION=ON \ -D__ANDROID_API__=21 \ -DPYTHON_EXECUTABLE=${PYTHON3_EXEC} \ -DPYTHON_LIBRARY=${PYTHON3_LIBRARY} \ -DPYTHON_INCLUDE_DIR=${PYTHON3_INCLUDE_DIR} \ -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake \ -DANDROID_FUNCTION_LEVEL_LINKING=OFF \ -DANDROID_NATIVE_API_LEVEL=${ANDROID_NATIVE_API_LEVEL} \ -DANDROID_TOOLCHAIN_NAME=${ANDROID_TOOLCHAIN_NAME} \ -DANDROID_STL=c++_shared \ -DANDROID_ABI=${ANDROID_ABI} \ -DANDROID_NDK=${ANDROID_NDK} \ -DTHIRDPARTY=ON \ -DCOMPILE_EXAMPLES=OFF \ -DCMAKE_FIND_ROOT_PATH="${PWD}/install"

If you have any ideas it would help a lot, thanks!

Luriwei commented 3 years ago

@ahmadnav I didn't encountered that problem, maybe you can use the dashing branch.

ahmadnav commented 3 years ago

@Luriwei I am using the dashing branch could that be an issue; Which branch are you on?

Luriwei commented 3 years ago

@ahmadnav I'm use the dashing branch, but i didn't encountered your issue. Sorry for not helping you.

ahmadnav commented 3 years ago

@Luriwei @fiaren @esteve @AlexKovalchukSomatic I got it running, thanks a lot for your guy's input.

Quick Notes on how I got nodes to run on android and see them on other computers.

Android studio side

ADD ndk { abiFilters 'armeabi-v7a', 'armeabi' }

Under defaultConfig

I am running the following permissions; CHANGE_WIFI_MULTICAST_STATE is there as fast DDS uses multicast.

<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" /> 
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

C++ and Java Code side

Return filename rather than "" for find_library_path () function line ~113. This will search for the rmw_fastrtps_cpp files in local apk files rather than the OS. Issue is the function for find_library_path () enters LD_LIBRARY_PATH section and searched library there this did not work on my s9.

Comment out ~line 130 functions.cpp. line 130 ->> // if (library_path.empty()) { // RMW_SET_ERROR_MSG( // ("failed to find shared library of rmw implementation. Searched " + env_var).c_str()); // return nullptr; // }

Domain ID setup This is needed to discover android node from different machines with same domainid. I modified the code such that BaseComposableNode takes in parameter Domaid ID on the java side and carries it through to the createNode function. domain id should be the same as ROS_DOMAIN_ID on the laptop or other machines.

RCLJava.java (231) add final int domain_id to createNode. Add domain_id to the nativeCreateNodeHandle(nodeName, namespace, domain_id, context.getHandle()); (232) RCLJava.java (163) Modify private static native long nativeCreateNodeHandle(String nodeName, String namespace, int domain_id ,long contextHandle); to reflect above changes,

Add following function to RCLJava.java <--- this is called in BaseComposableNode public static Node createNode(final String nodeName, final int domain_id) { return createNode(nodeName, "", domain_id,RCLJava.getDefaultContext()); }

Modify basecomposable node BaseComposableNode.java public class BaseComposableNode implements ComposableNode { private final String name; private final int domain_id;

protected final Node node;

public BaseComposableNode(String name, int domain_id) { this.name = name; this.domain_id = domain_id; node = RCLJava.createNode(this.name, this.domain_id); }

public Node getNode() { return node; } }

Modify org_ros2_rcljava_RCLJava.h:37 to JNIEXPORT jlong JNICALL Java_org_ros2_rcljava_RCLJava_nativeCreateNodeHandle( JNIEnv *, jclass, jstring, jstring, jint, jlong);

And org_ros2_rcljava_RCLJava.cpp:48 JNIEXPORT jlong JNICALL Java_org_ros2_rcljava_RCLJava_nativeCreateNodeHandle( JNIEnv * env, jclass, jstring jnode_name, jstring jnamespace, jint domain_id , jlong context_hand) Add default_options.domain_id = domain_id; after rcl_node_options_t default_options = rcl_node_get_default_options(); in Java_org_ros2_rcljava_RCLJava_nativeCreateNodeHandle

In android studio add all .so files from install folder to ros2_android/app/src/main/jniLibs/armeabi-v7a, and all .jars as dependencies. If you still can not see the node run ros2 daemon stop and start it again.

kruc1024 commented 3 years ago

Dear @ahmadnav ,

Could you please let me know if you have resolved following runtime error with sample applications clearly?

03-19 15:27:26.624 2019 2097 I am_crash: [18764,0,com.lge.robot.ros2.navigation,820526918,org.ros2.rcljava.exceptions.RCLException,Failed to create node: type support not from this implementation, at /src/ros2_android_ws/src/ros2/rmw_fastrtps/rmw_fastrtps_dynamic_cpp/src/rmw_publisher.cpp:108, at /src/ros2_android_ws/src/ros2/rcl/rcl/src/rcl/publisher.c:171,RCLJava.java,-2]

I also met above exception on runtime like your previous case, and i couldn't resolve it yet..ioi (only difference is that I used arm64-v8a abi as per my test device's architecture )

i.e. my question is:

  1. According to your last comment, what i understood that you removed some lines in function.cpp and it means you built with rmw_fastrtps_cpp instead of use rmw_fastrtps_dynamic_cpp. am i right?

  2. I had tested like your last comment but it was not working for me.. Are "domain_id" and "libraries hard copy" related to runtime error?

Please help me to overcome & clarify this runtime issue if you have any hints or tips. Thanks in advance.

ahmadnav commented 3 years ago

@kruc1024 The error you are experiencing is not based around domain_id and the hard changes to code. I didn't comment on it but I also changed the colon build function as follows:

colcon build \ --packages-ignore cyclonedds rcl_logging_log4cxx rosidl_generator_py rmw_fastrtps_cpp \ --packages-up-to rcljava \ --cmake-args \ -DRMW_IMPLEMENTATION=rmw_fastrtps_dynamic_cpp \ -DRMW_IMPLEMENTATION_DISABLE_RUNTIME_SELECTION=ON \ -DPYTHON_EXECUTABLE=${PYTHON3_EXEC} \ -DPYTHON_LIBRARY=${PYTHON3_LIBRARY} \ -DPYTHON_INCLUDE_DIR=${PYTHON3_INCLUDE_DIR} \ -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake \ -DANDROID_FUNCTION_LEVEL_LINKING=OFF \ -DANDROID_NATIVE_API_LEVEL=${ANDROID_NATIVE_API_LEVEL} \ -DANDROID_TOOLCHAIN_NAME=${ANDROID_TOOLCHAIN_NAME} \ -DANDROID_STL=c++_shared \ -DANDROID_ABI=${ANDROID_ABI} \ -DANDROID_NDK=${ANDROID_NDK} \ -DTHIRDPARTY=ON \ -DCOMPILE_EXAMPLES=OFF \ -DCMAKE_FIND_ROOT_PATH="${PWD}/install"

Key things are -DRMW_IMPLEMENTATION=rmw_fastrtps_dynamic_cpp \ -DRMW_IMPLEMENTATION_DISABLE_RUNTIME_SELECTION=ON \ this should disable searching for libraries during run time, which in turn causes the runtime errors as it cannot find the so libraries. Hope this helps!

kruc1024 commented 3 years ago

Dear @ahmadnav Thanks for your prompt & kind comment! thanks to you i can make narrow the scopt of this issue.

Actually i already used following key option in my build, "-DRMW_IMPLEMENTATION=rmw_fastrtps_dynamic_cpp \ -DRMW_IMPLEMENTATION_DISABLE_RUNTIME_SELECTION=ON but it is not working for me..

it helped me to avoid issue from finding LD_LIBRARY_PATH, but not made me to avoid type support error. [18764,0,com.lge.robot.ros2.navigation,820526918,org.ros2.rcljava.exceptions.RCLException,Failed to create node: type support not from this implementation, at /src/ros2_android_ws/src/ros2/rmw_fastrtps/rmwfastrtpsdynamic_cpp/src/rmw_publisher.cpp:108, at (diff by option : rmwfastrtpsdynamic_cpp -> rmw_fastrtps_cpp)

frankly speaking, i had tried to make build with ament build for now, but from now, i'll try to use colcon build. (i have being failed to colcon build in my system)

Thanks again!

Dear @esteve, Nice to meet you! from Dashing version, could you please let me know any reason to suggest colcon build instead of ament build? I wonder if it makes some effect on my runtime error of ros2 android.

Thanks in advance.

jacobperron commented 2 years ago

@kruc1024 ament build is no longer supported. colcon is now the recommended build tool for ROS 2.


@ahmadnav It's good to know you were able to get things working. We've made some updates to the main branch to support ROS Galactic. I'd be interested to know if the current instructions are valid for Android or if they could use some changes.