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.
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