Nested header dependencies (ROS, C++) - c++

Short context: I am trying to make a Node working on ROS for a TIAGo robot (https://pal-robotics.com/robots/tiago/). It has a working tutorial node on adjusting its head, which works, but I'd now like to make a customized version of that.
I have neatly separated .cpp and .h files of both my node and the tutorial node. Now, I'd like to borrow some functions and definitions from that tutorial node to make my node work. When I build my ROS workspace using catkin, it yields errors concerning 'undefined reference'. I suspect it might be due to the ways I import headers. Some include headers coincide, and I do not know how to handle 'nested' dependencies. Here's what I mean (I've renamed the nodes to my_node and tutorial_node here for simplicity):
my_node.h
#ifndef MY_NODE_H
#define MY_NODE_H
// Declare included packages
#include <ros/ros.h>
#include <math.h>
#include <geometry_msgs/PointStamped.h>
#include <tutorial_node/tutorial_node.h>
// Declare TIAGo's centered viewpoint as a stamped point
geometry_msgs::PointStamped tiagoCenterView;
// Function declarations
geometry_msgs::PointStamped calculateDesiredPoint(geometry_msgs::PointStamped faceCenter);
int calculateCenterDistance(geometry_msgs::PointStamped point_a, geometry_msgs::PointStamped point_b);
void faceCallback(geometry_msgs::PointStamped msg);
#endif
my_node.cpp
#include "my_node/my_node.h"
{actual code content}
tutorial_node.h
#ifndef TUTORIAL_NODE_H
#define TUTORIAL_NODE_H
// C++ standard headers
#include <exception>
#include <string>
// Boost headers
#include <boost/shared_ptr.hpp>
// ROS headers
#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <actionlib/client/simple_action_client.h>
#include <sensor_msgs/CameraInfo.h>
#include <geometry_msgs/PointStamped.h>
#include <control_msgs/PointHeadAction.h>
#include <sensor_msgs/image_encodings.h>
#include <ros/topic.h>
// OpenCV headers
#include <opencv2/highgui/highgui.hpp>
#include <cv_bridge/cv_bridge.h>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static const std::string windowName = "Inside of TIAGo's head";
static const std::string cameraFrame = "/xtion_rgb_optical_frame";
static const std::string imageTopic = "/xtion/rgb/image_raw";
static const std::string cameraInfoTopic = "/xtion/rgb/camera_info";
// Intrinsic parameters of the camera
cv::Mat cameraIntrinsics;
// Our Action interface type for moving TIAGo's head, provided as a typedef for convenience
typedef actionlib::SimpleActionClient<control_msgs::PointHeadAction> PointHeadClient;
typedef boost::shared_ptr<PointHeadClient> PointHeadClientPtr;
PointHeadClientPtr pointHeadClient;
ros::Time latestImageStamp;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Definitions
void imageCallback(const sensor_msgs::ImageConstPtr& imgMsg);
void onMouse( int event, int u, int v, int, void* );
void createPointHeadClient(PointHeadClientPtr& actionClient);
#endif
tutorial_node.cpp
#include <tutorial_node/tutorial_node.h>
{actual code contents}
In my_node.h, I include tutorial_node.h, which contains some of the includes I actually need for my_node.cpp. For example, I need the pointHeadClient object defined in tutorial_node.h, as well as the actionlib/client/simple_action_client.h. Is that the proper way of including or are those spaghetti headers? If those are, what's the better way to handle this?
I suspect that's where my error is coming from so I'll save you the specifics so that I can figure the actual error out myself once this header problem is clear.

Related

Full process for compiling/linking and using MATLAB coder generated C++ files

I've been struggling with this for a very long time.
Using MATLAB's coder, I've generated a C++ code, but I'm not sure how to implement it in my main file.
This is the directory containing the MATLAB generated C++ code. Could somebody please walk me through how to use this code in another main file?
(The whole process of making a make file, include statements, etc;) I really would appreciate it if the explanation is specific and thorough.
Here is one of the header files that I need to include (IOPfinal.h)
#ifndef IOPFINAL_H
#define IOPFINAL_H
// Include Files
#include <math.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include "rt_nonfinite.h"
#include "rtwtypes.h"
#include "IOPfinal_types.h"
// Function Declarations
extern double IOPfinal(const emxArray_real_T *wavelength, const emxArray_real_T *
intensity, double range, const emxArray_real_T *polymat);
#endif
I've heard that there are makefiles that are also provided by MATLAB but I'm not sure exactly how to use them and what I should do after using that makefile either. The code below is the main file that I intend to use.
#include "IOPfinal.h"
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include "IOPfinal.h"
#include "IOPfinal_emxAPI.h"
using namespace std;
int main() {
double *wavelength, *intensity;
// some code to initialize wavelength and intensity
emxArray_real_T *inputs, *outputs;
inputs = emxCreateWrapper_real_T(wavelength, 1, 3);
outputs = emxCreateWrapper_real_T(intensity, 1, 3);
return 0;
}
Thanks in advance!

Class differences between C++03 and C++11

I'm current building an application in which I have a log function that is accessible in most of my classes which was declared as below:
FileHandler.h
#ifndef FILEHANDLER_H
#define FILEHANDLER_H
#pragma once
#include <SDL.h>
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <cctype>
//Include to allow logging
#include "log.h"
class fileHandler
{
public:
fileHandler();
virtual ~fileHandler();
void WriteToFile(const std::string& filename, std::string textToWrite);
std::vector<std::string> ReadFromFile(const std::string& filename);
std::string& TrimString(std::string& stringToTrim);
protected:
private:
class log logHandler;
std::vector<std::string> blockOfText;
std::string currentLine;
};
#endif // FILEHANDLER_H
Log.h
#ifndef LOG_H
#define LOG_H
#pragma once
#include <SDL.h>
#include <string.h>
#include <iostream>
#include <sstream>
#include <fstream>
#include <time.h>
class log
{
public:
log();
virtual ~log();
void static WriteToConsole(std::string textToWrite);
void WriteToLogFile(std::string textToWrite);
protected:
private:
};
#endif // LOG_H
This worked fine for a long time and then I wanted to include another function elsewhere in my application that was only compatible with C++11 so I told the compiler to compile to these standards. I was then receiving an error on "log logHandler" saying log is not a declared name.
I was able to resolve the problem by changing the line to
class log logHandler;
I was wondering if anybody could tell me what has changed between C++03 and C++11 that required me to do this?
EDIT: Included all relevant code to make question more complete.
You don't show your real code (missing ; at the end of the class declaration, no #endif), but chances are that your problem is somehow related to std::log, which has received a new overload in C++11, in combination with a using namespace std somewhere in your code.
Note that the new overload is probably irrelevant to the problem at hand; the real reason may very well be a change somewhere in your compiler's standard-library implementation causing an internal #include <cmath>. This means that even in C++03, your code was only working by sheer coincidence, and a conforming C++03 compiler was always allowed to reject it.
Here is an example program which may reproduce your problem:
#include <cmath>
using namespace std;
struct log
{
};
int main()
{
// log l; // does not compile
struct log l; // compiles
}
Nothing has changed about how the code you posted is treated.
What I suspect is, that you somewhere have an
#include <cmath>
And below that, somewhere else
using namespace std;
This causes your compiler to not be able to unambiguously resolve the name log, since there is std::log (a function) and your class log.
By explicitly stating class log, you tell the compiler that you are referring to the class.

C++ include issue

I am writing a plugin for Autodesk Maya using C++ and have a linker error.
My main class is Maya_Search_Plugin.cpp
#include <Utilities.h>
DeclareSimpleCommand( search_face, PLUGIN_COMPANY, "4.5");
//doIt method is entry point for plugin
MStatus search_face::doIt( const MArgList& )
{
//calls to Maya types/functions and Utilities functions
}
Then I have a Utilities class containing some static methods with header looking like this
#ifndef __Maya_CPP_Plugin__Utilities__
#define __Maya_CPP_Plugin__Utilities__
//#pragma once
//standard libs
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <iostream>
#include <math.h>
//maya libs
#include <maya/MDagPath.h>
#include <maya/MFn.h>
#include <maya/MFileIO.h>
#include <maya/MIOStream.h>
#include <maya/MFnMesh.h>
#include <maya/MFnTransform.h>
#include <maya/MGlobal.h>
#include <maya/MSelectionList.h>
#include <maya/MSimple.h>
#include <maya/MTypes.h>
#include <maya/MPointArray.h>
#include <maya/MObjectArray.h>
class Utilities{
public: static const int max_mov = 50;
public:
static double get_mesh_error(MPointArray, MPointArray, int);
static MStatus translateManipulator(double amount, MObject *path);
static void GetSelected(MObjectArray* objects, MFn::Type type);
};
#endif /* defined(__Maya_CPP_Plugin__Utilities__) */
with the implementation like this
#include <Utilities.h>
double Utilities::get_mesh_error(MPointArray a, MPointArray b, int vertexCount){
...
}
MStatus Utilities::translateManipulator(double amount, MObject *path){
...
}
void Utilities::GetSelected(MObjectArray* objects, MFn::Type type) {
...
}
However I am getting the following error
duplicate symbol _MApiVersion in:
/Users/tmg06qyu/Library/Developer/Xcode/DerivedData/Maya_CPP_Plugin-hjrwvybwlvqyyscbmixdkcpdzjqr/Build/Intermediates/Maya_CPP_Plugin.build/Debug/Maya_CPP_Plugin.build/Objects-normal/x86_64/Maya_Search_Plugin.o
/Users/tmg06qyu/Library/Developer/Xcode/DerivedData/Maya_CPP_Plugin-hjrwvybwlvqyyscbmixdkcpdzjqr/Build/Intermediates/Maya_CPP_Plugin.build/Debug/Maya_CPP_Plugin.build/Objects-normal/x86_64/Utilities.o
ld: 1 duplicate symbol for architecture x86_64
Command /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld failed with exit code 1
Which I presume is a linking error and there is some circular reference somewhere, but I can't work out where it is.
Any help appreciated.
Thanks.
I know this is a year old. But I stumbled on this again a couple minutes ago...
Add
#define MNoVersionString
#define MNoPluginEntry
#include <maya/MFnPlugin.h>
to your header or cpp files where you wrote your plugin code. Include
#include <maya/MFnPlugin.h>
directly in your main.cpp that initializes the plugin.
Most of the examples in maya have the following string:
// This is added to prevent multiple definitions of the MApiVersion string.
#define _MApiVersion
before including anything. For example here.
The issue may happen if you have multiple files which include MFnPlugin.h

CPP include header file results in thousands of errors

When I include this header File "pathfinding.h":
#pragma once
#include <BWAPI.h>
#include "BWAPI/TilePosition.h"
#include <vector>
#include "PathNode.h"
#include "Logger.h"
#include "ArgosMap.h"
#include "MapField.h"
#include "Utils.h"
#include "ComparePathNodePointer.h"
using namespace BWAPI;
class Pathfinding {
private:
std::vector<PathNode*> openList;
std::vector<PathNode*> closedList;
std::vector<Position*> buildpath(PathNode* targetNode);
void expandNode(PathNode* currentNode, MapField* targetField);
ArgosMap* argosMap;
public:
Pathfinding();
~Pathfinding();
std::vector<Position*> getShortestPath(MapField* startField, MapField* targetField);
};
In this header File "UnitAgent.h":
#pragma once
#include <BWAPI.h>
#include <vector>
#include "ArgosMap.h"
#include "Pathfinding.h"
using namespace BWAPI;
class UnitAgent {
protected:
Unit* unit;
UnitType unitType;
int unitID;
std::vector<Position*> trail;
Position target;
public:
UnitAgent(Unit* unit);
std::vector<Position*> getTrail();
Position getTarget();
Position* getPosition();
int getUnitID();
void setTarget(Position target);
void addPositionToTrail(Position* targetLocation);
void moveTo(TilePosition* targetPosition);
};
I get like a million errors mostly error C2143, C2065. But thats not true, the errors do not exist. When I include the header file in another file its all totally fine (except naturally for the stuff that needs the specific header file).
Any Ideas what I should check. Anyone an Idea how i can check my C++ Code, in a way Eclipse checks my java code. I mean why doesnt Visual Studio do that?
This kind of directive should not be in a header file
using namespace BWAPI;
To start with, why do you need all this
#include <BWAPI.h>
#include "BWAPI/TilePosition.h"
#include <vector>
#include "PathNode.h"
#include "Logger.h"
#include "ArgosMap.h"
#include "MapField.h"
#include "Utils.h"
#include "ComparePathNodePointer.h"
using namespace BWAPI;
in pathfinding.h? Just forward declaring ArgosMap, MapField, PathNode, and Position like
class ArgosMap;
class MapField;
class PathNode;
class Position;
is sufficient for pathfinding.h looking at the declaration of Pathfinding class, the stuff above should go to pathfinding.cpp if it is necessary for implementation of Pathfinding methods. The less stuff and dependencies you have in your headers, the easier it will be to debug.
Declarations in pathfinding.h look fine, problem is that some of the methods are not implemented/are not implemented properly. To find out what this methods are, you would need to narrow the scope of the problem - by removing unnecessary dependencies to start with.
Including pathfinding.h in files that do not use it's methods/methods from other headers included would always work fine...

Undefined reference to 'Class::Class'

After fixing the previous problem (see my one other question that I have asked). I had declared more classes.
One of these is called CombatAdmin which does various things: (Header file)
#ifndef COMBATADMIN_H
#define COMBATADMIN_H
#include <string> // Need this line or it complains
#include <Player.h>
#include <Sound.h>
#include <Enemy.h>
#include <Narrator.h>
using namespace std;
class Enemy;
class Player;
class CombatAdmin // Code yet to be commented here, will come soon.
{
public:
CombatAdmin();
void healthSet(double newHealth, string playerName);
void comAdSay(string sayWhat);
void playerFindsChest(Player *player,Weapon *weapon,Armour *armour);
void youStoleOurStuffEncounter(Player *player);
void comAdWarning(string enemyName);
void comAdAtkNote(string attack, double damage,string target,string aggresor);
void entDefeated(string entName);
void comAdStateEntHp(string ent, double hp);
void comAdStateScanResults(string enemyName, double enemyHealth);
string doubleToString(double number);
string intToString(int number);
bool isRandEncounter();
void randomEncounter(Player *player,Sound *sound,Narrator *narrator);
bool combatRound(Player *player, Enemy *enemy, Sound *sound, bool ran);
void playerFindsItem(string playerName,string itemName,double itemWeight,double playerWeight);
void playerFindsGold(string playerName,double coinCnt,double playerCoinCnt);
};
#endif // COMBATADMIN_H
It is then instanced in the main.cpp file like this: (Snippet of the main.cpp file)
#include <iostream> // Required for input and output
#include <Item.h> // Item header file.
#include <Weapon.h> // Header files that I have made for my classes are needed for this program
#include <sstream> // Needed for proper type conversion functions
#include <windows.h> // for PlaySound() and other functions like sleep.
#include <time.h> // Needed to seed the rand() function.
#include <mmsystem.h> // Not sure about this one, possibly defunct in this program.
#include <stdio.h> // Needed for a similar kind of output as iostream for various functions error msgs.
#include <irrKlang.h> // The header file of the sound lib I am using in this program.
#include <Narrator.h> // The narrators's header file.
#include <Pibot.h> // Other header files of classes.
#include <Armour.h>
#include <Player.h>
#include <Weapon.h>
#include <CombatAdmin.h>
using namespace irrklang;
using namespace std;
// Forward referenced functions
void seedRandom(); // Seeds the random number so it will be random as apposed to pseudo random.
string getPlayerName(string temp); // Gets the player's new name.
int main(int argc, char* argv[])
{
// Variables and object pointers declared here.
CombatAdmin *comAd = new CombatAdmin(); // Handles combat.
Narrator *narrator = new Narrator(); // The Narrator that says stuff
Pibot *piebot = new Pibot(); // PIbot, the player's trusty companion
string temp; // Temp string for input and output
However, when I try to compile the project, I get the following error:
C:\Documents and Settings\James Moran.HOME-B288D626D8\My Documents\C++ projects\Test Project\main.cpp|59|undefined reference to `CombatAdmin::CombatAdmin()'|
I am using the Code::Blocks IDE (ver 10.05), with the GNU GCC compiler. The project is of type "Console application". I am using windows XP 32 bit SP3.
I have tried changing to search directories to include where the object files are, but no success there.
As can be seen from the code, the narrator and PIbot are instanced just fine. (then used, not shown)
My question is, therefore, what do I need to do to stop these errors occurring? As when I encountered similar "Undefined reference to x" errors before using libraries. I had just forgotten to link to them in Code::Blocks and as soon as I did, they would work.
As this class is of my own making I am not quite sure about this.
Do say if you need more information regarding the code etc.
You have declared the default constructor (CombatAdmin()) and thus prevented the compiler from automatically generating it. Thus, you either need to 1) remove declaration of the default constructor from the class, or 2) provide an implementation.
I had this kind of error and the cause was that the CombatAdmin.cpp file wasn't selected as a Build target file: Prject->Properties->Build targets
Are you sure you've to include your header as:
#include <CombatAdmin.h>
?
I think you need to include your header file as:
#include "CombatAdmin.h"
And same for other headers written by you, like these:
#include "Armour.h"
#include "Player.h"
#include "Weapon.h"
//and similarly other header files written by you!
See this topic:
What is the difference between #include <filename> and #include "filename"?
My solution was just to add a line in the header before the class defenition:
class CombatAdmin;