1. 概要
「python」でパッケージを作ってみようと思います。
まず、サンプルのパッケージ。
本ページは、下記のサイトを参考にさせていただきました。
「Writing a simple service and client (Python)」
2. パッケージ作成
「Ubuntu」で。
ワークスペースを「first_py」パッケージ名を「service_py」として、パッケージ作成。
mkdir -pv ~/first_py/src
cd ~/first_py/src
ros2 pkg create --build-type ament_python service_py --dependencies rclpy example_interfaces
こんなんでけました。
`-- service_py
|-- package.xml
|-- resource
| `-- service_py
|-- service_py
| `-- __init__.py
|-- setup.cfg
|-- setup.py
`-- test
|-- test_copyright.py
|-- test_flake8.py
`-- test_pep257.py
5 directories, 8 files
インタフェースの形式は、「C」言語のサンプルで使用したものと同じで、結局同じことをするものが出来上がるはずです。
3. ソース作成
「package.xml」
下記の箇所だけ書き換えろとのことです。
<description>Python client server tutorial</description>
<maintainer email="you@email.com">Your Name</maintainer>
<license>Apache License 2.0</license>
「setup.py」
これも、下記の箇所だけ書き換えろとのことです。
maintainer='Your Name',
maintainer_email='you@email.com',
description='Python client server tutorial',
license='Apache License 2.0',
ソースは、作成していきます。
「service_py/service_member_function.py」
from example_interfaces.srv import AddTwoInts
import rclpy
from rclpy.node import Node
class MinimalService(Node):
def __init__(self):
super().__init__('minimal_service')
self.srv = self.create_service(AddTwoInts, 'add_two_ints', self.add_two_ints_callback)
def add_two_ints_callback(self, request, response):
response.sum = request.a + request.b
self.get_logger().info('Incoming request\na: %d b: %d' % (request.a, request.b))
return response
def main(args=None):
rclpy.init(args=args)
minimal_service = MinimalService()
rclpy.spin(minimal_service)
rclpy.shutdown()
if __name__ == '__main__':
main()
「service_py/client_member_function.py」
import sys
from example_interfaces.srv import AddTwoInts
import rclpy
from rclpy.node import Node
class MinimalClientAsync(Node):
def __init__(self):
super().__init__('minimal_client_async')
self.cli = self.create_client(AddTwoInts, 'add_two_ints')
while not self.cli.wait_for_service(timeout_sec=1.0):
self.get_logger().info('service not available, waiting again...')
self.req = AddTwoInts.Request()
def send_request(self, a, b):
self.req.a = a
self.req.b = b
self.future = self.cli.call_async(self.req)
rclpy.spin_until_future_complete(self, self.future)
return self.future.result()
def main(args=None):
rclpy.init(args=args)
minimal_client = MinimalClientAsync()
response = minimal_client.send_request(int(sys.argv[1]), int(sys.argv[2]))
minimal_client.get_logger().info(
'Result of add_two_ints: for %d + %d = %d' %
(int(sys.argv[1]), int(sys.argv[2]), response.sum))
minimal_client.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
「setup.py」の「entry_points」の箇所を下記へ変更します。
entry_points={
'console_scripts': [
'service = service_py.service_member_function:main',
'client = service_py.client_member_function:main',
],
},
4. ビルド
cd ~/first_py
rosdep install -i --from-path src --rosdistro jazzy -y
rosdep update
colcon build --packages-select service_py
source install/setup.bash
5. 実行
端末を2つ開いて。
それぞれで。
source install/setup.bash
を実行後。
1つで。
ros2 run service_py service
1つで。
ros2 run service_py client 2 3
サーバ側に。
[INFO] [1734668285.105764294] [minimal_service]: Incoming request
a: 2 b: 3
クライアント側に。
[INFO] [1734668285.125642217] [minimal_client_async]: Result of add_two_ints: for 2 + 3 = 5
と、表示されます。
うまくいったようです。
6. Windows
「Windows」でも同じパッケージを作成してみます。
ワークスペースは「Windows」では。
C:\first_py
とします。
ワークスペースとパッケージを作成。
「x64 Native Tools Command Prompt for VS 2019」を管理者権限で開いて。
call C:\ros2_jazzy\local_setup.bat
mkdir C:\first_py\src
cd C:\first_py\src
ros2 pkg create --build-type ament_python service_py --dependencies rclpy example_interfaces
「Ubuntu」と同じソースを作成して。
cd C:\first_py
colcon build --merge-install --packages-select service_py
call install/setup.bat
実行は、「call install/setup.bat」の箇所だけ変えて、「Ubuntu」と同じことをやれば、同じ結果が得られるはずです。