Point Cloud Publisher inside class
I am trying to load and publish a point cloud within a class. For some reason it only works if I have a dummy function in my main.cpp, containing a publisher and PCD file reader. The function is never called but without it, compiling fails.
Any ideas what might be causing this error?
I am running ROS Kinetic on Ubuntu 16.04
main.cpp:
#include <iostream>
#include <string>
#include <array>
#include <vector>
#include <ros/ros.h>
#include <pcl_ros/point_cloud.h>
#include "pcl_debug.hpp"
typedef pcl::PointCloud<pcl::PointXYZ> PointCloud;
void dummy_function(PointCloud::Ptr cloud, ros::NodeHandle nh) {
ros::Publisher pub = nh.advertise< PointCloud > ("dummy", 1);
pcl::io::loadPCDFile<pcl::PointXYZ> ("dummy_path", *cloud);
pub.publish (cloud);
}
int main(int argc, char** argv)
{
ros::init (argc, argv, "main_debug");
ros::NodeHandle nh;
ros::Publisher pub;
int n = 2;
std::vector <std::string> link_names(n);
link_names[0] = "R1_Link";
link_names[1] = "A1_Link";
CPUPointCloud* links = new CPUPointCloud[n];
for(size_t i = 0; i < n; i++){
links[i].Init(link_names[i], nh);
}
ros::Rate r(1);
while (ros::ok()){
links[0].PublishPointCloud();
links[1].PublishPointCloud();
ros::spinOnce();
r.sleep();
}
}
pcl_debud.cpp:
#include "pcl_debug.hpp"
CPUPointCloud::CPUPointCloud(){}
void CPUPointCloud::Init(std::string link_name, ros::NodeHandle nh){
name = link_name;
pub = nh.advertise< pcl::PointCloud<pcl::PointXYZ> > (name, 1);
LoadPointCloud(name, p_cloud_in);
p_cloud_in->header.frame_id = "world"; }
void CPUPointCloud::LoadPointCloud(std::string name, pcl::PointCloud<pcl::PointXYZ>::Ptr cloud){
std::string path = "path_to_pcd_folder/";
if (pcl::io::loadPCDFile<pcl::PointXYZ> (path+name+".pcd", *cloud) == -1)
PCL_ERROR ("Couldn't read file name.pcd \n");
}
void CPUPointCloud::PublishPointCloud(){
std::cout << "Publish cloud " << std::endl;
pcl_conversions::toPCL(ros::Time::now(), p_cloud_in->header.stamp);
pub.publish(p_cloud_in);
}
pcl_debug.hpp:
#include <ros/ros.h>
#include <pcl_ros/point_cloud.h>
#include <iostream>
#include <string>
class CPUPointCloud{
typedef pcl::PointCloud<pcl::PointXYZ> PointCloud;
public:
PointCloud::Ptr p_cloud_in {new PointCloud};
ros::Publisher pub;
std::string name;
public:
CPUPointCloud();
void Init(std::string link_name, ros::NodeHandle nh);
void LoadPointCloud(std::string name, pcl::PointCloud<pcl::PointXYZ>::Ptr cloud);
void PublishPointCloud();
};
Error message without dummy function:
/usr/bin/ld: /opt/ros/kinetic/lib/libroscpp.so: undefined reference to symbol '_ZN3ros7console21initializeLogLocationEPNS0_11LogLocationERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS0_6levels5LevelE'
/opt/ros/kinetic/lib/librosconsole.so: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
make[2]: *** [/home/ubuntugpu/ws_ros/devel/.private/pcl_debug_pkg/lib/pcl_debug_pkg/pcl_debug] Error 1
make[1]: *** [CMakeFiles/pcl_debug.dir/all] Error 2
make: *** [all] Error 2
The
.so: undefined reference to symbol
indicates the complication is failing at the linker. First off, I would check ifdummy_function
is declared somewhere in one of your headers.Sadly no declaration of the dummy_function. I look like the issue is related to pcl_ros and Point Cloud publisher. I found a workaround by using pcl::PCLPointCloud2 instead,