pax_global_header00006660000000000000000000000064133656743630014532gustar00rootroot0000000000000052 comment=83ce5002decd5f312e3933ee28b9ab5fa2f7320d ros-image-common-1.11.13/000077500000000000000000000000001336567436300150475ustar00rootroot00000000000000ros-image-common-1.11.13/.gitignore000066400000000000000000000000111336567436300170270ustar00rootroot00000000000000*.pyc .* ros-image-common-1.11.13/.travis.yml000066400000000000000000000045431336567436300171660ustar00rootroot00000000000000sudo: required dist: trusty language: generic env: - OPENCV_VERSION=2 ROS_DISTRO=indigo - OPENCV_VERSION=3 ROS_DISTRO=indigo - OPENCV_VERSION=2 ROS_DISTRO=jade - OPENCV_VERSION=3 ROS_DISTRO=jade # Install system dependencies, namely ROS. before_install: # Define some config vars. - export ROS_CI_DESKTOP=`lsb_release -cs` # e.g. [precise|trusty] - export CI_SOURCE_PATH=$(pwd) - export REPOSITORY_NAME=${PWD##*/} - export ROSINSTALL_FILE=$CI_SOURCE_PATH/dependencies.rosinstall - export CATKIN_OPTIONS=$CI_SOURCE_PATH/catkin.options - export ROS_PARALLEL_JOBS='-j8 -l6' # Install ROS - sudo sh -c "echo \"deb http://packages.ros.org/ros-shadow-fixed/ubuntu $ROS_CI_DESKTOP main\" > /etc/apt/sources.list.d/ros-latest.list" - wget http://packages.ros.org/ros.key -O - | sudo apt-key add - - sudo apt-get update -qq &>/dev/null # Install ROS - sudo apt-get install -qq -y python-catkin-pkg python-catkin-tools python-rosdep python-wstool ros-$ROS_DISTRO-catkin >/dev/null - source /opt/ros/$ROS_DISTRO/setup.bash # Setup for rosdep - sudo rosdep init - rosdep update # Create a catkin workspace with the package under test. install: - mkdir -p ~/catkin_ws/src # Add the package under test to the workspace. - cd ~/catkin_ws/src - ln -s $CI_SOURCE_PATH . # Link the repo we are testing to the new workspace - if [ $OPENCV_VERSION == 3 ]; then sed -i 's@libopencv-dev@opencv3@' $REPOSITORY_NAME/*/package.xml ; fi # Install all dependencies, using wstool and rosdep. # wstool looks for a ROSINSTALL_FILE defined in before_install. before_script: # source dependencies: install using wstool. - cd ~/catkin_ws/src - wstool init - if [[ -f $ROSINSTALL_FILE ]] ; then wstool merge $ROSINSTALL_FILE ; fi - wstool up # package depdencies: install using rosdep. - cd ~/catkin_ws - rosdep install -q -y -r --from-paths src --ignore-src --rosdistro $ROS_DISTRO >/dev/null # Compile and test. script: - source /opt/ros/$ROS_DISTRO/setup.bash - cd ~/catkin_ws - catkin build --no-status -p1 -j1 - catkin run_tests -p1 -j1 - catkin_test_results --all build - catkin clean -b --yes - catkin config --install - catkin build --no-status -p1 -j1 after_failure: - find ${HOME}/.ros/test_results -type f -exec echo "== {} ==" \; -exec cat {} \; - for file in ${HOME}/.ros/log/rostest-*; do echo "=== $file ==="; cat $file; done ros-image-common-1.11.13/camera_calibration_parsers/000077500000000000000000000000001336567436300224055ustar00rootroot00000000000000ros-image-common-1.11.13/camera_calibration_parsers/CHANGELOG.rst000066400000000000000000000060741336567436300244350ustar00rootroot00000000000000^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Changelog for package camera_calibration_parsers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1.11.13 (2017-11-05) -------------------- * Use Boost_LIBRARIES instead of Boost_PYTHON_LIBRARY This was causing issues when building with python3 since then `Boost_PYTHON_LIBRARY` is not set, instead cmake sets `Boost_PYTHON3_LIBRARY`. So instead of adding each library separately, using `Boost_LIBRARIES` seems to be better. For reference, from the cmake docs: ``` Boost_LIBRARIES - Boost component libraries to be linked Boost\__LIBRARY - Libraries to link for component ``` * Contributors: Kartik Mohta, Vincent Rabaud 1.11.12 (2017-01-29) -------------------- * Properly detect Boost Python 2 or 3 This fixes `#59 `_ * 1.11.11 * update changelogs * Contributors: Vincent Rabaud 1.11.11 (2016-09-24) -------------------- 1.11.10 (2016-01-19) -------------------- * Add install target for python wrapper library * Only link against needed Boost libraries 9829b02 introduced a python dependency into find_package(Boost..) which results in ${Boost_LIBRARIES} containing boost_python and such a dependency to libpython at link time. With this patch we only link against the needed libraries. * Contributors: Jochen Sprickerhof, Vincent Rabaud 1.11.9 (2016-01-17) ------------------- * Add python wrapper for readCalibration. Reads .ini or .yaml calibration file and returns camera name and sensor_msgs/cameraInfo. * Use $catkin_EXPORTED_TARGETS * Contributors: Jochen Sprickerhof, Markus Roth 1.11.8 (2015-11-29) ------------------- * Remove no-longer-neccessary flags to allow OS X to use 0.3 and 0.5 of yaml-cpp. * remove buggy CMake message * Contributors: Helen Oleynikova, Vincent Rabaud 1.11.7 (2015-07-28) ------------------- * fix `#39 `_ * make sure test does not fail * Contributors: Vincent Rabaud 1.11.6 (2015-07-16) ------------------- * [camera_calibration_parsers] Better error message when calib file can't be written * add rosbash as a test dependency * add a test dependency now that we have tests * parse distortion of arbitraty length in INI This fixes `#33 `_ * add a test to parse INI calibration files with 5 or 8 D param * Add yaml-cpp case for building on Android * Contributors: Gary Servin, Isaac IY Saito, Vincent Rabaud 1.11.5 (2015-05-14) ------------------- * Fix catkin_make failure (due to yaml-cpp deps) for mac os * Contributors: Yifei Zhang 1.11.4 (2014-09-21) ------------------- * fix bad yaml-cpp usage in certain conditions fixes `#24 `_ * Contributors: Vincent Rabaud 1.11.3 (2014-05-19) ------------------- 1.11.2 (2014-02-13 08:32:06 +0100) ----------------------------------- * add a dependency on pkg-config to have it work on Indigo 1.11.1 (2014-01-26 02:32:06 +0100) ----------------------------------- * fix YAML CPP 0.5.x compatibility ros-image-common-1.11.13/camera_calibration_parsers/CMakeLists.txt000066400000000000000000000042611336567436300251500ustar00rootroot00000000000000cmake_minimum_required(VERSION 2.8) project(camera_calibration_parsers) find_package(catkin REQUIRED sensor_msgs rosconsole roscpp roscpp_serialization) find_package(PythonLibs REQUIRED) if(PYTHONLIBS_VERSION_STRING VERSION_LESS 3) find_package(Boost REQUIRED COMPONENTS filesystem python) else() find_package(Boost REQUIRED COMPONENTS filesystem python3) endif() include_directories(include ${catkin_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS}) catkin_python_setup() catkin_package( INCLUDE_DIRS include LIBRARIES ${PROJECT_NAME} CATKIN_DEPENDS sensor_msgs ) find_package(PkgConfig) if (ANDROID) find_package(yaml-cpp) add_definitions(-DHAVE_NEW_YAMLCPP) else() pkg_check_modules(YAML_CPP yaml-cpp) if(${YAML_CPP_VERSION} VERSION_GREATER 0.5) add_definitions(-DHAVE_NEW_YAMLCPP) endif() link_directories(${YAML_CPP_LIBRARY_DIRS}) endif() include_directories(${YAML_CPP_INCLUDE_DIRS}) # define the library add_library(${PROJECT_NAME} src/parse.cpp src/parse_ini.cpp src/parse_yml.cpp ) add_library(${PROJECT_NAME}_wrapper src/parse_wrapper.cpp) target_link_libraries(${PROJECT_NAME} ${catkin_LIBRARIES} ${YAML_CPP_LIBRARIES} ${Boost_FILESYSTEM_LIBRARY}) target_link_libraries(${PROJECT_NAME}_wrapper ${PROJECT_NAME} ${catkin_LIBRARIES} ${Boost_LIBRARIES} ${PYTHON_LIBRARIES}) # Don't prepend wrapper library name with lib and add to Python libs. set_target_properties(${PROJECT_NAME}_wrapper PROPERTIES PREFIX "" LIBRARY_OUTPUT_DIRECTORY ${CATKIN_DEVEL_PREFIX}/${CATKIN_PACKAGE_PYTHON_DESTINATION} ) add_dependencies(${PROJECT_NAME} ${catkin_EXPORTED_TARGETS}) install( TARGETS ${PROJECT_NAME} DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} COMPONENT main ) install( DIRECTORY include/${PROJECT_NAME}/ DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} ) # define the exe to convert add_executable(convert src/convert.cpp) target_link_libraries(convert ${PROJECT_NAME} ${rosconsole_LIBRARIES}) install( TARGETS convert DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} ) install(TARGETS ${PROJECT_NAME}_wrapper DESTINATION ${CATKIN_PACKAGE_PYTHON_DESTINATION} ) if(CATKIN_ENABLE_TESTING) add_subdirectory(test) endif() ros-image-common-1.11.13/camera_calibration_parsers/include/000077500000000000000000000000001336567436300240305ustar00rootroot00000000000000ros-image-common-1.11.13/camera_calibration_parsers/include/camera_calibration_parsers/000077500000000000000000000000001336567436300313665ustar00rootroot00000000000000ros-image-common-1.11.13/camera_calibration_parsers/include/camera_calibration_parsers/parse.h000066400000000000000000000062671336567436300326640ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #ifndef CAMERA_CALIBRATION_PARSERS_PARSE_H #define CAMERA_CALIBRATION_PARSERS_PARSE_H #include #include /// @todo: use stream-based API, so no read/parse distinction namespace camera_calibration_parsers { /** * \brief Write calibration parameters to a file. * * The file name extension (.yml, .yaml, or .ini) determines the output format. * * \param file_name File to write * \param camera_name Name of the camera * \param cam_info Camera parameters */ bool writeCalibration(const std::string& file_name, const std::string& camera_name, const sensor_msgs::CameraInfo& cam_info); /** * \brief Read calibration parameters from a file. * * The file may be YAML or INI format. * * \param file_name File to read * \param[out] camera_name Name of the camera * \param[out] cam_info Camera parameters */ bool readCalibration(const std::string& file_name, std::string& camera_name, sensor_msgs::CameraInfo& cam_info); /** * \brief Parse calibration parameters from a string in memory. * * \param buffer Calibration string * \param format Format of calibration string, "yml" or "ini" * \param[out] camera_name Name of the camera * \param[out] cam_info Camera parameters */ bool parseCalibration(const std::string& buffer, const std::string& format, std::string& camera_name, sensor_msgs::CameraInfo& cam_info); } //namespace camera_calibration_parsers #endif ros-image-common-1.11.13/camera_calibration_parsers/include/camera_calibration_parsers/parse_ini.h000066400000000000000000000071651336567436300335210ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #ifndef CAMERA_CALIBRATION_PARSERS_PARSE_INI_H #define CAMERA_CALIBRATION_PARSERS_PARSE_INI_H #include #include namespace camera_calibration_parsers { /** * \brief Write calibration parameters to a file in INI format. * * \param out Output stream to write to * \param camera_name Name of the camera * \param cam_info Camera parameters */ bool writeCalibrationIni(std::ostream& out, const std::string& camera_name, const sensor_msgs::CameraInfo& cam_info); /** * \brief Read calibration parameters from an INI file. * * \param in Input stream to read from * \param[out] camera_name Name of the camera * \param[out] cam_info Camera parameters */ bool readCalibrationIni(std::istream& in, std::string& camera_name, sensor_msgs::CameraInfo& cam_info); /** * \brief Write calibration parameters to a file in INI format. * * \param file_name File to write * \param camera_name Name of the camera * \param cam_info Camera parameters */ bool writeCalibrationIni(const std::string& file_name, const std::string& camera_name, const sensor_msgs::CameraInfo& cam_info); /** * \brief Read calibration parameters from an INI file. * * \param file_name File to read * \param[out] camera_name Name of the camera * \param[out] cam_info Camera parameters */ bool readCalibrationIni(const std::string& file_name, std::string& camera_name, sensor_msgs::CameraInfo& cam_info); /** * \brief Parse calibration parameters from a string in memory of INI format. * * \param buffer Calibration string * \param[out] camera_name Name of the camera * \param[out] cam_info Camera parameters */ bool parseCalibrationIni(const std::string& buffer, std::string& camera_name, sensor_msgs::CameraInfo& cam_info); //bool readCalibrationIni } //namespace camera_calibration_parsers #endif parse_wrapper.h000066400000000000000000000037441336567436300343420ustar00rootroot00000000000000ros-image-common-1.11.13/camera_calibration_parsers/include/camera_calibration_parsers/********************************************************************* * Software License Agreement (BSD License) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #ifndef CAMERA_CALIBRATION_PARSERS_PARSE_WRAPPER_H #define CAMERA_CALIBRATION_PARSERS_PARSE_WRAPPER_H #include #include namespace camera_calibration_parsers { boost::python::tuple readCalibrationWrapper(const std::string& file_name); } //namespace camera_calibration_parsers #endif ros-image-common-1.11.13/camera_calibration_parsers/include/camera_calibration_parsers/parse_yml.h000066400000000000000000000064411336567436300335370ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #ifndef CAMERA_CALIBRATION_PARSERS_PARSE_YML_H #define CAMERA_CALIBRATION_PARSERS_PARSE_YML_H #include #include #include #include namespace camera_calibration_parsers { /** * \brief Write calibration parameters to a file in YAML format. * * \param out Output stream to write to * \param camera_name Name of the camera * \param cam_info Camera parameters */ bool writeCalibrationYml(std::ostream& out, const std::string& camera_name, const sensor_msgs::CameraInfo& cam_info); /** * \brief Read calibration parameters from a YAML file. * * \param in Input stream to read from * \param[out] camera_name Name of the camera * \param[out] cam_info Camera parameters */ bool readCalibrationYml(std::istream& in, std::string& camera_name, sensor_msgs::CameraInfo& cam_info); /** * \brief Write calibration parameters to a file in YAML format. * * \param file_name File to write * \param camera_name Name of the camera * \param cam_info Camera parameters */ bool writeCalibrationYml(const std::string& file_name, const std::string& camera_name, const sensor_msgs::CameraInfo& cam_info); /** * \brief Read calibration parameters from a YAML file. * * \param file_name File to read * \param[out] camera_name Name of the camera * \param[out] cam_info Camera parameters */ bool readCalibrationYml(const std::string& file_name, std::string& camera_name, sensor_msgs::CameraInfo& cam_info); } //namespace camera_calibration_parsers #endif ros-image-common-1.11.13/camera_calibration_parsers/mainpage.dox000066400000000000000000000007621336567436300247070ustar00rootroot00000000000000/** \mainpage \htmlinclude manifest.html \b camera_calibration_parsers contains routines for reading and writing camera calibration parameters. Two human-readable file formats are supported: YAML and the Videre INI format. \section codeapi Code API - camera_calibration_parsers::writeCalibration - Write parameters to a file - camera_calibration_parsers::readCalibration - Read parameters from a file - camera_calibration_parsers::parseCalibration - Read parameters from an in-memory buffer */ ros-image-common-1.11.13/camera_calibration_parsers/package.xml000066400000000000000000000024031336567436300245210ustar00rootroot00000000000000 camera_calibration_parsers 1.11.13 camera_calibration_parsers contains routines for reading and writing camera calibration parameters. Patrick Mihelich Jack O'Quin Vincent Rabaud BSD http://ros.org/wiki/camera_calibration_parsers https://github.com/ros-perception/image_common/issues https://github.com/ros-perception/image_common catkin boost pkg-config rosconsole sensor_msgs yaml-cpp roscpp roscpp_serialization boost sensor_msgs yaml-cpp roscpp roscpp_serialization rosbash rosunit ros-image-common-1.11.13/camera_calibration_parsers/setup.py000066400000000000000000000005031336567436300241150ustar00rootroot00000000000000# ! DO NOT MANUALLY INVOKE THIS setup.py, USE CATKIN INSTEAD from distutils.core import setup from catkin_pkg.python_setup import generate_distutils_setup # fetch values from package.xml setup_args = generate_distutils_setup( packages=['camera_calibration_parsers'], package_dir={'': 'src'}) setup(**setup_args) ros-image-common-1.11.13/camera_calibration_parsers/src/000077500000000000000000000000001336567436300231745ustar00rootroot00000000000000ros-image-common-1.11.13/camera_calibration_parsers/src/camera_calibration_parsers/000077500000000000000000000000001336567436300305325ustar00rootroot00000000000000ros-image-common-1.11.13/camera_calibration_parsers/src/camera_calibration_parsers/__init__.py000066400000000000000000000011571336567436300326470ustar00rootroot00000000000000from camera_calibration_parsers.camera_calibration_parsers_wrapper import __readCalibrationWrapper from sensor_msgs.msg import CameraInfo def readCalibration(file_name): """Read .ini or .yaml calibration file and return (camera name and cameraInfo message). @param file_name: camera calibration file name @type file_name: str @return: (camera name, cameraInfo message) or None on Error @rtype: tuple(str, sensor_msgs.msg.CameraInfo | None """ ret, cn, ci = __readCalibrationWrapper(file_name) if not ret: return None c = CameraInfo() c.deserialize(ci) return cn, c ros-image-common-1.11.13/camera_calibration_parsers/src/convert.cpp000066400000000000000000000046521336567436300253670ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #include "camera_calibration_parsers/parse.h" #include #include using namespace camera_calibration_parsers; int main(int argc, char** argv) { if (argc < 3) { printf("Usage: %s input.yml output.ini\n" " %s input.ini output.yml\n", argv[0], argv[0]); return 0; } std::string name; sensor_msgs::CameraInfo cam_info; if (!readCalibration(argv[1], name, cam_info)) { ROS_ERROR("Failed to load camera model from file %s", argv[1]); return -1; } if (!writeCalibration(argv[2], name, cam_info)) { ROS_ERROR("Failed to save camera model to file %s", argv[2]); return -1; } ROS_INFO("Saved %s", argv[2]); return 0; } ros-image-common-1.11.13/camera_calibration_parsers/src/parse.cpp000066400000000000000000000061331336567436300250150ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #include "camera_calibration_parsers/parse.h" #include "camera_calibration_parsers/parse_ini.h" #include "camera_calibration_parsers/parse_yml.h" #include namespace camera_calibration_parsers { bool writeCalibration(const std::string& file_name, const std::string& camera_name, const sensor_msgs::CameraInfo& cam_info) { if (boost::iends_with(file_name, ".ini")) return writeCalibrationIni(file_name, camera_name, cam_info); if (boost::iends_with(file_name, ".yml") || boost::iends_with(file_name, ".yaml")) return writeCalibrationYml(file_name, camera_name, cam_info); return false; } bool readCalibration(const std::string& file_name, std::string& camera_name, sensor_msgs::CameraInfo& cam_info) { if (boost::iends_with(file_name, ".ini")) return readCalibrationIni(file_name, camera_name, cam_info); if (boost::iends_with(file_name, ".yml") || boost::iends_with(file_name, ".yaml")) return readCalibrationYml(file_name, camera_name, cam_info); return false; } bool parseCalibration(const std::string& buffer, const std::string& format, std::string& camera_name, sensor_msgs::CameraInfo& cam_info) { if (format != "ini") return false; return parseCalibrationIni(buffer, camera_name, cam_info); } } //namespace camera_calibration_parsers ros-image-common-1.11.13/camera_calibration_parsers/src/parse_ini.cpp000066400000000000000000000176321336567436300256620ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #include "camera_calibration_parsers/parse_ini.h" #include #include #include #include #include #include #include #include #include #include #include #include namespace camera_calibration_parsers { /// @todo Move to new spirit using namespace BOOST_SPIRIT_CLASSIC_NS; /// \cond struct SimpleMatrix { int rows; int cols; const double* data; SimpleMatrix(int rows, int cols, const double* data) : rows(rows), cols(cols), data(data) {} }; std::ostream& operator << (std::ostream& out, const SimpleMatrix& m) { for (int i = 0; i < m.rows; ++i) { for (int j = 0; j < m.cols; ++j) { out << m.data[m.cols*i+j] << " "; } out << std::endl; } return out; } /// \endcond bool writeCalibrationIni(std::ostream& out, const std::string& camera_name, const sensor_msgs::CameraInfo& cam_info) { // Videre INI format is legacy, only supports plumb bob distortion model. if (cam_info.distortion_model != sensor_msgs::distortion_models::PLUMB_BOB || cam_info.D.size() != 5) { ROS_ERROR("Videre INI format can only save calibrations using the plumb bob distortion model. " "Use the YAML format instead.\n" "\tdistortion_model = '%s', expected '%s'\n" "\tD.size() = %d, expected 5", cam_info.distortion_model.c_str(), sensor_msgs::distortion_models::PLUMB_BOB.c_str(), (int)cam_info.D.size()); return false; } out.precision(5); out << std::fixed; out << "# Camera intrinsics\n\n"; /// @todo time? out << "[image]\n\n"; out << "width\n" << cam_info.width << "\n\n"; out << "height\n" << cam_info.height << "\n\n"; out << "[" << camera_name << "]\n\n"; out << "camera matrix\n" << SimpleMatrix(3, 3, &cam_info.K[0]); out << "\ndistortion\n" << SimpleMatrix(1, 5, &cam_info.D[0]); out << "\n\nrectification\n" << SimpleMatrix(3, 3, &cam_info.R[0]); out << "\nprojection\n" << SimpleMatrix(3, 4, &cam_info.P[0]); return true; } bool writeCalibrationIni(const std::string& file_name, const std::string& camera_name, const sensor_msgs::CameraInfo& cam_info) { boost::filesystem::path dir(boost::filesystem::path(file_name).parent_path()); if (!dir.empty() && !boost::filesystem::exists(dir) && !boost::filesystem::create_directories(dir)){ ROS_ERROR("Unable to create directory for camera calibration file [%s]", dir.c_str()); } std::ofstream out(file_name.c_str()); if (!out.is_open()) { ROS_ERROR("Unable to open camera calibration file [%s] for writing", file_name.c_str()); return false; } return writeCalibrationIni(out, camera_name, cam_info); } /// \cond // Semantic action to store a sequence of values in an array template struct ArrayAssignActor { ArrayAssignActor(T* start) : ptr_(start) {} void operator()(T val) const { *ptr_++ = val; } mutable T* ptr_; }; // Semantic action generator template ArrayAssignActor array_assign_a(T* start) { return ArrayAssignActor(start); } template bool parseCalibrationIniRange(Iterator first, Iterator last, std::string& camera_name, sensor_msgs::CameraInfo& cam_info) { cam_info.D.clear(); // We don't actually use the [externals] info, but it's part of the format bool have_externals = false; double trans[3], rot[3]; /// @todo separate grammar out into separate function // Image section (width, height) BOOST_AUTO(image, str_p("[image]") >> "width" >> uint_p[assign_a(cam_info.width)] >> "height" >> uint_p[assign_a(cam_info.height)] ); // Optional externals section BOOST_AUTO(externals, str_p("[externals]") >> "translation" >> repeat_p(3)[real_p[array_assign_a(trans)]] >> "rotation" >> repeat_p(3)[real_p[array_assign_a(rot)]] ); // Parser to save name of camera section BOOST_AUTO(name, confix_p('[', (*anychar_p)[assign_a(camera_name)], ']')); // Camera section (intrinsics) BOOST_AUTO(camera, name >> "camera matrix" >> repeat_p(9)[real_p[array_assign_a(&cam_info.K[0])]] >> "distortion" >> *(real_p[push_back_a(cam_info.D)]) >> "rectification" >> repeat_p(9)[real_p[array_assign_a(&cam_info.R[0])]] >> "projection" >> repeat_p(12)[real_p[array_assign_a(&cam_info.P[0])]] ); // Full grammar BOOST_AUTO(ini_grammar, image >> !externals[assign_a(have_externals, true)] >> camera); // Skip whitespace and line comments BOOST_AUTO(skip, space_p | comment_p('#')); parse_info info = parse(first, last, ini_grammar, skip); // Figure out the distortion model if (cam_info.D.size() == 5) cam_info.distortion_model = sensor_msgs::distortion_models::PLUMB_BOB; else if (cam_info.D.size() == 8) cam_info.distortion_model = sensor_msgs::distortion_models::RATIONAL_POLYNOMIAL; return info.hit; } /// \endcond bool readCalibrationIni(std::istream& in, std::string& camera_name, sensor_msgs::CameraInfo& cam_info) { std::istream_iterator first(in), last; return parseCalibrationIniRange(first, last, camera_name, cam_info); } bool readCalibrationIni(const std::string& file_name, std::string& camera_name, sensor_msgs::CameraInfo& cam_info) { typedef file_iterator Iterator; Iterator first(file_name); if (!first) { ROS_INFO("Unable to open camera calibration file [%s]", file_name.c_str()); return false; } Iterator last = first.make_end(); return parseCalibrationIniRange(first, last, camera_name, cam_info); } bool parseCalibrationIni(const std::string& buffer, std::string& camera_name, sensor_msgs::CameraInfo& cam_info) { return parseCalibrationIniRange(buffer.begin(), buffer.end(), camera_name, cam_info); } } //namespace camera_calibration_parsers ros-image-common-1.11.13/camera_calibration_parsers/src/parse_wrapper.cpp000066400000000000000000000060441336567436300265560ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #include "camera_calibration_parsers/parse.h" #include "camera_calibration_parsers/parse_wrapper.h" #include #include namespace camera_calibration_parsers { /* Write a ROS message into a serialized string. * @from https://github.com/galou/python_bindings_tutorial/blob/master/src/add_two_ints_wrapper.cpp#L27 */ template std::string to_python(const M& msg) { size_t serial_size = ros::serialization::serializationLength(msg); boost::shared_array buffer(new uint8_t[serial_size]); ros::serialization::OStream stream(buffer.get(), serial_size); ros::serialization::serialize(stream, msg); std::string str_msg; str_msg.reserve(serial_size); for (size_t i = 0; i < serial_size; ++i) { str_msg.push_back(buffer[i]); } return str_msg; } // Wrapper for readCalibration() boost::python::tuple readCalibrationWrapper(const std::string& file_name) { std::string camera_name; sensor_msgs::CameraInfo camera_info; bool result = readCalibration(file_name, camera_name, camera_info); std::string cam_info = to_python(camera_info); return boost::python::make_tuple(result, camera_name, cam_info); } BOOST_PYTHON_MODULE(camera_calibration_parsers_wrapper) { boost::python::def("__readCalibrationWrapper", readCalibrationWrapper, boost::python::args("file_name"), ""); } } //namespace camera_calibration_parsers ros-image-common-1.11.13/camera_calibration_parsers/src/parse_yml.cpp000066400000000000000000000201351336567436300256740ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #include "camera_calibration_parsers/parse_yml.h" #include #include #include #include #include #include #include #include namespace camera_calibration_parsers { /// \cond static const char CAM_YML_NAME[] = "camera_name"; static const char WIDTH_YML_NAME[] = "image_width"; static const char HEIGHT_YML_NAME[] = "image_height"; static const char K_YML_NAME[] = "camera_matrix"; static const char D_YML_NAME[] = "distortion_coefficients"; static const char R_YML_NAME[] = "rectification_matrix"; static const char P_YML_NAME[] = "projection_matrix"; static const char DMODEL_YML_NAME[] = "distortion_model"; struct SimpleMatrix { int rows; int cols; double* data; SimpleMatrix(int rows, int cols, double* data) : rows(rows), cols(cols), data(data) {} }; YAML::Emitter& operator << (YAML::Emitter& out, const SimpleMatrix& m) { out << YAML::BeginMap; out << YAML::Key << "rows" << YAML::Value << m.rows; out << YAML::Key << "cols" << YAML::Value << m.cols; //out << YAML::Key << "dt" << YAML::Value << "d"; // OpenCV data type specifier out << YAML::Key << "data" << YAML::Value; out << YAML::Flow; out << YAML::BeginSeq; for (int i = 0; i < m.rows*m.cols; ++i) out << m.data[i]; out << YAML::EndSeq; out << YAML::EndMap; return out; } #ifdef HAVE_NEW_YAMLCPP template void operator >> (const YAML::Node& node, T& i) { i = node.as(); } #endif void operator >> (const YAML::Node& node, SimpleMatrix& m) { int rows, cols; node["rows"] >> rows; assert(rows == m.rows); node["cols"] >> cols; assert(cols == m.cols); const YAML::Node& data = node["data"]; for (int i = 0; i < rows*cols; ++i) data[i] >> m.data[i]; } /// \endcond bool writeCalibrationYml(std::ostream& out, const std::string& camera_name, const sensor_msgs::CameraInfo& cam_info) { YAML::Emitter emitter; emitter << YAML::BeginMap; #if 0 // Calibration time /// @todo Emitting the time breaks yaml-cpp on reading for some reason time_t raw_time; time( &raw_time ); emitter << YAML::Key << "calibration_time"; emitter << YAML::Value << asctime(localtime(&raw_time)); #endif // Image dimensions emitter << YAML::Key << WIDTH_YML_NAME << YAML::Value << (int)cam_info.width; emitter << YAML::Key << HEIGHT_YML_NAME << YAML::Value << (int)cam_info.height; // Camera name and intrinsics emitter << YAML::Key << CAM_YML_NAME << YAML::Value << camera_name; emitter << YAML::Key << K_YML_NAME << YAML::Value << SimpleMatrix(3, 3, const_cast(&cam_info.K[0])); emitter << YAML::Key << DMODEL_YML_NAME << YAML::Value << cam_info.distortion_model; emitter << YAML::Key << D_YML_NAME << YAML::Value << SimpleMatrix(1, cam_info.D.size(), const_cast(&cam_info.D[0])); emitter << YAML::Key << R_YML_NAME << YAML::Value << SimpleMatrix(3, 3, const_cast(&cam_info.R[0])); emitter << YAML::Key << P_YML_NAME << YAML::Value << SimpleMatrix(3, 4, const_cast(&cam_info.P[0])); emitter << YAML::EndMap; out << emitter.c_str(); return true; } bool writeCalibrationYml(const std::string& file_name, const std::string& camera_name, const sensor_msgs::CameraInfo& cam_info) { boost::filesystem::path dir(boost::filesystem::path(file_name).parent_path()); if (!dir.empty() && !boost::filesystem::exists(dir) && !boost::filesystem::create_directories(dir)){ ROS_ERROR("Unable to create directory for camera calibration file [%s]", dir.c_str()); } std::ofstream out(file_name.c_str()); if (!out.is_open()) { ROS_ERROR("Unable to open camera calibration file [%s] for writing", file_name.c_str()); return false; } return writeCalibrationYml(out, camera_name, cam_info); } bool readCalibrationYml(std::istream& in, std::string& camera_name, sensor_msgs::CameraInfo& cam_info) { try { #ifdef HAVE_NEW_YAMLCPP YAML::Node doc = YAML::Load(in); if (doc[CAM_YML_NAME]) doc[CAM_YML_NAME] >> camera_name; else camera_name = "unknown"; #else YAML::Parser parser(in); if (!parser) { ROS_ERROR("Unable to create YAML parser for camera calibration"); return false; } YAML::Node doc; parser.GetNextDocument(doc); if (const YAML::Node* name_node = doc.FindValue(CAM_YML_NAME)) *name_node >> camera_name; else camera_name = "unknown"; #endif doc[WIDTH_YML_NAME] >> cam_info.width; doc[HEIGHT_YML_NAME] >> cam_info.height; // Read in fixed-size matrices SimpleMatrix K_(3, 3, &cam_info.K[0]); doc[K_YML_NAME] >> K_; SimpleMatrix R_(3, 3, &cam_info.R[0]); doc[R_YML_NAME] >> R_; SimpleMatrix P_(3, 4, &cam_info.P[0]); doc[P_YML_NAME] >> P_; // Different distortion models may have different numbers of parameters #ifdef HAVE_NEW_YAMLCPP if (doc[DMODEL_YML_NAME]) { doc[DMODEL_YML_NAME] >> cam_info.distortion_model; } #else if (const YAML::Node* model_node = doc.FindValue(DMODEL_YML_NAME)) { *model_node >> cam_info.distortion_model; } #endif else { // Assume plumb bob for backwards compatibility cam_info.distortion_model = sensor_msgs::distortion_models::PLUMB_BOB; ROS_WARN("Camera calibration file did not specify distortion model, assuming plumb bob"); } const YAML::Node& D_node = doc[D_YML_NAME]; int D_rows, D_cols; D_node["rows"] >> D_rows; D_node["cols"] >> D_cols; const YAML::Node& D_data = D_node["data"]; cam_info.D.resize(D_rows*D_cols); for (int i = 0; i < D_rows*D_cols; ++i) D_data[i] >> cam_info.D[i]; return true; } catch (YAML::Exception& e) { ROS_ERROR("Exception parsing YAML camera calibration:\n%s", e.what()); return false; } } bool readCalibrationYml(const std::string& file_name, std::string& camera_name, sensor_msgs::CameraInfo& cam_info) { std::ifstream fin(file_name.c_str()); if (!fin.good()) { ROS_INFO("Unable to open camera calibration file [%s]", file_name.c_str()); return false; } bool success = readCalibrationYml(fin, camera_name, cam_info); if (!success) ROS_ERROR("Failed to parse camera calibration from file [%s]", file_name.c_str()); return success; } } //namespace camera_calibration_parsers ros-image-common-1.11.13/camera_calibration_parsers/test/000077500000000000000000000000001336567436300233645ustar00rootroot00000000000000ros-image-common-1.11.13/camera_calibration_parsers/test/CMakeLists.txt000066400000000000000000000002161336567436300261230ustar00rootroot00000000000000file(COPY calib5.ini calib8.ini DESTINATION ${CATKIN_DEVEL_PREFIX}/${CATKIN_PACKAGE_SHARE_DESTINATION}/test) catkin_add_nosetests(parser.py) ros-image-common-1.11.13/camera_calibration_parsers/test/calib5.ini000066400000000000000000000006601336567436300252260ustar00rootroot00000000000000[image] width 640 height 480 [mono_left] camera matrix 369.344588 0.000000 320.739078 0.000000 367.154330 203.592450 0.000000 0.000000 1.000000 distortion 0.189544 -0.018229 -0.000630 0.000054 -0.000212 rectification 1.000000 0.000000 0.000000 0.000000 1.000000 0.000000 0.000000 0.000000 1.000000 projection 262.927429 0.000000 320.984481 0.000000 0.000000 302.056213 188.592437 0.000000 0.000000 0.000000 1.000000 0.000000 ros-image-common-1.11.13/camera_calibration_parsers/test/calib8.ini000066400000000000000000000007141336567436300252310ustar00rootroot00000000000000[image] width 640 height 480 [mono_left] camera matrix 369.344588 0.000000 320.739078 0.000000 367.154330 203.592450 0.000000 0.000000 1.000000 distortion 0.189544 -0.018229 -0.000630 0.000054 -0.000212 0.543582 -0.027892 0.000000 rectification 1.000000 0.000000 0.000000 0.000000 1.000000 0.000000 0.000000 0.000000 1.000000 projection 262.927429 0.000000 320.984481 0.000000 0.000000 302.056213 188.592437 0.000000 0.000000 0.000000 1.000000 0.000000 ros-image-common-1.11.13/camera_calibration_parsers/test/parser.py000066400000000000000000000055071336567436300252410ustar00rootroot00000000000000#!/usr/bin/env python # # Software License Agreement (BSD License) # # Copyright (c) 2009, Willow Garage, Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of the Willow Garage nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. import rosunit import subprocess import unittest import os from camera_calibration_parsers import readCalibration class TestParser(unittest.TestCase): def test_ini(self): for files in [('calib5.ini', 'calib5.yaml'), ('calib8.ini', 'calib8.yaml')]: for dir in [ '', './']: p = subprocess.Popen('rosrun camera_calibration_parsers convert $(rospack find camera_calibration_parsers)/test/%s %s%s' % (files[0], dir, files[1]), shell=True, stderr=subprocess.PIPE) out, err = p.communicate() self.assertEqual(err, '') def test_readCalibration(self): script_dir = os.path.dirname(os.path.realpath(__file__)) camera_name, camera_info = readCalibration(os.path.join(script_dir, 'calib5.ini')) self.assertEqual(camera_name, 'mono_left') self.assertEqual(camera_info.height, 480) self.assertEqual(camera_info.width, 640) self.assertEqual(camera_info.P[0], 262.927429) camera_name, camera_info = readCalibration(os.path.join(script_dir, 'calib8.ini')) self.assertEqual(camera_info.distortion_model, 'rational_polynomial') if __name__ == '__main__': rosunit.unitrun('camera_calibration_parsers', 'parser', TestParser) ros-image-common-1.11.13/camera_info_manager/000077500000000000000000000000001336567436300210045ustar00rootroot00000000000000ros-image-common-1.11.13/camera_info_manager/CHANGELOG.rst000066400000000000000000000131711336567436300230300ustar00rootroot00000000000000^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Changelog for package camera_info_manager ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1.11.13 (2017-11-05) -------------------- * Fix the find_package(catkin) redundancy * Add a dependency between the test and the test executable * Add camera_calibration_parsers dependency to camera_info_manager * Contributors: Max Schettler, Vincent Rabaud 1.11.12 (2017-01-29) -------------------- * 1.11.11 * update changelogs * Return empty CameraInfo when !ros::ok() * Contributors: Enrique Fernandez, Vincent Rabaud 1.11.11 (2016-09-24) -------------------- * Return empty CameraInfo when !ros::ok() * Contributors: Enrique Fernandez 1.11.10 (2016-01-19) -------------------- 1.11.9 (2016-01-17) ------------------- 1.11.8 (2015-11-29) ------------------- * fix compilation on Fedora, fixes `#42 `_ * Contributors: Vincent Rabaud 1.11.7 (2015-07-28) ------------------- 1.11.6 (2015-07-16) ------------------- * simplify target_link_libraries That should fix `#35 `_ * Contributors: Vincent Rabaud 1.11.5 (2015-05-14) ------------------- 1.11.4 (2014-09-21) ------------------- 1.11.3 (2014-05-19) ------------------- * Add public member function to manually set camera info (`#19 `_) * make rostest in CMakeLists optional (`ros/rosdistro#3010 `_) * Contributors: Jack O'Quin, Jonathan Bohren, Lukas Bulwahn 1.11.2 (2014-02-13) ------------------- 1.11.1 (2014-01-26 02:33) ------------------------- * check for CATKIN_ENABLE_TESTING * Contributors: Lukas Bulwahn 1.11.0 (2013-07-20 12:23) ------------------------- 1.10.5 (2014-01-26 02:34) ------------------------- 1.10.4 (2013-07-20 11:42) ------------------------- * add Jack as maintainer * Contributors: Vincent Rabaud 1.10.3 (2013-02-21 05:33) ------------------------- * add gtest libraries linkage * Contributors: Vincent Rabaud 1.10.2 (2013-02-21 04:48) ------------------------- * fix the rostest dependency * Contributors: Vincent Rabaud 1.10.1 (2013-02-21 04:16) ------------------------- * fix catkin gtest and rostest problem * fix unit test dependencies * Removed duplicated test dependancy Test dependencies should never duplicate build or run dependencies. * Contributors: Aaron Blasdel, Jack O'Quin 1.10.0 (2013-01-13) ------------------- * fix the urls * Contributors: Vincent Rabaud 1.9.22 (2012-12-16) ------------------- 1.9.21 (2012-12-14) ------------------- * Updated package.xml file(s) to handle new catkin buildtool_depend requirement * Contributors: mirzashah 1.9.20 (2012-12-04) ------------------- 1.9.19 (2012-11-08) ------------------- 1.9.18 (2012-11-06) ------------------- * remove the brief attribute * Contributors: Vincent Rabaud 1.9.17 (2012-10-30 19:32) ------------------------- 1.9.16 (2012-10-30 09:10) ------------------------- 1.9.15 (2012-10-13 08:43) ------------------------- * fix bad folder/libraries * Contributors: Vincent Rabaud 1.9.14 (2012-10-13 01:07) ------------------------- 1.9.13 (2012-10-06) ------------------- 1.9.12 (2012-10-04) ------------------- 1.9.11 (2012-10-02 02:56) ------------------------- * add missing rostest dependency * Contributors: Vincent Rabaud 1.9.10 (2012-10-02 02:42) ------------------------- * fix bad dependency * Contributors: Vincent Rabaud 1.9.9 (2012-10-01) ------------------ * fix dependencies * Contributors: Vincent Rabaud 1.9.8 (2012-09-30) ------------------ * add catkin as a dependency * comply to the catkin API * Contributors: Vincent Rabaud 1.9.7 (2012-09-18 11:39) ------------------------ * add missing linkage * Contributors: Vincent Rabaud 1.9.6 (2012-09-18 11:07) ------------------------ 1.9.5 (2012-09-13) ------------------ * install the include directories * Contributors: Vincent Rabaud 1.9.4 (2012-09-12 23:37) ------------------------ 1.9.3 (2012-09-12 20:44) ------------------------ 1.9.2 (2012-09-10) ------------------ * fix build issues * Contributors: Vincent Rabaud 1.9.1 (2012-09-07 15:33) ------------------------ * make the libraries public * Contributors: Vincent Rabaud 1.9.0 (2012-09-07 13:03) ------------------------ * API documentation review update * suppress misleading camera_info_manager error messages [`#5273 `_] * remove deprecated global CameraInfoManager symbol for Fuerte (`#4971 `_) * Revert to using boost::mutex, not boost::recursive_mutex. * Hack saveCalibrationFile() to stat() the containing directory and attempt to create it if necessary. Test for this case. * Reload camera info when camera name changes. * Implement most new Electric API changes, with test cases. * Add ${ROS_HOME} expansion, with unit test cases. Do not use "$$" for a single '$', look for "${" instead. * Use case-insensitive comparisons for parsing URL tags (`#4761 `_). Add unit test cases to cover this. Add unit test case for camera name containing video mode. * add test for resolving an empty URL * Deprecate use of global CameraInfoManager symbol in E-turtle (`#4786 `_). Modify unit tests accordingly. * provide camera_info_manager namespace, fixes `#4760 `_ * Add support for "package://" URLs. * Fixed tests to work with new CameraInfo. * Moved image_common from camera_drivers. * Contributors: Vincent Rabaud, blaise, Jack O'Quin, mihelich ros-image-common-1.11.13/camera_info_manager/CMakeLists.txt000066400000000000000000000023631336567436300235500ustar00rootroot00000000000000cmake_minimum_required(VERSION 2.8) project(camera_info_manager) find_package(catkin REQUIRED COMPONENTS camera_calibration_parsers image_transport roscpp roslib sensor_msgs) find_package(Boost) catkin_package(INCLUDE_DIRS include LIBRARIES ${PROJECT_NAME} CATKIN_DEPENDS camera_calibration_parsers DEPENDS Boost roscpp sensor_msgs ) include_directories(${catkin_INCLUDE_DIRS}) include_directories(include) # add a library add_library(${PROJECT_NAME} src/camera_info_manager.cpp) target_link_libraries(${PROJECT_NAME} ${catkin_LIBRARIES}) install(TARGETS ${PROJECT_NAME} DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} COMPONENT main ) install(DIRECTORY include/${PROJECT_NAME}/ DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} ) if(CATKIN_ENABLE_TESTING) find_package(rostest) # Unit test uses gtest, but needs rostest to create a ROS environment. # Hence, it must be created as a normal executable, not using # catkin_add_gtest() which runs an additional test without rostest. add_executable(unit_test tests/unit_test.cpp) target_link_libraries(unit_test ${PROJECT_NAME} ${GTEST_LIBRARIES} ${catkin_LIBRARIES}) add_rostest(tests/unit_test.test DEPENDENCIES unit_test) endif() ros-image-common-1.11.13/camera_info_manager/include/000077500000000000000000000000001336567436300224275ustar00rootroot00000000000000ros-image-common-1.11.13/camera_info_manager/include/camera_info_manager/000077500000000000000000000000001336567436300263645ustar00rootroot00000000000000ros-image-common-1.11.13/camera_info_manager/include/camera_info_manager/camera_info_manager.h000066400000000000000000000223751336567436300325030ustar00rootroot00000000000000/* -*- mode: C++ -*- */ /* $Id$ */ /********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2010-2012 Jack O'Quin * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the author nor other contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #ifndef _CAMERA_INFO_MANAGER_H_ #define _CAMERA_INFO_MANAGER_H_ #include #include #include #include /** @file @brief CameraInfo Manager interface @author Jack O'Quin */ namespace camera_info_manager { /** @brief CameraInfo Manager class Provides CameraInfo, handles the sensor_msgs/SetCameraInfo service requests, saves and restores sensor_msgs/CameraInfo data. @par ROS Service - @b set_camera_info (sensor_msgs/SetCameraInfo) stores calibration information Typically, these service requests are made by a calibration package, such as: - http://www.ros.org/wiki/camera_calibration The calling node @em must invoke ros::spin() or ros::spinOnce() in some thread, so CameraInfoManager can handle arriving service requests. @par Camera Name The device driver sets a camera name via the CameraInfoManager::CameraInfoManager constructor or the setCameraName() method. This name is written when CameraInfo is saved, and checked when data are loaded, with a warning logged if the name read does not match. Syntax: a camera name contains any combination of alphabetic, numeric and '_' characters. Case is significant. Camera drivers may use any syntactically valid name they please. Where possible, it is best for the name to be unique to the device, such as a GUID, or the make, model and serial number. Any parameters that affect calibration, such as resolution, focus, zoom, etc., may also be included in the name, uniquely identifying each CameraInfo file. Beginning with Electric Emys, the camera name can be resolved as part of the URL, allowing direct access to device-specific calibration information. @par Uniform Resource Locator The location for getting and saving calibration data is expressed by Uniform Resource Locator. The driver defines a URL via the CameraInfoManager::CameraInfoManager constructor or the loadCameraInfo() method. Many drivers provide a @c ~camera_info_url parameter so users may customize this URL, but that is handled outside this class. Typically, cameras store calibration information in a file, which can be in any format supported by @c camera_calibration_parsers. Currently, that includes YAML and Videre INI files, identified by their .yaml or .ini extensions as shown in the examples. These file formats are described here: - http://www.ros.org/wiki/camera_calibration_parsers#File_formats Example URL syntax: - file:///full/path/to/local/file.yaml - file:///full/path/to/videre/file.ini - package://camera_info_manager/tests/test_calibration.yaml - package://ros_package_name/calibrations/camera3.yaml The @c file: URL specifies a full path name in the local system. The @c package: URL is handled the same as @c file:, except the path name is resolved relative to the location of the named ROS package, which @em must be reachable via @c $ROS_PACKAGE_PATH. Beginning with Electric Emys, the URL may contain substitution variables delimited by ${...}, including: - @c ${NAME} resolved to the current camera name defined by the device driver. - @c ${ROS_HOME} resolved to the @c $ROS_HOME environment variable if defined, ~/.ros if not. Resolution is done in a single pass through the URL string. Variable values containing substitutable strings are not resolved recursively. Unrecognized variable names are treated literally with no substitution, but an error is logged. Examples with variable substitution: - package://my_cameras/calibrations/${NAME}.yaml - file://${ROS_HOME}/camera_info/left_front_camera.yaml In C-turtle and Diamondback, if the URL was empty, no calibration data were loaded, and any data provided via `set_camera_info` would be stored in: - file:///tmp/calibration_${NAME}.yaml Beginning in Electric, the default URL changed to: - file://${ROS_HOME}/camera_info/${NAME}.yaml. If that file exists, its contents are used. Any new calibration will be stored there, missing parent directories being created if necessary and possible. @par Loading Calibration Data Prior to Fuerte, calibration information was loaded in the constructor, and again each time the URL or camera name was updated. This frequently caused logging of confusing and misleading error messages. Beginning in Fuerte, camera_info_manager loads nothing until the @c loadCameraInfo(), @c isCalibrated() or @c getCameraInfo() method is called. That suppresses bogus error messages, but allows (valid) load errors to occur during the first @c getCameraInfo(), or @c isCalibrated(). To avoid that, do an explicit @c loadCameraInfo() first. */ class CameraInfoManager { public: CameraInfoManager(ros::NodeHandle nh, const std::string &cname="camera", const std::string &url=""); sensor_msgs::CameraInfo getCameraInfo(void); bool isCalibrated(void); bool loadCameraInfo(const std::string &url); std::string resolveURL(const std::string &url, const std::string &cname); bool setCameraName(const std::string &cname); bool setCameraInfo(const sensor_msgs::CameraInfo &camera_info); bool validateURL(const std::string &url); private: // recognized URL types typedef enum { // supported URLs URL_empty = 0, // empty string URL_file, // file: URL_package, // package: // URLs not supported URL_invalid, // anything >= is invalid URL_flash, // flash: } url_type_t; // private methods std::string getPackageFileName(const std::string &url); bool loadCalibration(const std::string &url, const std::string &cname); bool loadCalibrationFile(const std::string &filename, const std::string &cname); url_type_t parseURL(const std::string &url); bool saveCalibration(const sensor_msgs::CameraInfo &new_info, const std::string &url, const std::string &cname); bool saveCalibrationFile(const sensor_msgs::CameraInfo &new_info, const std::string &filename, const std::string &cname); bool setCameraInfoService(sensor_msgs::SetCameraInfo::Request &req, sensor_msgs::SetCameraInfo::Response &rsp); /** @brief mutual exclusion lock for private data * * This non-recursive mutex is only held for a short time while * accessing or changing private class variables. To avoid * deadlocks and contention, it is never held during I/O or while * invoking a callback. Most private methods operate on copies of * class variables, keeping the mutex hold time short. */ boost::mutex mutex_; // private data ros::NodeHandle nh_; ///< node handle for service ros::ServiceServer info_service_; ///< set_camera_info service std::string camera_name_; ///< camera name std::string url_; ///< URL for calibration data sensor_msgs::CameraInfo cam_info_; ///< current CameraInfo bool loaded_cam_info_; ///< cam_info_ load attempted }; // class CameraInfoManager }; // namespace camera_info_manager #endif // _CAMERA_INFO_MANAGER_H_ ros-image-common-1.11.13/camera_info_manager/mainpage.dox000066400000000000000000000001721336567436300233010ustar00rootroot00000000000000/** \mainpage \htmlinclude manifest.html \section codeapi C++ API See: . */ ros-image-common-1.11.13/camera_info_manager/package.xml000066400000000000000000000026001336567436300231170ustar00rootroot00000000000000 camera_info_manager 1.11.13 This package provides a C++ interface for camera calibration information. It provides CameraInfo, and handles SetCameraInfo service requests, saving and restoring the camera calibration data. Jack O'Quin Jack O'Quin Vincent Rabaud BSD http://ros.org/wiki/camera_info_manager https://github.com/ros-perception/image_common/issues https://github.com/ros-perception/image_common catkin boost camera_calibration_parsers image_transport roscpp roslib rostest sensor_msgs boost camera_calibration_parsers image_transport roscpp roslib sensor_msgs gtest ros-image-common-1.11.13/camera_info_manager/src/000077500000000000000000000000001336567436300215735ustar00rootroot00000000000000ros-image-common-1.11.13/camera_info_manager/src/camera_info_manager.cpp000066400000000000000000000456071336567436300262500ustar00rootroot00000000000000/* $Id$ */ /********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2010-2012 Jack O'Quin * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the author nor other contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #include #include #include #include #include #include #include #include #include #include #include "camera_info_manager/camera_info_manager.h" /** @file @brief CameraInfo Manager implementation Provides CameraInfo, handles the SetCameraInfo service requests, saves and restores sensor_msgs/CameraInfo data. @author Jack O'Quin */ namespace camera_info_manager { using namespace camera_calibration_parsers; /** URL to use when no other is defined. */ const std::string default_camera_info_url = "file://${ROS_HOME}/camera_info/${NAME}.yaml"; /** Constructor * * @param nh node handle, normally for the driver's streaming name * space ("camera"). The service name is relative to this * handle. Nodes supporting multiple cameras may use * subordinate names, like "left/camera" and "right/camera". * @param cname default camera name * @param url default Uniform Resource Locator for loading and saving data. */ CameraInfoManager::CameraInfoManager(ros::NodeHandle nh, const std::string &cname, const std::string &url): nh_(nh), camera_name_(cname), url_(url), loaded_cam_info_(false) { // register callback for camera calibration service request info_service_ = nh_.advertiseService("set_camera_info", &CameraInfoManager::setCameraInfoService, this); } /** Get the current CameraInfo data. * * If CameraInfo has not yet been loaded, an attempt must be made * here. To avoid that, ensure that loadCameraInfo() ran previously. * If the load is attempted but fails, an empty CameraInfo will be * supplied. * * The matrices are all zeros if no calibration is available. The * image pipeline handles that as uncalibrated data. * * @warning The caller @em must fill in the message Header of the * CameraInfo returned. The time stamp and frame_id should * normally be the same as the corresponding Image message * Header fields. */ sensor_msgs::CameraInfo CameraInfoManager::getCameraInfo(void) { while (ros::ok()) { std::string cname; std::string url; { boost::mutex::scoped_lock lock_(mutex_); if (loaded_cam_info_) { return cam_info_; // all done } // load being attempted now loaded_cam_info_ = true; // copy the name and URL strings url = url_; cname = camera_name_; } // release the lock // attempt load without the lock, it is not recursive loadCalibration(url, cname); } return sensor_msgs::CameraInfo(); } /** Get file name corresponding to a @c package: URL. * * @param url a copy of the Uniform Resource Locator * @return file name if package found, "" otherwise */ std::string CameraInfoManager::getPackageFileName(const std::string &url) { ROS_DEBUG_STREAM("camera calibration URL: " << url); // Scan URL from after "package://" until next '/' and extract // package name. The parseURL() already checked that it's present. size_t prefix_len = std::string("package://").length(); size_t rest = url.find('/', prefix_len); std::string package(url.substr(prefix_len, rest - prefix_len)); // Look up the ROS package path name. std::string pkgPath(ros::package::getPath(package)); if (pkgPath.empty()) // package not found? { ROS_WARN_STREAM("unknown package: " << package << " (ignored)"); return pkgPath; } else { // Construct file name from package location and remainder of URL. return pkgPath + url.substr(rest); } } /** Is the current CameraInfo calibrated? * * If CameraInfo has not yet been loaded, an attempt must be made * here. To avoid that, ensure that loadCameraInfo() ran previously. * If the load failed, CameraInfo will be empty and this predicate * will return false. * * @return true if the current CameraInfo is calibrated. */ bool CameraInfoManager::isCalibrated(void) { while (true) { std::string cname; std::string url; { boost::mutex::scoped_lock lock_(mutex_); if (loaded_cam_info_) { return (cam_info_.K[0] != 0.0); } // load being attempted now loaded_cam_info_ = true; // copy the name and URL strings url = url_; cname = camera_name_; } // release the lock // attempt load without the lock, it is not recursive loadCalibration(url, cname); } } /** Load CameraInfo calibration data (if any). * * @pre mutex_ unlocked * * @param url a copy of the Uniform Resource Locator * @param cname is a copy of the camera_name_ * @return true if URL contains calibration data. * * sets cam_info_, if successful */ bool CameraInfoManager::loadCalibration(const std::string &url, const std::string &cname) { bool success = false; // return value const std::string resURL(resolveURL(url, cname)); url_type_t url_type = parseURL(resURL); if (url_type != URL_empty) { ROS_INFO_STREAM("camera calibration URL: " << resURL); } switch (url_type) { case URL_empty: { ROS_INFO("using default calibration URL"); success = loadCalibration(default_camera_info_url, cname); break; } case URL_file: { success = loadCalibrationFile(resURL.substr(7), cname); break; } case URL_flash: { ROS_WARN("[CameraInfoManager] reading from flash not implemented yet"); break; } case URL_package: { std::string filename(getPackageFileName(resURL)); if (!filename.empty()) success = loadCalibrationFile(filename, cname); break; } default: { ROS_ERROR_STREAM("Invalid camera calibration URL: " << resURL); break; } } return success; } /** Load CameraInfo calibration data from a file. * * @pre mutex_ unlocked * * @param filename containing CameraInfo to read * @param cname is a copy of the camera_name_ * @return true if URL contains calibration data. * * Sets cam_info_, if successful */ bool CameraInfoManager::loadCalibrationFile(const std::string &filename, const std::string &cname) { bool success = false; ROS_DEBUG_STREAM("reading camera calibration from " << filename); std::string cam_name; sensor_msgs::CameraInfo cam_info; if (readCalibration(filename, cam_name, cam_info)) { if (cname != cam_name) { ROS_WARN_STREAM("[" << cname << "] does not match name " << cam_name << " in file " << filename); } success = true; { // lock only while updating cam_info_ boost::mutex::scoped_lock lock(mutex_); cam_info_ = cam_info; } } else { ROS_WARN_STREAM("Camera calibration file " << filename << " not found."); } return success; } /** Set a new URL and load its calibration data (if any). * * If multiple threads call this method simultaneously with different * URLs, there is no guarantee which will prevail. * * @param url new Uniform Resource Locator for CameraInfo. * @return true if new URL contains calibration data. * * @post @c loaded_cam_info_ true (meaning a load was attempted, even * if it failed); @c cam_info_ updated, if successful. */ bool CameraInfoManager::loadCameraInfo(const std::string &url) { std::string cname; { boost::mutex::scoped_lock lock(mutex_); url_ = url; cname = camera_name_; loaded_cam_info_ = true; } // load using copies of the parameters, no need to hold the lock return loadCalibration(url, cname); } /** Resolve Uniform Resource Locator string. * * @param url a copy of the Uniform Resource Locator, which may * include ${...} substitution variables. * @param cname is a copy of the camera_name_ * * @return a copy of the URL with any variable information resolved. */ std::string CameraInfoManager::resolveURL(const std::string &url, const std::string &cname) { std::string resolved; size_t rest = 0; while (true) { // find the next '$' in the URL string size_t dollar = url.find('$', rest); if (dollar >= url.length()) { // no more variables left in the URL resolved += url.substr(rest); break; } // copy characters up to the next '$' resolved += url.substr(rest, dollar-rest); if (url.substr(dollar+1, 1) != "{") { // no '{' follows, so keep the '$' resolved += "$"; } else if (url.substr(dollar+1, 6) == "{NAME}") { // substitute camera name resolved += cname; dollar += 6; } else if (url.substr(dollar+1, 10) == "{ROS_HOME}") { // substitute $ROS_HOME std::string ros_home; char *ros_home_env; if ((ros_home_env = getenv("ROS_HOME"))) { // use environment variable ros_home = ros_home_env; } else if ((ros_home_env = getenv("HOME"))) { // use "$HOME/.ros" ros_home = ros_home_env; ros_home += "/.ros"; } resolved += ros_home; dollar += 10; } else { // not a valid substitution variable ROS_ERROR_STREAM("[CameraInfoManager]" " invalid URL substitution (not resolved): " << url); resolved += "$"; // keep the bogus '$' } // look for next '$' rest = dollar + 1; } return resolved; } /** Parse calibration Uniform Resource Locator. * * @param url string to parse * @return URL type * * @note Recognized but unsupported URL types have enum values >= URL_invalid. */ CameraInfoManager::url_type_t CameraInfoManager::parseURL(const std::string &url) { if (url == "") { return URL_empty; } if (boost::iequals(url.substr(0, 8), "file:///")) { return URL_file; } if (boost::iequals(url.substr(0, 9), "flash:///")) { return URL_flash; } if (boost::iequals(url.substr(0, 10), "package://")) { // look for a '/' following the package name, make sure it is // there, the name is not empty, and something follows it size_t rest = url.find('/', 10); if (rest < url.length()-1 && rest > 10) return URL_package; } return URL_invalid; } /** Save CameraInfo calibration data. * * @pre mutex_ unlocked * * @param new_info contains CameraInfo to save * @param url is a copy of the URL storage location (if empty, use * @c file://${ROS_HOME}/camera_info/${NAME}.yaml) * @param cname is a copy of the camera_name_ * @return true, if successful */ bool CameraInfoManager::saveCalibration(const sensor_msgs::CameraInfo &new_info, const std::string &url, const std::string &cname) { bool success = false; const std::string resURL(resolveURL(url, cname)); switch (parseURL(resURL)) { case URL_empty: { // store using default file name success = saveCalibration(new_info, default_camera_info_url, cname); break; } case URL_file: { success = saveCalibrationFile(new_info, resURL.substr(7), cname); break; } case URL_package: { std::string filename(getPackageFileName(resURL)); if (!filename.empty()) success = saveCalibrationFile(new_info, filename, cname); break; } default: { // invalid URL, save to default location ROS_ERROR_STREAM("invalid url: " << resURL << " (ignored)"); success = saveCalibration(new_info, default_camera_info_url, cname); break; } } return success; } /** Save CameraInfo calibration data to a file. * * @pre mutex_ unlocked * * @param new_info contains CameraInfo to save * @param filename is local file to store data * @param cname is a copy of the camera_name_ * @return true, if successful */ bool CameraInfoManager::saveCalibrationFile(const sensor_msgs::CameraInfo &new_info, const std::string &filename, const std::string &cname) { ROS_INFO_STREAM("writing calibration data to " << filename); // isolate the name of the containing directory size_t last_slash = filename.rfind('/'); if (last_slash >= filename.length()) { // No slash in the name. This should never happen, the URL // parser ensures there is at least one '/' at the beginning. ROS_ERROR_STREAM("filename [" << filename << "] has no '/'"); return false; // not a valid URL } // make sure the directory exists and is writable std::string dirname(filename.substr(0, last_slash+1)); struct stat stat_data; int rc = stat(dirname.c_str(), &stat_data); if (rc != 0) { if (errno == ENOENT) { // directory does not exist, try to create it and its parents std::string command("mkdir -p " + dirname); rc = system(command.c_str()); if (rc != 0) { // mkdir failed ROS_ERROR_STREAM("unable to create path to directory [" << dirname << "]"); return false; } } else { // not accessible, or something screwy ROS_ERROR_STREAM("directory [" << dirname << "] not accessible"); return false; } } else if (!S_ISDIR(stat_data.st_mode)) { // dirname exists but is not a directory ROS_ERROR_STREAM("[" << dirname << "] is not a directory"); return false; } // Directory exists and is accessible. Permissions might still be bad. // Currently, writeCalibration() always returns true no matter what // (ros-pkg ticket #5010). return writeCalibration(filename, cname, new_info); } /** Callback for SetCameraInfo request. * * Always updates cam_info_ class variable, even if save fails. * * @param req SetCameraInfo request message * @param rsp SetCameraInfo response message * @return true if message handled */ bool CameraInfoManager::setCameraInfoService(sensor_msgs::SetCameraInfo::Request &req, sensor_msgs::SetCameraInfo::Response &rsp) { // copies of class variables needed for saving calibration std::string url_copy; std::string cname; { boost::mutex::scoped_lock lock(mutex_); cam_info_ = req.camera_info; url_copy = url_; cname = camera_name_; loaded_cam_info_ = true; } if (!nh_.ok()) { ROS_ERROR("set_camera_info service called, but driver not running."); rsp.status_message = "Camera driver not running."; rsp.success = false; return false; } rsp.success = saveCalibration(req.camera_info, url_copy, cname); if (!rsp.success) rsp.status_message = "Error storing camera calibration."; return true; } /** Set a new camera name. * * @param cname new camera name to use for saving calibration data * * @return true if new name has valid syntax; valid names contain only * alphabetic, numeric, or '_' characters. * * @post @c cam_name_ updated, if valid; since it may affect the URL, * @c cam_info_ will be reloaded before being used again. */ bool CameraInfoManager::setCameraName(const std::string &cname) { // the camera name may not be empty if (cname.empty()) return false; // validate the camera name characters for (unsigned i = 0; i < cname.size(); ++i) { if (!isalnum(cname[i]) && cname[i] != '_') return false; } // The name is valid, so update our private copy. Since the new // name might cause the existing URL to resolve somewhere else, // force @c cam_info_ to be reloaded before being used again. { boost::mutex::scoped_lock lock(mutex_); camera_name_ = cname; loaded_cam_info_ = false; } return true; } /** Set the camera info manually * * @param camera_info new camera calibration data * * @return true if new camera info is set * * @post @c cam_info_ updated, if valid; */ bool CameraInfoManager::setCameraInfo(const sensor_msgs::CameraInfo &camera_info) { boost::mutex::scoped_lock lock(mutex_); cam_info_ = camera_info; loaded_cam_info_ = true; return true; } /** Validate URL syntax. * * @param url Uniform Resource Locator to check * * @return true if URL syntax is supported by CameraInfoManager * (although the resource need not actually exist) */ bool CameraInfoManager::validateURL(const std::string &url) { std::string cname; // copy of camera name { boost::mutex::scoped_lock lock(mutex_); cname = camera_name_; } // release the lock url_type_t url_type = parseURL(resolveURL(url, cname)); return (url_type < URL_invalid); } } // namespace camera_info_manager ros-image-common-1.11.13/camera_info_manager/tests/000077500000000000000000000000001336567436300221465ustar00rootroot00000000000000ros-image-common-1.11.13/camera_info_manager/tests/test_calibration.yaml000066400000000000000000000007301336567436300263600ustar00rootroot00000000000000image_width: 640 image_height: 480 camera_name: 08144361026320a0 camera_matrix: rows: 3 cols: 3 data: [1168.68, 0, 295.015, 0, 1169.01, 252.247, 0, 0, 1] distortion_model: plumb_bob distortion_coefficients: rows: 1 cols: 5 data: [-1.04482, 1.59252, -0.0196308, 0.0287906, 0] rectification_matrix: rows: 3 cols: 3 data: [1, 0, 0, 0, 1, 0, 0, 0, 1] projection_matrix: rows: 3 cols: 4 data: [1168.68, 0, 295.015, 0, 0, 1169.01, 252.247, 0, 0, 0, 1, 0]ros-image-common-1.11.13/camera_info_manager/tests/unit_test.cpp000066400000000000000000000545561336567436300247070ustar00rootroot00000000000000/* $Id$ */ /********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2010 Jack O'Quin * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the author nor other contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #include #include #include #include #include "camera_info_manager/camera_info_manager.h" #include #include #include /////////////////////////////////////////////////////////////// // global test data /////////////////////////////////////////////////////////////// namespace { const std::string g_package_name("camera_info_manager"); const std::string g_test_name("test_calibration"); const std::string g_package_filename("/tests/" + g_test_name +".yaml"); const std::string g_package_url("package://" + g_package_name + g_package_filename); const std::string g_package_name_url("package://" + g_package_name + "/tests/${NAME}.yaml"); const std::string g_default_url("file://${ROS_HOME}/camera_info/${NAME}.yaml"); const std::string g_camera_name("08144361026320a0"); } /////////////////////////////////////////////////////////////// // utility functions /////////////////////////////////////////////////////////////// // compare CameraInfo fields that are saved and loaded for calibration void compare_calibration(const sensor_msgs::CameraInfo &exp, const sensor_msgs::CameraInfo &ci) { // check image size EXPECT_EQ(exp.width, ci.width); EXPECT_EQ(exp.height, ci.height); // check distortion coefficients EXPECT_EQ(exp.distortion_model, ci.distortion_model); EXPECT_EQ(exp.D.size(), ci.D.size()); for (unsigned i = 0; i < ci.D.size(); ++i) { EXPECT_EQ(exp.D[i], ci.D[i]); } // check camera matrix for (unsigned i = 0; i < ci.K.size(); ++i) { EXPECT_EQ(exp.K[i], ci.K[i]); } // check rectification matrix for (unsigned i = 0; i < ci.R.size(); ++i) { EXPECT_EQ(exp.R[i], ci.R[i]); } // check projection matrix for (unsigned i = 0; i < ci.P.size(); ++i) { EXPECT_EQ(exp.P[i], ci.P[i]); } } // make sure this file does not exist void delete_file(std::string filename) { int rc = unlink(filename.c_str()); if (rc != 0) { if (errno != ENOENT) ROS_INFO_STREAM("unexpected unlink() error: " << errno); } } void delete_default_file(void) { std::string ros_home("/tmp"); setenv("ROS_HOME", ros_home.c_str(), true); std::string tmpFile(ros_home + "/camera_info/camera.yaml"); delete_file(tmpFile); } void do_system(const std::string &command) { int rc = system(command.c_str()); if (rc) std::cout << command << " returns " << rc; } void delete_tmp_camera_info_directory(void) { do_system(std::string("rm -rf /tmp/camera_info")); } void make_tmp_camera_info_directory(void) { do_system(std::string("mkdir -p /tmp/camera_info")); } // These data must match the contents of test_calibration.yaml. sensor_msgs::CameraInfo expected_calibration(void) { sensor_msgs::CameraInfo ci; ci.width = 640u; ci.height = 480u; // set distortion coefficients ci.distortion_model = sensor_msgs::distortion_models::PLUMB_BOB; ci.D.resize(5); ci.D[0] = -1.04482; ci.D[1] = 1.59252; ci.D[2] = -0.0196308; ci.D[3] = 0.0287906; ci.D[4] = 0.0; // set camera matrix ci.K[0] = 1168.68; ci.K[1] = 0.0; ci.K[2] = 295.015; ci.K[3] = 0.0; ci.K[4] = 1169.01; ci.K[5] = 252.247; ci.K[6] = 0.0; ci.K[7] = 0.0; ci.K[8] = 1.0; // set rectification matrix ci.R[0] = 1.0; ci.R[1] = 0.0; ci.R[2] = 0.0; ci.R[3] = 0.0; ci.R[4] = 1.0; ci.R[5] = 0.0; ci.R[6] = 0.0; ci.R[7] = 0.0; ci.R[8] = 1.0; // set projection matrix ci.P[0] = ci.K[0]; ci.P[1] = ci.K[1]; ci.P[2] = ci.K[2]; ci.P[3] = 0.0; ci.P[4] = ci.K[3]; ci.P[5] = ci.K[4]; ci.P[6] = ci.K[5]; ci.P[7] = 0.0; ci.P[8] = ci.K[6]; ci.P[9] = ci.K[7]; ci.P[10] = ci.K[8]; ci.P[11] = 0.0; return ci; } // issue SetCameraInfo service request bool set_calibration(ros::NodeHandle node, const sensor_msgs::CameraInfo &calib) { ros::ServiceClient client = node.serviceClient("set_camera_info"); sensor_msgs::SetCameraInfo set_camera_info; set_camera_info.request.camera_info = calib; bool success; EXPECT_TRUE((success = client.call(set_camera_info))); return success; } // resolve URL string, result should be as expected void check_url_substitution(ros::NodeHandle node, const std::string &url, const std::string &exp_url, const std::string &camera_name) { camera_info_manager::CameraInfoManager cinfo(node, camera_name, url); std::string sub_url = cinfo.resolveURL(url, camera_name); EXPECT_EQ(sub_url, exp_url); } /////////////////////////////////////////////////////////////// // Test cases /////////////////////////////////////////////////////////////// // Test that valid camera names are accepted TEST(CameraName, validNames) { ros::NodeHandle node; camera_info_manager::CameraInfoManager cinfo(node); EXPECT_TRUE(cinfo.setCameraName(std::string("a"))); EXPECT_TRUE(cinfo.setCameraName(std::string("1"))); EXPECT_TRUE(cinfo.setCameraName(std::string("_"))); EXPECT_TRUE(cinfo.setCameraName(std::string("abcdefghijklmnopqrstuvwxyz"))); EXPECT_TRUE(cinfo.setCameraName(std::string("ABCDEFGHIJKLMNOPQRSTUVWXYZ"))); EXPECT_TRUE(cinfo.setCameraName(std::string("0123456789"))); EXPECT_TRUE(cinfo.setCameraName(std::string("0123456789abcdef"))); EXPECT_TRUE(cinfo.setCameraName(std::string("A1"))); EXPECT_TRUE(cinfo.setCameraName(std::string("9z"))); EXPECT_TRUE(cinfo.setCameraName(std::string("08144361026320a0_640x480_mono8"))); } // Test that invalid camera names are rejected TEST(CameraName, invalidNames) { ros::NodeHandle node; camera_info_manager::CameraInfoManager cinfo(node); EXPECT_FALSE(cinfo.setCameraName(std::string(""))); EXPECT_FALSE(cinfo.setCameraName(std::string("-21"))); EXPECT_FALSE(cinfo.setCameraName(std::string("C++"))); EXPECT_FALSE(cinfo.setCameraName(std::string("file:///tmp/url.yaml"))); EXPECT_FALSE(cinfo.setCameraName(std::string("file://${INVALID}/xxx.yaml"))); } // Test that valid URLs are accepted TEST(UrlValidation, validURLs) { ros::NodeHandle node; camera_info_manager::CameraInfoManager cinfo(node); EXPECT_TRUE(cinfo.validateURL(std::string(""))); EXPECT_TRUE(cinfo.validateURL(std::string("file:///"))); EXPECT_TRUE(cinfo.validateURL(std::string("file:///tmp/url.yaml"))); EXPECT_TRUE(cinfo.validateURL(std::string("File:///tmp/url.ini"))); EXPECT_TRUE(cinfo.validateURL(std::string("FILE:///tmp/url.yaml"))); EXPECT_TRUE(cinfo.validateURL(g_default_url)); EXPECT_TRUE(cinfo.validateURL(g_package_url)); EXPECT_TRUE(cinfo.validateURL(std::string("package://no_such_package/calibration.yaml"))); EXPECT_TRUE(cinfo.validateURL(std::string("packAge://camera_info_manager/x"))); } // Test that invalid URLs are rejected TEST(UrlValidation, invalidURLs) { ros::NodeHandle node; camera_info_manager::CameraInfoManager cinfo(node); EXPECT_FALSE(cinfo.validateURL(std::string("file://"))); EXPECT_FALSE(cinfo.validateURL(std::string("flash:///"))); EXPECT_FALSE(cinfo.validateURL(std::string("html://ros.org/wiki/camera_info_manager"))); EXPECT_FALSE(cinfo.validateURL(std::string("package://"))); EXPECT_FALSE(cinfo.validateURL(std::string("package:///"))); EXPECT_FALSE(cinfo.validateURL(std::string("package://calibration.yaml"))); EXPECT_FALSE(cinfo.validateURL(std::string("package://camera_info_manager/"))); } // Test ability to provide uncalibrated CameraInfo TEST(GetInfo, uncalibrated) { ros::NodeHandle node; delete_default_file(); camera_info_manager::CameraInfoManager cinfo(node); EXPECT_FALSE(cinfo.isCalibrated()); sensor_msgs::CameraInfo ci(cinfo.getCameraInfo()); sensor_msgs::CameraInfo exp; compare_calibration(exp, ci); } // Test ability to load calibrated CameraInfo TEST(GetInfo, calibrated) { ros::NodeHandle node; delete_default_file(); camera_info_manager::CameraInfoManager cinfo(node); EXPECT_FALSE(cinfo.isCalibrated()); std::string pkgPath(ros::package::getPath(g_package_name)); std::string url("file://" + pkgPath + "/tests/test_calibration.yaml"); EXPECT_TRUE(cinfo.loadCameraInfo(url)); EXPECT_TRUE(cinfo.isCalibrated()); sensor_msgs::CameraInfo ci(cinfo.getCameraInfo()); sensor_msgs::CameraInfo exp(expected_calibration()); compare_calibration(exp, ci); } // Test ability to load calibrated CameraInfo from package TEST(GetInfo, fromPackage) { ros::NodeHandle node; camera_info_manager::CameraInfoManager cinfo(node); EXPECT_TRUE(cinfo.loadCameraInfo(g_package_url)); EXPECT_TRUE(cinfo.isCalibrated()); sensor_msgs::CameraInfo ci(cinfo.getCameraInfo()); sensor_msgs::CameraInfo exp(expected_calibration()); compare_calibration(exp, ci); } // Test ability to access named calibrated CameraInfo from package TEST(GetInfo, fromPackageWithName) { ros::NodeHandle node; camera_info_manager::CameraInfoManager cinfo(node, g_test_name, g_package_name_url); EXPECT_TRUE(cinfo.isCalibrated()); sensor_msgs::CameraInfo ci(cinfo.getCameraInfo()); sensor_msgs::CameraInfo exp(expected_calibration()); compare_calibration(exp, ci); } // Test load of unresolved "package:" URL files TEST(GetInfo, unresolvedLoads) { ros::NodeHandle node; camera_info_manager::CameraInfoManager cinfo(node); EXPECT_FALSE(cinfo.loadCameraInfo(std::string("package://"))); EXPECT_FALSE(cinfo.isCalibrated()); EXPECT_FALSE(cinfo.loadCameraInfo(std::string("package:///calibration.yaml"))); EXPECT_FALSE(cinfo.isCalibrated()); EXPECT_FALSE(cinfo.loadCameraInfo(std::string("package://no_such_package/calibration.yaml"))); EXPECT_FALSE(cinfo.isCalibrated()); EXPECT_FALSE(cinfo.loadCameraInfo(std::string("package://camera_info_manager/no_such_file.yaml"))); EXPECT_FALSE(cinfo.isCalibrated()); } // Test load of "package:" URL after changing name TEST(GetInfo, nameChange) { ros::NodeHandle node; const std::string missing_file("no_such_file"); // first declare using non-existent camera name camera_info_manager::CameraInfoManager cinfo(node, missing_file, g_package_name_url); EXPECT_FALSE(cinfo.isCalibrated()); // set name so it resolves to a test file that does exist EXPECT_TRUE(cinfo.setCameraName(g_test_name)); EXPECT_TRUE(cinfo.isCalibrated()); sensor_msgs::CameraInfo ci(cinfo.getCameraInfo()); sensor_msgs::CameraInfo exp(expected_calibration()); compare_calibration(exp, ci); } // Test load of invalid CameraInfo URLs TEST(GetInfo, invalidLoads) { ros::NodeHandle node; camera_info_manager::CameraInfoManager cinfo(node); EXPECT_FALSE(cinfo.loadCameraInfo(std::string("flash:///"))); EXPECT_FALSE(cinfo.isCalibrated()); EXPECT_FALSE(cinfo.loadCameraInfo(std::string("html://ros.org/wiki/camera_info_manager"))); EXPECT_FALSE(cinfo.isCalibrated()); sensor_msgs::CameraInfo ci(cinfo.getCameraInfo()); sensor_msgs::CameraInfo exp; compare_calibration(exp, ci); } // Test ability to set CameraInfo directly TEST(SetInfo, setCameraInfo) { ros::NodeHandle node; camera_info_manager::CameraInfoManager cinfo(node); // issue calibration service request sensor_msgs::CameraInfo exp(expected_calibration()); bool success = cinfo.setCameraInfo(exp); EXPECT_TRUE(success); // only check results if the service succeeded, avoiding confusing // and redundant failure messages if (success) { // check that it worked EXPECT_TRUE(cinfo.isCalibrated()); sensor_msgs::CameraInfo ci = cinfo.getCameraInfo(); compare_calibration(exp, ci); } } // Test ability to set calibrated CameraInfo TEST(SetInfo, setCalibration) { ros::NodeHandle node; camera_info_manager::CameraInfoManager cinfo(node); // issue calibration service request sensor_msgs::CameraInfo exp(expected_calibration()); bool success = set_calibration(node, exp); // only check results if the service succeeded, avoiding confusing // and redundant failure messages if (success) { // check that it worked EXPECT_TRUE(cinfo.isCalibrated()); sensor_msgs::CameraInfo ci = cinfo.getCameraInfo(); compare_calibration(exp, ci); } } // Test ability to save calibrated CameraInfo in default URL TEST(SetInfo, saveCalibrationDefault) { ros::NodeHandle node; sensor_msgs::CameraInfo exp(expected_calibration()); bool success; // Set ${ROS_HOME} to /tmp, then delete the /tmp/camera_info // directory and everything in it. setenv("ROS_HOME", "/tmp", true); delete_tmp_camera_info_directory(); { // create instance to save calibrated data camera_info_manager::CameraInfoManager cinfo(node); EXPECT_FALSE(cinfo.isCalibrated()); // issue calibration service request success = set_calibration(node, exp); EXPECT_TRUE(cinfo.isCalibrated()); } // only check results if the service succeeded, avoiding confusing // and redundant failure messages if (success) { // create a new instance to load saved calibration camera_info_manager::CameraInfoManager cinfo2(node); EXPECT_TRUE(cinfo2.isCalibrated()); if (cinfo2.isCalibrated()) { sensor_msgs::CameraInfo ci(cinfo2.getCameraInfo()); compare_calibration(exp, ci); } } } // Test ability to save calibrated CameraInfo to default location with // explicit camera name TEST(SetInfo, saveCalibrationCameraName) { ros::NodeHandle node; sensor_msgs::CameraInfo exp(expected_calibration()); bool success; // set ${ROS_HOME} to /tmp, delete the calibration file std::string ros_home("/tmp"); setenv("ROS_HOME", ros_home.c_str(), true); std::string tmpFile(ros_home + "/camera_info/" + g_camera_name + ".yaml"); delete_file(tmpFile); { // create instance to save calibrated data camera_info_manager::CameraInfoManager cinfo(node, g_camera_name); success = set_calibration(node, exp); EXPECT_TRUE(cinfo.isCalibrated()); } // only check results if the service succeeded, avoiding confusing // and redundant failure messages if (success) { // create a new instance to load saved calibration camera_info_manager::CameraInfoManager cinfo2(node); std::string url = "file://" + tmpFile; cinfo2.loadCameraInfo(std::string(url)); EXPECT_TRUE(cinfo2.isCalibrated()); if (cinfo2.isCalibrated()) { sensor_msgs::CameraInfo ci(cinfo2.getCameraInfo()); compare_calibration(exp, ci); } } } // Test ability to save calibrated CameraInfo in a file TEST(SetInfo, saveCalibrationFile) { return; ros::NodeHandle node; sensor_msgs::CameraInfo exp(expected_calibration()); std::string cname("camera"); std::string tmpFile("/tmp/camera_info_manager_calibration_test.yaml"); std::string url = "file://" + tmpFile; bool success; // first, delete the file delete_file(tmpFile); { // create instance to save calibrated data camera_info_manager::CameraInfoManager cinfo(node, cname, url); success = set_calibration(node, exp); EXPECT_TRUE(cinfo.isCalibrated()); } // only check results if the service succeeded, avoiding confusing // and redundant failure messages if (success) { // create a new instance to load saved calibration camera_info_manager::CameraInfoManager cinfo2(node, cname, url); EXPECT_TRUE(cinfo2.isCalibrated()); if (cinfo2.isCalibrated()) { sensor_msgs::CameraInfo ci(cinfo2.getCameraInfo()); compare_calibration(exp, ci); } } } // Test ability to save calibrated CameraInfo in a package // (needs write access). TEST(SetInfo, saveCalibrationPackage) { ros::NodeHandle node; sensor_msgs::CameraInfo exp(expected_calibration()); std::string pkgPath(ros::package::getPath(g_package_name)); std::string filename(pkgPath + g_package_filename); bool success; // first, delete the file delete_file(filename); { // create instance to save calibrated data camera_info_manager::CameraInfoManager cinfo(node, g_camera_name, g_package_url); success = set_calibration(node, exp); EXPECT_TRUE(cinfo.isCalibrated()); } // only check results if the service succeeded, avoiding confusing // and redundant failure messages if (success) { // create a new instance to load saved calibration camera_info_manager::CameraInfoManager cinfo2(node, g_camera_name, g_package_url); EXPECT_TRUE(cinfo2.isCalibrated()); if (cinfo2.isCalibrated()) { sensor_msgs::CameraInfo ci(cinfo2.getCameraInfo()); compare_calibration(exp, ci); } } } TEST(UrlSubstitution, cameraName) { ros::NodeHandle node; std::string name_url; std::string exp_url; // resolve a GUID camera name name_url = "package://" + g_package_name + "/tests/${NAME}.yaml"; exp_url = "package://" + g_package_name + "/tests/" + g_camera_name + ".yaml"; check_url_substitution(node, name_url, exp_url, g_camera_name); // substitute camera name "test" name_url = "package://" + g_package_name + "/tests/${NAME}_calibration.yaml"; std::string test_name("test"); exp_url = "package://" + g_package_name + "/tests/" + test_name + "_calibration.yaml"; check_url_substitution(node, name_url, exp_url, test_name); // with an '_' in the name test_name = "camera_1024x768"; exp_url = "package://" + g_package_name + "/tests/" + test_name + "_calibration.yaml"; check_url_substitution(node, name_url, exp_url, test_name); // substitute empty camera name name_url = "package://" + g_package_name + "/tests/${NAME}_calibration.yaml"; std::string empty_name(""); exp_url = "package://" + g_package_name + "/tests/" + empty_name + "_calibration.yaml"; check_url_substitution(node, name_url, exp_url, empty_name); // substitute test camera calibration from this package check_url_substitution(node, g_package_name_url, g_package_url, g_test_name); } TEST(UrlSubstitution, rosHome) { ros::NodeHandle node; std::string name_url; std::string exp_url; char *home_env = getenv("HOME"); std::string home(home_env); // resolve ${ROS_HOME} with environment variable undefined unsetenv("ROS_HOME"); name_url = "file://${ROS_HOME}/camera_info/test_camera.yaml"; exp_url = "file://" + home + "/.ros/camera_info/test_camera.yaml"; check_url_substitution(node, name_url, exp_url, g_camera_name); // resolve ${ROS_HOME} with environment variable defined setenv("ROS_HOME", "/my/ros/home", true); name_url = "file://${ROS_HOME}/camera_info/test_camera.yaml"; exp_url = "file:///my/ros/home/camera_info/test_camera.yaml"; check_url_substitution(node, name_url, exp_url, g_camera_name); } TEST(UrlSubstitution, unmatchedDollarSigns) { ros::NodeHandle node; // test for "$$" in the URL (NAME should be resolved) std::string name_url("file:///tmp/$${NAME}.yaml"); std::string exp_url("file:///tmp/$" + g_camera_name + ".yaml"); check_url_substitution(node, name_url, exp_url, g_camera_name); // test for "$" in middle of string name_url = "file:///$whatever.yaml"; check_url_substitution(node, name_url, name_url, g_camera_name); // test for "$$" in middle of string name_url = "file:///something$$whatever.yaml"; check_url_substitution(node, name_url, name_url, g_camera_name); // test for "$$" at end of string name_url = "file:///$$"; check_url_substitution(node, name_url, name_url, g_camera_name); } TEST(UrlSubstitution, emptyURL) { // test that empty URL is handled correctly ros::NodeHandle node; std::string empty_url(""); check_url_substitution(node, empty_url, empty_url, g_camera_name); } TEST(UrlSubstitution, invalidVariables) { ros::NodeHandle node; std::string name_url; // missing "{...}" name_url = "file:///tmp/$NAME.yaml"; check_url_substitution(node, name_url, name_url, g_camera_name); // invalid substitution variable name name_url = "file:///tmp/${INVALID}/calibration.yaml"; check_url_substitution(node, name_url, name_url, g_camera_name); // truncated substitution variable name_url = "file:///tmp/${NAME"; check_url_substitution(node, name_url, name_url, g_camera_name); // missing substitution variable name_url = "file:///tmp/${}"; check_url_substitution(node, name_url, name_url, g_camera_name); // no exception thrown for single "$" at end of string name_url = "file:///$"; check_url_substitution(node, name_url, name_url, g_camera_name); } // Run all the tests that were declared with TEST() int main(int argc, char **argv) { ros::init(argc, argv, "camera_info_manager_unit_test"); testing::InitGoogleTest(&argc, argv); // create asynchronous thread for handling service requests ros::AsyncSpinner spinner(1); spinner.start(); // run the tests in this thread return RUN_ALL_TESTS(); } ros-image-common-1.11.13/camera_info_manager/tests/unit_test.test000066400000000000000000000007011336567436300250630ustar00rootroot00000000000000 ros-image-common-1.11.13/image_common/000077500000000000000000000000001336567436300175015ustar00rootroot00000000000000ros-image-common-1.11.13/image_common/CHANGELOG.rst000066400000000000000000000044331336567436300215260ustar00rootroot00000000000000^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Changelog for package image_common ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1.11.13 (2017-11-05) -------------------- 1.11.12 (2017-01-29) -------------------- * 1.11.11 * update changelogs * Contributors: Vincent Rabaud 1.11.11 (2016-09-24) -------------------- 1.11.10 (2016-01-19) -------------------- 1.11.9 (2016-01-17) ------------------- 1.11.8 (2015-11-29) ------------------- 1.11.7 (2015-07-28) ------------------- 1.11.6 (2015-07-16) ------------------- 1.11.5 (2015-05-14) ------------------- 1.11.4 (2014-09-21) ------------------- 1.11.3 (2014-05-19) ------------------- 1.11.2 (2014-02-13) ------------------- 1.11.1 (2014-01-26 02:33) ------------------------- 1.11.0 (2013-07-20 12:23) ------------------------- 1.10.5 (2014-01-26 02:34) ------------------------- 1.10.4 (2013-07-20 11:42) ------------------------- * add Jack as maintainer * comply to REP 0127 * Contributors: Vincent Rabaud 1.10.3 (2013-02-21 05:33) ------------------------- 1.10.2 (2013-02-21 04:48) ------------------------- 1.10.1 (2013-02-21 04:16) ------------------------- 1.10.0 (2013-01-13) ------------------- 1.9.22 (2012-12-16) ------------------- 1.9.21 (2012-12-14) ------------------- 1.9.20 (2012-12-04) ------------------- 1.9.19 (2012-11-08) ------------------- 1.9.18 (2012-11-06) ------------------- 1.9.17 (2012-10-30 19:32) ------------------------- 1.9.16 (2012-10-30 09:10) ------------------------- 1.9.15 (2012-10-13 08:43) ------------------------- 1.9.14 (2012-10-13 01:07) ------------------------- 1.9.13 (2012-10-06) ------------------- * add missing description * Contributors: Vincent Rabaud 1.9.12 (2012-10-04) ------------------- * define metapackage * Contributors: Vincent Rabaud 1.9.11 (2012-10-02 02:56) ------------------------- 1.9.10 (2012-10-02 02:42) ------------------------- 1.9.9 (2012-10-01) ------------------ 1.9.8 (2012-09-30) ------------------ 1.9.7 (2012-09-18 11:39) ------------------------ 1.9.6 (2012-09-18 11:07) ------------------------ 1.9.5 (2012-09-13) ------------------ 1.9.4 (2012-09-12 23:37) ------------------------ 1.9.3 (2012-09-12 20:44) ------------------------ 1.9.2 (2012-09-10) ------------------ 1.9.1 (2012-09-07 15:33) ------------------------ 1.9.0 (2012-09-07 13:03) ------------------------ ros-image-common-1.11.13/image_common/CMakeLists.txt000066400000000000000000000001571336567436300222440ustar00rootroot00000000000000cmake_minimum_required(VERSION 2.8.3) project(image_common) find_package(catkin REQUIRED) catkin_metapackage() ros-image-common-1.11.13/image_common/package.xml000066400000000000000000000016371336567436300216250ustar00rootroot00000000000000 image_common 1.11.13 Common code for working with images in ROS. Patrick Mihelich James Bowman Jack O'Quin Vincent Rabaud BSD http://www.ros.org/wiki/image_common https://github.com/ros-perception/image_common/issues https://github.com/ros-perception/image_common catkin camera_calibration_parsers camera_info_manager image_transport polled_camera ros-image-common-1.11.13/image_transport/000077500000000000000000000000001336567436300202455ustar00rootroot00000000000000ros-image-common-1.11.13/image_transport/CHANGELOG.rst000066400000000000000000000126571336567436300223010ustar00rootroot00000000000000^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Changelog for package image_transport ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1.11.13 (2017-11-05) -------------------- * Disable image publisher plugins by name (`#60 `_) * Disable publisher plugins by name * Now have per publisher blacklist instead of image_transport wide. * update to use non deprecated pluginlib macro * Extend documentation of `getCameraInfoTopic` Document the fact that the `base_topic` argument must be resolved in order to build the correct camera info topic. * Added cv::waitkey(10) for blank popup Without the cv::waitkey(10), it results in a blank popup which crashes/ leads to a black popup. This change corrects that problem. ROS Kinetic, Ubuntu 16.04.3 * Contributors: Aaditya Saraiya, Lucas Walter, Mikael Arguedas, Thibaud Chupin, Vincent Rabaud 1.11.12 (2017-01-29) -------------------- * Fix CMake of image_transport/tutorial and polled_camera Fix loads of problems with the CMakeLists. * image_transport/tutorial: Add dependency on generated msg Without this, build fails on Kinetic because ResizedImage.h has not been generated yet. * image_transport/tutorial: Add missing catkin_INCLUDE_DIRS Without this, compilation files on Kinetic because ros.h cannot be found. * 1.11.11 * update changelogs * Contributors: Martin Guenther, Vincent Rabaud 1.11.11 (2016-09-24) -------------------- 1.11.10 (2016-01-19) -------------------- 1.11.9 (2016-01-17) ------------------- * fix linkage in tutorials * Use $catkin_EXPORTED_TARGETS * Contributors: Jochen Sprickerhof, Vincent Rabaud 1.11.8 (2015-11-29) ------------------- 1.11.7 (2015-07-28) ------------------- 1.11.6 (2015-07-16) ------------------- 1.11.5 (2015-05-14) ------------------- * image_transport: fix CameraSubscriber shutdown (circular shared_ptr ref) CameraSubscriber uses a private boost::shared_ptr to share an impl object between copied instances. In CameraSubscriber::CameraSubscriber(), it handed this shared_ptr to boost::bind() and saved the created wall timer in the impl object, thus creating a circular reference. The impl object was therefore never freed. Fix that by passing a plain pointer to boost::bind(). * avoid a memory copy for the raw publisher * add a way to publish an image with only the data pointer * Make function inline to avoid duplicated names when linking statically * add plugin examples for the tutorial * update instructions for catkin * remove uselessly linked library fixes `#28 `_ * add a tutorial for image_transport * Contributors: Gary Servin, Max Schwarz, Vincent Rabaud 1.11.4 (2014-09-21) ------------------- 1.11.3 (2014-05-19) ------------------- 1.11.2 (2014-02-13) ------------------- 1.11.1 (2014-01-26 02:33) ------------------------- 1.11.0 (2013-07-20 12:23) ------------------------- 1.10.5 (2014-01-26 02:34) ------------------------- 1.10.4 (2013-07-20 11:42) ------------------------- * add Jack as maintainer * update my email address * Contributors: Vincent Rabaud 1.10.3 (2013-02-21 05:33) ------------------------- 1.10.2 (2013-02-21 04:48) ------------------------- 1.10.1 (2013-02-21 04:16) ------------------------- 1.10.0 (2013-01-13) ------------------- * fix the urls * use the pluginlib script to remove some warnings * added license headers to various cpp and h files * Contributors: Aaron Blasdel, Vincent Rabaud 1.9.22 (2012-12-16) ------------------- * get rid of the deprecated class_loader interface * Contributors: Vincent Rabaud 1.9.21 (2012-12-14) ------------------- * CMakeLists.txt clean up * Updated package.xml file(s) to handle new catkin buildtool_depend requirement * Contributors: William Woodall, mirzashah 1.9.20 (2012-12-04) ------------------- 1.9.19 (2012-11-08) ------------------- * add the right link libraries * Contributors: Vincent Rabaud 1.9.18 (2012-11-06) ------------------- * Isolated plugins into their own library to follow new class_loader/pluginlib guidelines. * remove the brief attribute * Contributors: Mirza Shah, Vincent Rabaud 1.9.17 (2012-10-30 19:32) ------------------------- 1.9.16 (2012-10-30 09:10) ------------------------- * add xml file * Contributors: Vincent Rabaud 1.9.15 (2012-10-13 08:43) ------------------------- * fix bad folder/libraries * Contributors: Vincent Rabaud 1.9.14 (2012-10-13 01:07) ------------------------- 1.9.13 (2012-10-06) ------------------- 1.9.12 (2012-10-04) ------------------- 1.9.11 (2012-10-02 02:56) ------------------------- 1.9.10 (2012-10-02 02:42) ------------------------- 1.9.9 (2012-10-01) ------------------ * fix dependencies * Contributors: Vincent Rabaud 1.9.8 (2012-09-30) ------------------ * add catkin as a dependency * comply to the catkin API * Contributors: Vincent Rabaud 1.9.7 (2012-09-18 11:39) ------------------------ 1.9.6 (2012-09-18 11:07) ------------------------ 1.9.5 (2012-09-13) ------------------ * install the include directories * Contributors: Vincent Rabaud 1.9.4 (2012-09-12 23:37) ------------------------ 1.9.3 (2012-09-12 20:44) ------------------------ 1.9.2 (2012-09-10) ------------------ 1.9.1 (2012-09-07 15:33) ------------------------ * make the libraries public * Contributors: Vincent Rabaud 1.9.0 (2012-09-07 13:03) ------------------------ * catkinize for Groovy * Initial image_common stack check-in, containing image_transport. * Contributors: Vincent Rabaud, gerkey, kwc, mihelich, pmihelich, straszheim, vrabaud ros-image-common-1.11.13/image_transport/CMakeLists.txt000066400000000000000000000032611336567436300230070ustar00rootroot00000000000000cmake_minimum_required(VERSION 2.8.3) project(image_transport) find_package(catkin REQUIRED COMPONENTS message_filters pluginlib rosconsole roscpp roslib sensor_msgs ) find_package(Boost REQUIRED) catkin_package( INCLUDE_DIRS include LIBRARIES ${PROJECT_NAME} DEPENDS message_filters pluginlib rosconsole roscpp roslib sensor_msgs ) include_directories(include ${catkin_INCLUDE_DIRS}) # Build libimage_transport add_library(${PROJECT_NAME} src/camera_common.cpp src/camera_publisher.cpp src/camera_subscriber.cpp src/image_transport.cpp src/publisher.cpp src/single_subscriber_publisher.cpp src/subscriber.cpp ) add_dependencies(${PROJECT_NAME} ${catkin_EXPORTED_TARGETS}) target_link_libraries(${PROJECT_NAME} ${Boost_LIBRARIES} ${catkin_LIBRARIES} ) # Build libimage_transport_plugins add_library(${PROJECT_NAME}_plugins src/manifest.cpp src/raw_publisher.cpp) target_link_libraries(${PROJECT_NAME}_plugins ${PROJECT_NAME}) install(TARGETS ${PROJECT_NAME} ${PROJECT_NAME}_plugins DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} COMPONENT main ) install(DIRECTORY include/${PROJECT_NAME}/ DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} ) # add two execs add_executable(republish src/republish.cpp) target_link_libraries(republish ${PROJECT_NAME}) add_executable(list_transports src/list_transports.cpp) target_link_libraries(list_transports ${PROJECT_NAME} ${catkin_LIBRARIES} ) install(TARGETS list_transports republish DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} ) # add xml file install(FILES default_plugins.xml DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} ) ros-image-common-1.11.13/image_transport/default_plugins.xml000066400000000000000000000011151336567436300241520ustar00rootroot00000000000000 This is the default publisher. It publishes the Image as-is on the base topic. This is the default pass-through subscriber for topics of type sensor_msgs/Image. ros-image-common-1.11.13/image_transport/include/000077500000000000000000000000001336567436300216705ustar00rootroot00000000000000ros-image-common-1.11.13/image_transport/include/image_transport/000077500000000000000000000000001336567436300250665ustar00rootroot00000000000000ros-image-common-1.11.13/image_transport/include/image_transport/camera_common.h000066400000000000000000000043051336567436300300410ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #ifndef IMAGE_TRANSPORT_CAMERA_COMMON_H #define IMAGE_TRANSPORT_CAMERA_COMMON_H #include namespace image_transport { /** * \brief Form the camera info topic name, sibling to the base topic. * * \note This function assumes that the name is completely resolved. If the \c * base_topic is remapped the resulting camera info topic will be incorrect. */ std::string getCameraInfoTopic(const std::string& base_topic); } //namespace image_transport #endif ros-image-common-1.11.13/image_transport/include/image_transport/camera_publisher.h000066400000000000000000000121441336567436300305460ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #ifndef IMAGE_TRANSPORT_CAMERA_PUBLISHER_H #define IMAGE_TRANSPORT_CAMERA_PUBLISHER_H #include #include #include #include "image_transport/single_subscriber_publisher.h" namespace image_transport { class ImageTransport; /** * \brief Manages advertisements for publishing camera images. * * CameraPublisher is a convenience class for publishing synchronized image and * camera info topics using the standard topic naming convention, where the info * topic name is "camera_info" in the same namespace as the base image topic. * * On the client side, CameraSubscriber simplifies subscribing to camera images. * * A CameraPublisher should always be created through a call to * ImageTransport::advertiseCamera(), or copied from one that was. * Once all copies of a specific CameraPublisher go out of scope, any subscriber callbacks * associated with that handle will stop being called. Once all CameraPublisher for a * given base topic go out of scope the topic (and all subtopics) will be unadvertised. */ class CameraPublisher { public: CameraPublisher() {} /*! * \brief Returns the number of subscribers that are currently connected to * this CameraPublisher. * * Returns max(image topic subscribers, info topic subscribers). */ uint32_t getNumSubscribers() const; /*! * \brief Returns the base (image) topic of this CameraPublisher. */ std::string getTopic() const; /** * \brief Returns the camera info topic of this CameraPublisher. */ std::string getInfoTopic() const; /*! * \brief Publish an (image, info) pair on the topics associated with this CameraPublisher. */ void publish(const sensor_msgs::Image& image, const sensor_msgs::CameraInfo& info) const; /*! * \brief Publish an (image, info) pair on the topics associated with this CameraPublisher. */ void publish(const sensor_msgs::ImageConstPtr& image, const sensor_msgs::CameraInfoConstPtr& info) const; /*! * \brief Publish an (image, info) pair with given timestamp on the topics associated with * this CameraPublisher. * * Convenience version, which sets the timestamps of both image and info to stamp before * publishing. */ void publish(sensor_msgs::Image& image, sensor_msgs::CameraInfo& info, ros::Time stamp) const; /*! * \brief Shutdown the advertisements associated with this Publisher. */ void shutdown(); operator void*() const; bool operator< (const CameraPublisher& rhs) const { return impl_ < rhs.impl_; } bool operator!=(const CameraPublisher& rhs) const { return impl_ != rhs.impl_; } bool operator==(const CameraPublisher& rhs) const { return impl_ == rhs.impl_; } private: CameraPublisher(ImageTransport& image_it, ros::NodeHandle& info_nh, const std::string& base_topic, uint32_t queue_size, const SubscriberStatusCallback& image_connect_cb, const SubscriberStatusCallback& image_disconnect_cb, const ros::SubscriberStatusCallback& info_connect_cb, const ros::SubscriberStatusCallback& info_disconnect_cb, const ros::VoidPtr& tracked_object, bool latch); struct Impl; typedef boost::shared_ptr ImplPtr; typedef boost::weak_ptr ImplWPtr; ImplPtr impl_; friend class ImageTransport; }; } //namespace image_transport #endif ros-image-common-1.11.13/image_transport/include/image_transport/camera_subscriber.h000066400000000000000000000104131336567436300307110ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #ifndef IMAGE_TRANSPORT_CAMERA_SUBSCRIBER_H #define IMAGE_TRANSPORT_CAMERA_SUBSCRIBER_H #include #include #include #include "image_transport/transport_hints.h" namespace image_transport { class ImageTransport; /** * \brief Manages a subscription callback on synchronized Image and CameraInfo topics. * * CameraSubscriber is the client-side counterpart to CameraPublisher, and assumes the * same topic naming convention. The callback is of type: \verbatim void callback(const sensor_msgs::ImageConstPtr&, const sensor_msgs::CameraInfoConstPtr&); \endverbatim * * A CameraSubscriber should always be created through a call to * ImageTransport::subscribeCamera(), or copied from one that was. * Once all copies of a specific CameraSubscriber go out of scope, the subscription callback * associated with that handle will stop being called. Once all CameraSubscriber for a given * topic go out of scope the topic will be unsubscribed. */ class CameraSubscriber { public: typedef boost::function Callback; CameraSubscriber() {} /** * \brief Get the base topic (on which the raw image is published). */ std::string getTopic() const; /** * \brief Get the camera info topic. */ std::string getInfoTopic() const; /** * \brief Returns the number of publishers this subscriber is connected to. */ uint32_t getNumPublishers() const; /** * \brief Returns the name of the transport being used. */ std::string getTransport() const; /** * \brief Unsubscribe the callback associated with this CameraSubscriber. */ void shutdown(); operator void*() const; bool operator< (const CameraSubscriber& rhs) const { return impl_ < rhs.impl_; } bool operator!=(const CameraSubscriber& rhs) const { return impl_ != rhs.impl_; } bool operator==(const CameraSubscriber& rhs) const { return impl_ == rhs.impl_; } private: CameraSubscriber(ImageTransport& image_it, ros::NodeHandle& info_nh, const std::string& base_topic, uint32_t queue_size, const Callback& callback, const ros::VoidPtr& tracked_object = ros::VoidPtr(), const TransportHints& transport_hints = TransportHints()); struct Impl; typedef boost::shared_ptr ImplPtr; typedef boost::weak_ptr ImplWPtr; ImplPtr impl_; friend class ImageTransport; }; } //namespace image_transport #endif ros-image-common-1.11.13/image_transport/include/image_transport/exception.h000066400000000000000000000051511336567436300272370ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #ifndef IMAGE_TRANSPORT_EXCEPTION_H #define IMAGE_TRANSPORT_EXCEPTION_H #include namespace image_transport { /** * \brief A base class for all image_transport exceptions inheriting from std::runtime_error. */ class Exception : public std::runtime_error { public: Exception(const std::string& message) : std::runtime_error(message) {} }; /** * \brief An exception class thrown when image_transport is unable to load a requested transport. */ class TransportLoadException : public Exception { public: TransportLoadException(const std::string& transport, const std::string& message) : Exception("Unable to load plugin for transport '" + transport + "', error string:\n" + message), transport_(transport.c_str()) { } std::string getTransport() const { return transport_; } protected: const char* transport_; }; } //namespace image_transport #endif ros-image-common-1.11.13/image_transport/include/image_transport/image_transport.h000066400000000000000000000215451336567436300304440ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #ifndef IMAGE_TRANSPORT_IMAGE_TRANSPORT_H #define IMAGE_TRANSPORT_IMAGE_TRANSPORT_H #include "image_transport/publisher.h" #include "image_transport/subscriber.h" #include "image_transport/camera_publisher.h" #include "image_transport/camera_subscriber.h" namespace image_transport { /** * \brief Advertise and subscribe to image topics. * * ImageTransport is analogous to ros::NodeHandle in that it contains advertise() and * subscribe() functions for creating advertisements and subscriptions of image topics. */ class ImageTransport { public: explicit ImageTransport(const ros::NodeHandle& nh); ~ImageTransport(); /*! * \brief Advertise an image topic, simple version. */ Publisher advertise(const std::string& base_topic, uint32_t queue_size, bool latch = false); /*! * \brief Advertise an image topic with subcriber status callbacks. */ Publisher advertise(const std::string& base_topic, uint32_t queue_size, const SubscriberStatusCallback& connect_cb, const SubscriberStatusCallback& disconnect_cb = SubscriberStatusCallback(), const ros::VoidPtr& tracked_object = ros::VoidPtr(), bool latch = false); /** * \brief Subscribe to an image topic, version for arbitrary boost::function object. */ Subscriber subscribe(const std::string& base_topic, uint32_t queue_size, const boost::function& callback, const ros::VoidPtr& tracked_object = ros::VoidPtr(), const TransportHints& transport_hints = TransportHints()); /** * \brief Subscribe to an image topic, version for bare function. */ Subscriber subscribe(const std::string& base_topic, uint32_t queue_size, void(*fp)(const sensor_msgs::ImageConstPtr&), const TransportHints& transport_hints = TransportHints()) { return subscribe(base_topic, queue_size, boost::function(fp), ros::VoidPtr(), transport_hints); } /** * \brief Subscribe to an image topic, version for class member function with bare pointer. */ template Subscriber subscribe(const std::string& base_topic, uint32_t queue_size, void(T::*fp)(const sensor_msgs::ImageConstPtr&), T* obj, const TransportHints& transport_hints = TransportHints()) { return subscribe(base_topic, queue_size, boost::bind(fp, obj, _1), ros::VoidPtr(), transport_hints); } /** * \brief Subscribe to an image topic, version for class member function with shared_ptr. */ template Subscriber subscribe(const std::string& base_topic, uint32_t queue_size, void(T::*fp)(const sensor_msgs::ImageConstPtr&), const boost::shared_ptr& obj, const TransportHints& transport_hints = TransportHints()) { return subscribe(base_topic, queue_size, boost::bind(fp, obj.get(), _1), obj, transport_hints); } /*! * \brief Advertise a synchronized camera raw image + info topic pair, simple version. */ CameraPublisher advertiseCamera(const std::string& base_topic, uint32_t queue_size, bool latch = false); /*! * \brief Advertise a synchronized camera raw image + info topic pair with subscriber status * callbacks. */ CameraPublisher advertiseCamera(const std::string& base_topic, uint32_t queue_size, const SubscriberStatusCallback& image_connect_cb, const SubscriberStatusCallback& image_disconnect_cb = SubscriberStatusCallback(), const ros::SubscriberStatusCallback& info_connect_cb = ros::SubscriberStatusCallback(), const ros::SubscriberStatusCallback& info_disconnect_cb = ros::SubscriberStatusCallback(), const ros::VoidPtr& tracked_object = ros::VoidPtr(), bool latch = false); /** * \brief Subscribe to a synchronized image & camera info topic pair, version for arbitrary * boost::function object. * * This version assumes the standard topic naming scheme, where the info topic is * named "camera_info" in the same namespace as the base image topic. */ CameraSubscriber subscribeCamera(const std::string& base_topic, uint32_t queue_size, const CameraSubscriber::Callback& callback, const ros::VoidPtr& tracked_object = ros::VoidPtr(), const TransportHints& transport_hints = TransportHints()); /** * \brief Subscribe to a synchronized image & camera info topic pair, version for bare function. */ CameraSubscriber subscribeCamera(const std::string& base_topic, uint32_t queue_size, void(*fp)(const sensor_msgs::ImageConstPtr&, const sensor_msgs::CameraInfoConstPtr&), const TransportHints& transport_hints = TransportHints()) { return subscribeCamera(base_topic, queue_size, CameraSubscriber::Callback(fp), ros::VoidPtr(), transport_hints); } /** * \brief Subscribe to a synchronized image & camera info topic pair, version for class member * function with bare pointer. */ template CameraSubscriber subscribeCamera(const std::string& base_topic, uint32_t queue_size, void(T::*fp)(const sensor_msgs::ImageConstPtr&, const sensor_msgs::CameraInfoConstPtr&), T* obj, const TransportHints& transport_hints = TransportHints()) { return subscribeCamera(base_topic, queue_size, boost::bind(fp, obj, _1, _2), ros::VoidPtr(), transport_hints); } /** * \brief Subscribe to a synchronized image & camera info topic pair, version for class member * function with shared_ptr. */ template CameraSubscriber subscribeCamera(const std::string& base_topic, uint32_t queue_size, void(T::*fp)(const sensor_msgs::ImageConstPtr&, const sensor_msgs::CameraInfoConstPtr&), const boost::shared_ptr& obj, const TransportHints& transport_hints = TransportHints()) { return subscribeCamera(base_topic, queue_size, boost::bind(fp, obj.get(), _1, _2), obj, transport_hints); } /** * \brief Returns the names of all transports declared in the system. Declared * transports are not necessarily built or loadable. */ std::vector getDeclaredTransports() const; /** * \brief Returns the names of all transports that are loadable in the system. */ std::vector getLoadableTransports() const; private: struct Impl; typedef boost::shared_ptr ImplPtr; typedef boost::weak_ptr ImplWPtr; ImplPtr impl_; }; } //namespace image_transport #endif ros-image-common-1.11.13/image_transport/include/image_transport/loader_fwds.h000066400000000000000000000044611336567436300275350ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #ifndef IMAGE_TRANSPORT_LOADER_FWDS_H #define IMAGE_TRANSPORT_LOADER_FWDS_H // Forward-declare some classes most users shouldn't care about so that // image_transport.h doesn't bring them in. namespace pluginlib { template class ClassLoader; } namespace image_transport { class PublisherPlugin; class SubscriberPlugin; typedef pluginlib::ClassLoader PubLoader; typedef boost::shared_ptr PubLoaderPtr; typedef pluginlib::ClassLoader SubLoader; typedef boost::shared_ptr SubLoaderPtr; } #endif ros-image-common-1.11.13/image_transport/include/image_transport/publisher.h000066400000000000000000000114351336567436300272400ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #ifndef IMAGE_TRANSPORT_PUBLISHER_H #define IMAGE_TRANSPORT_PUBLISHER_H #include #include #include "image_transport/single_subscriber_publisher.h" #include "image_transport/exception.h" #include "image_transport/loader_fwds.h" namespace image_transport { /** * \brief Manages advertisements of multiple transport options on an Image topic. * * Publisher is a drop-in replacement for ros::Publisher when publishing * Image topics. In a minimally built environment, they behave the same; however, * Publisher is extensible via plugins to publish alternative representations of * the image on related subtopics. This is especially useful for limiting bandwidth and * latency over a network connection, when you might (for example) use the theora plugin * to transport the images as streamed video. All topics are published only on demand * (i.e. if there are subscribers). * * A Publisher should always be created through a call to ImageTransport::advertise(), * or copied from one that was. * Once all copies of a specific Publisher go out of scope, any subscriber callbacks * associated with that handle will stop being called. Once all Publisher for a * given base topic go out of scope the topic (and all subtopics) will be unadvertised. */ class Publisher { public: Publisher() {} /*! * \brief Returns the number of subscribers that are currently connected to * this Publisher. * * Returns the total number of subscribers to all advertised topics. */ uint32_t getNumSubscribers() const; /*! * \brief Returns the base topic of this Publisher. */ std::string getTopic() const; /*! * \brief Publish an image on the topics associated with this Publisher. */ void publish(const sensor_msgs::Image& message) const; /*! * \brief Publish an image on the topics associated with this Publisher. */ void publish(const sensor_msgs::ImageConstPtr& message) const; /*! * \brief Shutdown the advertisements associated with this Publisher. */ void shutdown(); operator void*() const; bool operator< (const Publisher& rhs) const { return impl_ < rhs.impl_; } bool operator!=(const Publisher& rhs) const { return impl_ != rhs.impl_; } bool operator==(const Publisher& rhs) const { return impl_ == rhs.impl_; } private: Publisher(ros::NodeHandle& nh, const std::string& base_topic, uint32_t queue_size, const SubscriberStatusCallback& connect_cb, const SubscriberStatusCallback& disconnect_cb, const ros::VoidPtr& tracked_object, bool latch, const PubLoaderPtr& loader); struct Impl; typedef boost::shared_ptr ImplPtr; typedef boost::weak_ptr ImplWPtr; ImplPtr impl_; static void weakSubscriberCb(const ImplWPtr& impl_wptr, const SingleSubscriberPublisher& plugin_pub, const SubscriberStatusCallback& user_cb); SubscriberStatusCallback rebindCB(const SubscriberStatusCallback& user_cb); friend class ImageTransport; }; } //namespace image_transport #endif ros-image-common-1.11.13/image_transport/include/image_transport/publisher_plugin.h000066400000000000000000000125661336567436300306240ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #ifndef IMAGE_TRANSPORT_PUBLISHER_PLUGIN_H #define IMAGE_TRANSPORT_PUBLISHER_PLUGIN_H #include #include #include "image_transport/single_subscriber_publisher.h" namespace image_transport { /** * \brief Base class for plugins to Publisher. */ class PublisherPlugin : boost::noncopyable { public: virtual ~PublisherPlugin() {} /** * \brief Get a string identifier for the transport provided by * this plugin. */ virtual std::string getTransportName() const = 0; /** * \brief Advertise a topic, simple version. */ void advertise(ros::NodeHandle& nh, const std::string& base_topic, uint32_t queue_size, bool latch = true) { advertiseImpl(nh, base_topic, queue_size, SubscriberStatusCallback(), SubscriberStatusCallback(), ros::VoidPtr(), latch); } /** * \brief Advertise a topic with subscriber status callbacks. */ void advertise(ros::NodeHandle& nh, const std::string& base_topic, uint32_t queue_size, const SubscriberStatusCallback& connect_cb, const SubscriberStatusCallback& disconnect_cb = SubscriberStatusCallback(), const ros::VoidPtr& tracked_object = ros::VoidPtr(), bool latch = true) { advertiseImpl(nh, base_topic, queue_size, connect_cb, disconnect_cb, tracked_object, latch); } /** * \brief Returns the number of subscribers that are currently connected to * this PublisherPlugin. */ virtual uint32_t getNumSubscribers() const = 0; /** * \brief Returns the communication topic that this PublisherPlugin will publish on. */ virtual std::string getTopic() const = 0; /** * \brief Publish an image using the transport associated with this PublisherPlugin. */ virtual void publish(const sensor_msgs::Image& message) const = 0; /** * \brief Publish an image using the transport associated with this PublisherPlugin. */ virtual void publish(const sensor_msgs::ImageConstPtr& message) const { publish(*message); } /** * \brief Publish an image using the transport associated with this PublisherPlugin. * This version of the function can be used to optimize cases where you don't want to * fill a ROS message first to avoid useless copies. * @param message an image message to use information from (but not data) * @param data a pointer to the image data to use to fill the Image message */ virtual void publish(const sensor_msgs::Image& message, const uint8_t* data) const { sensor_msgs::Image msg; msg.header = message.header; msg.height = message.height; msg.width = message.width; msg.encoding = message.encoding; msg.is_bigendian = message.is_bigendian; msg.step = message.step; msg.data = std::vector(data, data + msg.step*msg.height); publish(msg); } /** * \brief Shutdown any advertisements associated with this PublisherPlugin. */ virtual void shutdown() = 0; /** * \brief Return the lookup name of the PublisherPlugin associated with a specific * transport identifier. */ static std::string getLookupName(const std::string& transport_name) { return "image_transport/" + transport_name + "_pub"; } protected: /** * \brief Advertise a topic. Must be implemented by the subclass. */ virtual void advertiseImpl(ros::NodeHandle& nh, const std::string& base_topic, uint32_t queue_size, const SubscriberStatusCallback& connect_cb, const SubscriberStatusCallback& disconnect_cb, const ros::VoidPtr& tracked_object, bool latch) = 0; }; } //namespace image_transport #endif ros-image-common-1.11.13/image_transport/include/image_transport/raw_publisher.h000066400000000000000000000056711336567436300301160ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #ifndef IMAGE_TRANSPORT_RAW_PUBLISHER_H #define IMAGE_TRANSPORT_RAW_PUBLISHER_H #include "image_transport/simple_publisher_plugin.h" namespace image_transport { /** * \brief The default PublisherPlugin. * * RawPublisher is a simple wrapper for ros::Publisher, publishing unaltered Image * messages on the base topic. */ class RawPublisher : public SimplePublisherPlugin { public: virtual ~RawPublisher() {} virtual std::string getTransportName() const { return "raw"; } // Override the default implementation because publishing the message pointer allows // the no-copy intraprocess optimization. virtual void publish(const sensor_msgs::ImageConstPtr& message) const { getPublisher().publish(message); } // Override the default implementation to not copy data to a sensor_msgs::Image first virtual void publish(const sensor_msgs::Image& message, const uint8_t* data) const; protected: virtual void publish(const sensor_msgs::Image& message, const PublishFn& publish_fn) const { publish_fn(message); } virtual std::string getTopicToAdvertise(const std::string& base_topic) const { return base_topic; } }; } //namespace image_transport #endif ros-image-common-1.11.13/image_transport/include/image_transport/raw_subscriber.h000066400000000000000000000050601336567436300302540ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #ifndef IMAGE_TRANSPORT_RAW_SUBSCRIBER_H #define IMAGE_TRANSPORT_RAW_SUBSCRIBER_H #include "image_transport/simple_subscriber_plugin.h" namespace image_transport { /** * \brief The default SubscriberPlugin. * * RawSubscriber is a simple wrapper for ros::Subscriber which listens for Image messages * and passes them through to the callback. */ class RawSubscriber : public SimpleSubscriberPlugin { public: virtual ~RawSubscriber() {} virtual std::string getTransportName() const { return "raw"; } protected: virtual void internalCallback(const sensor_msgs::ImageConstPtr& message, const Callback& user_cb) { user_cb(message); } virtual std::string getTopicToSubscribe(const std::string& base_topic) const { return base_topic; } }; } //namespace image_transport #endif ros-image-common-1.11.13/image_transport/include/image_transport/simple_publisher_plugin.h000066400000000000000000000215071336567436300321700ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #ifndef IMAGE_TRANSPORT_SIMPLE_PUBLISHER_PLUGIN_H #define IMAGE_TRANSPORT_SIMPLE_PUBLISHER_PLUGIN_H #include "image_transport/publisher_plugin.h" #include namespace image_transport { /** * \brief Base class to simplify implementing most plugins to Publisher. * * This base class vastly simplifies implementing a PublisherPlugin in the common * case that all communication with the matching SubscriberPlugin happens over a * single ROS topic using a transport-specific message type. SimplePublisherPlugin * is templated on the transport-specific message type. * * A subclass need implement only two methods: * - getTransportName() from PublisherPlugin * - publish() with an extra PublishFn argument * * For access to the parameter server and name remappings, use nh(). * * getTopicToAdvertise() controls the name of the internal communication topic. * It defaults to \/\. */ template class SimplePublisherPlugin : public PublisherPlugin { public: virtual ~SimplePublisherPlugin() {} virtual uint32_t getNumSubscribers() const { if (simple_impl_) return simple_impl_->pub_.getNumSubscribers(); return 0; } virtual std::string getTopic() const { if (simple_impl_) return simple_impl_->pub_.getTopic(); return std::string(); } virtual void publish(const sensor_msgs::Image& message) const { if (!simple_impl_ || !simple_impl_->pub_) { ROS_ASSERT_MSG(false, "Call to publish() on an invalid image_transport::SimplePublisherPlugin"); return; } publish(message, bindInternalPublisher(simple_impl_->pub_)); } virtual void shutdown() { if (simple_impl_) simple_impl_->pub_.shutdown(); } protected: virtual void advertiseImpl(ros::NodeHandle& nh, const std::string& base_topic, uint32_t queue_size, const SubscriberStatusCallback& user_connect_cb, const SubscriberStatusCallback& user_disconnect_cb, const ros::VoidPtr& tracked_object, bool latch) { std::string transport_topic = getTopicToAdvertise(base_topic); ros::NodeHandle param_nh(transport_topic); simple_impl_.reset(new SimplePublisherPluginImpl(param_nh)); simple_impl_->pub_ = nh.advertise(transport_topic, queue_size, bindCB(user_connect_cb, &SimplePublisherPlugin::connectCallback), bindCB(user_disconnect_cb, &SimplePublisherPlugin::disconnectCallback), tracked_object, latch); } //! Generic function for publishing the internal message type. typedef boost::function PublishFn; /** * \brief Publish an image using the specified publish function. Must be implemented by * the subclass. * * The PublishFn publishes the transport-specific message type. This indirection allows * SimpleSubscriberPlugin to use this function for both normal broadcast publishing and * single subscriber publishing (in subscription callbacks). */ virtual void publish(const sensor_msgs::Image& message, const PublishFn& publish_fn) const = 0; /** * \brief Return the communication topic name for a given base topic. * * Defaults to \/\. */ virtual std::string getTopicToAdvertise(const std::string& base_topic) const { return base_topic + "/" + getTransportName(); } /** * \brief Function called when a subscriber connects to the internal publisher. * * Defaults to noop. */ virtual void connectCallback(const ros::SingleSubscriberPublisher& pub) {} /** * \brief Function called when a subscriber disconnects from the internal publisher. * * Defaults to noop. */ virtual void disconnectCallback(const ros::SingleSubscriberPublisher& pub) {} /** * \brief Returns the ros::NodeHandle to be used for parameter lookup. */ const ros::NodeHandle& nh() const { return simple_impl_->param_nh_; } /** * \brief Returns the internal ros::Publisher. * * This really only exists so RawPublisher can implement no-copy intraprocess message * passing easily. */ const ros::Publisher& getPublisher() const { ROS_ASSERT(simple_impl_); return simple_impl_->pub_; } private: struct SimplePublisherPluginImpl { SimplePublisherPluginImpl(const ros::NodeHandle& nh) : param_nh_(nh) { } const ros::NodeHandle param_nh_; ros::Publisher pub_; }; boost::scoped_ptr simple_impl_; typedef void (SimplePublisherPlugin::*SubscriberStatusMemFn)(const ros::SingleSubscriberPublisher& pub); /** * Binds the user callback to subscriberCB(), which acts as an intermediary to expose * a publish(Image) interface to the user while publishing to an internal topic. */ ros::SubscriberStatusCallback bindCB(const SubscriberStatusCallback& user_cb, SubscriberStatusMemFn internal_cb_fn) { ros::SubscriberStatusCallback internal_cb = boost::bind(internal_cb_fn, this, _1); if (user_cb) return boost::bind(&SimplePublisherPlugin::subscriberCB, this, _1, user_cb, internal_cb); else return internal_cb; } /** * Forms the ros::SingleSubscriberPublisher for the internal communication topic into * an image_transport::SingleSubscriberPublisher for Image messages and passes it * to the user subscriber status callback. */ void subscriberCB(const ros::SingleSubscriberPublisher& ros_ssp, const SubscriberStatusCallback& user_cb, const ros::SubscriberStatusCallback& internal_cb) { // First call the internal callback (for sending setup headers, etc.) internal_cb(ros_ssp); // Construct a function object for publishing sensor_msgs::Image through the // subclass-implemented publish() using the ros::SingleSubscriberPublisher to send // messages of the transport-specific type. typedef void (SimplePublisherPlugin::*PublishMemFn)(const sensor_msgs::Image&, const PublishFn&) const; PublishMemFn pub_mem_fn = &SimplePublisherPlugin::publish; ImagePublishFn image_publish_fn = boost::bind(pub_mem_fn, this, _1, bindInternalPublisher(ros_ssp)); SingleSubscriberPublisher ssp(ros_ssp.getSubscriberName(), getTopic(), boost::bind(&SimplePublisherPlugin::getNumSubscribers, this), image_publish_fn); user_cb(ssp); } typedef boost::function ImagePublishFn; /** * Returns a function object for publishing the transport-specific message type * through some ROS publisher type. * * @param pub An object with method void publish(const M&) */ template PublishFn bindInternalPublisher(const PubT& pub) const { // Bind PubT::publish(const Message&) as PublishFn typedef void (PubT::*InternalPublishMemFn)(const M&) const; InternalPublishMemFn internal_pub_mem_fn = &PubT::publish; return boost::bind(internal_pub_mem_fn, &pub, _1); } }; } //namespace image_transport #endif ros-image-common-1.11.13/image_transport/include/image_transport/simple_subscriber_plugin.h000066400000000000000000000120271336567436300323330ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #ifndef IMAGE_TRANSPORT_SIMPLE_SUBSCRIBER_PLUGIN_H #define IMAGE_TRANSPORT_SIMPLE_SUBSCRIBER_PLUGIN_H #include "image_transport/subscriber_plugin.h" #include namespace image_transport { /** * \brief Base class to simplify implementing most plugins to Subscriber. * * The base class simplifies implementing a SubscriberPlugin in the common case that * all communication with the matching PublisherPlugin happens over a single ROS * topic using a transport-specific message type. SimpleSubscriberPlugin is templated * on the transport-specific message type. * * A subclass need implement only two methods: * - getTransportName() from SubscriberPlugin * - internalCallback() - processes a message and invoked the user Image callback if * appropriate. * * For access to the parameter server and name remappings, use nh(). * * getTopicToSubscribe() controls the name of the internal communication topic. It * defaults to \/\. */ template class SimpleSubscriberPlugin : public SubscriberPlugin { public: virtual ~SimpleSubscriberPlugin() {} virtual std::string getTopic() const { if (simple_impl_) return simple_impl_->sub_.getTopic(); return std::string(); } virtual uint32_t getNumPublishers() const { if (simple_impl_) return simple_impl_->sub_.getNumPublishers(); return 0; } virtual void shutdown() { if (simple_impl_) simple_impl_->sub_.shutdown(); } protected: /** * \brief Process a message. Must be implemented by the subclass. * * @param message A message from the PublisherPlugin. * @param user_cb The user Image callback to invoke, if appropriate. */ virtual void internalCallback(const typename M::ConstPtr& message, const Callback& user_cb) = 0; /** * \brief Return the communication topic name for a given base topic. * * Defaults to \/\. */ virtual std::string getTopicToSubscribe(const std::string& base_topic) const { return base_topic + "/" + getTransportName(); } virtual void subscribeImpl(ros::NodeHandle& nh, const std::string& base_topic, uint32_t queue_size, const Callback& callback, const ros::VoidPtr& tracked_object, const TransportHints& transport_hints) { // Push each group of transport-specific parameters into a separate sub-namespace ros::NodeHandle param_nh(transport_hints.getParameterNH(), getTransportName()); simple_impl_.reset(new SimpleSubscriberPluginImpl(param_nh)); simple_impl_->sub_ = nh.subscribe(getTopicToSubscribe(base_topic), queue_size, boost::bind(&SimpleSubscriberPlugin::internalCallback, this, _1, callback), tracked_object, transport_hints.getRosHints()); } /** * \brief Returns the ros::NodeHandle to be used for parameter lookup. */ const ros::NodeHandle& nh() const { return simple_impl_->param_nh_; } private: struct SimpleSubscriberPluginImpl { SimpleSubscriberPluginImpl(const ros::NodeHandle& nh) : param_nh_(nh) { } const ros::NodeHandle param_nh_; ros::Subscriber sub_; }; boost::scoped_ptr simple_impl_; }; } //namespace image_transport #endif ros-image-common-1.11.13/image_transport/include/image_transport/single_subscriber_publisher.h000066400000000000000000000060371336567436300330260ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #ifndef IMAGE_TRANSPORT_SINGLE_SUBSCRIBER_PUBLISHER #define IMAGE_TRANSPORT_SINGLE_SUBSCRIBER_PUBLISHER #include #include #include namespace image_transport { /** * \brief Allows publication of an image to a single subscriber. Only available inside * subscriber connection callbacks. */ class SingleSubscriberPublisher : boost::noncopyable { public: typedef boost::function GetNumSubscribersFn; typedef boost::function PublishFn; SingleSubscriberPublisher(const std::string& caller_id, const std::string& topic, const GetNumSubscribersFn& num_subscribers_fn, const PublishFn& publish_fn); std::string getSubscriberName() const; std::string getTopic() const; uint32_t getNumSubscribers() const; void publish(const sensor_msgs::Image& message) const; void publish(const sensor_msgs::ImageConstPtr& message) const; private: std::string caller_id_; std::string topic_; GetNumSubscribersFn num_subscribers_fn_; PublishFn publish_fn_; friend class Publisher; // to get publish_fn_ directly }; typedef boost::function SubscriberStatusCallback; } //namespace image_transport #endif ros-image-common-1.11.13/image_transport/include/image_transport/subscriber.h000066400000000000000000000101311336567436300273760ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #ifndef IMAGE_TRANSPORT_SUBSCRIBER_H #define IMAGE_TRANSPORT_SUBSCRIBER_H #include #include #include "image_transport/transport_hints.h" #include "image_transport/exception.h" #include "image_transport/loader_fwds.h" namespace image_transport { /** * \brief Manages a subscription callback on a specific topic that can be interpreted * as an Image topic. * * Subscriber is the client-side counterpart to Publisher. By loading the * appropriate plugin, it can subscribe to a base image topic using any available * transport. The complexity of what transport is actually used is hidden from the user, * who sees only a normal Image callback. * * A Subscriber should always be created through a call to ImageTransport::subscribe(), * or copied from one that was. * Once all copies of a specific Subscriber go out of scope, the subscription callback * associated with that handle will stop being called. Once all Subscriber for a given * topic go out of scope the topic will be unsubscribed. */ class Subscriber { public: Subscriber() {} /** * \brief Returns the base image topic. * * The Subscriber may actually be subscribed to some transport-specific topic that * differs from the base topic. */ std::string getTopic() const; /** * \brief Returns the number of publishers this subscriber is connected to. */ uint32_t getNumPublishers() const; /** * \brief Returns the name of the transport being used. */ std::string getTransport() const; /** * \brief Unsubscribe the callback associated with this Subscriber. */ void shutdown(); operator void*() const; bool operator< (const Subscriber& rhs) const { return impl_ < rhs.impl_; } bool operator!=(const Subscriber& rhs) const { return impl_ != rhs.impl_; } bool operator==(const Subscriber& rhs) const { return impl_ == rhs.impl_; } private: Subscriber(ros::NodeHandle& nh, const std::string& base_topic, uint32_t queue_size, const boost::function& callback, const ros::VoidPtr& tracked_object, const TransportHints& transport_hints, const SubLoaderPtr& loader); struct Impl; typedef boost::shared_ptr ImplPtr; typedef boost::weak_ptr ImplWPtr; ImplPtr impl_; friend class ImageTransport; }; } //namespace image_transport #endif ros-image-common-1.11.13/image_transport/include/image_transport/subscriber_filter.h000066400000000000000000000116541336567436300307560ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #ifndef IMAGE_TRANSPORT_SUBSCRIBER_FILTER_H #define IMAGE_TRANSPORT_SUBSCRIBER_FILTER_H #include #include #include "image_transport/image_transport.h" namespace image_transport { /** * \brief Image subscription filter. * * This class wraps Subscriber as a "filter" compatible with the message_filters * package. It acts as a highest-level filter, simply passing messages from an image * transport subscription through to the filters which have connected to it. * * When this object is destroyed it will unsubscribe from the ROS subscription. * * \section connections CONNECTIONS * * SubscriberFilter has no input connection. * * The output connection for the SubscriberFilter object is the same signature as for roscpp * subscription callbacks, ie. \verbatim void callback(const boost::shared_ptr&); \endverbatim */ class SubscriberFilter : public message_filters::SimpleFilter { public: /** * \brief Constructor * * See the ros::NodeHandle::subscribe() variants for more information on the parameters * * \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 */ SubscriberFilter(ImageTransport& it, const std::string& base_topic, uint32_t queue_size, const TransportHints& transport_hints = TransportHints()) { subscribe(it, base_topic, queue_size, transport_hints); } /** * \brief Empty constructor, use subscribe() to subscribe to a topic */ SubscriberFilter() { } ~SubscriberFilter() { unsubscribe(); } /** * \brief Subscribe to a topic. * * If this Subscriber is already subscribed to a topic, this function will first unsubscribe. * * \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 */ void subscribe(ImageTransport& it, const std::string& base_topic, uint32_t queue_size, const TransportHints& transport_hints = TransportHints()) { unsubscribe(); sub_ = it.subscribe(base_topic, queue_size, boost::bind(&SubscriberFilter::cb, this, _1), ros::VoidPtr(), transport_hints); } /** * \brief Force immediate unsubscription of this subscriber from its topic */ void unsubscribe() { sub_.shutdown(); } std::string getTopic() const { return sub_.getTopic(); } /** * \brief Returns the number of publishers this subscriber is connected to. */ uint32_t getNumPublishers() const { return sub_.getNumPublishers(); } /** * \brief Returns the name of the transport being used. */ std::string getTransport() const { return sub_.getTransport(); } /** * \brief Returns the internal image_transport::Subscriber object. */ const Subscriber& getSubscriber() const { return sub_; } private: void cb(const sensor_msgs::ImageConstPtr& m) { signalMessage(m); } Subscriber sub_; }; } #endif ros-image-common-1.11.13/image_transport/include/image_transport/subscriber_plugin.h000066400000000000000000000124611336567436300307640ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #ifndef IMAGE_TRANSPORT_SUBSCRIBER_PLUGIN_H #define IMAGE_TRANSPORT_SUBSCRIBER_PLUGIN_H #include #include #include #include "image_transport/transport_hints.h" namespace image_transport { /** * \brief Base class for plugins to Subscriber. */ class SubscriberPlugin : boost::noncopyable { public: typedef boost::function Callback; virtual ~SubscriberPlugin() {} /** * \brief Get a string identifier for the transport provided by * this plugin. */ virtual std::string getTransportName() const = 0; /** * \brief Subscribe to an image topic, version for arbitrary boost::function object. */ void subscribe(ros::NodeHandle& nh, const std::string& base_topic, uint32_t queue_size, const Callback& callback, const ros::VoidPtr& tracked_object = ros::VoidPtr(), const TransportHints& transport_hints = TransportHints()) { return subscribeImpl(nh, base_topic, queue_size, callback, tracked_object, transport_hints); } /** * \brief Subscribe to an image topic, version for bare function. */ void subscribe(ros::NodeHandle& nh, const std::string& base_topic, uint32_t queue_size, void(*fp)(const sensor_msgs::ImageConstPtr&), const TransportHints& transport_hints = TransportHints()) { return subscribe(nh, base_topic, queue_size, boost::function(fp), ros::VoidPtr(), transport_hints); } /** * \brief Subscribe to an image topic, version for class member function with bare pointer. */ template void subscribe(ros::NodeHandle& nh, const std::string& base_topic, uint32_t queue_size, void(T::*fp)(const sensor_msgs::ImageConstPtr&), T* obj, const TransportHints& transport_hints = TransportHints()) { return subscribe(nh, base_topic, queue_size, boost::bind(fp, obj, _1), ros::VoidPtr(), transport_hints); } /** * \brief Subscribe to an image topic, version for class member function with shared_ptr. */ template void subscribe(ros::NodeHandle& nh, const std::string& base_topic, uint32_t queue_size, void(T::*fp)(const sensor_msgs::ImageConstPtr&), const boost::shared_ptr& obj, const TransportHints& transport_hints = TransportHints()) { return subscribe(nh, base_topic, queue_size, boost::bind(fp, obj.get(), _1), obj, transport_hints); } /** * \brief Get the transport-specific communication topic. */ virtual std::string getTopic() const = 0; /** * \brief Returns the number of publishers this subscriber is connected to. */ virtual uint32_t getNumPublishers() const = 0; /** * \brief Unsubscribe the callback associated with this SubscriberPlugin. */ virtual void shutdown() = 0; /** * \brief Return the lookup name of the SubscriberPlugin associated with a specific * transport identifier. */ static std::string getLookupName(const std::string& transport_type) { return "image_transport/" + transport_type + "_sub"; } protected: /** * \brief Subscribe to an image transport topic. Must be implemented by the subclass. */ virtual void subscribeImpl(ros::NodeHandle& nh, const std::string& base_topic, uint32_t queue_size, const Callback& callback, const ros::VoidPtr& tracked_object, const TransportHints& transport_hints) = 0; }; } //namespace image_transport #endif ros-image-common-1.11.13/image_transport/include/image_transport/transport_hints.h000066400000000000000000000066671336567436300305170ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #ifndef IMAGE_TRANSPORT_TRANSPORT_HINTS_H #define IMAGE_TRANSPORT_TRANSPORT_HINTS_H #include namespace image_transport { /** * \brief Stores transport settings for an image topic subscription. */ class TransportHints { public: /** * \brief Constructor. * * The default transport can be overridden by setting a certain parameter to the * name of the desired transport. By default this parameter is named "image_transport" * in the node's local namespace. For consistency across ROS applications, the * name of this parameter should not be changed without good reason. * * @param default_transport Preferred transport to use * @param ros_hints Hints to pass through to ROS subscriptions * @param parameter_nh Node handle to use when looking up the transport parameter. * Defaults to the local namespace. * @param parameter_name The name of the transport parameter */ TransportHints(const std::string& default_transport = "raw", const ros::TransportHints& ros_hints = ros::TransportHints(), const ros::NodeHandle& parameter_nh = ros::NodeHandle("~"), const std::string& parameter_name = "image_transport") : ros_hints_(ros_hints), parameter_nh_(parameter_nh) { parameter_nh_.param(parameter_name, transport_, default_transport); } const std::string& getTransport() const { return transport_; } const ros::TransportHints& getRosHints() const { return ros_hints_; } const ros::NodeHandle& getParameterNH() const { return parameter_nh_; } private: std::string transport_; ros::TransportHints ros_hints_; ros::NodeHandle parameter_nh_; }; } //namespace image_transport #endif ros-image-common-1.11.13/image_transport/mainpage.dox000066400000000000000000000045071336567436300225500ustar00rootroot00000000000000/** \mainpage \htmlinclude manifest.html \section codeapi Code API When transporting images, you should use image_transport's classes as drop-in replacements for ros::Publisher and ros::Subscriber. - image_transport::ImageTransport - use this to create a Publisher or Subscriber - image_transport::Publisher - manage advertisements for an image topic, using all available transport options - image_transport::Subscriber - manage an Image subscription callback using a particular transport Camera drivers publish a "camera_info" sibling topic containing important metadata on how to interpret an image for vision applications. image_transport included helper classes to publish (image, info) message pairs and re-synchronize them on the client side: - image_transport::CameraPublisher - manage advertisements for camera images - image_transport::CameraSubscriber - manage a single subscription callback to synchronized image (using any transport) and CameraInfo topics For other synchronization or filtering needs, see the low-level filter class: - image_transport::SubscriberFilter - a wrapper for image_transport::Subscriber compatible with message_filters \subsection writing_plugin Writing a plugin If you are an advanced user implementing your own image transport option, you will need to implement these base-level interfaces: - image_transport::PublisherPlugin - image_transport::SubscriberPlugin In the common case that all communication between PublisherPlugin and SubscriberPlugin happens over a single ROS topic using a transport-specific message type, writing the plugins is vastly simplified by using these base classes instead: - image_transport::SimplePublisherPlugin - see image_transport::RawPublisher for a trivial example - image_transport::SimpleSubscriberPlugin - see image_transport::RawSubscriber for a trivial example \section rosapi ROS API \subsection pub_sub_rosapi Publishers and Subscribers Because they encapsulate complicated communication behavior, image_transport publisher and subscriber classes have a public ROS API as well as a code API. See the wiki documentation for details. Although image_transport::Publisher may publish many topics, in all code interfaces you should use only the name of the "base topic." The image transport classes will figure out the name of the dedicated ROS topic to use for the desired transport. */ ros-image-common-1.11.13/image_transport/package.xml000066400000000000000000000026471336567436300223730ustar00rootroot00000000000000 image_transport 1.11.13 image_transport should always be used to subscribe to and publish images. It provides transparent support for transporting images in low-bandwidth compressed formats. Examples (provided by separate plugin packages) include JPEG/PNG compression and Theora streaming video. Patrick Mihelich Jack O'Quin Vincent Rabaud BSD http://ros.org/wiki/image_transport https://github.com/ros-perception/image_common/issues https://github.com/ros-perception/image_common catkin message_filters pluginlib rosconsole roscpp roslib sensor_msgs message_filters pluginlib rosconsole roscpp roslib sensor_msgs ros-image-common-1.11.13/image_transport/src/000077500000000000000000000000001336567436300210345ustar00rootroot00000000000000ros-image-common-1.11.13/image_transport/src/camera_common.cpp000066400000000000000000000050171336567436300243430ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #include "image_transport/camera_common.h" #include #include #include #include namespace image_transport { std::string getCameraInfoTopic(const std::string& base_topic) { // Split into separate names std::vector names; boost::algorithm::split(names, base_topic, boost::algorithm::is_any_of("/"), boost::algorithm::token_compress_on); // Get rid of empty tokens from trailing slashes while (names.back().empty()) names.pop_back(); // Replace image name with "camera_info" names.back() = "camera_info"; // Join back together into topic name return boost::algorithm::join(names, "/"); } } //namespace image_transport ros-image-common-1.11.13/image_transport/src/camera_publisher.cpp000066400000000000000000000123341336567436300250500ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #include "image_transport/image_transport.h" #include "image_transport/camera_common.h" namespace image_transport { struct CameraPublisher::Impl { Impl() : unadvertised_(false) { } ~Impl() { shutdown(); } bool isValid() const { return !unadvertised_; } void shutdown() { if (!unadvertised_) { unadvertised_ = true; image_pub_.shutdown(); info_pub_.shutdown(); } } Publisher image_pub_; ros::Publisher info_pub_; bool unadvertised_; //double constructed_; }; CameraPublisher::CameraPublisher(ImageTransport& image_it, ros::NodeHandle& info_nh, const std::string& base_topic, uint32_t queue_size, const SubscriberStatusCallback& image_connect_cb, const SubscriberStatusCallback& image_disconnect_cb, const ros::SubscriberStatusCallback& info_connect_cb, const ros::SubscriberStatusCallback& info_disconnect_cb, const ros::VoidPtr& tracked_object, bool latch) : impl_(new Impl) { // Explicitly resolve name here so we compute the correct CameraInfo topic when the // image topic is remapped (#4539). std::string image_topic = info_nh.resolveName(base_topic); std::string info_topic = getCameraInfoTopic(image_topic); impl_->image_pub_ = image_it.advertise(image_topic, queue_size, image_connect_cb, image_disconnect_cb, tracked_object, latch); impl_->info_pub_ = info_nh.advertise(info_topic, queue_size, info_connect_cb, info_disconnect_cb, tracked_object, latch); } uint32_t CameraPublisher::getNumSubscribers() const { if (impl_ && impl_->isValid()) return std::max(impl_->image_pub_.getNumSubscribers(), impl_->info_pub_.getNumSubscribers()); return 0; } std::string CameraPublisher::getTopic() const { if (impl_) return impl_->image_pub_.getTopic(); return std::string(); } std::string CameraPublisher::getInfoTopic() const { if (impl_) return impl_->info_pub_.getTopic(); return std::string(); } void CameraPublisher::publish(const sensor_msgs::Image& image, const sensor_msgs::CameraInfo& info) const { if (!impl_ || !impl_->isValid()) { ROS_ASSERT_MSG(false, "Call to publish() on an invalid image_transport::CameraPublisher"); return; } impl_->image_pub_.publish(image); impl_->info_pub_.publish(info); } void CameraPublisher::publish(const sensor_msgs::ImageConstPtr& image, const sensor_msgs::CameraInfoConstPtr& info) const { if (!impl_ || !impl_->isValid()) { ROS_ASSERT_MSG(false, "Call to publish() on an invalid image_transport::CameraPublisher"); return; } impl_->image_pub_.publish(image); impl_->info_pub_.publish(info); } void CameraPublisher::publish(sensor_msgs::Image& image, sensor_msgs::CameraInfo& info, ros::Time stamp) const { if (!impl_ || !impl_->isValid()) { ROS_ASSERT_MSG(false, "Call to publish() on an invalid image_transport::CameraPublisher"); return; } image.header.stamp = stamp; info.header.stamp = stamp; publish(image, info); } void CameraPublisher::shutdown() { if (impl_) { impl_->shutdown(); impl_.reset(); } } CameraPublisher::operator void*() const { return (impl_ && impl_->isValid()) ? (void*)1 : (void*)0; } } //namespace image_transport ros-image-common-1.11.13/image_transport/src/camera_subscriber.cpp000066400000000000000000000137261336567436300252240ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #include "image_transport/camera_subscriber.h" #include "image_transport/subscriber_filter.h" #include "image_transport/camera_common.h" #include #include inline void increment(int* value) { ++(*value); } namespace image_transport { struct CameraSubscriber::Impl { Impl(uint32_t queue_size) : sync_(queue_size), unsubscribed_(false), image_received_(0), info_received_(0), both_received_(0) {} ~Impl() { shutdown(); } bool isValid() const { return !unsubscribed_; } void shutdown() { if (!unsubscribed_) { unsubscribed_ = true; image_sub_.unsubscribe(); info_sub_.unsubscribe(); } } void checkImagesSynchronized() { int threshold = 3 * both_received_; if (image_received_ > threshold || info_received_ > threshold) { ROS_WARN_NAMED("sync", // Can suppress ros.image_transport.sync independent of anything else "[image_transport] Topics '%s' and '%s' do not appear to be synchronized. " "In the last 10s:\n" "\tImage messages received: %d\n" "\tCameraInfo messages received: %d\n" "\tSynchronized pairs: %d", image_sub_.getTopic().c_str(), info_sub_.getTopic().c_str(), image_received_, info_received_, both_received_); } image_received_ = info_received_ = both_received_ = 0; } SubscriberFilter image_sub_; message_filters::Subscriber info_sub_; message_filters::TimeSynchronizer sync_; bool unsubscribed_; // For detecting when the topics aren't synchronized ros::WallTimer check_synced_timer_; int image_received_, info_received_, both_received_; }; CameraSubscriber::CameraSubscriber(ImageTransport& image_it, ros::NodeHandle& info_nh, const std::string& base_topic, uint32_t queue_size, const Callback& callback, const ros::VoidPtr& tracked_object, const TransportHints& transport_hints) : impl_(new Impl(queue_size)) { // Must explicitly remap the image topic since we then do some string manipulation on it // to figure out the sibling camera_info topic. std::string image_topic = info_nh.resolveName(base_topic); std::string info_topic = getCameraInfoTopic(image_topic); impl_->image_sub_.subscribe(image_it, image_topic, queue_size, transport_hints); impl_->info_sub_ .subscribe(info_nh, info_topic, queue_size, transport_hints.getRosHints()); impl_->sync_.connectInput(impl_->image_sub_, impl_->info_sub_); // need for Boost.Bind here is kind of broken impl_->sync_.registerCallback(boost::bind(callback, _1, _2)); // Complain every 10s if it appears that the image and info topics are not synchronized impl_->image_sub_.registerCallback(boost::bind(increment, &impl_->image_received_)); impl_->info_sub_.registerCallback(boost::bind(increment, &impl_->info_received_)); impl_->sync_.registerCallback(boost::bind(increment, &impl_->both_received_)); impl_->check_synced_timer_ = info_nh.createWallTimer(ros::WallDuration(10.0), boost::bind(&Impl::checkImagesSynchronized, impl_.get())); } std::string CameraSubscriber::getTopic() const { if (impl_) return impl_->image_sub_.getTopic(); return std::string(); } std::string CameraSubscriber::getInfoTopic() const { if (impl_) return impl_->info_sub_.getTopic(); 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(); return 0; } std::string CameraSubscriber::getTransport() const { if (impl_) return impl_->image_sub_.getTransport(); return std::string(); } void CameraSubscriber::shutdown() { if (impl_) impl_->shutdown(); } CameraSubscriber::operator void*() const { return (impl_ && impl_->isValid()) ? (void*)1 : (void*)0; } } //namespace image_transport ros-image-common-1.11.13/image_transport/src/image_transport.cpp000066400000000000000000000147001336567436300247400ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #include "image_transport/image_transport.h" #include "image_transport/publisher_plugin.h" #include "image_transport/subscriber_plugin.h" #include #include #include #include namespace image_transport { struct ImageTransport::Impl { ros::NodeHandle nh_; PubLoaderPtr pub_loader_; SubLoaderPtr sub_loader_; Impl(const ros::NodeHandle& nh) : nh_(nh), pub_loader_( boost::make_shared("image_transport", "image_transport::PublisherPlugin") ), sub_loader_( boost::make_shared("image_transport", "image_transport::SubscriberPlugin") ) { } }; ImageTransport::ImageTransport(const ros::NodeHandle& nh) : impl_(new Impl(nh)) { } ImageTransport::~ImageTransport() { } Publisher ImageTransport::advertise(const std::string& base_topic, uint32_t queue_size, bool latch) { return advertise(base_topic, queue_size, SubscriberStatusCallback(), SubscriberStatusCallback(), ros::VoidPtr(), latch); } Publisher ImageTransport::advertise(const std::string& base_topic, uint32_t queue_size, const SubscriberStatusCallback& connect_cb, const SubscriberStatusCallback& disconnect_cb, const ros::VoidPtr& tracked_object, bool latch) { return Publisher(impl_->nh_, base_topic, queue_size, connect_cb, disconnect_cb, tracked_object, latch, impl_->pub_loader_); } Subscriber ImageTransport::subscribe(const std::string& base_topic, uint32_t queue_size, const boost::function& callback, const ros::VoidPtr& tracked_object, const TransportHints& transport_hints) { return Subscriber(impl_->nh_, base_topic, queue_size, callback, tracked_object, transport_hints, impl_->sub_loader_); } CameraPublisher ImageTransport::advertiseCamera(const std::string& base_topic, uint32_t queue_size, bool latch) { return advertiseCamera(base_topic, queue_size, SubscriberStatusCallback(), SubscriberStatusCallback(), ros::SubscriberStatusCallback(), ros::SubscriberStatusCallback(), ros::VoidPtr(), latch); } CameraPublisher ImageTransport::advertiseCamera(const std::string& base_topic, uint32_t queue_size, const SubscriberStatusCallback& image_connect_cb, const SubscriberStatusCallback& image_disconnect_cb, const ros::SubscriberStatusCallback& info_connect_cb, const ros::SubscriberStatusCallback& info_disconnect_cb, const ros::VoidPtr& tracked_object, bool latch) { return CameraPublisher(*this, impl_->nh_, base_topic, queue_size, image_connect_cb, image_disconnect_cb, info_connect_cb, info_disconnect_cb, tracked_object, latch); } CameraSubscriber ImageTransport::subscribeCamera(const std::string& base_topic, uint32_t queue_size, const CameraSubscriber::Callback& callback, const ros::VoidPtr& tracked_object, const TransportHints& transport_hints) { return CameraSubscriber(*this, impl_->nh_, base_topic, queue_size, callback, tracked_object, transport_hints); } std::vector ImageTransport::getDeclaredTransports() const { std::vector transports = impl_->sub_loader_->getDeclaredClasses(); // Remove the "_sub" at the end of each class name. BOOST_FOREACH(std::string& transport, transports) { transport = boost::erase_last_copy(transport, "_sub"); } return transports; } std::vector ImageTransport::getLoadableTransports() const { std::vector loadableTransports; BOOST_FOREACH( const std::string& transportPlugin, impl_->sub_loader_->getDeclaredClasses() ) { // If the plugin loads without throwing an exception, add its // transport name to the list of valid plugins, otherwise ignore // it. try { boost::shared_ptr sub = impl_->sub_loader_->createInstance(transportPlugin); loadableTransports.push_back(boost::erase_last_copy(transportPlugin, "_sub")); // Remove the "_sub" at the end of each class name. } catch (const pluginlib::LibraryLoadException& e) {} catch (const pluginlib::CreateClassException& e) {} } return loadableTransports; } } //namespace image_transport ros-image-common-1.11.13/image_transport/src/list_transports.cpp000066400000000000000000000131641336567436300250170ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #include "image_transport/publisher_plugin.h" #include "image_transport/subscriber_plugin.h" #include #include #include #include using namespace image_transport; using namespace pluginlib; enum PluginStatus {SUCCESS, CREATE_FAILURE, LIB_LOAD_FAILURE, DOES_NOT_EXIST}; /// \cond struct TransportDesc { TransportDesc() : pub_status(DOES_NOT_EXIST), sub_status(DOES_NOT_EXIST) {} std::string package_name; std::string pub_name; PluginStatus pub_status; std::string sub_name; PluginStatus sub_status; }; /// \endcond int main(int argc, char** argv) { ClassLoader pub_loader("image_transport", "image_transport::PublisherPlugin"); ClassLoader sub_loader("image_transport", "image_transport::SubscriberPlugin"); typedef std::map StatusMap; StatusMap transports; BOOST_FOREACH(const std::string& lookup_name, pub_loader.getDeclaredClasses()) { std::string transport_name = boost::erase_last_copy(lookup_name, "_pub"); transports[transport_name].pub_name = lookup_name; transports[transport_name].package_name = pub_loader.getClassPackage(lookup_name); try { boost::shared_ptr pub = pub_loader.createInstance(lookup_name); transports[transport_name].pub_status = SUCCESS; } catch (const LibraryLoadException& e) { transports[transport_name].pub_status = LIB_LOAD_FAILURE; } catch (const CreateClassException& e) { transports[transport_name].pub_status = CREATE_FAILURE; } } BOOST_FOREACH(const std::string& lookup_name, sub_loader.getDeclaredClasses()) { std::string transport_name = boost::erase_last_copy(lookup_name, "_sub"); transports[transport_name].sub_name = lookup_name; transports[transport_name].package_name = sub_loader.getClassPackage(lookup_name); try { boost::shared_ptr sub = sub_loader.createInstance(lookup_name); transports[transport_name].sub_status = SUCCESS; } catch (const LibraryLoadException& e) { transports[transport_name].sub_status = LIB_LOAD_FAILURE; } catch (const CreateClassException& e) { transports[transport_name].sub_status = CREATE_FAILURE; } } bool problem_package = false; printf("Declared transports:\n"); BOOST_FOREACH(const StatusMap::value_type& value, transports) { const TransportDesc& td = value.second; printf("%s", value.first.c_str()); if ((td.pub_status == CREATE_FAILURE || td.pub_status == LIB_LOAD_FAILURE) || (td.sub_status == CREATE_FAILURE || td.sub_status == LIB_LOAD_FAILURE)) { printf(" (*): Not available. Try 'catkin_make --pkg %s'.", td.package_name.c_str()); problem_package = true; } printf("\n"); } #if 0 if (problem_package) printf("(*) \n"); #endif printf("\nDetails:\n"); BOOST_FOREACH(const StatusMap::value_type& value, transports) { const TransportDesc& td = value.second; printf("----------\n"); printf("\"%s\"\n", value.first.c_str()); if (td.pub_status == CREATE_FAILURE || td.sub_status == CREATE_FAILURE) { printf("*** Plugins are built, but could not be loaded. The package may need to be rebuilt or may not be compatible with this release of image_common. ***\n"); } else if (td.pub_status == LIB_LOAD_FAILURE || td.sub_status == LIB_LOAD_FAILURE) { printf("*** Plugins are not built. ***\n"); } printf(" - Provided by package: %s\n", td.package_name.c_str()); if (td.pub_status == DOES_NOT_EXIST) printf(" - No publisher provided\n"); else printf(" - Publisher: %s\n", pub_loader.getClassDescription(td.pub_name).c_str()); if (td.sub_status == DOES_NOT_EXIST) printf(" - No subscriber provided\n"); else printf(" - Subscriber: %s\n", sub_loader.getClassDescription(td.sub_name).c_str()); } return 0; } ros-image-common-1.11.13/image_transport/src/manifest.cpp000066400000000000000000000040451336567436300233510ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #include #include "image_transport/raw_publisher.h" #include "image_transport/raw_subscriber.h" PLUGINLIB_EXPORT_CLASS( image_transport::RawPublisher, image_transport::PublisherPlugin) PLUGINLIB_EXPORT_CLASS( image_transport::RawSubscriber, image_transport::SubscriberPlugin) ros-image-common-1.11.13/image_transport/src/publisher.cpp000066400000000000000000000153661336567436300235500ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #include "image_transport/publisher.h" #include "image_transport/publisher_plugin.h" #include #include #include namespace image_transport { struct Publisher::Impl { Impl() : unadvertised_(false) { } ~Impl() { shutdown(); } uint32_t getNumSubscribers() const { uint32_t count = 0; BOOST_FOREACH(const boost::shared_ptr& pub, publishers_) count += pub->getNumSubscribers(); return count; } std::string getTopic() const { return base_topic_; } bool isValid() const { return !unadvertised_; } void shutdown() { if (!unadvertised_) { unadvertised_ = true; BOOST_FOREACH(boost::shared_ptr& pub, publishers_) pub->shutdown(); publishers_.clear(); } } void subscriberCB(const SingleSubscriberPublisher& plugin_pub, const SubscriberStatusCallback& user_cb) { SingleSubscriberPublisher ssp(plugin_pub.getSubscriberName(), getTopic(), boost::bind(&Publisher::Impl::getNumSubscribers, this), plugin_pub.publish_fn_); user_cb(ssp); } std::string base_topic_; PubLoaderPtr loader_; std::vector > publishers_; bool unadvertised_; //double constructed_; }; Publisher::Publisher(ros::NodeHandle& nh, const std::string& base_topic, uint32_t queue_size, const SubscriberStatusCallback& connect_cb, const SubscriberStatusCallback& disconnect_cb, const ros::VoidPtr& tracked_object, bool latch, const PubLoaderPtr& loader) : impl_(new Impl) { // Resolve the name explicitly because otherwise the compressed topics don't remap // properly (#3652). impl_->base_topic_ = nh.resolveName(base_topic); impl_->loader_ = loader; std::vector blacklist_vec; std::set blacklist; nh.getParam(impl_->base_topic_ + "/disable_pub_plugins", blacklist_vec); for (size_t i = 0; i < blacklist_vec.size(); ++i) { blacklist.insert(blacklist_vec[i]); } BOOST_FOREACH(const std::string& lookup_name, loader->getDeclaredClasses()) { const std::string transport_name = boost::erase_last_copy(lookup_name, "_pub"); if (blacklist.count(transport_name)) { continue; } try { boost::shared_ptr pub = loader->createInstance(lookup_name); impl_->publishers_.push_back(pub); pub->advertise(nh, impl_->base_topic_, queue_size, rebindCB(connect_cb), rebindCB(disconnect_cb), tracked_object, latch); } catch (const std::runtime_error& e) { ROS_DEBUG("Failed to load plugin %s, error string: %s", lookup_name.c_str(), e.what()); } } if (impl_->publishers_.empty()) throw Exception("No plugins found! Does `rospack plugins --attrib=plugin " "image_transport` find any packages?"); } uint32_t Publisher::getNumSubscribers() const { if (impl_ && impl_->isValid()) return impl_->getNumSubscribers(); return 0; } std::string Publisher::getTopic() const { if (impl_) return impl_->getTopic(); return std::string(); } void Publisher::publish(const sensor_msgs::Image& message) const { if (!impl_ || !impl_->isValid()) { ROS_ASSERT_MSG(false, "Call to publish() on an invalid image_transport::Publisher"); return; } BOOST_FOREACH(const boost::shared_ptr& pub, impl_->publishers_) { if (pub->getNumSubscribers() > 0) pub->publish(message); } } void Publisher::publish(const sensor_msgs::ImageConstPtr& message) const { if (!impl_ || !impl_->isValid()) { ROS_ASSERT_MSG(false, "Call to publish() on an invalid image_transport::Publisher"); return; } BOOST_FOREACH(const boost::shared_ptr& pub, impl_->publishers_) { if (pub->getNumSubscribers() > 0) pub->publish(message); } } void Publisher::shutdown() { if (impl_) { impl_->shutdown(); impl_.reset(); } } Publisher::operator void*() const { return (impl_ && impl_->isValid()) ? (void*)1 : (void*)0; } void Publisher::weakSubscriberCb(const ImplWPtr& impl_wptr, const SingleSubscriberPublisher& plugin_pub, const SubscriberStatusCallback& user_cb) { if (ImplPtr impl = impl_wptr.lock()) impl->subscriberCB(plugin_pub, user_cb); } SubscriberStatusCallback Publisher::rebindCB(const SubscriberStatusCallback& user_cb) { // Note: the subscriber callback must be bound to the internal Impl object, not // 'this'. Due to copying behavior the Impl object may outlive the original Publisher // instance. But it should not outlive the last Publisher, so we use a weak_ptr. if (user_cb) { ImplWPtr impl_wptr(impl_); return boost::bind(&Publisher::weakSubscriberCb, impl_wptr, _1, user_cb); } else return SubscriberStatusCallback(); } } //namespace image_transport ros-image-common-1.11.13/image_transport/src/raw_publisher.cpp000066400000000000000000000115371336567436300244150ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #include #include #include /** The code in the following namespace copies a lof of code from cv_bridge * It does not depend on cv_bridge to not depend on OpenCV * It re-defines a CvImage so that we can publish that object and not a * sensor_msgs::Image, which requires a memory copy */ class ImageTransportImage { public: sensor_msgs::Image image_; //!< ROS header const uint8_t* data_; //!< Image data for use with OpenCV /** * \brief Empty constructor. */ ImageTransportImage() {} /** * \brief Constructor. */ ImageTransportImage(const sensor_msgs::Image& image, const uint8_t* data) : image_(image), data_(data) { } }; /// @cond DOXYGEN_IGNORE namespace ros { namespace message_traits { template<> struct MD5Sum { static const char* value() { return MD5Sum::value(); } static const char* value(const ImageTransportImage&) { return value(); } static const uint64_t static_value1 = MD5Sum::static_value1; static const uint64_t static_value2 = MD5Sum::static_value2; // If the definition of sensor_msgs/Image changes, we'll get a compile error here. ROS_STATIC_ASSERT(MD5Sum::static_value1 == 0x060021388200f6f0ULL); ROS_STATIC_ASSERT(MD5Sum::static_value2 == 0xf447d0fcd9c64743ULL); }; template<> struct DataType { static const char* value() { return DataType::value(); } static const char* value(const ImageTransportImage&) { return value(); } }; template<> struct Definition { static const char* value() { return Definition::value(); } static const char* value(const ImageTransportImage&) { return value(); } }; template<> struct HasHeader : TrueType {}; } // namespace ros::message_traits namespace serialization { template<> struct Serializer { /// @todo Still ignoring endianness... template inline static void write(Stream& stream, const ImageTransportImage& m) { stream.next(m.image_.header); stream.next((uint32_t)m.image_.height); // height stream.next((uint32_t)m.image_.width); // width stream.next(m.image_.encoding); uint8_t is_bigendian = 0; stream.next(is_bigendian); stream.next((uint32_t)m.image_.step); size_t data_size = m.image_.step*m.image_.height; stream.next((uint32_t)data_size); if (data_size > 0) memcpy(stream.advance(data_size), m.data_, data_size); } inline static uint32_t serializedLength(const ImageTransportImage& m) { size_t data_size = m.image_.step*m.image_.height; return serializationLength(m.image_.header) + serializationLength(m.image_.encoding) + 17 + data_size; } }; } // namespace ros::serialization } // namespace ros namespace image_transport { void RawPublisher::publish(const sensor_msgs::Image& message, const uint8_t* data) const { getPublisher().publish(ImageTransportImage(message, data)); } } //namespace image_transport ros-image-common-1.11.13/image_transport/src/republish.cpp000066400000000000000000000073301336567436300235400ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #include "image_transport/image_transport.h" #include "image_transport/publisher_plugin.h" #include int main(int argc, char** argv) { ros::init(argc, argv, "image_republisher", ros::init_options::AnonymousName); if (argc < 2) { printf("Usage: %s in_transport in:= [out_transport] out:=\n", argv[0]); return 0; } ros::NodeHandle nh; std::string in_topic = nh.resolveName("in"); std::string in_transport = argv[1]; std::string out_topic = nh.resolveName("out"); image_transport::ImageTransport it(nh); image_transport::Subscriber sub; if (argc < 3) { // Use all available transports for output image_transport::Publisher pub = it.advertise(out_topic, 1); // Use Publisher::publish as the subscriber callback typedef void (image_transport::Publisher::*PublishMemFn)(const sensor_msgs::ImageConstPtr&) const; PublishMemFn pub_mem_fn = &image_transport::Publisher::publish; sub = it.subscribe(in_topic, 1, boost::bind(pub_mem_fn, &pub, _1), ros::VoidPtr(), in_transport); ros::spin(); } else { // Use one specific transport for output std::string out_transport = argv[2]; // Load transport plugin typedef image_transport::PublisherPlugin Plugin; pluginlib::ClassLoader loader("image_transport", "image_transport::PublisherPlugin"); std::string lookup_name = Plugin::getLookupName(out_transport); boost::shared_ptr pub( loader.createInstance(lookup_name) ); pub->advertise(nh, out_topic, 1, image_transport::SubscriberStatusCallback(), image_transport::SubscriberStatusCallback(), ros::VoidPtr(), false); // Use PublisherPlugin::publish as the subscriber callback typedef void (Plugin::*PublishMemFn)(const sensor_msgs::ImageConstPtr&) const; PublishMemFn pub_mem_fn = &Plugin::publish; sub = it.subscribe(in_topic, 1, boost::bind(pub_mem_fn, pub.get(), _1), pub, in_transport); ros::spin(); } return 0; } ros-image-common-1.11.13/image_transport/src/single_subscriber_publisher.cpp000066400000000000000000000054271336567436300273310ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #include "image_transport/single_subscriber_publisher.h" #include "image_transport/publisher.h" namespace image_transport { SingleSubscriberPublisher::SingleSubscriberPublisher(const std::string& caller_id, const std::string& topic, const GetNumSubscribersFn& num_subscribers_fn, const PublishFn& publish_fn) : caller_id_(caller_id), topic_(topic), num_subscribers_fn_(num_subscribers_fn), publish_fn_(publish_fn) { } std::string SingleSubscriberPublisher::getSubscriberName() const { return caller_id_; } std::string SingleSubscriberPublisher::getTopic() const { return topic_; } uint32_t SingleSubscriberPublisher::getNumSubscribers() const { return num_subscribers_fn_(); } void SingleSubscriberPublisher::publish(const sensor_msgs::Image& message) const { publish_fn_(message); } void SingleSubscriberPublisher::publish(const sensor_msgs::ImageConstPtr& message) const { publish_fn_(*message); } } //namespace image_transport ros-image-common-1.11.13/image_transport/src/subscriber.cpp000066400000000000000000000117141336567436300237070ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #include "image_transport/subscriber.h" #include "image_transport/subscriber_plugin.h" #include #include #include namespace image_transport { struct Subscriber::Impl { Impl() : unsubscribed_(false) { } ~Impl() { shutdown(); } bool isValid() const { return !unsubscribed_; } void shutdown() { if (!unsubscribed_) { unsubscribed_ = true; if (subscriber_) subscriber_->shutdown(); } } SubLoaderPtr loader_; boost::shared_ptr subscriber_; bool unsubscribed_; //double constructed_; }; Subscriber::Subscriber(ros::NodeHandle& nh, const std::string& base_topic, uint32_t queue_size, const boost::function& callback, const ros::VoidPtr& tracked_object, const TransportHints& transport_hints, const SubLoaderPtr& loader) : impl_(new Impl) { // Load the plugin for the chosen transport. std::string lookup_name = SubscriberPlugin::getLookupName(transport_hints.getTransport()); try { impl_->subscriber_ = loader->createInstance(lookup_name); } catch (pluginlib::PluginlibException& e) { throw TransportLoadException(transport_hints.getTransport(), e.what()); } // Hang on to the class loader so our shared library doesn't disappear from under us. impl_->loader_ = loader; // Try to catch if user passed in a transport-specific topic as base_topic. std::string clean_topic = ros::names::clean(base_topic); size_t found = clean_topic.rfind('/'); if (found != std::string::npos) { std::string transport = clean_topic.substr(found+1); std::string plugin_name = SubscriberPlugin::getLookupName(transport); std::vector plugins = loader->getDeclaredClasses(); if (std::find(plugins.begin(), plugins.end(), plugin_name) != plugins.end()) { std::string real_base_topic = clean_topic.substr(0, found); ROS_WARN("[image_transport] It looks like you are trying to subscribe directly to a " "transport-specific image topic '%s', in which case you will likely get a connection " "error. Try subscribing to the base topic '%s' instead with parameter ~image_transport " "set to '%s' (on the command line, _image_transport:=%s). " "See http://ros.org/wiki/image_transport for details.", clean_topic.c_str(), real_base_topic.c_str(), transport.c_str(), transport.c_str()); } } // Tell plugin to subscribe. impl_->subscriber_->subscribe(nh, base_topic, queue_size, callback, tracked_object, transport_hints); } std::string Subscriber::getTopic() const { if (impl_) return impl_->subscriber_->getTopic(); return std::string(); } uint32_t Subscriber::getNumPublishers() const { if (impl_) return impl_->subscriber_->getNumPublishers(); return 0; } std::string Subscriber::getTransport() const { if (impl_) return impl_->subscriber_->getTransportName(); return std::string(); } void Subscriber::shutdown() { if (impl_) impl_->shutdown(); } Subscriber::operator void*() const { return (impl_ && impl_->isValid()) ? (void*)1 : (void*)0; } } //namespace image_transport ros-image-common-1.11.13/image_transport/tutorial/000077500000000000000000000000001336567436300221105ustar00rootroot00000000000000ros-image-common-1.11.13/image_transport/tutorial/CMakeLists.txt000066400000000000000000000032171336567436300246530ustar00rootroot00000000000000cmake_minimum_required(VERSION 2.8) project(image_transport_tutorial) find_package(catkin REQUIRED COMPONENTS cv_bridge image_transport message_generation sensor_msgs) # add the resized image message add_message_files(DIRECTORY msg FILES ResizedImage.msg ) generate_messages(DEPENDENCIES sensor_msgs) catkin_package(CATKIN_DEPENDS cv_bridge image_transport message_runtime sensor_msgs) find_package(OpenCV) include_directories(include ${catkin_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS}) # add the publisher example add_executable(my_publisher src/my_publisher.cpp) add_dependencies(my_publisher ${catkin_EXPORTED_TARGETS} ${${PROJECT_NAME}_EXPORTED_TARGETS}) target_link_libraries(my_publisher ${catkin_LIBRARIES} ${OpenCV_LIBRARIES}) # add the subscriber example add_executable(my_subscriber src/my_subscriber.cpp) add_dependencies(my_subscriber ${catkin_EXPORTED_TARGETS} ${${PROJECT_NAME}_EXPORTED_TARGETS}) target_link_libraries(my_subscriber ${catkin_LIBRARIES} ${OpenCV_LIBRARIES}) # add the plugin example add_library(resized_publisher src/manifest.cpp src/resized_publisher.cpp src/resized_subscriber.cpp) add_dependencies(resized_publisher ${catkin_EXPORTED_TARGETS} ${${PROJECT_NAME}_EXPORTED_TARGETS}) target_link_libraries(resized_publisher ${catkin_LIBRARIES} ${OpenCV_LIBRARIES}) # Mark executables and/or libraries for installation install(TARGETS my_publisher my_subscriber resized_publisher ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} ) install(FILES resized_plugins.xml DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} ) ros-image-common-1.11.13/image_transport/tutorial/include/000077500000000000000000000000001336567436300235335ustar00rootroot00000000000000ros-image-common-1.11.13/image_transport/tutorial/include/image_transport_tutorial/000077500000000000000000000000001336567436300306545ustar00rootroot00000000000000resized_publisher.h000066400000000000000000000006631336567436300344750ustar00rootroot00000000000000ros-image-common-1.11.13/image_transport/tutorial/include/image_transport_tutorial#include #include class ResizedPublisher : public image_transport::SimplePublisherPlugin { public: virtual std::string getTransportName() const { return "resized"; } protected: virtual void publish(const sensor_msgs::Image& message, const PublishFn& publish_fn) const; }; resized_subscriber.h000066400000000000000000000010101336567436300346260ustar00rootroot00000000000000ros-image-common-1.11.13/image_transport/tutorial/include/image_transport_tutorial#include #include class ResizedSubscriber : public image_transport::SimpleSubscriberPlugin { public: virtual ~ResizedSubscriber() {} virtual std::string getTransportName() const { return "resized"; } protected: virtual void internalCallback(const typename image_transport_tutorial::ResizedImage::ConstPtr& message, const Callback& user_cb); }; ros-image-common-1.11.13/image_transport/tutorial/msg/000077500000000000000000000000001336567436300226765ustar00rootroot00000000000000ros-image-common-1.11.13/image_transport/tutorial/msg/ResizedImage.msg000066400000000000000000000001051336567436300257520ustar00rootroot00000000000000uint32 original_height uint32 original_width sensor_msgs/Image image ros-image-common-1.11.13/image_transport/tutorial/package.xml000066400000000000000000000016331336567436300242300ustar00rootroot00000000000000 image_transport_tutorial 0.0.0 Tutorial for image_transport. This is useful for the tutorials at http://wiki.ros.org/image_transport/Tutorials/ Vincent Rabaud Vincent Rabaud Apache 2.0 cv_bridge image_transport message_generation opencv2 sensor_msgs cv_bridge image_transport message_runtime opencv2 sensor_msgs catkin ros-image-common-1.11.13/image_transport/tutorial/resized_plugins.xml000066400000000000000000000007571336567436300260510ustar00rootroot00000000000000 This plugin publishes a decimated version of the image. This plugin rescales a decimated image to its original size. ros-image-common-1.11.13/image_transport/tutorial/src/000077500000000000000000000000001336567436300226775ustar00rootroot00000000000000ros-image-common-1.11.13/image_transport/tutorial/src/manifest.cpp000066400000000000000000000004641336567436300252150ustar00rootroot00000000000000#include #include #include PLUGINLIB_EXPORT_CLASS(ResizedPublisher, image_transport::PublisherPlugin) PLUGINLIB_EXPORT_CLASS(ResizedSubscriber, image_transport::SubscriberPlugin) ros-image-common-1.11.13/image_transport/tutorial/src/my_publisher.cpp000066400000000000000000000011641336567436300261070ustar00rootroot00000000000000#include #include #include #include int main(int argc, char** argv) { ros::init(argc, argv, "image_publisher"); ros::NodeHandle nh; image_transport::ImageTransport it(nh); image_transport::Publisher pub = it.advertise("camera/image", 1); cv::Mat image = cv::imread(argv[1], CV_LOAD_IMAGE_COLOR); sensor_msgs::ImagePtr msg = cv_bridge::CvImage(std_msgs::Header(), "bgr8", image).toImageMsg(); ros::Rate loop_rate(5); while (nh.ok()) { pub.publish(msg); ros::spinOnce(); loop_rate.sleep(); } } ros-image-common-1.11.13/image_transport/tutorial/src/my_subscriber.cpp000066400000000000000000000013561336567436300262600ustar00rootroot00000000000000#include #include #include #include void imageCallback(const sensor_msgs::ImageConstPtr& msg) { try { cv::imshow("view", cv_bridge::toCvShare(msg, "bgr8")->image); cv::waitKey(10); } catch (cv_bridge::Exception& e) { ROS_ERROR("Could not convert from '%s' to 'bgr8'.", msg->encoding.c_str()); } } int main(int argc, char **argv) { ros::init(argc, argv, "image_listener"); ros::NodeHandle nh; cv::namedWindow("view"); cv::startWindowThread(); image_transport::ImageTransport it(nh); image_transport::Subscriber sub = it.subscribe("camera/image", 1, imageCallback); ros::spin(); cv::destroyWindow("view"); } ros-image-common-1.11.13/image_transport/tutorial/src/resized_publisher.cpp000066400000000000000000000024661336567436300271350ustar00rootroot00000000000000#include #include #include void ResizedPublisher::publish(const sensor_msgs::Image& message, const PublishFn& publish_fn) const { cv::Mat cv_image; boost::shared_ptr tracked_object; try { cv_image = cv_bridge::toCvShare(message, tracked_object, message.encoding)->image; } catch (cv::Exception &e) { ROS_ERROR("Could not convert from '%s' to '%s'.", message.encoding.c_str(), message.encoding.c_str()); return; } // Retrieve subsampling factor from the parameter server double subsampling_factor; std::string param_name; nh().param("resized_image_transport_subsampling_factor", subsampling_factor, 2.0); // Rescale image int new_width = cv_image.cols / subsampling_factor + 0.5; int new_height = cv_image.rows / subsampling_factor + 0.5; cv::Mat buffer; cv::resize(cv_image, buffer, cv::Size(new_width, new_height)); // Set up ResizedImage and publish image_transport_tutorial::ResizedImage resized_image; resized_image.original_height = cv_image.rows; resized_image.original_width = cv_image.cols; resized_image.image = *(cv_bridge::CvImage(message.header, "bgr8", cv_image).toImageMsg()); publish_fn(resized_image); } ros-image-common-1.11.13/image_transport/tutorial/src/resized_subscriber.cpp000066400000000000000000000014631336567436300272770ustar00rootroot00000000000000#include #include #include void ResizedSubscriber::internalCallback(const image_transport_tutorial::ResizedImage::ConstPtr& msg, const Callback& user_cb) { // This is only for optimization, not to copy the image boost::shared_ptr tracked_object_tmp; cv::Mat img_rsz = cv_bridge::toCvShare(msg->image, tracked_object_tmp)->image; // Resize the image to its original size cv::Mat img_restored; cv::resize(img_rsz, img_restored, cv::Size(msg->original_width, msg->original_height)); // Call the user callback with the restored image cv_bridge::CvImage cv_img(msg->image.header, msg->image.encoding, img_restored); user_cb(cv_img.toImageMsg()); }; ros-image-common-1.11.13/polled_camera/000077500000000000000000000000001336567436300176365ustar00rootroot00000000000000ros-image-common-1.11.13/polled_camera/CHANGELOG.rst000066400000000000000000000107741336567436300216700ustar00rootroot00000000000000^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Changelog for package polled_camera ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1.11.13 (2017-11-05) -------------------- 1.11.12 (2017-01-29) -------------------- * Fix CMake of image_transport/tutorial and polled_camera Fix loads of problems with the CMakeLists. * 1.11.11 * update changelogs * address gcc6 build error in polled_camera With gcc6, compiling fails with `stdlib.h: No such file or directory`, as including '-isystem /usr/include' breaks with gcc6, cf., https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70129. This commit addresses this issue for this package in the same way it was addressed in various other ROS packages. A list of related commits and pull requests is at: https://github.com/ros/rosdistro/issues/12783 Signed-off-by: Lukas Bulwahn * Contributors: Lukas Bulwahn, Martin Guenther, Vincent Rabaud 1.11.11 (2016-09-24) -------------------- * address gcc6 build error in polled_camera With gcc6, compiling fails with `stdlib.h: No such file or directory`, as including '-isystem /usr/include' breaks with gcc6, cf., https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70129. This commit addresses this issue for this package in the same way it was addressed in various other ROS packages. A list of related commits and pull requests is at: https://github.com/ros/rosdistro/issues/12783 Signed-off-by: Lukas Bulwahn * Contributors: Lukas Bulwahn 1.11.10 (2016-01-19) -------------------- 1.11.9 (2016-01-17) ------------------- 1.11.8 (2015-11-29) ------------------- 1.11.7 (2015-07-28) ------------------- 1.11.6 (2015-07-16) ------------------- 1.11.5 (2015-05-14) ------------------- 1.11.4 (2014-09-21) ------------------- 1.11.3 (2014-05-19) ------------------- 1.11.2 (2014-02-13) ------------------- 1.11.1 (2014-01-26 02:33) ------------------------- 1.11.0 (2013-07-20 12:23) ------------------------- 1.10.5 (2014-01-26 02:34) ------------------------- 1.10.4 (2013-07-20 11:42) ------------------------- * add Jack as maintainer * Contributors: Vincent Rabaud 1.10.3 (2013-02-21 05:33) ------------------------- 1.10.2 (2013-02-21 04:48) ------------------------- 1.10.1 (2013-02-21 04:16) ------------------------- 1.10.0 (2013-01-13) ------------------- * use CATKIN_DEVEL_PREFIX instead of obsolete CATKIN_BUILD_PREFIX * fix the urls * Missing link flags exposed on OS X * added license headers to various cpp and h files * Contributors: Aaron Blasdel, Dirk Thomas, Vincent Rabaud, William Woodall 1.9.22 (2012-12-16) ------------------- * replace genmsg by message_generation * Contributors: Vincent Rabaud 1.9.21 (2012-12-14) ------------------- * Updated package.xml file(s) to handle new catkin buildtool_depend requirement * Contributors: mirzashah 1.9.20 (2012-12-04) ------------------- 1.9.19 (2012-11-08) ------------------- 1.9.18 (2012-11-06) ------------------- * remove the brief attribute * Contributors: Vincent Rabaud 1.9.17 (2012-10-30 19:32) ------------------------- * comlpy to the new catkin API * Contributors: Vincent Rabaud 1.9.16 (2012-10-30 09:10) ------------------------- 1.9.15 (2012-10-13 08:43) ------------------------- * fix bad folder/libraries * Contributors: Vincent Rabaud 1.9.14 (2012-10-13 01:07) ------------------------- * fix typo that resulted in bad installation of include folder * Contributors: Vincent Rabaud 1.9.13 (2012-10-06) ------------------- 1.9.12 (2012-10-04) ------------------- 1.9.11 (2012-10-02 02:56) ------------------------- 1.9.10 (2012-10-02 02:42) ------------------------- 1.9.9 (2012-10-01) ------------------ * fix dependencies * Contributors: Vincent Rabaud 1.9.8 (2012-09-30) ------------------ * add catkin as a dependency * comply to the catkin API * Contributors: Vincent Rabaud 1.9.7 (2012-09-18 11:39) ------------------------ 1.9.6 (2012-09-18 11:07) ------------------------ 1.9.5 (2012-09-13) ------------------ * install the include directories * Contributors: Vincent Rabaud 1.9.4 (2012-09-12 23:37) ------------------------ * make sure we depend on the server * Contributors: Vincent Rabaud 1.9.3 (2012-09-12 20:44) ------------------------ 1.9.2 (2012-09-10) ------------------ 1.9.1 (2012-09-07 15:33) ------------------------ 1.9.0 (2012-09-07 13:03) ------------------------ * catkinize for Groovy * polled_camera (rep0104): Changed callback to allow filling status_message field. * polled_camera (rep0104): Applied changes to GetPolledImage service. * Contributors: Vincent Rabaud, eitan, gerkey, kwc, mihelich ros-image-common-1.11.13/polled_camera/CMakeLists.txt000066400000000000000000000025501336567436300224000ustar00rootroot00000000000000cmake_minimum_required(VERSION 2.8) project(polled_camera) # generate the server find_package(catkin REQUIRED COMPONENTS image_transport message_generation roscpp sensor_msgs std_msgs) add_service_files(DIRECTORY srv FILES GetPolledImage.srv) generate_messages(DEPENDENCIES sensor_msgs std_msgs) # define the project catkin_package(CATKIN_DEPENDS image_transport message_runtime roscpp sensor_msgs std_msgs INCLUDE_DIRS include LIBRARIES ${PROJECT_NAME} ) # create some library and exe include_directories(include ${catkin_INCLUDE_DIRS} ${CATKIN_DEVEL_PREFIX}/${CATKIN_GLOBAL_INCLUDE_DESTINATION} ) add_library(${PROJECT_NAME} src/publication_server.cpp) add_dependencies(${PROJECT_NAME} ${catkin_EXPORTED_TARGETS} ${${PROJECT_NAME}_EXPORTED_TARGETS}) target_link_libraries(${PROJECT_NAME} ${catkin_LIBRARIES}) install(TARGETS ${PROJECT_NAME} DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} ) install(DIRECTORY include/${PROJECT_NAME}/ DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} ) add_executable(poller src/poller.cpp) add_dependencies(poller ${catkin_EXPORTED_TARGETS} ${${PROJECT_NAME}_EXPORTED_TARGETS}) target_link_libraries(poller ${PROJECT_NAME} ${catkin_LIBRARIES} ) install(TARGETS poller DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} ) ros-image-common-1.11.13/polled_camera/include/000077500000000000000000000000001336567436300212615ustar00rootroot00000000000000ros-image-common-1.11.13/polled_camera/include/polled_camera/000077500000000000000000000000001336567436300240505ustar00rootroot00000000000000ros-image-common-1.11.13/polled_camera/include/polled_camera/publication_server.h000066400000000000000000000125131336567436300301220ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #ifndef POLLED_CAMERA_PUBLICATION_SERVER_H #define POLLED_CAMERA_PUBLICATION_SERVER_H #include #include #include #include "polled_camera/GetPolledImage.h" namespace polled_camera { /** * \brief Manage image requests from one or more clients. * * Instances of polled_camera::PublicationServer should be created using one of * the overloads of polled_camera::advertise(). You must specify a driver * callback that populates the requested data: \code void callback(polled_camera::GetPolledImage::Request& req, polled_camera::GetPolledImage::Response& rsp, sensor_msgs::Image& image, sensor_msgs::CameraInfo& info) { // Capture an image and fill in the Image and CameraInfo messages here. // On success, set rsp.success = true. rsp.timestamp will be filled in // automatically. // On failure, set rsp.success = false and fill rsp.status_message with an // informative error message. } \endcode */ class PublicationServer { public: typedef boost::function DriverCallback; PublicationServer() {} /** * \brief Unadvertise the request service and shut down all published topics. */ void shutdown(); std::string getService() const; operator void*() const; bool operator< (const PublicationServer& rhs) const { return impl_ < rhs.impl_; } bool operator==(const PublicationServer& rhs) const { return impl_ == rhs.impl_; } bool operator!=(const PublicationServer& rhs) const { return impl_ != rhs.impl_; } private: PublicationServer(const std::string& service, ros::NodeHandle& nh, const DriverCallback& cb, const ros::VoidPtr& tracked_object); class Impl; boost::shared_ptr impl_; friend PublicationServer advertise(ros::NodeHandle&, const std::string&, const DriverCallback&, const ros::VoidPtr&); }; /** * \brief Advertise a polled image service, version for arbitrary boost::function object. */ PublicationServer advertise(ros::NodeHandle& nh, const std::string& service, const PublicationServer::DriverCallback& cb, const ros::VoidPtr& tracked_object = ros::VoidPtr()); /** * \brief Advertise a polled image service, version for class member function with bare pointer. */ template PublicationServer advertise(ros::NodeHandle& nh, const std::string& service, void(T::*fp)(polled_camera::GetPolledImage::Request&, polled_camera::GetPolledImage::Response&, sensor_msgs::Image&, sensor_msgs::CameraInfo&), T* obj) { return advertise(nh, service, boost::bind(fp, obj, _1, _2, _3, _4)); } /** * \brief Advertise a polled image service, version for class member function with bare pointer. */ template PublicationServer advertise(ros::NodeHandle& nh, const std::string& service, void(T::*fp)(polled_camera::GetPolledImage::Request&, polled_camera::GetPolledImage::Response&, sensor_msgs::Image&, sensor_msgs::CameraInfo&), const boost::shared_ptr& obj) { return advertise(nh, service, boost::bind(fp, obj.get(), _1, _2, _3, _4), obj); } } //namespace polled_camera #endif ros-image-common-1.11.13/polled_camera/mainpage.dox000066400000000000000000000035631336567436300221420ustar00rootroot00000000000000/** \mainpage \htmlinclude manifest.html NOTE: This package's API is not yet released. It may change from its current form. \b polled_camera contains a service definition for requesting polled images, as well as a C++ server class to simplify publishing polled images to clients. The protocol for polling images from a camera driver node that supports it is as follows: - The camera driver advertises a service call \c \/request_image. - The client calls the service, specifying an output namespace in the request. - On receiving a request, the driver captures an image and returns its time stamp in the service response. - The \c Image and \c CameraInfo are published to \c \/image_raw and \c \/camera_info, latched. - Clients subscribe to the response topics just like any other camera image stream. \section codeapi Code API Use polled_camera::PublicationServer in camera driver nodes (or similar) to track client connections and respond to image requests. There is not currently a matching client class, but receiving polled images is identical to subscribing to any other image topic. The only additional step is using a ros::ServiceClient to make explicit requests: \code #include #include #include void callback(const sensor_msgs::ImageConstPtr& image, const sensor_msgs::CameraInfoConstPtr& info); ros::NodeHandle nh; image_transport::ImageTransport it(nh); image_transport::CameraSubscriber sub = it.subscribeCamera("output_ns/image_raw", 1, callback); ros::ServiceClient client = nh.serviceClient("my_camera/request_image"); polled_camera::GetPolledImage srv; srv.request.response_namespace = "output_ns"; if (client.call(srv)) { ROS_INFO_STREAM("Image captured with timestamp " << srv.response.stamp); } \endcode */ ros-image-common-1.11.13/polled_camera/package.xml000066400000000000000000000023221336567436300217520ustar00rootroot00000000000000 polled_camera 1.11.13 polled_camera contains a service and C++ helper classes for implementing a polled camera driver node and requesting images from it. The package is currently for internal use as the API is still under development. Patrick Mihelich Jack O'Quin Vincent Rabaud BSD http://ros.org/wiki/polled_camera https://github.com/ros-perception/image_common/issues https://github.com/ros-perception/image_common catkin image_transport message_generation roscpp sensor_msgs std_msgs image_transport message_runtime roscpp sensor_msgs std_msgs ros-image-common-1.11.13/polled_camera/src/000077500000000000000000000000001336567436300204255ustar00rootroot00000000000000ros-image-common-1.11.13/polled_camera/src/poller.cpp000066400000000000000000000053221336567436300224300ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #include #include #include #include "polled_camera/GetPolledImage.h" int main(int argc, char** argv) { ros::init(argc, argv, "poller", ros::init_options::AnonymousName); if (argc < 2) { printf("Usage: %s camera:= output:=\n", argv[0]); return 0; } double hz = boost::lexical_cast(argv[1]); ros::NodeHandle nh; std::string service_name = nh.resolveName("camera") + "/request_image"; ros::ServiceClient client = nh.serviceClient(service_name); polled_camera::GetPolledImage::Request req; polled_camera::GetPolledImage::Response rsp; req.response_namespace = nh.resolveName("output"); ros::Rate loop_rate(hz); while (nh.ok()) { if (client.call(req, rsp)) { std::cout << "Timestamp: " << rsp.stamp << std::endl; loop_rate.sleep(); } else { ROS_ERROR("Service call failed"); client.waitForExistence(); } } } ros-image-common-1.11.13/polled_camera/src/publication_server.cpp000066400000000000000000000126151336567436300250350ustar00rootroot00000000000000/********************************************************************* * Software License Agreement (BSD License) * * Copyright (c) 2009, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Willow Garage nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ #include "polled_camera/publication_server.h" #include namespace polled_camera { /// \cond class PublicationServer::Impl { public: ros::ServiceServer srv_server_; DriverCallback driver_cb_; ros::VoidPtr tracked_object_; image_transport::ImageTransport it_; std::map client_map_; bool unadvertised_; double constructed_; Impl(const ros::NodeHandle& nh) : it_(nh), unadvertised_(false), constructed_(ros::WallTime::now().toSec()) { } ~Impl() { if (ros::WallTime::now().toSec() - constructed_ < 0.001) ROS_WARN("PublicationServer destroyed immediately after creation. Did you forget to store the handle?"); unadvertise(); } bool isValid() const { return !unadvertised_; } void unadvertise() { if (!unadvertised_) { unadvertised_ = true; srv_server_.shutdown(); client_map_.clear(); } } bool requestCallback(polled_camera::GetPolledImage::Request& req, polled_camera::GetPolledImage::Response& rsp) { std::string image_topic = req.response_namespace + "/image_raw"; image_transport::CameraPublisher& pub = client_map_[image_topic]; if (!pub) { // Create a latching camera publisher. pub = it_.advertiseCamera(image_topic, 1, image_transport::SubscriberStatusCallback(), boost::bind(&Impl::disconnectCallback, this, _1), ros::SubscriberStatusCallback(), ros::SubscriberStatusCallback(), ros::VoidPtr(), true /*latch*/); ROS_INFO("Advertising %s", pub.getTopic().c_str()); } // Correct zero binning values to one for convenience req.binning_x = std::max(req.binning_x, (uint32_t)1); req.binning_y = std::max(req.binning_y, (uint32_t)1); /// @todo Use pointers in prep for nodelet drivers? sensor_msgs::Image image; sensor_msgs::CameraInfo info; driver_cb_(req, rsp, image, info); if (rsp.success) { assert(image.header.stamp == info.header.stamp); rsp.stamp = image.header.stamp; pub.publish(image, info); } else { ROS_ERROR("Failed to capture requested image, status message: '%s'", rsp.status_message.c_str()); } return true; // Success/failure indicated by rsp.success } void disconnectCallback(const image_transport::SingleSubscriberPublisher& ssp) { // Shut down the publication when the subscription count drops to zero. if (ssp.getNumSubscribers() == 0) { ROS_INFO("Shutting down %s", ssp.getTopic().c_str()); client_map_.erase(ssp.getTopic()); } } }; /// \endcond PublicationServer::PublicationServer(const std::string& service, ros::NodeHandle& nh, const DriverCallback& cb, const ros::VoidPtr& tracked_object) : impl_(new Impl(nh)) { impl_->driver_cb_ = cb; impl_->tracked_object_ = tracked_object; impl_->srv_server_ = nh.advertiseService<>(service, &Impl::requestCallback, impl_); } void PublicationServer::shutdown() { if (impl_) impl_->unadvertise(); } std::string PublicationServer::getService() const { if (impl_) return impl_->srv_server_.getService(); return std::string(); } PublicationServer::operator void*() const { return (impl_ && impl_->isValid()) ? (void*)1 : (void*)0; } PublicationServer advertise(ros::NodeHandle& nh, const std::string& service, const PublicationServer::DriverCallback& cb, const ros::VoidPtr& tracked_object) { return PublicationServer(service, nh, cb, tracked_object); } } //namespace polled_camera ros-image-common-1.11.13/polled_camera/srv/000077500000000000000000000000001336567436300204505ustar00rootroot00000000000000ros-image-common-1.11.13/polled_camera/srv/GetPolledImage.srv000066400000000000000000000014671336567436300240360ustar00rootroot00000000000000# Namespace to publish response topics in. A polled camera driver node # should publish: # /image_raw # /camera_info string response_namespace # Timeout for attempting to capture data from the device. This does not # include latency from ROS communication, post-processing of raw camera # data, etc. A zero duration indicates no time limit. duration timeout # Binning settings, if supported by the camera. uint32 binning_x uint32 binning_y # Region of interest, if supported by the camera. sensor_msgs/RegionOfInterest roi --- bool success # Could the image be captured? string status_message # Error message in case of failure time stamp # Timestamp of the captured image. Can be matched # against incoming sensor_msgs/Image header.