ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

Importing std_msgs.msg with Python

asked 2019-08-26 07:13:24 -0600

Ricky98 gravatar image

Hi guys, I am following the ROS Beginner's Tutorials, on the part Writing a Simple Publisher and Subscriber (Python). In the publisher code given, there is a line which says from std_msgs.msg import String. From my knowledge of python, this means that std_msgs.msg is a module name (i.e. a .py file) and there should be a class definition for String inside that file. However, I can't seem to find this file (i.e. I can't find any file named std_msgs.msg.py). I looked through the documentation and it says that rospy do create python source code for msg files, so there must be this std_msgs.msg.py file somewhere. Anyone knows where this file is located? Or perhaps my understanding is wrong?

edit retag flag offensive close merge delete

2 Answers

Sort by » oldest newest most voted
2

answered 2019-08-26 07:28:13 -0600

gvdhoorn gravatar image

updated 2019-08-26 07:53:07 -0600

From my knowledge of python, this means that std_msgs.msg is a module name (i.e. a .py file) and there should be a class definition for String inside that file.

[..]

I looked through the documentation and it says that rospy do create python source code for msg files, so there must be this std_msgs.msg.py file somewhere [..]

While it is true that Python modules are contained in a single file (ie: one with the same name as the module + .py), there is a second construct called a package that is what is used here in this case.

Any directory with a __init__.py file in it will be considered a package by the Python interpreter. Any files inside that directory (apart from __init__.py) are again modules (which can contain classes and other Python entities), and sub directories of a package's directory will be considered sub packages (as long as they also contain a __init__.py file).

In the case of std_msgs, this is what that looks like:

└── /opt/ros/kinetic/lib/python2.7/dist-packages
  └── std_msgs
    ├── __init__.py
    └── msg
      ├── _Bool.py
      ├── _ByteMultiArray.py
      ├── _Byte.py
      ├── ..
      ├── __init__.py
      ├── ..
      ├── _String.py
      ├── ..
      ├── _UInt8MultiArray.py
      └── _UInt8.py

So all ROS Python (2) packages (note: not necessarily ROS packages, as a single ROS package may contain multiple Python packages) are located in /opt/ros/kinetic/lib/python2.7/dist-packages, in which there is a sub directory called std_msgs. This contains a __init__.py file, marking it as a sub package. This has a sub directory msg, which then contains both a __init__.py as well as all the files that contain the implementations of all the message classes (and which were generated by genpy (not rospy).

When you write from std_msgs.msg import String, the Python interpreter will traverse this directory structure and end up at _String.py, load it and make all the contained symbols available to the session.

edit flag offensive delete link more

Comments

1

I'd absolutely support this explanation, if there wouldn't be this distinction in the Python docs:

A module is a file containing Python definitions and statements.

and

Packages are a way of structuring Python’s module namespace by using “dotted module names”.

Though this distinction is kind of strange/unintuitive in my perspective. And as far as I have seen you are absolutely fine going with this explanation.

mgruhler gravatar image mgruhler  ( 2019-08-26 07:33:58 -0600 )edit

Oh wow, I didn't even know about python packages and importing them, since I just learned python a week ago. Thank you so much for clarifying the whole thing. The link posted by mgruhler was very helpful too.

Ricky98 gravatar image Ricky98  ( 2019-08-26 07:51:55 -0600 )edit
1

@mgruhler: you're correct, and I've updated the answer.

gvdhoorn gravatar image gvdhoorn  ( 2019-08-26 07:53:35 -0600 )edit

The answer by @gvdhoorn is way more self-contained now, so I suggest to mark this as the correct one.

mgruhler gravatar image mgruhler  ( 2019-08-26 08:00:56 -0600 )edit

If you have installed and build ROS from source the path is as example ~/ros_catkin_ws/install_isolated/lib/python2.7/dist-packages/ instead of /opt/ros/$ROSDISTRO/lib/python2.7/dist-packages

Michdo93 gravatar image Michdo93  ( 2021-06-29 05:00:59 -0600 )edit
2

answered 2019-08-26 07:30:02 -0600

mgruhler gravatar image

Not quite correct.

String is the module, which is located in the std_msgs.msg (sub-)package. So you would need to be looking for a String.py file (or to be correct in this case, _String.py). The full path to the file, if installed via apt, is /opt/ros/kinetic/lib/python2.7/dist-packages/std_msgs/msg/_String.py.

See also this SO question or this explanation of Python Packages.

edit flag offensive delete link more

Question Tools

Stats

Asked: 2019-08-26 07:13:24 -0600

Seen: 10,111 times

Last updated: Aug 26 '19