ROS(ROS2) - プログラム終了


クラウディア 


1. 概要
2. 初期状態
3. 終了させる

1. 概要

 「ROS2」の「Tutorials」のページのまま、サービスのパッケージを作成すると、サーバ側を終わらせる方法がわからない。  どうやって終わらせるかを、「python」のソースで、自分なりにやってみた結果です。  本ページは、下記のサイトを参考にさせていただきました。
Writing a simple service and client (Python) 

2. 初期状態

 初期状態の、サーバ側プログラム(処理の本質的なところは省略しています、以下同文)。

from my_interface.srv import MyInstruction

import rclpy # type: ignore
from rclpy.node import Node # type: ignore

class MinimalService(Node):

  def __init__(self):
    super().__init__('minimal_service')
    self.srv = self.create_service(MyInstruction, 'MyInstruction', self.my_callback)

  def my_callback(self, request, response):

    self.get_logger().info('coming code[0x%02X]' % (request.code))

	・・・  処理  ・・・

    return response

def main(args=None):
  rclpy.init(args=args)

  minimal_service = MinimalService()
  rclpy.spin(minimal_service)

  rclpy.shutdown()

if __name__ == '__main__':
  main()
 クライアント側プログラム。

from my_interface.srv import MyInstruction
import rclpy                # type: ignore
from rclpy.node import Node # type: ignore

class MinimalClientAsync(Node):

  def __init__(self):
    super().__init__('minimal_client_async')
    self.cli = self.create_client(MyInstruction, 'MyInstruction')

    while not self.cli.wait_for_service(timeout_sec=1.0):
      self.get_logger().info('service not available, waiting again...')

    self.req = MyInstruction.Request()

  def send_request(self, code):

    self.get_logger().info('send [0x%02X]' % (code))
    self.req.code = code
    self.future = self.cli.call_async(self.req)
    rclpy.spin_until_future_complete(self, self.future)
    return self.future.result()

def main(args=None):
  # import pdb; pdb.set_trace()

  rclpy.init(args=args)
  client = MinimalClientAsync()

  while True:

    print("0:exit")
    print("Please input: ", end='')
    str = input()

    if str == '0':
      break

    response = client.send_request(int(str))

  client.destroy_node()
  rclpy.shutdown()

if __name__ == '__main__':
  main()
 実際には、0 以外の入力があれば、何らかの処理を行っているわけで・・・。  クライアント側は、0 を入力すれば、終了できますが、サーバ側は、Ctrl+C で止めないと終わらないことになっております。

3. 終了させる

 サーバ側。

from my_interface.srv import MyInstruction

import rclpy # type: ignore
from rclpy.node import Node # type: ignore

class MinimalService(Node):

  def __init__(self):
    super().__init__('minimal_service')
    self.serial = serial
    self.srv = self.create_service(MyInstruction, 'MyInstruction', self.my_callback)

  def my_callback(self, request, response):

    self.get_logger().info('coming code[0x%02X]' % (request.code))

    if request.code == 0:
      exit()

	・・・  処理  ・・・

    return response


def main(args=None):
  rclpy.init(args=args)

  minimal_service = MinimalService(serial)
  rclpy.spin(minimal_service)

  rclpy.shutdown()

if __name__ == '__main__':
  main()
 17、18行で、0 がクライアント側からはいってきたら、終了するようにしています。  クライアント側。

from my_interface.srv import MyInstruction
import rclpy                # type: ignore
from rclpy.node import Node # type: ignore

class MinimalClientAsync(Node):

  def __init__(self):
    super().__init__('minimal_client_async')
    self.cli = self.create_client(MyInstruction, 'MyInstruction')

    while not self.cli.wait_for_service(timeout_sec=1.0):
      self.get_logger().info('service not available, waiting again...')

    self.req = MyInstruction.Request()

  def send_request(self, code):

    self.get_logger().info('send [0x%02X]' % (code))
    self.req.code = code
    self.future = self.cli.call_async(self.req)

    if code == 0:
      rclpy.spin_until_future_complete(self, self.future, None, 0)
      return

    rclpy.spin_until_future_complete(self, self.future)
    return self.future.result()

def main(args=None):
  # import pdb; pdb.set_trace()

  rclpy.init(args=args)
  client = MinimalClientAsync()

  while True:

    print("0:exit")
    print("Please input: ", end='')
    str = input()

    response = client.send_request(int(str))

    if str == '0':
      break

  client.destroy_node()
  rclpy.shutdown()

if __name__ == '__main__':
  main()
 22~24行を加えています。  '0' が入力されたら、サーバにリクエストを送ったうえで、タイムアウト付きの待ち処理を行います。  待ち処理がないと、送った後に止まります。  待ち処理は、当然タイムアウトしますので、終了することができます。

AbemaTV 無料体験
【usus ウズウズ】