pcl::IntegralImageNormalEstimation< PointInT, PointOutT >::setInputCloud() makes runtime SFINAE exception - templates

I am using PCL version 1.12.1 on Ubuntu 22.
The eigen3 version is 3.4.0
The full code is in written here.
In here, pcl::IntegralImageNormalEstimation< PointInT, PointOutT > is used.
int main ()
{
// load point cloud
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile ("./img/table_scene_mug_stereo_textured.pcd", *cloud);
// estimate normals
pcl::PointCloud<pcl::Normal>::Ptr normals (new pcl::PointCloud<pcl::Normal>);
pcl::IntegralImageNormalEstimation<pcl::PointXYZ, pcl::Normal> ne;
ne.setNormalEstimationMethod (ne.AVERAGE_3D_GRADIENT);
ne.setMaxDepthChangeFactor(0.02f);
ne.setNormalSmoothingSize(10.0f);
ne.setInputCloud(cloud); /*Here comes a problem.*/
ne.compute(*normals); /*The debugger couldn't reach here.*/
// visualize normals
pcl::visualization::PCLVisualizer viewer("PCL Viewer");
viewer.setBackgroundColor (0.0, 0.0, 0.5);
viewer.addPointCloudNormals<pcl::PointXYZ,pcl::Normal>(cloud, normals);
while (!viewer.wasStopped ())
{
viewer.spinOnce();
}
return 0;
}
It makes no compile error but makes runtime error and the program is terminated.
normal_estimation_using_integral_images: /usr/include/eigen3/Eigen/src/Core/util/XprHelper.h:133: Eigen::internal::variable_if_dynamic<T, Value>::variable_if_dynamic(T) [with T = long int; int Value = 3]: Assertion `v == T(Value)' failed.
Call stack is as the below.
libc.so.6!__pthread_kill_implementation(int no_tid, int signo, pthread_t threadid) (pthread_kill.c:44)
libc.so.6!__pthread_kill_internal(int signo, pthread_t threadid) (pthread_kill.c:78)
libc.so.6!__GI___pthread_kill(pthread_t threadid, int signo) (pthread_kill.c:89)
libc.so.6!__GI_raise(int sig) (raise.c:26)
libc.so.6!__GI_abort() (abort.c:79)
libc.so.6!__assert_fail_base(const char * fmt, const char * assertion, const char * file, unsigned int line, const char * function) (assert.c:92)
libc.so.6!__GI___assert_fail(const char * assertion, const char * file, unsigned int line, const char * function) (assert.c:101)
libpcl_features.so.1.12![Unknown/Just-In-Time compiled code] (Unknown Source:0)
libpcl_features.so.1.12!pcl::IntegralImageNormalEstimation<pcl::PointXYZ, pcl::Normal>::initAverage3DGradientMethod() (Unknown Source:0)
pcl::IntegralImageNormalEstimation<pcl::PointXYZ, pcl::Normal>::setInputCloud(pcl::IntegralImageNormalEstimation<pcl::PointXYZ, pcl::Normal> * const this, const pcl::PointCloud<pcl::PointXYZ>::ConstPtr & cloud) (/usr/include/pcl-1.12/pcl/features/integral_image_normal.h:251)
main() (/home/sagal/bire/pcl_tutorial/src/normal_estimation_using_integral_images.cpp:91)
I suspect the problem have came from just-in-time code generation failure of PCL library of which couldn't pass SFINAE check of Eigen library.
But I cannot know why and where the type-test is needed.
How can I resolve or bypass the error?

Related

Abort() error encountered when adding points from input PointCloud to OctreePointCloud in PCL

I've encountered an error I'm having some difficulty solving in my current PCL c++ program. My original code is much larger and part of a classification project so I have tested using the following code and am still encountering my issue. When calling addPointsFromInputCloud() from my octree the function is running once for the first point, then appears to be unable to read the memory in which the defined input cloud is located. It throws the following error: R6010 - abort() has been called. I'm using PCL 1.8 with Visual Studio 2012. I have had PCL up and running in this project but started to have this issue yesterday after changing some binary reading code in an unrelated part of the project. In my header file I include:
#include <pcl\point_types.h>
#include <pcl\point_cloud.h>
#include <pcl\octree\octree.h>
In my function in the corresponding class I attempt to implement the code from the basic PCL octree tutorial (http://www.pointclouds.org/documentation/tutorials/octree.php):
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
// Generate pointcloud data
cloud->width = 1000;
cloud->height = 1;
cloud->points.resize (cloud->width * cloud->height);
for (size_t i = 0; i < cloud->points.size (); ++i) {
cloud->points[i].x = 1024.0f * rand () / (RAND_MAX + 1.0f);
cloud->points[i].y = 1024.0f * rand () / (RAND_MAX + 1.0f);
cloud->points[i].z = 1024.0f * rand () / (RAND_MAX + 1.0f);
}
float resolution = 128.0f;
pcl::octree::OctreePointCloudSearch<pcl::PointXYZ> octree (resolution);
octree.setInputCloud(cloud);
octree.addPointsFromInputCloud();
This throws the error above when attempting to execute the final line.
This is the code from octree_poointcloud.hpp wherein the failure occurs:
//////////////////////////////////////////////////////////////////////////////////////////////
template<typename PointT, typename LeafContainerT, typename BranchContainerT, typename OctreeT> void
pcl::octree::OctreePointCloud<PointT, LeafContainerT, BranchContainerT, OctreeT>::addPointsFromInputCloud ()
{
size_t i;
if (indices_)
{
for (std::vector<int>::const_iterator current = indices_->begin (); current != indices_->end (); ++current)
{
assert( (*current>=0) && (*current < static_cast<int> (input_->points.size ())));
if (isFinite (input_->points[*current]))
{
// add points to octree
this->addPointIdx (*current);
}
}
}
else
{
for (i = 0; i < input_->points.size (); i++)
{
if (isFinite (input_->points[i]))
{
// add points to octree
this->addPointIdx (static_cast<unsigned int> (i));
}
}
}
}
The first execution of the loop under the else statement is successful but it then appears to be unable to read from _input and errors.
Answered my own question and figured I'd let everyone know what my issue was. In the reading section of my program I had altered the packing to ensure there was no padding when I was casting the read bytes to my struct. Simply changing '#pragma pack(1)' to #pragma pack(push,1) before the declaration of my struct and '#pragma pack(pop)' after the declaration brought PCL back to life. Of course that wasn't until recompiling PCL from scratch...lesson learned though!

Debugging failed: vector subscript out of range in PCL "Smoothing and normal estimation based on polynomial reconstruction" tutorial

I am new to pcl and I am trying to visualize the code from the "Smoothing and normal estimation based on polynomial reconstruction" tutorial and I get this message when I debug it in VS2012 (I'm using pcl 1.7):
Debug Assertion Failed!
Program: C:\Windows\system32\MSVCP110D.dll File: C:\Program Files
(x86)\Microsoft Visual Studio 11.0\VC\include\vector Line: 1140
Expression: vector subscript out of range
For information on how your program can cause an assertion failure,
see the Visual C++ documentation on asserts.
and after I press "Retry" I get another one:
Debug Assertion Failed!
Program: ...tudio
2012\Projects\Tutorials\x64\Debug\pcl_surface_debug.dll File:
C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\vector
Line: 1141
Expression: "Standard C++ Libraries Out of Range" && 0
For information on how your program can cause an assertion failure,
see the Visual C++ documentation on asserts.
(Press Retry to debug the application) The program '[964] MLS.exe' has
exited with code 3 (0x3).
then I debugged it line by line it stops at
mls.process(mls_points);
It also opens the "stdthrow.cpp" :
ifdef _DEBUG
_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL _Debug_message(const wchar_t *message, const wchar_t *file, unsigned int line)
{ // report error and die
if(::_CrtDbgReportW(_CRT_ASSERT, file, line, NULL, L"%s", message)==1)
{
::_CrtDbgBreak();
}
}
_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL _Debug_message(const unsigned short *message, const unsigned short *file, unsigned int
line)
{ // report error and die
_Debug_message((wchar_t *) message, (wchar_t *) file, line);
}
endif
and stops at
::_CrtDbgBreak();
Can someone explain the problem? Here is the code from pcl tutorial page:
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/surface/mls.h>
int
main (int argc, char** argv)
{
// Load input file into a PointCloud<T> with an appropriate type
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ> ());
// Load bun0.pcd -- should be available with the PCL archive in test
pcl::io::loadPCDFile ("bun0.pcd", *cloud);
// Create a KD-Tree
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ>);
// Output has the PointNormal type in order to store the normals calculated by MLS
pcl::PointCloud<pcl::PointNormal> mls_points;
// Init object (second point type is for the normals, even if unused)
pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointNormal> mls;
mls.setComputeNormals (true);
// Set parameters
mls.setInputCloud (cloud);
mls.setPolynomialFit (true);
mls.setSearchMethod (tree);
mls.setSearchRadius (0.03);
// Reconstruct
mls.process (mls_points);
// Save output
pcl::io::savePCDFile ("bun0-mls.pcd", mls_points);
}
Your KdTree has no input, this will solve your problem:
Add tree->setInputCloud (cloud); Afterpcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ>);

Error: X86CodeEmitter LLVM

I'm having the following problem when I run my program:
pseudo instructions should be removed before code emission
UNREACHABLE executed at /home/leonor/llvm/llvm/lib/Target/X86/X86CodeEmitter.cpp:1164!
Stack dump:
0. Running pass 'X86 Machine Code Emitter' on function '#main'
./build/Release+Asserts/bin/llvm-dis: Bitcode stream must be at least 16 bytes in length
My program takes as input a .bc file and then loads the file and shows it.
My doubt is: Why is this error happens only when the C program contains conditional statements (if, for ..). How to solve??
My code:
int main(int argc, char **argv) {
InitializeNativeTarget();
LLVMContext &Context = getGlobalContext();
std::string Err;
const std::string InputFile = "teste_f1.bc";
OwningPtr<MemoryBuffer> result;
error_code ec = MemoryBuffer::getFile(InputFile, result);
MemoryBuffer *buffer = result.take();
Module * Mod = ParseBitcodeFile(buffer, Context);
ExecutionEngine* EE = 0;
EngineBuilder builder(Mod);
builder.setErrorStr(&Err);
builder.setEngineKind(EngineKind::JIT);
EE = builder.create();
Function * func = Mod->getFunction("main");
std::vector <std::string> params;
params.push_back(Mod->getModuleIdentifier());
EE->runStaticConstructorsDestructors(false);
int Result = EE->runFunctionAsMain(func, params, NULL);
EE->runStaticConstructorsDestructors(true);
WriteBitcodeToFile(Mod, outs());
delete Mod;
return 0;
}
It is because the code containing conditional statements (if,for etc), results in an IR which contains phi nodes. You can remove the phi nodes by using reg2mem pass. The command would be:
opt -reg2mem -o output.bc input.bc

boost test case from dll access violation

I want to start Boost test case from dll under Windows RT. I built test case as dll via the Visual Studio command prompt using the following comandline:
cl.exe /EHsc /D_USRDLL /D_WINDLL /LDd ~location\testcase.cpp ~library location\libboost_unit_test_framework-vc110-mt-sgd-1_53.lib /link /DLL /OUT:~output directory\testcase.dll
placed it into my application’s folder and set property "Content" to "true". After launching of my application I have the following error:
Unhadled exception at the 0x00B9AF16 in TestApp.exe: 0xC0000005: Access violation reading location 0x00000000
Top of the call stack is below:
> TestApp.exe!boost::unit_test::framework::get(unsigned long id, boost::unit_test::test_unit_type t) Line 388 C++
TestApp.exe!boost::unit_test::framework::get(unsigned long id) Line 73 C++
TestApp.exe!boost::unit_test::traverse_test_tree(unsigned long id, boost::unit_test::test_tree_visitor & V) Line 232 C++
TestApp.exe!boost::unit_test::traverse_test_tree(const boost::unit_test::test_suite & suite, boost::unit_test::test_tree_visitor & V) Line 207 C++
TestApp.exe!boost::unit_test::traverse_test_tree(unsigned long id, boost::unit_test::test_tree_visitor & V) Line 234 C++
TestApp.exe!boost::unit_test::framework::run(unsigned long id, bool continue_test) Line 403 C++
TestApp.exe!boost::unit_test::unit_test_main(boost::unit_test::test_suite * (int, char * *) * init_func, int argc, char * * argv) Line 185 C++
Here is the dll code (NOTE: If I place the same code directly into my source, it works fine):
void test_stat()
{
//some code there
}
extern "C" {
__declspec (dllexport) test_suite* init_unit_test_suite( int argc, char* argv[] )
{
test_suite *test = BOOST_TEST_SUITE("test name");
test->add(BOOST_TEST_CASE(&test_stat));
return test;
}
}
Code of the application for launching of the test case:
boost::unit_test::test_suite* main_global_test_suite;
test_suite* init_unit_test_suite( int argc, char* argv[] ) {
return NULL; }
test_suite* run_global_test_suite (int, char* []) {
return main_global_test_suite;
}
HINSTANCE hMyDll;
typedef test_suite* (*PFN_MyFunction)(int,const char*);
PFN_MyFunction pfnMyFunction;
test_suite* rPtr;
if((hMyDll=::LoadPackagedLibrary(L"testcase", 0))==NULL)
{
return;
}
pfnMyFunction=(PFN_MyFunction)GetProcAddress(hMyDll,"init_unit_test_suite");
if (pfnMyFunction != NULL)
{
//just create fake arguments for the boost::unit_test::unit_test_main function call
char* argv[1024];
argv[0] = "Text";
rPtr = pfnMyFunction(1, NULL);
main_global_test_suite = rPtr;
const int error =
boost::unit_test::unit_test_main(&run_global_test_suite, 1, argv );
}
else
{
//handling code
}
FreeLibrary(hMyDll);
Is there any ideas how to solve the problem?
Check what console_test_runner is doing. This is command line application (part of Boost.Test), which intended to do just that - load and execute test units implemented in shared library. Also please make sure you tell UTF that you want to build dll: define BOOST_TEST_DYN_LINK.

PCL: Visualize a point cloud

I'm trying to visualize a point cloud using PCL CloudViewer. The problem is that I'm quite new to C++ and I have found two tutorials first demonstrating the creation of PointCloud and second demonstrating the visualization of a PointCloud. However, I'm not able to combine these two tutorials.
Here is what I have come up with:
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/cloud_viewer.h>
int main (int argc, char** argv)
{
pcl::PointCloud<pcl::PointXYZ> cloud;
// Fill in the cloud data
cloud.width = 5;
cloud.height = 1;
cloud.is_dense = false;
cloud.points.resize (cloud.width * cloud.height);
for (size_t i = 0; i < cloud.points.size (); ++i)
{
cloud.points[i].x = 1024 * rand () / (RAND_MAX + 1.0f);
cloud.points[i].y = 1024 * rand () / (RAND_MAX + 1.0f);
cloud.points[i].z = 1024 * rand () / (RAND_MAX + 1.0f);
}
pcl::visualization::CloudViewer viewer ("Simple Cloud Viewer");
viewer.showCloud (cloud);
while (!viewer.wasStopped ())
{
}
return (0);
}
but that even do not compile:
error: no matching function for call to
‘pcl::visualization::CloudViewer::showCloud(pcl::PointCloud<pcl::PointXYZ>&)’
Your error message tells you what you need to do:
error: no matching function for call to ‘pcl::visualization::CloudViewer::showCloud(pcl::PointCloud<pcl::PointXYZ>&)’
So go to the documentation for CloudViewer and see what arguments this member function takes: http://docs.pointclouds.org/1.5.1/classpcl_1_1visualization_1_1_cloud_viewer.html
There we see that it takes a const MonochromeCloud::ConstPtr &cloud not the raw reference that you are passing in. This is a typedef of a smart pointer from boost:
typedef boost::shared_ptr<const PointCloud<PointT> > pcl::PointCloud< PointT >::ConstPtr
So when you create your cloud you need to wrap it in one of these smart pointers instead of making it a local variable. Something like (untested):
pcl::MonochromeCloud::ConstPtr cloud(new pcl::PointCloud<pcl::PointXYZ>());
Then, when you pass in the variable cloud, it will have the correct type and you won't get the error that you report. You will also have to change your cloud.foos to cloud->foos.
Looking at the second example you give, they do this as well:
pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZRGBA>);
To give the answer straight away:
pcl::PointCloud<pcl::PointXYZRGB>::Ptr ptrCloud(&cloud);
Then put in ptrCloud in the viewer, it's what it expects:
viewer.showCloud (ptrCloud);
If anybody else is just searching how to do this in ROS it can be simply done using:
#include <ros/ros.h>
#include <pcl_ros/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/visualization/cloud_viewer.h>
#include <sensor_msgs/PointCloud2.h>
#include <pcl_conversions/pcl_conversions.h>
#include <iostream>
#include <pcl/common/common_headers.h>
#include <pcl/features/normal_3d.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/console/parse.h>
typedef pcl::PointCloud<pcl::PointXYZ> PointCloud;
class cloudHandler
{
public:
cloudHandler():viewer("Cloud Viewer")
{
pcl_sub = nh.subscribe("/camera/depth_registered/points", 10, &cloudHandler::cloudCB, this);
viewer_timer = nh.createTimer(ros::Duration(0.1), &cloudHandler::timerCB,this);
}
void cloudCB(const sensor_msgs::PointCloud2 &input)
{
pcl::PointCloud<pcl::PointXYZRGB> cloud;
pcl::fromROSMsg (input, cloud);
viewer.showCloud(cloud.makeShared());
}
void timerCB(const ros::TimerEvent&)
{
if(viewer.wasStopped())
{
ros::shutdown();
}
}
protected:
ros::NodeHandle nh;
ros::Subscriber pcl_sub;
pcl::visualization::CloudViewer viewer;
ros::Timer viewer_timer;
};
int main(int argc, char** argv)
{
ros::init(argc, argv, "pcl_visualize");
cloudHandler handler;
ros::spin();
return 0;
}
The includes could probably be cleaned more :)
The tutorial for CloudViewer pcl cloudviewer tutorialhttp://pointclouds.org/documentation/tutorials/cloud_viewer.php#cloud-viewer defines the point cloud as follows:
pcl::PointCloud<pcl::PointXYZRGB>**::Ptr** cloud;
But you have written:
pcl::PointCloud<pcl::PointXYZ> cloud;
So try passing the cloud as &cloud instead of cloud, or declare it as a pointer.