estimate_transform.h
Go to the documentation of this file.
00001 /*********************************************************************
00002  *
00003  * Software License Agreement (BSD License)
00004  *
00005  *  Copyright (c) 2015-2016, Jiri Horner.
00006  *  All rights reserved.
00007  *
00008  *  Redistribution and use in source and binary forms, with or without
00009  *  modification, are permitted provided that the following conditions
00010  *  are met:
00011  *
00012  *   * Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *   * Redistributions in binary form must reproduce the above
00015  *     copyright notice, this list of conditions and the following
00016  *     disclaimer in the documentation and/or other materials provided
00017  *     with the distribution.
00018  *   * Neither the name of the author nor the names of its
00019  *     contributors may be used to endorse or promote products derived
00020  *     from this software without specific prior written permission.
00021  *
00022  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00023  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00024  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00025  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00026  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00027  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00028  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00029  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00030  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00032  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00033  *  POSSIBILITY OF SUCH DAMAGE.
00034  *
00035  *********************************************************************/
00036 
00037 #ifndef ESTIMATE_TRANSFORM_H_
00038 #define ESTIMATE_TRANSFORM_H_
00039 
00040 #include <vector>
00041 #include <type_traits>
00042 #include <cmath>
00043 
00044 #include <ros/console.h>
00045 #include <ros/assert.h>
00046 #include <nav_msgs/OccupancyGrid.h>
00047 #include <geometry_msgs/Pose.h>
00048 #include <tf/transform_datatypes.h>
00049 
00050 #include <opencv2/core/utility.hpp>
00051 
00052 namespace combine_grids
00053 {
00078 template <typename ForwardIt, typename OutputIt>
00079 size_t estimateGridTransform(ForwardIt grids_begin, ForwardIt grids_end,
00080                              OutputIt transforms_begin,
00081                              double confidence = 1.0);
00082 
00083 namespace internal
00084 {
00100 size_t opencvEstimateTransform(const std::vector<cv::Mat>& images,
00101                                std::vector<cv::Mat>& transforms,
00102                                double confidence);
00103 
00104 }  // namespace internal
00105 }  // namespace combine_grids
00106 
00107 /* implementation */
00108 
00109 namespace combine_grids
00110 {
00111 template <typename ForwardIt, typename OutputIt>
00112 size_t estimateGridTransform(ForwardIt grids_begin, ForwardIt grids_end,
00113                              OutputIt transforms_begin, double confidence)
00114 {
00115   static_assert(std::is_assignable<nav_msgs::OccupancyGrid&,
00116                                    decltype(*grids_begin)>::value,
00117                 "grids_begin must point to nav_msgs::OccupancyGrid data");
00118 
00119   static_assert(std::is_assignable<geometry_msgs::Pose&,
00120                                    decltype(*transforms_begin)>::value,
00121                 "transforms_begin must point to geometry_msgs::Pose data");
00122 
00123   std::vector<cv::Mat> images;
00124   std::vector<cv::Mat> transforms;
00125 
00126   ROS_DEBUG("estimating transformations between grids");
00127 
00128   /* convert to opencv images. it creates only a view for opencv and does not
00129    * copy actual data. */
00130   ROS_DEBUG("generating opencv stub images");
00131   images.reserve(std::distance(grids_begin, grids_end));
00132   for (ForwardIt it = grids_begin; it != grids_end; ++it) {
00133     nav_msgs::OccupancyGrid& it_ref = *it;  // support reference_wrapper
00134     // we need to skip empty grids, does not play well in opencv
00135     if (it_ref.data.empty()) {
00136       continue;
00137     }
00138     // Mat does no support constness in constructor
00139     images.emplace_back(it_ref.info.height, it_ref.info.width, CV_8UC1,
00140                         it_ref.data.data());
00141   }
00142 
00143   size_t num_estimates =
00144       internal::opencvEstimateTransform(images, transforms, confidence);
00145 
00146   auto transform_it = transforms_begin;
00147   auto grid_it = grids_begin;
00148   for (auto& transform : transforms) {
00149     nav_msgs::OccupancyGrid& grid = *grid_it;  // support reference_wrapper
00150     geometry_msgs::Pose& output_transform =
00151         *transform_it;  // support reference_wrapper
00152     if (transform.empty()) {
00153       // empty means transformation could not be found
00154       output_transform = geometry_msgs::Pose();
00155     } else {
00156       double translation_x = transform.at<double>(0, 2);
00157       double translation_y = transform.at<double>(1, 2);
00158       double rotation_rad =
00159           std::atan2(transform.at<double>(0, 1), transform.at<double>(1, 1));
00160 
00161       /* transformation was computed in pixels, we need to convert to meters
00162        * (map resolution). also we want to compesate this trasformation so we
00163        * need to use oposite values. */
00164       output_transform.position.x = 1. * translation_x * grid.info.resolution;
00165       output_transform.position.y = 1. * translation_y * grid.info.resolution;
00166       output_transform.position.z = 0;
00167       output_transform.orientation =
00168           tf::createQuaternionMsgFromYaw(1. * rotation_rad);
00169     }
00170     ++grid_it;
00171     ++transform_it;
00172   }
00173 
00174   return num_estimates;
00175 }
00176 
00177 }  // namespace combine_grids
00178 
00179 #endif  // ESTIMATE_TRANSFORM_H_


map_merge
Author(s): Jiri Horner
autogenerated on Sun Mar 26 2017 03:48:10