[roscpp] Get package name from argv vector
Hello everyone,
as per the title of the post, I am looking for a method able to get the package name from the argv
vector inside my ROS node implementation, bearing in mind that it is my plan to always use the roslaunch
utility to run the executable.
As far as I have seen, roslaunch
converts the line of the launch file:
<node pkg="pkg_name" type="exec_name" name="node_name"/>
into the command:
path-to-catkin-ws/devel/lib/pkg_name/exec_name __name:=node_name
which is then used to build the argv
parameters vector. Is there any other way to get the package name other than extracting it from the string contained in argv[0]
?
EDIT
I'll try to explain briefly the reason why I need this. My working group is in the process of refactoring some code in our system. In particular, we have two packages, say base_pkg and derived_pkg, where the latter depends on the former.
The package base_pkg provides a library containing a class, say MyROSNodeInterface
, which defines the interface for the ROS nodes we are developing in our system.
The package derived_pkg contains a class, say MyROSNode
, which implements an actual ROS node inheriting from the MyROSNodeInterface
class.
The MyROSNodeInterface
class implements some functionalities that we want all the actual nodes to have in common, so we want to be able to have access to information about the derived class, such as the package name, in the base one.
In the legacy version of the code, these functionalities were implemented in the header file of the class MyROSNodeInterface
using ROS defines such as ROS_PACKAGE_NAME
.
This file was then included in the file MyROSNode.h and compiled when compiling the package derived_pkg
. In this case everything worked fine, as the compile-time constants assumed the values specified in the compilation of derived_pkg
, e.g. ROS_PACKAGE_NAME=derived_pkg
.
Now, we want to refactor the implementation of the class MyROSNodeInterface
in header file and implementation file. In this case, the compile-time constants will be used in the MyROSNodeInterface.cpp file, which will only be compiled when the base_pkg
is compiled. In this case, the compile-time constants will assume the values given during the compilation of base_pkg
, e.g. ROS_PACKAGE_NAME=base_pkg
.
The only way that came to my mind to solve this problem is to add the all the additional information about the actual node, such as the package name, in the interface of the MyROSNodeInterface
class, but this would require a change in the code of MyROSNode
(and all the other actual nodes) to pass an additional parameter to the base class constructor.
Since at the moment the interface of the class MyROSNodeInterface
is the following:
class MyROSNodeInterface {
MyROSNodeInterface(int argc, char **argv, const std::string& node_name);
// Other interface methods
};
I was wondering whether it is possible to retrieve at least the package name from the argv
vector.
I hope this helps to understand better the problem.
There should be no need to parse
argv
yourself.The ros::this_node namespace contains a function get_name() which:
Thank you for replying. That function returns the node name (
node_name
in the example), not the package name (pkg_name
). Am I wrong?Ah, you're right. I misread your question.
In that case, your question is a duplicate of #q254330.
As to your question: I don't believe there is API provided for this.
Relying on the package name to be part of the path to the binary is probably rather brittle, as it doesn't always have to be the case it's present.
Thanks, I'll follow it then. I though mine was a bit more specific than that one, that's why I opened a new one. Apologies if I was wrong
Yes, I don't like it either and I understand your concern. In my mind, I would always rely on
roslaunch
to run the node, and since you always need to provide the package name as a parameter in the launch file, I thought it could always be retrieved somehow. I know it sounds a silly problem, but it is just the last bit in a bigger matter. Maybe I will add this to the question for completeness.Do you want to do this dynamically btw, or would a compile-time option be acceptable?
And also: please explain why you want the name of the package. We may be discussing an xy-problem.
Ok, I'll edit the post now and try to explain what I'm trying to solve