Skip to content

Instantly share code, notes, and snippets.

@aemarkov
Last active February 12, 2019 21:05
Show Gist options
  • Save aemarkov/e20321a221ae4e03b074c77b75968fcc to your computer and use it in GitHub Desktop.
Save aemarkov/e20321a221ae4e03b074c77b75968fcc to your computer and use it in GitHub Desktop.

Короче, ты хочшеь сделать пакет 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, а затем можно менять свои файлы и все будет работать!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment