Ruby から ROS 2 を利用する

Ruby のプログラムから ROS 2 のトピックを読み書きする手順を説明する。ROS 2 のディストリビューションは Lyrical Luth を使う。

ROS 2 のクライアントライブラリは、C++ 用の rclcpp と Python 用の rclpy である。Ruby 用のものは無い。Ruby から使う場合は、rosbridge_suite の WebSocket サーバに接続し、JSON 形式のメッセージをやり取りする。

関連する外部ページ】は https://github.com/RobotWebTools/rosbridge_suite

前準備

rosbridge_suite のインストールと起動

  1. rosbridge_suite のインストール

    端末で、次のコマンドを実行する。

    # パッケージリストの情報を更新
    sudo apt update
    sudo apt -y install ros-lyrical-rosbridge-suite
    
  2. WebSocket サーバの起動

    ポート番号の初期値は 9090 である。端末で、次のコマンドを実行する。

    source /opt/ros/lyrical/setup.bash
    ros2 launch rosbridge_server rosbridge_websocket_launch.xml
    
  3. 起動の確認

    別の端末で、次のコマンドを実行し、/rosbridge_websocket が表示されることを確認する。

    source /opt/ros/lyrical/setup.bash
    ros2 node list
    

Ruby 用の WebSocket クライアントのインストール

端末で、次のコマンドを実行する。

sudo gem install websocket-client-simple

Ruby からトピックを配信する

  1. プログラムの作成

    次の内容のファイルを pub.rb という名前で保存する。advertise でトピックを宣言し、publish でメッセージを送る。

    require 'websocket-client-simple'
    require 'json'
    
    ws = WebSocket::Client::Simple.connect 'ws://localhost:9090'
    
    ws.on :open do
      ws.send({ 'op' => 'advertise', 'topic' => '/chatter',
                'type' => 'std_msgs/msg/String' }.to_json)
    end
    
    sleep 1
    10.times do |i|
      ws.send({ 'op' => 'publish', 'topic' => '/chatter',
                'msg' => { 'data' => "hello #{i}" } }.to_json)
      sleep 1
    end
    
  2. 実行

    端末で、次のコマンドを実行する。

    ruby pub.rb
    
  3. 受信の確認

    data: hello 0 のように表示される。別の端末で、次のコマンドを実行する。

    source /opt/ros/lyrical/setup.bash
    ros2 topic echo /chatter
    

Ruby からトピックを購読する

  1. プログラムの作成

    次の内容のファイルを sub.rb という名前で保存する。subscribe でトピックの購読を要求する。

    require 'websocket-client-simple'
    require 'json'
    
    ws = WebSocket::Client::Simple.connect 'ws://localhost:9090'
    
    ws.on :open do
      ws.send({ 'op' => 'subscribe', 'topic' => '/chatter',
                'type' => 'std_msgs/msg/String' }.to_json)
    end
    
    ws.on :message do |msg|
      data = JSON.parse(msg.data)
      puts data['msg']['data'] if data['op'] == 'publish'
    end
    
    loop { sleep 1 }
    
  2. 実行

    端末で、次のコマンドを実行する。

    ruby sub.rb
    
  3. 送信して動作を確認

    sub.rb を実行した端末に test と表示される。別の端末で、次のコマンドを実行する。

    source /opt/ros/lyrical/setup.bash
    ros2 topic pub -1 /chatter std_msgs/msg/String "{data: 'test'}"