My team will be starting a large ros project soon. Much of our non-ROS legacy code is written in Java and we are debating how best to integrate ROS. I have some questions which would be helpful in making a decision. What is the usability of rosjava for large projects? It seems to still be in development and has been updated to kinetic, but much of the documentation and discussion around it seems to be a couple of years old. Would anyone recommend it for projects that don’t involve android development? Is there a substantial performance impact from using rosjava vs ros-native? Is communication between a rosjava node and a ros-native node difficult? Also does it support tf2? I realize this is quite a bit to ask in one question, but I hope someone can help.
Let me try to answer your questions the best I can:
- Rosjava can be used “as is” in a real project. I’m using it myself in a project where roscpp and rospy are not an option, and it does its job. The documentation in the wiki should be good enough to get started, and I offer myself to help to improve it if necessary.
It has some issues as you can see in its public repository, but its currently under active maintenance: if you find something that is wrong, or want to contribute a new feature, you will get a response within a short time lapse.
- I don’t have an accurate answer about its performance; it will probably depend on what you want to do. What is your application about? My short answer would be that you shouldn’t have problems with it (see next item).
- You can write native nodes and execute them from a java application if you want; Rosjava kinetic has support for that. I’ve tried it and it can be done. You can take a look here: http://wiki.ros.org/android_ndk/Tutorials/WrappingNativeRosjavaNode. (The link is under Android, but it can be done for pure java). Then, nodes can communicate through topics as usual in ROS. From the java side of the application, all the nodes have the same interface, so you don’t care if the node’s implementation is in Java or in native code when you execute it (does this answer your question?).
- TF2 messages are included in rosjava messages (here’s the Maven artifact: https://github.com/rosjava/rosjava_mvn_repo/tree/master/org/ros/rosjava_messages/tf2_msgs).
Hope this helps! Don’t hesitate to ask again if you need any clarification about anything.
Thank you so much for the detailed response! This has definitely cleared up most of my questions. I imagine performance won’t be an issue since we can wrap native nodes. I’m going to start experimenting with rosjava a bit more, now that I know it is worth looking into. I’ll let you know if I have any more questions. Thanks again for the great answer!
Awesome, good luck with that!
I will try to help you whenever possible, just let me know!
Can I use rosjava at my OSX without installing some ros-related installations ?
ROS OSX did not install and is no option at OSX Sierra
Thanks for some suggestions
Yes, that would work. Rosjava is a pure Java implementation.
Note that the available functionality is highly reduced compared to the core client libraries, but you would definitely be able to create nodes and connect to other ROS systems
I have another question. Is there an implementation of any tf2 functions beyond the messages. The Maven artifact you posted works well for creating tf2 messages, but I haven’t been able to find any information on an implementation of the rest of the tf2 libraries. Have tf2 classes such as the transform broadcaster been ported/wrapped?
I’ve never worked with tf2 in depth, but a transform broadcaster or static broadcaster is not hard to implement: it’s pretty much a node that publishes tf2 messages. There are also some helper classes around to handle geometry transformations and stuff like that.
Another option would be to use a cross compiled version of the Cpp library, but I’d only do that if the library you need is too complicated to implement in Java (for a simple publisher, I think it’s not the case).
Perhaps if you open a concrete thread in ROS Answers I can be more helpful. Please point me to the link if you do so!
Ok. I am looking into implementing the transform broadcaster. It looks like it should be doable. I’ll update after I give it a shot.
That’s great! Good luck and feel free to PR your contribution to the rosjava repo. We’ll try to review and accept it quickly.
After digging into the structure of tf2 more I decided there was not much value in recreating the transform broadcaster. In order to fully utilize tf2 much of the library needs to be recompiled with JNI wrappers. This was done for RosTango 3 years ago, but has not since been maintained. I came across the FrameTransformTree in the ros_geometry package. This tree is compatible with tf2 and provides the same basic query functionality. This can be used with a simple subscriber setup to maintain the transforms from the /tf topic while still using tf2 tools for visualization etc.
Could you comment on your experience so far? What major difficulties you faced and what was straightforward?
I am currently in the same situation than you were a year ago. I also have to start a big project of robotic control and we are discussing the choices. Our context makes java almost the only possibility, but we are afraid to start with rosjava and be left aside from the ros community and the ros future enhancements…
We have found ROS Java capable of handling our use cases in general. However, if we were to start over I think the team would go with C++. The ability to leverage our legacy Java code saved time but the difficulties in understanding how to integrate with ROS Java offset that benefit. The primary issue was lack of documentation, but there were a couple bugs in the source code which were also identified. While ROS Java is still actively updated, the documentation and support for C++ is far greater by comparison.
Here are some key areas we struggled with
Clean System Shutdown
Launching ROS Java Nodes:
- ROS Java generates two executables which can confuse roslaunch/rosrun. The extra executable can be deleted to get around this issue
No action lib support (as far as I know)
Service calls are not blocking and have a multi-threading bug
Default gradle build requires internet connection for pulling down a build script
Documentation for installing compiled binaries on external systems wasn’t clear to us
rosjava does not properly sync with std_msgs set which can limit the rosbag api
- (Problem was similar to this) https://answers.ros.org/question/108956/cannot-convert-imu-messages-from-bagfile-to-csv-file/
- rosbags can still be played back just not fully controlled using the client api’s
There were some benefits as well though
- Gradle build system is fast and easy to use
- Unit testing and connecting a debugger to unit tests is easy with gradle
- Catkin/CMake integration is straight forward
- API Is pretty straightforward and pub/sub is fully interoperable with C++/Python nodes
- There is support for integration tests written in Java
I have acquired quite a bit of knowledge on workarounds for rosjava and would be happy to answer more detailed questions, but can’t promise I’ll be able to respond right away.
A bit of a plug but I wrote a primitive and ugly script that attempts to embed msg definitions in
.bags after they have been recorded. For the limited time I was required to use
rosjava this allowed me to still use
Surely one of many implementations of something similar, but: rosbag_fixer.
Not sure what the status of it is, but I came across ernestmc/rosjava_actionlib while looking into that.
Thanks a lot for your detailed answer. This helps a lot on the decision process.
One more thing:
What do you mean by that?
The rosjava message generator cannot handle .action files as defined here
This library is pretty common among ros packages which is why I mentioned it.
we use a forked actionlib support library: https://github.com/CentralLabFacilities/rosjava_actionlib
but it was somewhat clumsy to use (and still is)
.actions get actually transformed in distinct .msg files so the generator is able to generate the corresponding messages.
example MoveBaseActions: https://mvn.cit-ec.de/nexus/content/repositories/releases/org/ros/rosjava_messages/move_base_msgs/1.14.1/
Maybe it took changes from our rosjava forks.