Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Image Transport rework port in progress for review #84

Merged
merged 25 commits into from
Aug 21, 2018
Merged

Conversation

mjcarroll
Copy link
Contributor

@mjcarroll mjcarroll commented Jul 31, 2018

Builds upon: ros2/message_filters#5

Port of image_transport to work with ROS2.

To use, the branch from the ros2/message_filters repo above needs to be used.

There's now more commits in the history than I plan to have at the end. Several of the later ones are reverting non-essential changes earlier. I plan to find where they were changed and squash the revert of the changes down.

@j-rivero
Copy link

j-rivero commented Aug 2, 2018

Small patch to export headers and libraries to downstream package and the ament_package() to enable the full support inside ament (install setup.* files and some other friends):

diff --git a/image_transport/CMakeLists.txt b/image_transport/CMakeLists.txt
index e19da36..4c7fbe3 100644
--- a/image_transport/CMakeLists.txt
+++ b/image_transport/CMakeLists.txt
@@ -59,6 +59,9 @@ install(
   DESTINATION include
 )
 
+ament_export_include_directories(include)
+ament_export_libraries(${PROJECT_NAME})
+
 if(BUILD_TESTING)
   find_package(ament_lint_auto REQUIRED)
   ament_lint_auto_find_test_dependencies()
@@ -90,3 +93,5 @@ if(BUILD_TESTING)
     target_link_libraries(${PROJECT_NAME}-single_subscriber_publisher ${PROJECT_NAME})
   endif()
 endif()
+
+ament_package()

After these changes (and source install/setup.bash) we have one test failing:

4: Test timeout computed to be: 60
4: -- run_test.py: invoking following command in '/home/jrivero/code/ros2/image_transport_ws/src/image_common/image_transport':
4:  - /home/jrivero/code/ros2/image_transport_ws/build/image_transport/image_transport-message_passing --gtest_output=xml:/home/jrivero/code/ros2/image_transport_ws/build/image_transport/test_results/image_transport/image_transport-message_passing.gtest.xml
4: [==========] Running 2 tests from 1 test case.
4: [----------] Global test environment set-up.
4: [----------] 2 tests from MessagePassingTesting
4: [ RUN      ] MessagePassingTesting.one_message_passing
4: [WARN] [pluginlib.ClassLoader]: given plugin name 'lib/libimage_transport_plugins' should be '/libimage_transport_plugins' for better portability
4: unknown file: Failure
4: C++ exception with description "No plugins found! Does `rospack plugins --attrib=plugin image_transport` find any packages?" thrown in the test body.
4: [  FAILED  ] MessagePassingTesting.one_message_passing (18 ms)
4: [ RUN      ] MessagePassingTesting.stress_message_passing
4: [WARN] [pluginlib.ClassLoader]: given plugin name 'lib/libimage_transport_plugins' should be '/libimage_transport_plugins' for better portability
4: unknown file: Failure
4: C++ exception with description "No plugins found! Does `rospack plugins --attrib=plugin image_transport` find any packages?" thrown in the test body.
4: [  FAILED  ] MessagePassingTesting.stress_message_passing (13 ms)
4: [----------] 2 tests from MessagePassingTesting (31 ms total)
4: 
4: [----------] Global test environment tear-down
4: [==========] 2 tests from 1 test case ran. (31 ms total)
4: [  PASSED  ] 0 tests.
4: [  FAILED  ] 2 tests, listed below:
4: [  FAILED  ] MessagePassingTesting.one_message_passing
4: [  FAILED  ] MessagePassingTesting.stress_message_passing

And a bunch of QA linters are also complaining:

40% tests passed, 6 tests failed out of 10

Label Time Summary:
copyright     =   0.43 sec*proc (1 test)
cppcheck      =   0.53 sec*proc (1 test)
cpplint       =   1.77 sec*proc (1 test)
gtest         =   0.71 sec*proc (5 tests)
lint_cmake    =   0.40 sec*proc (1 test)
linter        =   3.77 sec*proc (5 tests)
uncrustify    =   0.64 sec*proc (1 test)

Total Test time (real) =   4.48 sec

The following tests FAILED:
	  4 - image_transport-message_passing (Failed)
	  6 - copyright (Failed)
	  7 - cppcheck (Failed)
	  8 - cpplint (Failed)
	  9 - lint_cmake (Failed)
	 10 - uncrustify (Failed)
Errors while running CTest

I can help fixing some of these linters. Let me know which ones do you want me to take care of.

@dirk-thomas dirk-thomas mentioned this pull request Aug 2, 2018
8 tasks
@j-rivero
Copy link

j-rivero commented Aug 6, 2018

After these changes (and source install/setup.bash) we have one test failing:

The latest changes make the tests to pass for me.

The following tests passed:
	image_transport-camera_common
	image_transport-publisher
	image_transport-subscriber
	image_transport-message_passing
	image_transport-single_subscriber_publisher

100% tests passed, 0 tests failed out of 5

To fix the lint_cmake, a minimal patch is required:

diff --git a/image_transport/tutorial/CMakeLists.txt b/image_transport/tutorial/CMakeLists.txt
index ed5f28f..6b8455a 100644
--- a/image_transport/tutorial/CMakeLists.txt
+++ b/image_transport/tutorial/CMakeLists.txt
@@ -5,7 +5,7 @@ find_package(catkin REQUIRED COMPONENTS cv_bridge image_transport message_genera
 
 # add the resized image message
 add_message_files(DIRECTORY msg
-   FILES ResizedImage.msg
+  FILES ResizedImage.msg
 )
 generate_messages(DEPENDENCIES sensor_msgs)

To fix the other linters a bit more of work is needed. We can disable them by now or spend some hours fixing them.

@mjcarroll mjcarroll requested a review from tfoote August 6, 2018 13:55
Copy link
Contributor

@tfoote tfoote left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this looks good. There are a few places to improve the debug outputs from fprintf and also a few places to add TODOs where things were skipped for the MVP

if (simple_impl_) return simple_impl_->sub_.getNumPublishers();
return 0;
//if (simple_impl_) return simple_impl_->node_->count_publishers(getTopic());
return 1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a TODO to implement this

}

virtual void shutdown()
{
if (simple_impl_) simple_impl_->sub_.shutdown();
//if (simple_impl_) simple_impl_->sub_.shutdown();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs a TODO too.

@@ -72,12 +70,11 @@ class SubscriberFilter : public message_filters::SimpleFilter<sensor_msgs::Image
* \param nh The ros::NodeHandle to use to subscribe.
* \param base_topic The topic to subscribe to.
* \param queue_size The subscription queue size
* \param transport_hints The transport hints to pass along
* \param transportThe transport hints to pass along
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing space

* \brief Subscribe to an image topic, version for class member function with shared_ptr.
*/
template<class T>
void subscribe(ros::NodeHandle& nh, const std::string& base_topic, uint32_t queue_size,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason to cut the shared_ptr implementation/option here?

};

CameraPublisher::CameraPublisher(ImageTransport& image_it, ros::NodeHandle& info_nh,
const std::string& base_topic, uint32_t queue_size,
const SubscriberStatusCallback& image_connect_cb,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A todo to restore support for these callbacks would be good. Maybe they shouldn't be in the constructor, but as an additional method etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

void shutdown()
{
if (!unsubscribed_) {
unsubscribed_ = true;
image_sub_.unsubscribe();
info_sub_.unsubscribe();
//image_sub_.unsubscribe();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reset the pointers here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which pointers? I think that the only one in this scope is the timer pointer?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The info_sub_ and image_sub_ are shared pointers to the subscribers. If we're not explicitly calling unsubscribe on them they'll keep subscribing to data. So to get them to stop subscribing you can reset the shared pointers info_sub_.reset() to stop them from subscribing, assuming that no one else has stored a reference to them.

}
}

void checkImagesSynchronized()
{
int threshold = 3 * both_received_;
if (image_received_ > threshold || info_received_ > threshold) {
/*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can use RCUTILS_LOG_WARN

return std::string();
}

uint32_t CameraSubscriber::getNumPublishers() const
{
/// @todo Fix this when message_filters::Subscriber has getNumPublishers()
//if (impl_) return std::max(impl_->image_sub_.getNumPublishers(), impl_->info_sub_.getNumPublishers());
if (impl_) return impl_->image_sub_.getNumPublishers();
//if (impl_) return impl_->image_sub_.getNumPublishers();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add TODO

if (blacklist.count(transport_name))
{
for (const auto & lookup_name: loader->getDeclaredClasses()) {
//TODO(ros2) remove boost::erase_last_copy
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO resolved with local implementation

pub->advertise(node, image_topic, custom_qos);
impl_->publishers_.push_back(std::move(pub));
} catch (const std::runtime_error & e) {
fprintf(stderr, "Failed to load plugin %s, error string: %s\n",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More places here for debug macros instead of fprintf

@mjcarroll
Copy link
Contributor Author

  • Linux Build Status
  • Linux-aarch64 Build Status
  • macOS Build Status
  • Windows Build Status

#include <sensor_msgs/Image.h>
#include <boost/noncopyable.hpp>
#include "image_transport/transport_hints.h"
#include <rclcpp/macros.hpp>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

while implementing the theora plugin I made the following changes to be able to compile the package:

diff --git a/image_transport/include/image_transport/subscriber_plugin.h b/image_transport/include/image_transport/subscriber_plugin.h
index 61d5011..0f0afb0 100644
--- a/image_transport/include/image_transport/subscriber_plugin.h
+++ b/image_transport/include/image_transport/subscriber_plugin.h
@@ -36,6 +36,8 @@
 #define IMAGE_TRANSPORT_SUBSCRIBER_PLUGIN_H
 
 #include <rclcpp/macros.hpp>
+#include <rclcpp/node.hpp>
+#include <sensor_msgs/msg/image.hpp>
 
 namespace image_transport
 {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Included, thanks.

Copy link
Contributor

@mikaelarguedas mikaelarguedas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a quick review just for the CMake and package.xml part of the PR

find_package(rclcpp REQUIRED)
find_package(sensor_msgs REQUIRED)
find_package(tinyxml_vendor REQUIRED)
find_package(TinyXML REQUIRED)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is tinyxml_vendor/tinyxml used anywhere in this package?

add_library(${PROJECT_NAME}
SHARED
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there is a use case for this to be built statically (maybe there is not), we recommend using ament_cmake_ros to allow people to chose to build statically or dynamically via the BUILD_SHARED_LIBS CMake option

# Install libraries
install(
TARGETS ${PROJECT_NAME} ${PROJECT_NAME}_plugins
LIBRARY DESTINATION lib
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  ARCHIVE DESTINATION lib
  LIBRARY DESTINATION lib
  RUNTIME DESTINATION bin

For multi OS support in the future

# Install executables
install(
TARGETS list_transports republish
RUNTIME DESTINATION share/${PROJECT_NAME}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Executables should be installed to DESTINATION lib/${PROJECT_NAME} to be found by ros2 run

DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
# Install include directories
install(
DIRECTORY "include/"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: quotes unnecessary here

@@ -17,23 +17,21 @@
<url type="bugtracker">https://github.com/ros-perception/image_common/issues</url>
<url type="repository">https://github.com/ros-perception/image_common</url>

<buildtool_depend>ament_cmake</buildtool_depend>

<depend>class_loader</depend>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This dependency seems to be unused

<depend>message_filters</depend>
<depend>sensor_msgs</depend>
<depend>pluginlib</depend>
<depend>tinyxml_vendor</depend>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This dependency seems to be unused


<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>
<test_depend>ament_cmake_gtest</test_depend>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: alphabetical order

@@ -1,4 +1,4 @@
<package>
<package format="2">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should update maintainer names to avoid original maintainers receiving email when we start testing / releasing this on the ROS 2 farm

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@j-rivero
Copy link

Changes looks good to me, it works well on my Bionic system. Great work Michael, thanks.

const std::string & base_topic,
const Subscriber::Callback& callback,
const std::string& transport,
rmw_qos_profile_t custom_qos = rmw_qos_profile_default);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be helpful for porting existing code if *at least additionally) the previous function signature is maintained. So in this case keep a queue_size parameter and set it internally on the profile.

Same applies to other signatures.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess there are several other API changes which will make it a not straight forward conversion at this point.

It looks like the hints have been removed from several signature but instead the transport string has been introduced. What is the plan around the TransportHints?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can do for queue_size.
I had originally cut TransportHints because it would require a parameters_client internally in order to retrieve the string parameter. The only other thing it was doing was interacting with the ROS1 transport hints, so it seemed easier to pass a string in from the outside.

I can make another similar structure if keeping the API the same is important.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have ported the web_video_server package already. I just noticed the effort during that work. I am not sure if anything should be done but every change in the API (as small as it might be) will be perceived as an (unnecessary?) burden by every user / developer when porting their code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds reasonable, can I do it in a second PR so I can get this one merged?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Absolutely. Not a blocker.

@mjcarroll
Copy link
Contributor Author

  • Linux Build Status
  • Linux-aarch64 Build Status
  • macOS Build Status
  • Windows Build Status

@mjcarroll
Copy link
Contributor Author

mjcarroll commented Aug 20, 2018

Windows and OSX failures expected, due to cv_bridge deps
Linux and aarch unstable due to failing cv_bridge tests.

@mikaelarguedas
Copy link
Contributor

Windows and OSX failures expected, due to cv_bridge deps

Can you clarify what deps are missing ?
If we expect this PR to be tested on all platforms, we should make sure CI can test it. Otherwise we can just "not run CI" for these PRs on Windows/MacOS

Linux and aarch unstable due to failing cv_bridge tests.

While I don't think there is much we can do about the CMake warning. It would be valuable to modify the CI branch you use so that the cv_bridge tests pass so that we have a "clean" state (no failing tests).

@mjcarroll
Copy link
Contributor Author

Looks like Boost on Windows, and boost_python3 on OS X, I'll see what I can do to get them fixed.

@mjcarroll mjcarroll merged commit 2aaa970 into ros2 Aug 21, 2018
@mjcarroll mjcarroll deleted the ros2-devel branch August 21, 2018 15:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants