Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Good descriptor #1907

Open
wants to merge 24 commits into
base: master
Choose a base branch
from

Conversation

SeyedHamidreza
Copy link

@SeyedHamidreza SeyedHamidreza commented Jun 27, 2017

This is an implementation of the Global Orthographic Object Descriptor (GOOD) which has been presented in the following papers:

[1] Kasaei, S. Hamidreza,  Ana Maria Tomé, Luís Seabra Lopes, Miguel Oliveira 
"GOOD: A global orthographic object descriptor for 3D object recognition and manipulation." 
Pattern Recognition Letters 83 (2016): 312-320.

[2] Kasaei, S. Hamidreza, Luís Seabra Lopes, Ana Maria Tomé, Miguel Oliveira 
"An orthographic descriptor for 3D object learning and recognition." 
2016 IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS), Daejeon, 2016, 
pp. 4158-4163. 

The GOOD descriptor has been designed to be robust, descriptive and efficient to compute and use. GOOD descriptor has two outstanding characteristics:

(1) Providing a good trade-off among:
- descriptiveness,
- robustness,
- computation time,
- memory usage.

(2) Allowing concurrent object recognition and pose estimation for manipulation.

The performance of the proposed object descriptor is compared with the main state-of-the-art descriptors. Experimental results show that the overall classification performance obtained with GOOD is comparable to the best performances obtained with the state-of-the-art descriptors. Concerning memory and computation time, GOOD clearly outperforms the other descriptors. Therefore, GOOD is especially suited for real-time applications.

The current implementation of GOOD descriptor supports several functionalities for 3D Object Recognition and Object Manipulation. In the current distribution, you can find

- an implementation of the GOOD Descriptor (good.h, good.hpp and good.cpp) in "pcl/features/" path
- an example namely "/pcl/examples/features/example_good_descriptor.cpp" that demonstrates how to use  the GOOD Descriptor on a test object

To show all the functionalities and properties of the GOOD descriptor, a real demonstration was performed. A video of this demonstration is available in: https://youtu.be/iEq9TAaY9u8

Cheers,
Hamidreza

Hamidreza added 3 commits June 27, 2017 17:31
…nted in Pattern Recognition Letters Journal (JULY2016) and IROS2016 (October).
@taketwo taketwo added the needs: code review Specify why not closed/merged yet label Jun 28, 2017
@taketwo taketwo added this to the pcl-1.9.0 milestone Jun 28, 2017
@SergioRAgostinho
Copy link
Member

SergioRAgostinho commented Jun 28, 2017

Thanks @SeyedHamidreza. Can you suppress these though? Also note, it's threshold not thereshold 😅

In file included from /home/travis/build/PointCloudLibrary/pcl/features/src/good.cpp:39:

/home/travis/build/PointCloudLibrary/pcl/features/include/pcl/features/impl/good.hpp:227:58: warning: comparison of integers of different signs: 'int' and 'unsigned int' [-Wsign-compare]

  if ((Xpositive < Xnegative) and (Xnegative - Xpositive >= thereshold))

                                   ~~~~~~~~~~~~~~~~~~~~~ ^  ~~~~~~~~~~

/home/travis/build/PointCloudLibrary/pcl/features/src/good.cpp:46:23: note: in instantiation of member function 'pcl::GOODEstimation<pcl::PointXYZ>::signDisambiguationXAxis' requested here

  template class pcl::GOODEstimation<pcl::PointXYZ>; template class pcl::GOODEstimation<pcl::PointXYZI>; template class pcl::GOODEstimation<pcl::PointXYZRGB>; template class pcl::GOODEstimation<pcl::PointXYZRGBA>;

                      ^

In file included from /home/travis/build/PointCloudLibrary/pcl/features/src/good.cpp:39:

/home/travis/build/PointCloudLibrary/pcl/features/include/pcl/features/impl/good.hpp:257:58: warning: comparison of integers of different signs: 'int' and 'unsigned int' [-Wsign-compare]

  if ((Ypositive < Ynegative) and (Ynegative - Ypositive >= thereshold))

                                   ~~~~~~~~~~~~~~~~~~~~~ ^  ~~~~~~~~~~

/home/travis/build/PointCloudLibrary/pcl/features/src/good.cpp:46:23: note: in instantiation of member function 'pcl::GOODEstimation<pcl::PointXYZ>::signDisambiguationYAxis' requested here

  template class pcl::GOODEstimation<pcl::PointXYZ>; template class pcl::GOODEstimation<pcl::PointXYZI>; template class pcl::GOODEstimation<pcl::PointXYZRGB>; template class pcl::GOODEstimation<pcl::PointXYZRGBA>;

                      ^

In file included from /home/travis/build/PointCloudLibrary/pcl/features/src/good.cpp:39:

/home/travis/build/PointCloudLibrary/pcl/features/include/pcl/features/impl/good.hpp:227:58: warning: comparison of integers of different signs: 'int' and 'unsigned int' [-Wsign-compare]

  if ((Xpositive < Xnegative) and (Xnegative - Xpositive >= thereshold))

                                   ~~~~~~~~~~~~~~~~~~~~~ ^  ~~~~~~~~~~

/home/travis/build/PointCloudLibrary/pcl/features/src/good.cpp:46:74: note: in instantiation of member function 'pcl::GOODEstimation<pcl::PointXYZI>::signDisambiguationXAxis' requested here

  template class pcl::GOODEstimation<pcl::PointXYZ>; template class pcl::GOODEstimation<pcl::PointXYZI>; template class pcl::GOODEstimation<pcl::PointXYZRGB>; template class pcl::GOODEstimation<pcl::PointXYZRGBA>;

                                                                         ^

In file included from /home/travis/build/PointCloudLibrary/pcl/features/src/good.cpp:39:

/home/travis/build/PointCloudLibrary/pcl/features/include/pcl/features/impl/good.hpp:257:58: warning: comparison of integers of different signs: 'int' and 'unsigned int' [-Wsign-compare]

  if ((Ypositive < Ynegative) and (Ynegative - Ypositive >= thereshold))

                                   ~~~~~~~~~~~~~~~~~~~~~ ^  ~~~~~~~~~~

/home/travis/build/PointCloudLibrary/pcl/features/src/good.cpp:46:74: note: in instantiation of member function 'pcl::GOODEstimation<pcl::PointXYZI>::signDisambiguationYAxis' requested here

  template class pcl::GOODEstimation<pcl::PointXYZ>; template class pcl::GOODEstimation<pcl::PointXYZI>; template class pcl::GOODEstimation<pcl::PointXYZRGB>; template class pcl::GOODEstimation<pcl::PointXYZRGBA>;

                                                                         ^

In file included from /home/travis/build/PointCloudLibrary/pcl/features/src/good.cpp:39:

/home/travis/build/PointCloudLibrary/pcl/features/include/pcl/features/impl/good.hpp:227:58: warning: comparison of integers of different signs: 'int' and 'unsigned int' [-Wsign-compare]

  if ((Xpositive < Xnegative) and (Xnegative - Xpositive >= thereshold))

                                   ~~~~~~~~~~~~~~~~~~~~~ ^  ~~~~~~~~~~

/home/travis/build/PointCloudLibrary/pcl/features/src/good.cpp:46:126: note: in instantiation of member function 'pcl::GOODEstimation<pcl::PointXYZRGB>::signDisambiguationXAxis' requested here

  template class pcl::GOODEstimation<pcl::PointXYZ>; template class pcl::GOODEstimation<pcl::PointXYZI>; template class pcl::GOODEstimation<pcl::PointXYZRGB>; template class pcl::GOODEstimation<pcl::PointXYZRGBA>;

                                                                                                                             ^

In file included from /home/travis/build/PointCloudLibrary/pcl/features/src/good.cpp:39:

/home/travis/build/PointCloudLibrary/pcl/features/include/pcl/features/impl/good.hpp:257:58: warning: comparison of integers of different signs: 'int' and 'unsigned int' [-Wsign-compare]

  if ((Ypositive < Ynegative) and (Ynegative - Ypositive >= thereshold))

                                   ~~~~~~~~~~~~~~~~~~~~~ ^  ~~~~~~~~~~

/home/travis/build/PointCloudLibrary/pcl/features/src/good.cpp:46:126: note: in instantiation of member function 'pcl::GOODEstimation<pcl::PointXYZRGB>::signDisambiguationYAxis' requested here

  template class pcl::GOODEstimation<pcl::PointXYZ>; template class pcl::GOODEstimation<pcl::PointXYZI>; template class pcl::GOODEstimation<pcl::PointXYZRGB>; template class pcl::GOODEstimation<pcl::PointXYZRGBA>;

                                                                                                                             ^

In file included from /home/travis/build/PointCloudLibrary/pcl/features/src/good.cpp:39:

/home/travis/build/PointCloudLibrary/pcl/features/include/pcl/features/impl/good.hpp:227:58: warning: comparison of integers of different signs: 'int' and 'unsigned int' [-Wsign-compare]

  if ((Xpositive < Xnegative) and (Xnegative - Xpositive >= thereshold))

                                   ~~~~~~~~~~~~~~~~~~~~~ ^  ~~~~~~~~~~

/home/travis/build/PointCloudLibrary/pcl/features/src/good.cpp:46:180: note: in instantiation of member function 'pcl::GOODEstimation<pcl::PointXYZRGBA>::signDisambiguationXAxis' requested here

  template class pcl::GOODEstimation<pcl::PointXYZ>; template class pcl::GOODEstimation<pcl::PointXYZI>; template class pcl::GOODEstimation<pcl::PointXYZRGB>; template class pcl::GOODEstimation<pcl::PointXYZRGBA>;

                                                                                                                                                                                   ^

In file included from /home/travis/build/PointCloudLibrary/pcl/features/src/good.cpp:39:

/home/travis/build/PointCloudLibrary/pcl/features/include/pcl/features/impl/good.hpp:257:58: warning: comparison of integers of different signs: 'int' and 'unsigned int' [-Wsign-compare]

  if ((Ypositive < Ynegative) and (Ynegative - Ypositive >= thereshold))

                                   ~~~~~~~~~~~~~~~~~~~~~ ^  ~~~~~~~~~~

/home/travis/build/PointCloudLibrary/pcl/features/src/good.cpp:46:180: note: in instantiation of member function 'pcl::GOODEstimation<pcl::PointXYZRGBA>::signDisambiguationYAxis' requested here

  template class pcl::GOODEstimation<pcl::PointXYZ>; template class pcl::GOODEstimation<pcl::PointXYZI>; template class pcl::GOODEstimation<pcl::PointXYZRGB>; template class pcl::GOODEstimation<pcl::PointXYZRGBA>;

* Software License Agreement (BSD License)
*
* Point Cloud Library (PCL) - www.pointclouds.org
* Copyright (c) 2010-2012, Willow Garage, Inc.
Copy link
Member

@taketwo taketwo Jun 28, 2017

Choose a reason for hiding this comment

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

Unless you developed this code back in 2010-2012 while working at Willow Garage, please remove this copyright.
Instead, please add Copyright (c) 2017-, Open Perception, Inc.
Same for the remaining files.

Copy link
Author

Choose a reason for hiding this comment

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

done

@@ -1,6 +1,6 @@
set(SUBSYS_NAME features)
set(SUBSYS_DESC "Point cloud features library")
set(SUBSYS_DEPS common search kdtree octree filters 2d)
set(SUBSYS_DEPS common sample_consensus search kdtree octree filters 2d)
Copy link
Member

Choose a reason for hiding this comment

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

@SergioRAgostinho I hope this new dependency won't break your CI job distribution :)

Copy link
Member

Choose a reason for hiding this comment

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

Filters also has it fortunately :phew:

@@ -62,6 +62,8 @@ if(build)
"include/pcl/${SUBSYS_NAME}/usc.h"
"include/pcl/${SUBSYS_NAME}/boundary.h"
"include/pcl/${SUBSYS_NAME}/range_image_border_extractor.h"
"include/pcl/${SUBSYS_NAME}/range_image_border_extractor.h"
Copy link
Member

Choose a reason for hiding this comment

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

Duplicate line

Copy link
Author

Choose a reason for hiding this comment

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

done

Copy link
Member

Choose a reason for hiding this comment

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

Duplicate line is still here :x

* \param[in] number_of_bins_
* \param[in] threshold_
*/
GOODEstimation(unsigned int, float);
Copy link
Member

Choose a reason for hiding this comment

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

Please add parameter names to the signature. Also, it would be nice to see explanation what these parameters mean.

Copy link
Author

Choose a reason for hiding this comment

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

done

* \param[in] cloud the boost shared pointer to a point cloud.
*/
void
setInputCloud (boost::shared_ptr<pcl::PointCloud<PointInT> > cloud);
Copy link
Member

Choose a reason for hiding this comment

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

Please use typename pcl::PointCloud<PointInT>::Ptr here and everywhere. At some point in future we may want to switch to std::shared_ptr, and it will be simpler if the typedef is used.

Copy link
Author

Choose a reason for hiding this comment

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

done

*/

template <typename PointInT>
class GOODEstimation
Copy link
Member

Choose a reason for hiding this comment

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

Why don't you derive from pcl::Feature class?

Copy link
Member

Choose a reason for hiding this comment

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

Also, we need PCL_EXPORTS here, i.e. class PCL_EXPORTS GOODEstimation

@taketwo
Copy link
Member

taketwo commented Jun 28, 2017

A general comment: please update to conform to the PCL Style guide. Especially spaces between function names and braces.

Copy link
Member

@SergioRAgostinho SergioRAgostinho left a comment

Choose a reason for hiding this comment

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

I haven't completed by there's considerable changes to be done:

  • Not being derived from pcl::feature!
  • Code style
  • Copyright notices
  • No use of const qualifiers

#include <boost/filesystem.hpp>

typedef pcl::PointXYZRGBA PointT;
using namespace pcl;
Copy link
Member

Choose a reason for hiding this comment

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

Please refrain from using using namespace whatever;, even though this is a contained example. Just define the symbols you use the most. I also noticed you then use the fully qualified names later on in the file, so in this case just remove it.

Copy link
Author

Choose a reason for hiding this comment

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

done

int main(int argc, char* argv[])
{

if (argc < 2 ||argc > 2)
Copy link
Member

@SergioRAgostinho SergioRAgostinho Jun 28, 2017

Choose a reason for hiding this comment

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

why not simply != 2 ?

Copy link
Author

Choose a reason for hiding this comment

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

done

std::cout << "Cloud reading failed." << std::endl;
return (-1);
}
}
Copy link
Member

Choose a reason for hiding this comment

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

Consider replacing both these blocks for pcl::io::load defined in <pcl/io/auto_io.h>. This will refrain you from having to check file extensions.

using namespace pcl;

int
readPointCloud(std::string object_path, boost::shared_ptr<pcl::PointCloud<PointT> > point_cloud)
Copy link
Member

Choose a reason for hiding this comment

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

Regarding spacing of the parenthesis in functions have a look at http://www.pointclouds.org/documentation/advanced/pcl_style_guide.php#spacing

This would lead to

readPointCloud (std::string object_path, boost::shared_ptr<pcl::PointCloud<PointT>> point_cloud)

This comment is applicable to the remaining functions, methods and template instantiations of this PR.

return -1;

std::vector< float > object_description;
std::vector < boost::shared_ptr<pcl::PointCloud<PointT> > > vector_of_projected_views;
Copy link
Member

Choose a reason for hiding this comment

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

Not a required change. All these boost::shared_ptr<pcl::PointCloud<PointT>> invocations can be replaced by the equivalent pcl::PointCloud<PointT>::Ptr saving you some trouble writing the full name.

Copy link
Author

Choose a reason for hiding this comment

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

done

{
input_ = cloud;
};
//////////////////////////////////////////////////////////////////////////////////////////////
Copy link
Member

Choose a reason for hiding this comment

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

Please delete. To be derived from PCLBase

{
threshold_ = threshold;
}
//////////////////////////////////////////////////////////////////////////////////////////////
Copy link
Member

Choose a reason for hiding this comment

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

Move both of these to the .h and define them inline and add the const qualifier to the function argument.

{
transformation = transformation_;
}
//////////////////////////////////////////////////////////////////////////////////////////////
Copy link
Member

Choose a reason for hiding this comment

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

Move the four above methods to the .h, declare them inline and declare the methods const

getTransformationMatrix (Eigen::Matrix4f &transformation) const

dimensions.x = (maximum_pt.x - minimum_pt.x);
dimensions.y = (maximum_pt.y - minimum_pt.y);
dimensions.z = (maximum_pt.z - minimum_pt.z);
}
Copy link
Member

Choose a reason for hiding this comment

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

why not simply
dimensions = maximum_pt - minimum_pt;

Copy link
Author

Choose a reason for hiding this comment

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

since the type of dimentions variable is XYZ, while the type of maximum_pt and minimum_pt can be XYZRGB or other.

Copy link
Member

Choose a reason for hiding this comment

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

Fair enough. What you need is maximum_pt.getVector3fMap () - minimum_pt.getVector3fMap ().

* \param[out] pc_out the resultant projected point cloud
*/
void
projectPointCloudToPlane (boost::shared_ptr<pcl::PointCloud<PointInT> > pc_in, boost::shared_ptr<pcl::ModelCoefficients> coefficients, boost::shared_ptr<pcl::PointCloud<PointInT> > pc_out);
Copy link
Member

Choose a reason for hiding this comment

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

From here on out you start forgetting to include & on your function parameters...

Copy link
Author

@SeyedHamidreza SeyedHamidreza Jun 28, 2017

Choose a reason for hiding this comment

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

That is OK, I used pointers instead of references.

Copy link
Member

Choose a reason for hiding this comment

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

As you know, a shared_ptr is not just a trivial pointer. The difference in size compared to a raw ptr can in most cases be considered negligible, unless you specify its custom allocator through means of a functor object. But you are in fact triggering unnecessarily the reference counting mechanism because none of these methods really has the intent of "taking ownership" of the object. They just use it briefly and then release it.

Basically we're gaining nothing in this scenario, in passing the pointer by value.

Copy link
Member

Choose a reason for hiding this comment

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

This function forwards the point cloud parameter to projection.setInputCloud. So you can just have same qualifiers as in that function.

@SeyedHamidreza
Copy link
Author

@SergioRAgostinho @taketwo : Thanks for all your comments, I am going to check one by one and will commit a new version soon :D 💯

@SergioRAgostinho SergioRAgostinho added needs: author reply Specify why not closed/merged yet and removed needs: code review Specify why not closed/merged yet labels Jun 28, 2017
@jspricke
Copy link
Member

@SeyedHamidreza no need to put done under each comment, just push a commit with the change and Github will detect it.

…o derive GOODEstimation from pcl::Feature, since I got confused.
@taketwo
Copy link
Member

taketwo commented Jun 29, 2017

So your proposed code looks like this:

template <typename PointInT, int number_of_bins >
class PCL_EXPORTS GOODEstimation : public Feature<PointInT, PointOutT>

First problem is that PointOutT is not defined. Am I right that your feature descriptor is basically a float?

@SeyedHamidreza
Copy link
Author

I made a mistake to write it here, In the code it was correct,
Actually the output of the GOOD descriptor is a vector of float

@taketwo
Copy link
Member

taketwo commented Jun 29, 2017

Assuming the number of bins is fixed, do you know in advance the length of this descriptor vector?

@SeyedHamidreza
Copy link
Author

yes, the length of the descriptor will be 3 * (number_of_bins^2)

@taketwo
Copy link
Member

taketwo commented Jun 29, 2017

Great, it means we can use the Histogram<N> point type for output. Class declaration hence will be:

template <typename PointInT, int N>
class PCL_EXPORTS GOODEstimation : public Feature<PointInT, Histogram<3*N*N> >

@SeyedHamidreza
Copy link
Author

SeyedHamidreza commented Jun 29, 2017

Thank you, I think about it since I see something similar in spin_image but still, the following items are not clear to me:

what about the definition of a method, assume the following one:

template <typename PointInT, int N>
void 
pcl::GOODEstimation<PointInT, pcl::Histogram<3*N*N> >::computeBoundingBoxDimensions (PointCloudIn pc, pcl::PointXYZ &dimensions)
{
...
}

and also about the cpp file:

#ifdef PCL_ONLY_CORE_POINT_TYPES
  PCL_INSTANTIATE_PRODUCT(GOODEstimation, ((pcl::PointXYZ)(pcl::PointXYZI)(pcl::PointXYZRGB)(pcl::PointXYZRGBA))(pcl::Histogram<3*N*N>) )
#else
  PCL_INSTANTIATE_PRODUCT(GOODEstimation, (PCL_XYZ_POINT_TYPES)((pcl::Histogram<75>)))
#endif
#endif    // PCL_NO_PRECOMPILE

@taketwo
Copy link
Member

taketwo commented Jun 29, 2017

Method definitions should read like:

template <typename PointInT, int N>
void 
pcl::GOODEstimation<PointInT, N>::computeBoundingBoxDimensions (PointCloudIn pc, pcl::PointXYZ &dimensions)
{
...
}

Regarding the instantiation in cpp file, do you have any N in mind that will work in most of the cases, a kind of "one-size-fits-all"? If yes then we can instantiate GOODEstimation for this bin size. Otherwise we just skip precompilation.

@SeyedHamidreza
Copy link
Author

yes, Actually N=5 is a good option that we put it also as a default value for the number of bins parameters,
I am going to test and update you about the result soon

@SergioRAgostinho SergioRAgostinho removed the needs: author reply Specify why not closed/merged yet label Dec 13, 2017
@SeyedHamidreza
Copy link
Author

@SergioRAgostinho
I have applied your suggestions and comments and also change the std::vector with Eigen::array. 👍

Every time before pushing the code, I checked it out with my original code and some synthetic inputs to be sure everything is in a right way.

Thanks for your comments.
let me know if you have any other comments.
Hamidreza

@SergioRAgostinho
Copy link
Member

I've pre selected this for the 1.9 release but this is still lacking unit tests so I'm gonna remove this for now. If you want to meet this release please let us know and get those unit tests out.

@SergioRAgostinho SergioRAgostinho removed this from the pcl-1.9.0 milestone Feb 14, 2018
@SeyedHamidreza
Copy link
Author

I would like to release the GOOD in PCL 1.9, just let me know what should I do for the unit tests. :)

@SergioRAgostinho
Copy link
Member

Here are some guidelines for writing good unit tests:

Here's specific documentation for the framework we use to test our stuff:

Here's a comprehensive example I particularly like in PCL:

Keep it simple and tractable and remember whatever process you went through when you originally designed this feature. I assume you had one/some cases to validate things. You need to be able to predict whatever your descriptor is going to be, without actually running the code you just implemented.

@SergioRAgostinho SergioRAgostinho added the needs: more work Specify why not closed/merged yet label Feb 14, 2018
@SergioRAgostinho SergioRAgostinho added this to the pcl-1.9.0 milestone Feb 14, 2018
@SeyedHamidreza
Copy link
Author

Thank you.
I did not know that I should create this test file.
I will create it and push it back by the end of this week.

Best regards,

@SeyedHamidreza
Copy link
Author

I have added the unit test 💯
Please have a look and let me know if I should do anything else.
Wish you a good day.

Best regards,
Hamidreza

@SergioRAgostinho SergioRAgostinho removed this from the pcl-1.9.0 milestone Aug 26, 2018
@HKasaei
Copy link

HKasaei commented Dec 23, 2018

@SergioRAgostinho @taketwo
Good evening,
I wonder should I do anything else?
Thank you.

@SergioRAgostinho
Copy link
Member

@SeyedHamidreza Not at this moment. Right now we're focused on other more pressing goals, so reviewing this became low priority. My apologies.

@stale
Copy link

stale bot commented Feb 21, 2020

This pull request has been automatically marked as stale because it hasn't had
any activity in the past 60 days. Commenting or adding a new commit to the
pull request will revert this.

Come back whenever you have time. We look forward to your contribution.

@stale stale bot added the status: stale label Feb 21, 2020
@kunaltyagi kunaltyagi removed the needs: code review Specify why not closed/merged yet label May 20, 2020
@stale stale bot removed the status: stale label May 20, 2020
@stale
Copy link

stale bot commented Jun 20, 2020

Marking this as stale due to 30 days of inactivity. Commenting or adding a new commit to the pull request will revert this.

@stale stale bot added the status: stale label Jun 20, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants