Point Cloud Publisher inside class

asked 2019-04-05 03:21:27 -0500

MRRobot gravatar image

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
edit retag flag offensive close merge delete

Comments

The .so: undefined reference to symbol indicates the complication is failing at the linker. First off, I would check if dummy_function is declared somewhere in one of your headers.

bsaund gravatar image bsaund  ( 2019-04-05 09:55:08 -0500 )edit

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,

MRRobot gravatar image MRRobot  ( 2019-04-07 12:12:42 -0500 )edit