diff --git a/README.md b/README.md index 1994153..3df3ec5 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,8 @@ Subscriptions: * `image` (`sensor_msgs/msg/Image`) Publisher: -* `barcode` (`std_msgs/msg/String`) +* `symbol` (`zbar_ros_interfaces/msg/Symbol`) +* `barcode` (`std_msgs/msg/String`) - **DEPRECATED** ## Debugging the barcode_reader node diff --git a/CMakeLists.txt b/zbar_ros/CMakeLists.txt similarity index 94% rename from CMakeLists.txt rename to zbar_ros/CMakeLists.txt index 8f656af..b6e12e6 100644 --- a/CMakeLists.txt +++ b/zbar_ros/CMakeLists.txt @@ -19,7 +19,7 @@ endif() find_package(ament_cmake REQUIRED) find_package(rclcpp REQUIRED) find_package(sensor_msgs REQUIRED) -find_package(std_msgs REQUIRED) +find_package(zbar_ros_interfaces REQUIRED) find_package(cv_bridge REQUIRED) # Include header files @@ -32,7 +32,8 @@ ament_target_dependencies(barcode_reader_node rclcpp sensor_msgs std_msgs - cv_bridge) + cv_bridge + zbar_ros_interfaces) target_link_libraries(barcode_reader_node zbar) # Build executable diff --git a/include/zbar_ros/barcode_reader_node.hpp b/zbar_ros/include/zbar_ros/barcode_reader_node.hpp similarity index 94% rename from include/zbar_ros/barcode_reader_node.hpp rename to zbar_ros/include/zbar_ros/barcode_reader_node.hpp index 8d95007..76f2822 100644 --- a/include/zbar_ros/barcode_reader_node.hpp +++ b/zbar_ros/include/zbar_ros/barcode_reader_node.hpp @@ -38,6 +38,7 @@ #include "./zbar.h" #include "sensor_msgs/msg/image.hpp" #include "std_msgs/msg/string.hpp" +#include "zbar_ros_interfaces/msg/symbol.hpp" namespace zbar_ros { @@ -52,7 +53,8 @@ class BarcodeReaderNode : public rclcpp::Node void cleanCb(); rclcpp::Subscription::SharedPtr camera_sub_; - rclcpp::Publisher::SharedPtr barcode_pub_; + rclcpp::Publisher::SharedPtr symbol_pub_; + rclcpp::Publisher::SharedPtr barcode_pub_; // DEPRECATED zbar::ImageScanner scanner_; rclcpp::TimerBase::SharedPtr clean_timer_; diff --git a/package.xml b/zbar_ros/package.xml similarity index 95% rename from package.xml rename to zbar_ros/package.xml index c4966e1..618fb79 100644 --- a/package.xml +++ b/zbar_ros/package.xml @@ -16,6 +16,7 @@ cv_bridge sensor_msgs std_msgs + zbar_ros_interfaces ament_lint_auto ament_lint_common diff --git a/src/barcode_reader_main.cpp b/zbar_ros/src/barcode_reader_main.cpp similarity index 100% rename from src/barcode_reader_main.cpp rename to zbar_ros/src/barcode_reader_main.cpp diff --git a/src/barcode_reader_node.cpp b/zbar_ros/src/barcode_reader_node.cpp similarity index 74% rename from src/barcode_reader_node.cpp rename to zbar_ros/src/barcode_reader_node.cpp index b135ed0..d2d4b16 100644 --- a/src/barcode_reader_node.cpp +++ b/zbar_ros/src/barcode_reader_node.cpp @@ -44,10 +44,10 @@ BarcodeReaderNode::BarcodeReaderNode() { scanner_.set_config(zbar::ZBAR_NONE, zbar::ZBAR_CFG_ENABLE, 1); - camera_sub_ = this->create_subscription( "image", 10, std::bind(&BarcodeReaderNode::imageCb, this, std::placeholders::_1)); + symbol_pub_ = this->create_publisher("symbol", 10); barcode_pub_ = this->create_publisher("barcode", 10); throttle_ = this->declare_parameter("throttle_repeated_barcodes", 0.0); @@ -74,14 +74,29 @@ void BarcodeReaderNode::imageCb(sensor_msgs::msg::Image::ConstSharedPtr image) auto it_end = zbar_image.symbol_end(); if (it_start != it_end) { // If there are barcodes in the image, iterate over all barcode readings from image - for (zbar::Image::SymbolIterator symbol = it_start; symbol != it_end; ++symbol) { - std::string barcode = symbol->get_data(); - RCLCPP_DEBUG(get_logger(), "Barcode detected with data: '%s'", barcode.c_str()); + for (zbar::Image::SymbolIterator symbol_it = it_start; symbol_it != it_end; ++symbol_it) { + zbar_ros_interfaces::msg::Symbol symbol; + symbol.data = symbol_it->get_data(); + RCLCPP_DEBUG(get_logger(), "Barcode detected with data: '%s'", symbol.data.c_str()); + + RCLCPP_DEBUG( + get_logger(), "Polygon around barcode has %d points", symbol_it->get_location_size()); + for (zbar::Symbol::PointIterator point_it = symbol_it->point_begin(); + point_it != symbol_it->point_end(); + ++point_it) + { + vision_msgs::msg::Point2D point; + point.x = (*point_it).x; + point.y = (*point_it).y; + RCLCPP_DEBUG(get_logger(), " Point: %f, %f", point.x, point.y); + symbol.points.push_back(point); + } // verify if repeated barcode throttling is enabled if (throttle_ > 0.0) { const std::lock_guard lock(memory_mutex_); + const std::string & barcode = symbol.data; // check if barcode has been recorded as seen, and skip detection if (barcode_memory_.count(barcode) > 0) { // check if time reached to forget barcode @@ -100,16 +115,32 @@ void BarcodeReaderNode::imageCb(sensor_msgs::msg::Image::ConstSharedPtr image) now() + rclcpp::Duration(std::chrono::duration(throttle_)))); } - // publish barcode + // publish symbol + RCLCPP_DEBUG(get_logger(), "Publishing Symbol"); + symbol_pub_->publish(symbol); + + // publish on deprecated barcode topic RCLCPP_DEBUG(get_logger(), "Publishing data as string"); std_msgs::msg::String barcode_string; - barcode_string.data = barcode; + barcode_string.data = symbol.data; barcode_pub_->publish(barcode_string); } } else { RCLCPP_DEBUG(get_logger(), "No barcode detected in image"); } + // Warn if there are subscriptions on barcode topic, because it's deprecated. + static bool alreadyWarnedDeprecation = false; + if (!alreadyWarnedDeprecation && count_subscribers("barcode") > 0) { + alreadyWarnedDeprecation = true; + RCLCPP_WARN( + get_logger(), + "A subscription was detected on the deprecated topic 'barcode'. Please update the node " + "that is subscribing to use the new topic 'symbol' with type " + "'zbar_ros_interfaces::msg::Symbol' instead. The 'barcode' topic will be removed " + "in the next distribution."); + } + zbar_image.set_data(NULL, 0); } diff --git a/zbar_ros_interfaces/CMakeLists.txt b/zbar_ros_interfaces/CMakeLists.txt new file mode 100644 index 0000000..58ded16 --- /dev/null +++ b/zbar_ros_interfaces/CMakeLists.txt @@ -0,0 +1,36 @@ +cmake_minimum_required(VERSION 3.5) +project(zbar_ros_interfaces) + +# Default to C99 +if(NOT CMAKE_C_STANDARD) + set(CMAKE_C_STANDARD 99) +endif() + +# Default to C++14 +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 14) +endif() + +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +endif() + +# find dependencies +find_package(ament_cmake REQUIRED) +find_package(rosidl_default_generators REQUIRED) +find_package(vision_msgs REQUIRED) + +# generate interfaces +rosidl_generate_interfaces(${PROJECT_NAME} + "msg/Symbol.msg" + DEPENDENCIES vision_msgs +) + +ament_export_dependencies(rosidl_default_runtime) + +if(BUILD_TESTING) + find_package(ament_lint_auto REQUIRED) + ament_lint_auto_find_test_dependencies() +endif() + +ament_package() diff --git a/zbar_ros_interfaces/msg/Symbol.msg b/zbar_ros_interfaces/msg/Symbol.msg new file mode 100644 index 0000000..2245e4b --- /dev/null +++ b/zbar_ros_interfaces/msg/Symbol.msg @@ -0,0 +1,2 @@ +string data +vision_msgs/Point2D[] points diff --git a/zbar_ros_interfaces/package.xml b/zbar_ros_interfaces/package.xml new file mode 100644 index 0000000..1884d92 --- /dev/null +++ b/zbar_ros_interfaces/package.xml @@ -0,0 +1,24 @@ + + + + zbar_ros_interfaces + 0.0.0 + Package containing interfaces for zbar_ros to use to publish results + ijnek + BSD + + ament_cmake + + vision_msgs + + ament_lint_auto + ament_lint_common + + rosidl_default_generators + rosidl_default_runtime + rosidl_interface_packages + + + ament_cmake + +