c++cmakeroscatkin

CMake with ROS Package:Header files not detected


I am trying to organise my code into a more OOP style with each class taking on its own header and cpp file. This is my tree in the package folder in the workspace

- CMakeLists.txt
- include
- - Master_Thread.h
- - Entry.h
- - ROS_Topic_Thread.h
- src
- - pcl_ros_init.cpp
- - archive
- - - pcl_ros_not_updated.cpp
- - - pc_ros_old2.cpp
- - - thread.cpp
- - - pcl_ros_old.cpp
- package.xml

I haven't placed the classes definition in the cpp files respectively, i have placed them all with the main code(pcl_ros_init.cpp) for the time being. My classes have some slight dependency on one another, for example Master_Thread class uses ROS_Topic_Thread in its declaration and right now, Cmake is able to find the include files but within the header files like Master_Thread.h, it is unable to find the class signature of ROS_Topic_Thread as such pcl_ros_custom/include/Master_Thread.h:38:36: error: ‘ROS_Topic_Thread’ has not been declared

This is my CMakeLists.txt

cmake_minimum_required(VERSION 3.0.2)
project(pcl_ros_custom)

find_package(catkin REQUIRED COMPONENTS
roscpp
pcl_conversions
pcl_ros)

catkin_package(
INCLUDE_DIRS
CATKIN_DEPENDS roscpp
           pcl_conversions
           pcl_ros
)

include_directories(
include
${catkin_INCLUDE_DIRS}/include/**
)

add_executable(pcl_ros_init src/pcl_ros_init.cpp)
target_link_libraries(pcl_ros_init 
            ${catkin_LIBRARIES} ${roslib_LIBRARIES} ${PCL_LIBRARIES} )

These are 2 of the header files

#ifndef MASTER_THREAD_H
#define MASTER_THREAD_H
#include <ros/ros.h>
#include <pcl_conversions/pcl_conversions.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <sensor_msgs/PointCloud2.h>

#include <thread>
#include <mutex>
#include <chrono>
#include <functional>
#include <utility>
#include <string>

//include custom classes
#include "ROS_Topic_Thread.h"
#include "ClusteringBenchmarkEntry.h"


namespace OCB
{
    class Master_Thread
{
    private:
    std::atomic<bool> mKillswitch;
    std::vector<sensor_msgs::PointCloud2ConstPtr> mMasterbuffer1, mMasterbuffer2, mMasterbuffer3, mMasterbuffer4, mMergedPointCloud2Ptr_buffer;
    public:
    Master_Thread();
    void transfer_to_master_buffer(ROS_Topic_Thread&t1,ROS_Topic_Thread&t2, ROS_Topic_Thread&t3, ROS_Topic_Thread&t4 );
    
    void process_buffer();
    void setkillswitch();
};

} 
#endif
#ifndef ROS_TOPIC_THREAD_H
#define ROS_TOPIC_THREAD_H

#include <ros/ros.h>
#include <pcl_conversions/pcl_conversions.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <sensor_msgs/PointCloud2.h>

#include <thread>
#include <mutex>
#include <chrono>
#include <functional>
#include <utility>
#include <string>


#include "Master_Thread.h"
#include "ClusteringBenchmarkEntry.h"

namespace OCB
{
class ROS_Topic_Thread
{
    private:
    ros::Subscriber mSub;

    // Topic
    const std::string mSUB_TOPIC;

    //buffer
    std::vector<sensor_msgs::PointCloud2ConstPtr> mThreadbuffer;
    
    std::mutex mMutex;

    public:
    ROS_Topic_Thread()= delete;
    ROS_Topic_Thread(ros::NodeHandle* nodehandle, const std::string& SUBTOPIC, ClusteringBenchmarkEntry* entry);
  
    void callback(const sensor_msgs::PointCloud2ConstPtr& sub_ptr);
    friend class Master_Thread;

};

} //namespace close scope

#endif //for ROS_TOPIC_THREAD_H

Where am i going wrong?

EDIT

This is a really good link which clears up most of my header files organisation in C++ which on top of the answers helps me get project building to go smoothly. Hope it helps whoever is reading this.


Solution

  • In essence you don't need to include either header into the other. This fixes the circular includes. In ROS_Topic_Thread.h, friend class Master_Thread; already forward declares Mater_Thread, so you don't need the Master_Thread.h header. In Master_Thread.h, you can also forward declare class ROS_Topic_Thread; before the declaration of the Master_Thread class, since you only use references to ROS_Topic_Thread in the transfer_to_master_buffer method.

    #ifndef MASTER_THREAD_H
    #define MASTER_THREAD_H
    #include <ros/ros.h>
    #include <pcl_conversions/pcl_conversions.h>
    #include <pcl/point_cloud.h>
    #include <pcl/point_types.h>
    #include <sensor_msgs/PointCloud2.h>
    
    #include <thread>
    #include <mutex>
    #include <chrono>
    #include <functional>
    #include <utility>
    #include <string>
    
    //include custom classes
    #include "ClusteringBenchmarkEntry.h"
    
    
    namespace OCB
    {
        class ROS_Topic_Thread;
        class Master_Thread
    {
        private:
        std::atomic<bool> mKillswitch;
        std::vector<sensor_msgs::PointCloud2ConstPtr> mMasterbuffer1, mMasterbuffer2, mMasterbuffer3, mMasterbuffer4, mMergedPointCloud2Ptr_buffer;
        public:
        Master_Thread();
        void transfer_to_master_buffer(ROS_Topic_Thread&t1,ROS_Topic_Thread&t2, ROS_Topic_Thread&t3, ROS_Topic_Thread&t4 );
        
        void process_buffer();
        void setkillswitch();
    };
    
    } 
    #endif
    
    #ifndef ROS_TOPIC_THREAD_H
    #define ROS_TOPIC_THREAD_H
    
    #include <ros/ros.h>
    #include <pcl_conversions/pcl_conversions.h>
    #include <pcl/point_cloud.h>
    #include <pcl/point_types.h>
    #include <sensor_msgs/PointCloud2.h>
    
    #include <thread>
    #include <mutex>
    #include <chrono>
    #include <functional>
    #include <utility>
    #include <string>
    
    #include "ClusteringBenchmarkEntry.h"
    
    namespace OCB
    {
    class ROS_Topic_Thread
    {
        private:
        ros::Subscriber mSub;
    
        // Topic
        const std::string mSUB_TOPIC;
    
        //buffer
        std::vector<sensor_msgs::PointCloud2ConstPtr> mThreadbuffer;
        
        std::mutex mMutex;
    
        public:
        ROS_Topic_Thread()= delete;
        ROS_Topic_Thread(ros::NodeHandle* nodehandle, const std::string& SUBTOPIC, ClusteringBenchmarkEntry* entry);
      
        void callback(const sensor_msgs::PointCloud2ConstPtr& sub_ptr);
        friend class Master_Thread;
    
    };
    
    } //namespace close scope
    
    #endif //for ROS_TOPIC_THREAD_H