Короче, ты хочшеь сделать пакет ROS, где есть Python. И хочешь переиспользовать некий общий код.
my_package\
scripts\
common\
helper.py
node_a\
node_a.py
wtf.py
node_b\
node_b.py
omg.py
Надо импортировать helper.py
в node_a.py
и node_b.py
. Как? Надо правильно настроить структуировать пакет.
Информации полно, но т.к. некоторые моменты мне были по началу не очевидны, и я потратил какое-то время на это, то вот гайд.
Я встречал разные варианты структуры пакета, но я хочу так:
my_package\
scripts\
my_package\ # Наш модуль, здесь то, что мы хотим импортировать
common\
__init__.py
helper.py
__init.py
node_a # То, что не хотим импортировать, напр. ноды
node_b
CMakeLists.txt
package.xml
setup.py
Summary:
- рекомендуется ноды называть без
.py
, чтобы они именовались так же, как и C++ ноды - рекомендуется помещать в ноду чуть-чуть кода, если нода большая, лучше вынести в модуль и вызвать из ноды
- все, что хотим импортировать, кладем в папку, создаем там
__init__.py
- это наш python-модуль, его потом можно будет импортировтаь. Конечно же, модуль может содержать в себе под-модули - рекомендуется называть модуль также, как и ROS-пакет
- располагать модуль и ноды можно как угодно. Я видел варианты класть модуль в
src/
, а ноды вnodes/
илиbin/
(WTF?)
Добавляем в корень нашего пакета файл setup.py
:
## ! DO NOT MANUALLY INVOKE THIS setup.py, USE CATKIN INSTEAD
from distutils.core import setup
from catkin_pkg.python_setup import generate_distutils_setup
# fetch values from package.xml
setup_args = generate_distutils_setup(
packages=['my_package'], # Имя нашего модуля (ну или нескольких модулей)
package_dir={'': 'scripts'}, # Пути поиска модуля
requires=['std_msgs', 'rospy'] # Фиг знает, думаю, можно не указывать
)
setup(**setup_args)
А в CMakeLists.txt
расскомментить (или добавить) строку:
catkin_python_setup()
Сделать catkin_make
.
Все, теперь можно спокойно импортировать:
#!/usr/bin/python
# node_a
import my_package.common.helper
...
ВНИМАНИЕ. То, что это "setup" вовсе не значит, что что-то куда-то копируется. catkin создает __init__.py
в директории
ros_workspace/devel/lib/python2.7/dist-packages/my_package
, который уже содержит путь до пакета. Таким образом, достаточно
один раз сделать catkin_make
, а затем можно менять свои файлы и все будет работать!