test_extract_indices.cpp
Go to the documentation of this file.
00001 // -*- mode: c++ -*-
00002 /*********************************************************************
00003  * Software License Agreement (BSD License)
00004  *
00005  *  Copyright (c) 2015, JSK Lab
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/o2r other materials provided
00017  *     with the distribution.
00018  *   * Neither the name of the JSK Lab 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 
00042 #include <ros/ros.h>
00043 #include <gtest/gtest.h>
00044 #include <sensor_msgs/PointCloud2.h>
00045 #include <pcl_msgs/PointIndices.h>
00046 #include <pcl_conversions/pcl_conversions.h>
00047 
00048 class ExtractIndicesTest: public testing::Test
00049 {
00050 protected:
00051   virtual void SetUp()
00052   {
00053     // generate a pointcloud
00054     generateTestData();
00055     // setup ROS
00056     ros::NodeHandle n("~");
00057     pub_cloud_ = n.advertise<sensor_msgs::PointCloud2>("output", 1);
00058     pub_even_indices_ = n.advertise<pcl_msgs::PointIndices>("output/even_indices", 1);
00059     pub_odd_indices_ = n.advertise<pcl_msgs::PointIndices>("output/odd_indices", 1);
00060     sub_even_result_ = n.subscribe("input/even_result", 1, &ExtractIndicesTest::evenCallback, this);
00061     sub_odd_result_ = n.subscribe("input/odd_result", 1, &ExtractIndicesTest::oddCallback, this);
00062     sub_even_organized_result_ = n.subscribe("input/even_organized_result", 1,
00063                                              &ExtractIndicesTest::evenOrganizedCallback, this);
00064     sub_odd_organized_result_ = n.subscribe("input/odd_organized_result",
00065                                             1, &ExtractIndicesTest::oddOrganizedCallback, this);
00066 
00067     // wait until
00068     ros::Time start_time = ros::Time::now();
00069     while (!isReady()) {
00070       publishData();
00071 #if ROS_VERSION_MINIMUM(1,14,0) // melodic
00072       /*
00073         on melodic, it hugs after first test.
00074         not sure why and if we move SetUp code to class function, then it will raise
00075            terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::lock_error> >'
00076            what():  boost: mutex lock failed in pthread_mutex_lock: Invalid argument
00077         error on exit.
00078         related ? -> https://github.com/ros/ros_comm/issues/838
00079        */
00080 #else
00081       ros::spinOnce();
00082 #endif
00083       ros::Duration(0.5).sleep();
00084     }
00085     ros::Time end_time = ros::Time::now();
00086     ROS_INFO("took %f sec to retrieve result", (end_time - start_time).toSec());
00087   }
00088 
00089   virtual void generateTestData()
00090   {
00091     // cloud
00092     original_cloud_.reset(new pcl::PointCloud<pcl::PointXYZ>);
00093     for (size_t i = 0; i < 1000; i++) {
00094       pcl::PointXYZ p;
00095       p.x = i; p.y = 0; p.z = 0;
00096       original_cloud_->points.push_back(p);
00097       if (i % 2 == 0) {
00098         even_indices_msg_.indices.push_back(i);
00099       }
00100       else {
00101         odd_indices_msg_.indices.push_back(i);
00102       }
00103     }
00104     pcl::toROSMsg(*original_cloud_, original_cloud_msg_);
00105   }
00106   
00107   virtual bool isReady()
00108   {
00109     boost::mutex::scoped_lock lock(mutex_);
00110     ROS_INFO("even_cloud_ %d, odd_cloud_ %d, even_organized_cloud_ %d, odd_organized_cloud_ %d",
00111              !!even_cloud_, !!odd_cloud_, !!even_organized_cloud_, !!odd_organized_cloud_);
00112     return (even_cloud_ && odd_cloud_ && even_organized_cloud_ && odd_organized_cloud_);
00113   }
00114 
00115   virtual void publishData()
00116   {
00117     ros::Time now = ros::Time::now();
00118     original_cloud_msg_.header.stamp = now;
00119     even_indices_msg_.header.stamp = now;
00120     odd_indices_msg_.header.stamp = now;
00121     pub_cloud_.publish(original_cloud_msg_);
00122     pub_even_indices_.publish(even_indices_msg_);
00123     pub_odd_indices_.publish(odd_indices_msg_);
00124   }
00125   
00126   virtual void evenCallback(const sensor_msgs::PointCloud2::ConstPtr& cloud_msg)
00127   {
00128     boost::mutex::scoped_lock lock(mutex_);
00129     even_cloud_.reset(new pcl::PointCloud<pcl::PointXYZ>);
00130     pcl::fromROSMsg(*cloud_msg, *even_cloud_);
00131   }
00132   
00133   virtual void oddCallback(const sensor_msgs::PointCloud2::ConstPtr& cloud_msg)
00134   {
00135     boost::mutex::scoped_lock lock(mutex_);
00136     odd_cloud_.reset(new pcl::PointCloud<pcl::PointXYZ>);
00137     pcl::fromROSMsg(*cloud_msg, *odd_cloud_);
00138   }
00139 
00140   virtual void evenOrganizedCallback(const sensor_msgs::PointCloud2::ConstPtr& cloud_msg)
00141   {
00142     boost::mutex::scoped_lock lock(mutex_);
00143     even_organized_cloud_.reset(new pcl::PointCloud<pcl::PointXYZ>);
00144     pcl::fromROSMsg(*cloud_msg, *even_organized_cloud_);
00145   }
00146   
00147   virtual void oddOrganizedCallback(const sensor_msgs::PointCloud2::ConstPtr& cloud_msg)
00148   {
00149     boost::mutex::scoped_lock lock(mutex_);
00150     odd_organized_cloud_.reset(new pcl::PointCloud<pcl::PointXYZ>);
00151     pcl::fromROSMsg(*cloud_msg, *odd_organized_cloud_);
00152   }
00153 
00154   boost::mutex mutex_;
00155   ros::Subscriber sub_even_result_, sub_odd_result_;
00156   ros::Subscriber sub_even_organized_result_, sub_odd_organized_result_;
00157   ros::Publisher pub_cloud_, pub_even_indices_, pub_odd_indices_;
00158   pcl::PointCloud<pcl::PointXYZ>::Ptr original_cloud_;
00159   pcl::PointCloud<pcl::PointXYZ>::Ptr even_cloud_, odd_cloud_;
00160   pcl::PointCloud<pcl::PointXYZ>::Ptr even_organized_cloud_, odd_organized_cloud_;
00161   sensor_msgs::PointCloud2 original_cloud_msg_;
00162   pcl_msgs::PointIndices even_indices_msg_, odd_indices_msg_;
00163 };
00164 
00165 TEST_F(ExtractIndicesTest, testEvenIndices)
00166 {
00167   EXPECT_EQ(even_cloud_->points.size(), even_indices_msg_.indices.size());
00168   for (size_t i = 0; i < even_cloud_->points.size(); i++) {
00169     EXPECT_FLOAT_EQ(even_cloud_->points[i].x, i * 2.0);
00170   }
00171 }
00172 
00173 TEST_F(ExtractIndicesTest, testOddIndices)
00174 {
00175   EXPECT_EQ(odd_cloud_->points.size(), odd_indices_msg_.indices.size());
00176   for (size_t i = 0; i < odd_cloud_->points.size(); i++) {
00177     EXPECT_FLOAT_EQ(odd_cloud_->points[i].x, i * 2.0 + 1.0);
00178   }
00179 }
00180 
00181 TEST_F(ExtractIndicesTest, testEvenOrganizedIndices)
00182 {
00183   EXPECT_EQ(even_organized_cloud_->points.size(), original_cloud_->points.size());
00184   size_t non_nan_count = 0;
00185   for (size_t i = 0; i < even_organized_cloud_->points.size(); i++) {
00186     if (!std::isnan(even_organized_cloud_->points[i].x)) {
00187       EXPECT_FLOAT_EQ(even_organized_cloud_->points[i].x, i);
00188       non_nan_count++;
00189     }
00190   }
00191   EXPECT_EQ(non_nan_count, even_indices_msg_.indices.size());
00192 }
00193 
00194 TEST_F(ExtractIndicesTest, testOddOrganizedIndices)
00195 {
00196   EXPECT_EQ(odd_organized_cloud_->points.size(), original_cloud_->points.size());
00197   size_t non_nan_count = 0;
00198   for (size_t i = 0; i < odd_organized_cloud_->points.size(); i++) {
00199     if (!std::isnan(odd_organized_cloud_->points[i].x)) {
00200       EXPECT_FLOAT_EQ(odd_organized_cloud_->points[i].x, i);
00201       non_nan_count++;
00202     }
00203   }
00204   EXPECT_EQ(non_nan_count, odd_indices_msg_.indices.size());
00205 }
00206 
00207 
00208 int main(int argc, char** argv)
00209 {
00210   ros::init(argc, argv, "test_extract_indices");
00211 #if ROS_VERSION_MINIMUM(1,14,0) // melodic
00212   ros::AsyncSpinner spinner(1);
00213   spinner.start();
00214 #endif
00215   testing::InitGoogleTest(&argc, argv);
00216   return RUN_ALL_TESTS();
00217 }


jsk_pcl_ros
Author(s): Yohei Kakiuchi
autogenerated on Tue Jul 2 2019 19:41:45