タグアーカイブ software

著者:yamamoto.yosuke

SwitchBot を ROS から利用する – コマンド操作編1

本記事では SwitchBot を ROS から利用できるソフトウェア switchbot_ros の使い方を紹介します.


SwitchBot は多くの IoT スマートホームデバイス製品を提供しているブランドで,既にそれらを日常生活の中で活用されている方も多いのではないでしょうか.

SwitchBot からはソフトウェアインターフェースとして WebAPI が提供されていて,2024年2月はじめの時点での最新バージョンが v1.1 となっています.

SwitchBot の WebAPI を ROS から利用する switchbot_ros は下記のリポジトリで公開されていて SwitchBot API v1.1 にも対応しています.

SwitchBot の機器を ROS のシステムに組み込むことによりロボットとスマートホームデバイスを組み合わせた動作システムを簡単に実現することが可能となります.


今回は switchbot_ros を含む jsk_3rdparty リポジトリを Ubuntu PC 内の ROS ワークスペースにクローン・ビルドして ROS から SwitchBot デバイスを動作させます.

switchbot_ros のビルド

本記事では次の環境で switchbot_ros を利用しています.

  • Ubuntu 20.04
  • ROS Noetic

Ubuntu や ROS のインストールが済んだ状態で次のように switchbot_ros を利用するためのワークスペースを作成して jsk_3rdparty リポジトリをクローンしてビルドします.

$ source /opt/ros/noetic/setup.bash
$ mkdir -p ~/switchbot_ws/src
$ cd ~/switchbot_ws
$ catkin build 
$ source ~/switchbot_ws/devel/setup.bash
$ cd ~/switchbot_ws/src
$ git clone https://github.com/jsk-ros-pkg/jsk_3rdparty.git
$ cd ~/switchbot_ws
$ rosdep install -y -r --from-paths src --ignore-src
$ catkin build
$ source ~/switchbot_ws/devel/setup.bash

SwitchBot API のトークンとシークレットの取得

switchbot_ros は SwitchBot API を利用していますので SwitchBot API にアクセスするための SwitchBot アカウント各々に固有の「トークン(token)」と「シークレット(secret)」の2つの情報が必要になります.

SwitchBot Magazine – 【API】新バージョンAPI v1.1を公開しました にトークンとシークレットの取得方法などが書かれています.この記事から引用・まとめをするとトークンとシークレットの取得方法はつぎのようになっています.

  1. App Store または Google Play Store より SwitchBot アプリをダウンロード
  2. SwitchBot アカウントを作成またはサインイン
  3. オープントークンを生成
    1. 「プロフィールページ」 → 「設定」へ移動
    2. 「アプリバージョン」を10回タップ → 「開発者向けオプション」が表示される
    3. 「開発者向けオプション」をタップ
    4. 「トークン」と「クライアントシークレット」をコピーしてテキストとして保存

switchbot_ros の実行

switchbot_ros の中にあるコマンドを発する Python コード例 control_switchbot.py を実行して ROS から SwitchBot デバイスのハブの赤外線リモコン発信で部屋の電気を点灯した後にボット(スイッチ)を動作させます.

control_switchbot.py の中身はシンプルで 12行目 で照明を点灯させて,14行目 でボット(スイッチ)を On しています.

control_switchbot.py

#!/usr/bin/env python

import rospy
from switchbot_ros.switchbot_ros_client import SwitchBotROSClient

rospy.init_node('controler_node')
client = SwitchBotROSClient()

devices = client.get_devices()
print(devices)

client.control_device('pendant-light', 'turnOff')

client.control_device('bot74a', 'turnOn')
12行目で client.control_device('pendant-light', 'turnOff')'turnOff' となっているのに点灯?と思いますが筆者のペンダントライトのリモコンを SwitchBot アプリで登録する際に電源の On/Off ボタンが1つのものとして扱われていて 'turnOn''turnOff' も On/Off の切り替えボタンとして機能してしまっているためです. ( = もう一度 client.control_device('pendant-light', 'turnOff') を実行すると消灯になる) このように特に登録するリモコンについてはどのようにマッピングができたかに挙動が依存するのでコマンドに対する各々のデバイスの挙動を確認してから利用する必要があります.

操作コマンドの SwitchBot デバイスに至るまでの大まかな流れは次のようになっています.

  • control_switchbot.py
  • → SwitchBot ROS Client
  • → SwitchBot ROS Action Server
  • → SwitchBot WebAPI
  • → SwitchBot デバイス

それでは実際に実行してみます. SwitchBot ROS アクションサーバを起動してから別ターミナルで control_switchbot.py を実行します.

ターミナル 1 : SwitchBot ROS アクションサーバの起動

下記コマンドの SwichBot ROS アクションサーバの起動実行時に launch オプションの token:=YOUR_TOKENYOUR_TOKEN を SwitchBot アプリで取得したトークンに置き換えて, secret:=YOUR_SECRETYOUR_SECRET を取得したシークレットに置き換えて書いて実行します.

switchbot.launch 実行入力

$ source ~/switchbot_ws/devel/setup.bash
$ roslaunch switchbot_ros switchbot.launch token:=YOUR_TOKEN secret:=YOUR_SECRET

switchbot.launch 実行出力例

... logging to /home/robotuser/.ros/log/87b6e5c8-c1a2-11ee-bce7-1d89a9d14e1f/roslaunch-robotuser-PC-62866.log
Checking log directory for disk usage. This may take a while.
Press Ctrl-C to interrupt
Done checking log file disk usage. Usage is <1GB.

started roslaunch server http://robotuser-PC:40731/

SUMMARY
========

PARAMETERS
 * /rosdistro: noetic
 * /rosversion: 1.16.0
 * /switchbot_ros/secret: (シークレットの上位数桁が表示)...
 * /switchbot_ros/token: (トークンの上位数桁が表示)...

NODES
  /
    switchbot_ros (switchbot_ros/switchbot_ros_server.py)

auto-starting new master
process[master]: started with pid [62874]
ROS_MASTER_URI=http://localhost:11311

setting /run_id to 87b6e5c8-c1a2-11ee-bce7-1d89a9d14e1f
process[rosout-1]: started with pid [62884]
started core service [/rosout]
process[switchbot_ros-2]: started with pid [62891]
[INFO] [1706861436.195243]: Switchbot API Client initialized.
[INFO] [1706861436.199678]: Using SwitchBot API v1.1
[INFO] [1706861436.204957]: Switchbot Device List:
6 Item(s)
deviceName: bot74a, deviceID: (固有のID番号が表示), deviceType: Bot
deviceName: hub2a, deviceID: (固有のID番号が表示), deviceType: Hub 2
deviceName: plugmini7a1, deviceID: (固有のID番号が表示), deviceType: Plug Mini (JP)
deviceName: remote-button10a, deviceID: (固有のID番号が表示), deviceType: Remote
deviceName: tapelight7a1, deviceID: (固有のID番号が表示), deviceType: Strip Light
deviceName: thermo-hygrometer-f7a, deviceID: (固有のID番号が表示), deviceType: Meter

[INFO] [1706861436.208853]: Switchbot Remote List:
2 Item(s)
deviceName: air-conditioner, deviceID: (固有のID番号が表示), remoteType: Air Conditioner
deviceName: pendant-light, deviceID: (固有のID番号が表示), remoteType: DIY Light

[INFO] [1706861436.214168]: Switchbot Scene List:
3 Item(s)
sceneName: turnoff-all-lights, sceneID: (固有のID番号が表示)
sceneName: turnon-all-lights, sceneID: (固有のID番号が表示)
sceneName: turnon-all-lights, sceneID: (固有のID番号が表示)

[INFO] [1706861436.254126]: Ready.

ターミナル 2 : control_switchbot.py の実行

ターミナル1 の switchbot.launch を起動したままの状態で別のターミナルで control_switchbot.py を実行します.

control_switchbot.py 実行入力

$ source ~/switchbot_ws/devel/setup.bash
$ rosrun switchbot_ros control_switchbot.py 

control_switchbot.py 実行出力例

devices: 
  - 
    name: "bot74a"
    type: "Bot"
  - 
    name: "hub2a"
    type: "None"
  - 
    name: "plugmini7a1"
    type: "Plug Mini (JP)"
  - 
    name: "remote-button10a"
    type: "Remote"
  - 
    name: "tapelight7a1"
    type: "Strip Light"
  - 
    name: "thermo-hygrometer-f7a"
    type: "Meter"
  - 
    name: "air-conditioner"
    type: "Air Conditioner"
  - 
    name: "pendant-light"
    type: "DIY Light"

control_switchbot.py 実行出力時の SwitchBot デバイス動作の様子

SwitchBot を ROS から操作する感じが伝わりましたでしょうか?

今回の記事はここまでです.


本シリーズ次回の記事では今回実行した Python コード例で扱われていたもの以外の SwitchBot デバイスを ROS から操作するために SwitchBot API を調べて control_switchbot.py にコマンドを追加する様子についてお伝えする予定です.

著者:yamamoto.yosuke

ChatGPT と ROS – ROS Topic を介した ChatGPT チャットプログラム

本シリーズ前回の記事 1. ROS Service プログラムの文脈をふまえたチャット対応 では OpenAI の Chat Completion API を利用して過去のチャット履歴もふまえたチャットを行える ROS Service プログラムを作成した様子をお伝えしました.

今回の記事では Chat Completion API を利用した「文脈をふまえたチャット」をする ROS ソフトウェアを実装してみた2つ目の方法「2. ROS Topic を介した ChatGPT チャットプログラム」を作成した様子を紹介します.

  1. ROS Service プログラムの文脈をふまえたチャット対応
    • 「1問1答」形式 →「チャット」形式
  2. ROS Topic を介した ChatGPT チャットプログラム
    • ROS Service の応答 → ROS Topic のやり取りによる ChatGPT とのチャット

ROS Topic を介した ChatGPT のチャットプログラム

前回,比較的短文のチャットを扱う Chat Completion API へのアクセスであれば ROS Service よりも ROS Topic を介したメッセージのやり取りの方が ROS ノード内でのチャット会話に限られず,より ROS に親和的でよりシンプルな構成になるのでは?という反省がありました.

今回の ROS Topic を用いたチャットプログラムの作成方針は次のようにしました.

  • Chat Completion API にアクセスする ROS Node
    • ROS Topic /request を購読してユーザの発言を得る
    • ユーザの発言をふまえて Chat Completion API にアクセスして応答を ROS Topic /response としてパブリッシュする
    • チャットの履歴データを蓄積する
  • チャットユーザ側
    • 質問を ROS Topic /request にパブリッシュする
    • 返答は ROS Topic /response を購読して得る

ROS Service プログラムの場合はチャット履歴をふまえたとしてもチャット機能提供側とユーザとの1者対1者でのやり取りでしたが,ROS Topic にすることでチャット機能提供側と複数のユーザの1者対他者でのやり取りも可能になる利点もあります.

ソースコード

ROS Topic を介した文脈をふまえたチャットプログラムで追加したファイルは次の2つです.

  • scripts / openai_chat_rostopic.py
  • launch / openai_chat.launch

サービスの定義など考慮しなくて良いので非常にシンプルです.

以下,それぞれのファイル内のコードを記載して少し説明をします.

scripts / openai_chat_rostopic.py

#!/usr/bin/env python3

import rospy
import openai

from std_msgs.msg import String


class Chatter:
    """
    Chat with ChatGPT on ROS topics
    """
    def __init__(self):
        # Get ROS parameters
        prompt = rospy.get_param('~prompt')
        self.model = rospy.get_param('~model')
        openai.api_key = rospy.get_param('~key')
        
        rospy.loginfo("For \'system\': %s" % (prompt))
        
        # Set initial message with a prompt
        self.messages = []
        self.messages.append({"role": "system", "content": str(prompt)})
        
        self.sub = rospy.Subscriber('request', String, self.callback)
        self.pub = rospy.Publisher('response', String, queue_size=10)
        
        rospy.spin()


    def callback(self, data):
        rospy.loginfo("request: %s", data.data)
        
        # Add user's input to the history
        self.messages.append({"role": "user", "content": str(data.data)})
        
        response = openai.ChatCompletion.create(
            model=self.model,
            messages=self.messages
        )
        
        content = response["choices"][0]["message"]["content"]
        role = response["choices"][0]["message"]["role"]
        token = response["usage"]["total_tokens"]
        
        # Add GPT's response to the history
        self.messages.append({"role": str(role), "content": str(content)})
        
        rospy.loginfo("%s(token:%d): %s" % (role, token, content))
        self.pub.publish(content)


if __name__ == "__main__":
    rospy.init_node('chat_rostopic', anonymous=True)
    chatter = Chatter()
    
  • L25,31: ROS Topic /request を購読(Subscribe)してトピックを受け取ったら callback() メソッドを呼び出す
  • L35: callback() メソッド内で新たなリクエストをチャット履歴に追加
  • L37-40: Chat Completion API に投げる
  • L47: Chat Completion API からの返答をチャット履歴に追加
  • ROS Topic /response としてパブリッシュ

launch / openai_chat.launch

launch オプション service を用いて前回の記事で紹介した ROS Service によるチャットプログラムと今回の ROS Topic を介したチャットプログラムのどちらを実行するかを切り替えるようにしています.

<launch>
  
  <arg name="key" default="$(env OPENAI_API_KEY)" />
  <arg name="model" default="gpt-3.5-turbo" />
  <arg name="service" default="false" />
  <arg name="prompt" default="You are a helpful assistant." />
  
  <node if="$(arg service)"
        pkg="openai_ros" type="openai_chat_server.py" name="openai_chat_service" output="screen">
    <param name="key" value="$(arg key)" />
    <param name="model" value="$(arg model)" />
  </node>
  
  <node unless="$(arg service)"
        pkg="openai_ros" type="openai_chat_rostopic.py" name="openai_chat_topic" output="screen">
    <param name="key" value="$(arg key)" />
    <param name="model" value="$(arg model)" />
    <param name="prompt" value="$(arg prompt)" />
  </node>
  
</launch>

実行例

文脈をふまえた ROS Topic を介したチャットプログラムを実行した例を以下に記載します.

ターミナル 1 : チャットノードの起動

Chat Completion API にアクセスして ROS Topic でやり取りする ROS Node を openai_chat.launch で起動しています.

robotuser@robotuser-PC:~$ source ~/openai_ws/devel/setup.bash
robotuser@robotuser-PC:~$ export OPENAI_API_KEY="sk-..."
robotuser@robotuser-PC:~$ roslaunch openai_ros openai_chat.launch 
... logging to /home/robotuser/.ros/log/609f8d12-52cd-11ee-9968-6b3ff6703622/roslaunch-robotuser-PC-5035.log
Checking log directory for disk usage. This may take a while.
Press Ctrl-C to interrupt
Done checking log file disk usage. Usage is <1GB.

started roslaunch server http://robotuser-PC:40257/

SUMMARY
========

PARAMETERS
 * /openai_chat/key: sk-3JDluBbxsNuIhi...
 * /openai_chat/model: gpt-3.5-turbo
 * /openai_chat/prompt: You are a helpful...
 * /rosdistro: noetic
 * /rosversion: 1.16.0

NODES
  /
    openai_chat (openai_ros/openai_chat_rostopic.py)

auto-starting new master
process[master]: started with pid [5043]
ROS_MASTER_URI=http://localhost:11311

setting /run_id to 609f8d12-52cd-11ee-9968-6b3ff6703622
process[rosout-1]: started with pid [5053]
started core service [/rosout]
process[openai_chat-2]: started with pid [5060]
[INFO] [1694675254.662674]: For 'system': You are a helpful assistant.
[INFO] [1694675266.017788]: request: Hello
[INFO] [1694675267.401076]: assistant(token:27): Hello! How can I assist you today?
[INFO] [1694675292.897892]: request: インターネットはどこにありますか?
[INFO] [1694675300.168180]: assistant(token:183): インターネットは物理的な場所にあるのではなく,世界中のコンピューターがネットワークで結ばれている仮想的な空間です.インターネットは,データを送信し受け取るためのプロトコルとパケット交換技術を使用しています.つまり,インターネットは世界中のコンピューターネットワークの集合体です.
[INFO] [1694675347.975610]: request: 世界中とは地球のことですか?
[INFO] [1694675354.647098]: assistant(token:324): はい,正確に言えば,インターネットは地球上のコンピューターネットワークの集合体です.このネットワークには,地球上の様々な場所に設置されたサーバーやルーターなどの機器が含まれます.インターネットのデータ通信は,これらの機器を介して行われます.
[INFO] [1694675387.510775]: request: あなたは誰ですか?
[INFO] [1694675391.409440]: assistant(token:407): 私はAI(人工知能)ベースのヘルプフルなアシスタントです.質問や問題解決,情報の提供など,お手伝いできることがありましたらお知らせください.
[INFO] [1694675436.047036]: request: どのようにヘルプフルですか?
[INFO] [1694675447.019485]: assistant(token:645): 私は多くの情報と知識を持つAIですので,様々な質問や問題に対してお答えすることができます.例えば,旅行の予約や天気予報の確認,翻訳や研究のサポート,一般的な知識の提供など,さまざまな分野でお手伝いすることができます.また,自然言語処理の技術を利用して,あなたの質問や要求を理解し,最適な回答やソリューションを提供することも可能です.お困りのことや疑問があれば,いつでもお気軽にお知らせください.
[INFO] [1694675485.687087]: request: 東京の明日の天気もわかりますか?
[INFO] [1694675507.944942]: assistant(token:1064): もちろんです!東京の天気予報を調べてみましょう.

私はリアルタイムのデータにアクセスできるわけではありませんが,一般的に天気予報を提供する公式のウェブサイトやアプリを利用して,詳細な天気予報を確認することができます.天気予報は頻繁に更新されるため,事前に確認することをおすすめします.以下は一般的な天気予報サービスの利用方法です.

- インターネット検索エンジンで「東京の天気予報」と検索すると,現在の天気情報と明日の天気予報を含む結果が表示されます.
- スマートフォンやタブレットを使用している場合は,天気予報を提供するアプリをダウンロードしてインストールすることもできます.定番のアプリには「Weather」や「Weather Underground」などがあります.

これらの方法を使用して,明日の東京の天気を確認してみてください.天気予報に関する詳細な情報を入手するためには,地元の気象庁や天気予報サービスの公式ウェブサイトを参照することもおすすめです.
^C[openai_chat-2] killing on exit
[rosout-1] killing on exit
[master] killing on exit
shutting down processing monitor...
... shutting down processing monitor complete
done
robotuser@robotuser-PC:~$ 

ターミナル 2 : ROS Topic に発言をパブリッシュ

1つ目のターミナルで openai_chat.launch を起動したままの状態で2つ目のターミナルから ROS Topic をパブリッシュします.

robotuser@robotuser-PC:~$ rostopic pub -1 /request std_msgs/String "Hello"
publishing and latching message for 3.0 seconds
robotuser@robotuser-PC:~$ rostopic pub -1 /request std_msgs/String "インターネットはどこにありますか ?"
publishing and latching message for 3.0 seconds
robotuser@robotuser-PC:~$ rostopic pub -1 /request std_msgs/String "世界中とは地球のことですか?"
publishing and latching message for 3.0 seconds
robotuser@robotuser-PC:~$ rostopic pub -1 /request std_msgs/String "あなたは誰ですか?"
publishing and latching message for 3.0 seconds
robotuser@robotuser-PC:~$ rostopic pub -1 /request std_msgs/String "どのようにヘルプフルですか?"
publishing and latching message for 3.0 seconds
robotuser@robotuser-PC:~$ rostopic pub -1 /request std_msgs/String "東京の明日の天気もわかりますか?"
publishing and latching message for 3.0 seconds
robotuser@robotuser-PC:~$ 

ターミナル 3 : チャットノードからの応答の ROS Topic を確認

3つ目のターミナルで ROS Topic /response に Chat Completion API からの応答がパブリッシュされているかを確認します.コンソール出力では文字コード化して可読性がないですが Python で print()rospy.loginfo() で出力すると ターミナル 1 のような読める日本語で表示されます.

robotuser@robotuser-PC:~$ rostopic echo /response 
data: "\u79C1\u306FAI\uFF08\u4EBA\u5DE5\u77E5\u80FD\uFF09\u30D9\u30FC\u30B9\u306E\u30D8\u30EB\
  \u30D7\u30D5\u30EB\u306A\u30A2\u30B7\u30B9\u30BF\u30F3\u30C8\u3067\u3059\u3002\u8CEA\
  \u554F\u3084\u554F\u984C\u89E3\u6C7A\u3001\u60C5\u5831\u306E\u63D0\u4F9B\u306A\u3069\
  \u3001\u304A\u624B\u4F1D\u3044\u3067\u304D\u308B\u3053\u3068\u304C\u3042\u308A\u307E\
  \u3057\u305F\u3089\u304A\u77E5\u3089\u305B\u304F\u3060\u3055\u3044\u3002"
---
data: "\u79C1\u306F\u591A\u304F\u306E\u60C5\u5831\u3068\u77E5\u8B58\u3092\u6301\u3064AI\u3067\
  \u3059\u306E\u3067\u3001\u69D8\u3005\u306A\u8CEA\u554F\u3084\u554F\u984C\u306B\u5BFE\
  \u3057\u3066\u304A\u7B54\u3048\u3059\u308B\u3053\u3068\u304C\u3067\u304D\u307E\u3059\
  \u3002\u4F8B\u3048\u3070\u3001\u65C5\u884C\u306E\u4E88\u7D04\u3084\u5929\u6C17\u4E88\
  \u5831\u306E\u78BA\u8A8D\u3001\u7FFB\u8A33\u3084\u7814\u7A76\u306E\u30B5\u30DD\u30FC\
  \u30C8\u3001\u4E00\u822C\u7684\u306A\u77E5\u8B58\u306E\u63D0\u4F9B\u306A\u3069\u3001\
  \u3055\u307E\u3056\u307E\u306A\u5206\u91CE\u3067\u304A\u624B\u4F1D\u3044\u3059\u308B\
  \u3053\u3068\u304C\u3067\u304D\u307E\u3059\u3002\u307E\u305F\u3001\u81EA\u7136\u8A00\
  \u8A9E\u51E6\u7406\u306E\u6280\u8853\u3092\u5229\u7528\u3057\u3066\u3001\u3042\u306A\
  \u305F\u306E\u8CEA\u554F\u3084\u8981\u6C42\u3092\u7406\u89E3\u3057\u3001\u6700\u9069\
  \u306A\u56DE\u7B54\u3084\u30BD\u30EA\u30E5\u30FC\u30B7\u30E7\u30F3\u3092\u63D0\u4F9B\
  \u3059\u308B\u3053\u3068\u3082\u53EF\u80FD\u3067\u3059\u3002\u304A\u56F0\u308A\u306E\
  \u3053\u3068\u3084\u7591\u554F\u304C\u3042\u308C\u3070\u3001\u3044\u3064\u3067\u3082\
  \u304A\u6C17\u8EFD\u306B\u304A\u77E5\u3089\u305B\u304F\u3060\u3055\u3044\u3002"
---
data: "\u3082\u3061\u308D\u3093\u3067\u3059\uFF01\u6771\u4EAC\u306E\u5929\u6C17\u4E88\u5831\
  \u3092\u8ABF\u3079\u3066\u307F\u307E\u3057\u3087\u3046\u3002\n\n\u79C1\u306F\u30EA\
  \u30A2\u30EB\u30BF\u30A4\u30E0\u306E\u30C7\u30FC\u30BF\u306B\u30A2\u30AF\u30BB\u30B9\
  \u3067\u304D\u308B\u308F\u3051\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u304C\u3001\
  \u4E00\u822C\u7684\u306B\u5929\u6C17\u4E88\u5831\u3092\u63D0\u4F9B\u3059\u308B\u516C\
  \u5F0F\u306E\u30A6\u30A7\u30D6\u30B5\u30A4\u30C8\u3084\u30A2\u30D7\u30EA\u3092\u5229\
  \u7528\u3057\u3066\u3001\u8A73\u7D30\u306A\u5929\u6C17\u4E88\u5831\u3092\u78BA\u8A8D\
  \u3059\u308B\u3053\u3068\u304C\u3067\u304D\u307E\u3059\u3002\u5929\u6C17\u4E88\u5831\
  \u306F\u983B\u7E41\u306B\u66F4\u65B0\u3055\u308C\u308B\u305F\u3081\u3001\u4E8B\u524D\
  \u306B\u78BA\u8A8D\u3059\u308B\u3053\u3068\u3092\u304A\u3059\u3059\u3081\u3057\u307E\
  \u3059\u3002\u4EE5\u4E0B\u306F\u4E00\u822C\u7684\u306A\u5929\u6C17\u4E88\u5831\u30B5\
  \u30FC\u30D3\u30B9\u306E\u5229\u7528\u65B9\u6CD5\u3067\u3059\u3002\n\n- \u30A4\u30F3\
  \u30BF\u30FC\u30CD\u30C3\u30C8\u691C\u7D22\u30A8\u30F3\u30B8\u30F3\u3067\u300C\u6771\
  \u4EAC\u306E\u5929\u6C17\u4E88\u5831\u300D\u3068\u691C\u7D22\u3059\u308B\u3068\u3001\
  \u73FE\u5728\u306E\u5929\u6C17\u60C5\u5831\u3068\u660E\u65E5\u306E\u5929\u6C17\u4E88\
  \u5831\u3092\u542B\u3080\u7D50\u679C\u304C\u8868\u793A\u3055\u308C\u307E\u3059\u3002\
  \n- \u30B9\u30DE\u30FC\u30C8\u30D5\u30A9\u30F3\u3084\u30BF\u30D6\u30EC\u30C3\u30C8\
  \u3092\u4F7F\u7528\u3057\u3066\u3044\u308B\u5834\u5408\u306F\u3001\u5929\u6C17\u4E88\
  \u5831\u3092\u63D0\u4F9B\u3059\u308B\u30A2\u30D7\u30EA\u3092\u30C0\u30A6\u30F3\u30ED\
  \u30FC\u30C9\u3057\u3066\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u3059\u308B\u3053\u3068\
  \u3082\u3067\u304D\u307E\u3059\u3002\u5B9A\u756A\u306E\u30A2\u30D7\u30EA\u306B\u306F\
  \u300CWeather\u300D\u3084\u300CWeather Underground\u300D\u306A\u3069\u304C\u3042\
  \u308A\u307E\u3059\u3002\n\n\u3053\u308C\u3089\u306E\u65B9\u6CD5\u3092\u4F7F\u7528\
  \u3057\u3066\u3001\u660E\u65E5\u306E\u6771\u4EAC\u306E\u5929\u6C17\u3092\u78BA\u8A8D\
  \u3057\u3066\u307F\u3066\u304F\u3060\u3055\u3044\u3002\u5929\u6C17\u4E88\u5831\u306B\
  \u95A2\u3059\u308B\u8A73\u7D30\u306A\u60C5\u5831\u3092\u5165\u624B\u3059\u308B\u305F\
  \u3081\u306B\u306F\u3001\u5730\u5143\u306E\u6C17\u8C61\u5E81\u3084\u5929\u6C17\u4E88\
  \u5831\u30B5\u30FC\u30D3\u30B9\u306E\u516C\u5F0F\u30A6\u30A7\u30D6\u30B5\u30A4\u30C8\
  \u3092\u53C2\u7167\u3059\u308B\u3053\u3068\u3082\u304A\u3059\u3059\u3081\u3067\u3059\
  \u3002"
---

ChatGPT に対して問い合わせる側が人間であれば応答から自分で文脈をふまえて次の会話をすると思いますが,クライアントプログラムの場合は文脈をふまえた会話をしたければクライアント側のソフトウェアも ROS Topic を拾って自分で文脈を記録して解釈する必要があります.

ChatGPT vs ChatGPT

Chat Completion API との応答を ROS Topic を介してやり取りしているので,複数の Chat ノード(openai_chat_rostopic.py)を実行してトピックの remap をして互いのノードの応答を自らのノードの入力にすれば ChatGPT 同士で会話を続けるようにすることも簡単にできます.

そのために openai_chat.launch を次のように変更しました.

<launch>
  
  <arg name="key" default="$(env OPENAI_API_KEY)" />
  <arg name="model" default="gpt-3.5-turbo" />
  <arg name="service" default="false" />
  <arg name="opponent" default="false" />
  <arg name="prompt" default="You are a helpful assistant." />
  
  <node if="$(arg service)"
        pkg="openai_ros" type="openai_chat_server.py" name="openai_chat_service" output="screen">
    <param name="key" value="$(arg key)" />
    <param name="model" value="$(arg model)" />
  </node>
  
  <group unless="$(arg service)">
    <node pkg="openai_ros" type="openai_chat_rostopic.py" name="openai_chat_topic" output="screen">
      <param name="key" value="$(arg key)" />
      <param name="model" value="$(arg model)" />
      <param name="prompt" value="$(arg prompt)" />
    </node>
   
    <group ns="opponent" if="$(arg opponent)">
      <node pkg="openai_ros" type="openai_chat_rostopic.py" name="openai_chat_topic">
        <param name="key" value="$(arg key)" />
        <param name="model" value="$(arg model)" />
        <param name="prompt" value="You are a good talker." />
        <remap from="/opponent/request" to="/response" />
        <remap from="/opponent/response" to="/request" />
      </node>
    </group>  
  </group>
  
</launch>
  • L6: launch オプシション opponent で ChatGPT 同士の会話にするかを指定
  • L22: 2つ目のチャットノードは別のネームスペースとして区別
  • L23: 2つ目のチャットノードのコンソール出力も表示すると内容が重複するので output="screen" はなし
  • L26: prompt の設定でアシスタント同士だと会話が不自然な感じがしたので(とりあえず)2つ目のプロンプトは “You are a good talker.” としてみた
  • L27-28: remap/request/response を入れ替え

ターミナル 1 : 2つのチャットノードの起動

openai_chat.launch の起動オプション opponent:=true で2つのチャットノード実行とトピックの remap を行います.

起動した状態では応答は何もないですが ターミナル 2 から ROS トピック /request に最初のリクエストを1つパブリッシュすることで以後 ChatGPT 同士の会話が始まります.

robotuser@robotuser-PC:~$ roslaunch openai_ros openai_chat.launch opponent:=true
... logging to /home/robotuser/.ros/log/9cc9a1be-5dc8-11ee-9968-6b3ff6703622/roslaunch-robotuser-PC-35705.log
Checking log directory for disk usage. This may take a while.
Press Ctrl-C to interrupt
Done checking log file disk usage. Usage is <1GB.

started roslaunch server http://robotuser-PC:42615/

SUMMARY
========

PARAMETERS
 * /openai_chat_topic/key: sk-3JDluBbxsNuIhi...
 * /openai_chat_topic/model: gpt-3.5-turbo
 * /openai_chat_topic/prompt: You are a helpful...
 * /opponent/openai_chat_topic/key: sk-3JDluBbxsNuIhi...
 * /opponent/openai_chat_topic/model: gpt-3.5-turbo
 * /opponent/openai_chat_topic/prompt: You are a good ta...
 * /rosdistro: noetic
 * /rosversion: 1.16.0

NODES
  /
    openai_chat_topic (openai_ros/openai_chat_rostopic.py)
  /opponent/
    openai_chat_topic (openai_ros/openai_chat_rostopic.py)

auto-starting new master
process[master]: started with pid [35714]
ROS_MASTER_URI=http://localhost:11311

setting /run_id to 9cc9a1be-5dc8-11ee-9968-6b3ff6703622
process[rosout-1]: started with pid [35724]
started core service [/rosout]
process[openai_chat_topic-2]: started with pid [35731]
process[opponent/openai_chat_topic-3]: started with pid [35732]
[INFO] [1695882670.941923]: For 'system': You are a helpful assistant.
[INFO] [1695882677.451265]: request: サッカーの盛んな国を1つ挙げてください.
[INFO] [1695882679.335665]: assistant(token:60): ブラジルはサッカーの盛んな国として知られています.
[INFO] [1695882705.653403]: request: そうですね,ブラジルは世界でも有名なサッカーの強豪国として知られています.ブラジルではサッカーは国民的なスポーツであり,多くの人々が熱狂的に応援しています.

ブラジル代表チームは過去に5回のワールドカップ優勝を果たし,サッカーの歴史においても最も成功した国の一つです.有名な選手も多く輩出しており,ペレやジーコ,ロナウド,ロナウジーニョ,ネイマールなど,数々の伝説的なプレーヤーがブラジルから生まれています.

ブラジルではサッカーの試合が行われると,町中が一体となって応援に熱が入ります.カラフルな応援旗やドラム,歌声,そして華麗なサンバの踊りなど,独特のエネルギーと情熱が試合会場を包みます.

また,ブラジルには多くの有名なサッカークラブがあります.サンパウロのサンパウロFC,リオデジャネイロのフラメンゴ,サントス,リオグランデ・ド・スールのグレミオ,コリンチャンスなど,これらのクラブは強豪として名高いだけでなく,ファンの熱心さも有名です.

ブラジルのサッカーは単なるスポーツ以上のものであり,国民の誇りやアイデンティティの一部となっています.サッカーを通じて,ブラジルの文化や人々の情熱を感じることができるでしょう.
[INFO] [1695882713.741564]: assistant(token:754): その通りです.ブラジルのサッカーは国民の誇りであり,文化の一部として重要な役割を果たしています.多くの人々がサッカーに情熱を注ぎ,試合を熱狂的に応援する様子は見る価値があります.ブラジルのサッカーは世界中で愛され,その魅力は他の国にも広まっています.それだけに,ブラジルはサッカーの盛んな国として有名です.
[INFO] [1695882744.670979]: request: そうですね,ブラジルのサッカーの魅力は世界中に広まっており,多くの人々がその情熱に共感しています.ブラジル代表チームやクラブチームの試合は,テレビやインターネットを通じて世界中に配信されており,多くのサッカーファンがその魅力に触れることができます.

さらに,ブラジルのサッカー文化は技術,創造性,スピード,そしてリズム感を特徴としています.ブラジルのサッカー選手は驚くほど優れたテクニックを持ち,美しいプレーを見せることで知られています.彼らのキレのあるドリブル,正確なパス,そして豪快なシュートは,多くの人々に感動を与えます.

ブラジルのサッカーの成功は,その国の熱狂的なサッカーカルチャーとも関連しています.子供たちは幼い頃からサッカーボールを蹴り,街角やビーチでプレーする様子をよく見かけます.サッカースクールやアカデミーも充実しており,若い才能は早いうちから育成されています.

ブラジルのサッカーは単なるスポーツの一環ではなく,国民の誇りやアイデンティティの一部です.多くの人々が試合を通じて喜びや感動を共有し,サッカーを通じて結びついています.ブラジルのサッカー文化は他の国々にも影響を与え,彼らのスタイルやプレースタイルが憧れとなっています.

ブラジルのサッカーは確かに盛んな国であり,その魅力は世界中に広がっています.それはブラジルの人々の情熱と才能,そしてサッカー文化の豊かさによるものです.
[INFO] [1695882752.038028]: assistant(token:1519): 完全に同意します.ブラジルのサッカーカルチャーは,国民の情熱と才能,そして豊かなサッカー文化によって支えられています.その魅力は世界中に広まり,多くの人々がブラジルのサッカーに感動を覚えています.ブラジルのサッカーは間違いなく世界的な影響力を持っており,多くの国々で愛される存在です.
[INFO] [1695882760.235372]: request: ありがとうございます.ブラジルのサッカーは確かに世界的な影響力を持っており,多くの人々に愛されています.その独特のスタイルと情熱は,他の国々のサッカーカルチャーにも大きな影響を与えています.ブラジルのサッカーは常に進化し,新たな才能が次々に生まれることで,さらなる魅力と成功を築いていくでしょう.
^C[opponent/openai_chat_topic-3] killing on exit
[openai_chat_topic-2] killing on exit
[rosout-1] killing on exit
[master] killing on exit
shutting down processing monitor...
... shutting down processing monitor complete
done
robotuser@robotuser-PC:~$ 

ターミナル 2 : 最初の話題投下

robotuser@robotuser-PC:~$ rostopic pub -1 /request std_msgs/String "サッカーの盛んな国を1つ挙げてください."
publishing and latching message for 3.0 seconds
robotuser@robotuser-PC:~$ 

ROS ノードグラフ

rqt の ROS Node Graph でノードとトピックの様子を確認してみると,2つのノード /openai_chat_topic/opponent/openai_chat_topic とが互いの応答トピックを参照して循環していることが見て取れます.

ターミナル 1 の出力にも現れていますが段々と応答の文字数が互いに多くなる傾向があります.ChatGPT の token 数の上限に達して終わったりしますが,そうでない限りはずっと ChatGPT 同士で応答を続けるので終わらせたい場合は Ctrl-C で終わらせます.


文脈のデータを蓄積して多くなると Chat Completion API の token を消費してしまいますし,応答に時間がかかったりもします.一定時間会話がなかった場合やそれまでの文脈からがらりと話題を変える場合のために文脈を含めたメッセージデータを初期化するメソッドも運用上は必要かもしれません.

また,OpenAI 以外の大規模言語モデル(LLM)の API の ROS Topic ラッパがあれば(or を作れば)異なる LLM 間での会話も可能であろうと思います.


今回の記事はここまでです.

著者:yamamoto.yosuke

ChatGPT と ROS – 文書生成 ROS ラッパー生成編(Chat Completion API)

本シリーズ前回の記事 ChatGPT と ROS – 文書生成 ROS ラッパー利用編(Completion API) では OpenAI API の ROS ラッパーの中で Completion API を利用している ROS1 の Python ラッパ https://github.com/davesarmoury/openai_ros を使ってみました.

今回は OpenAI の Chat Completion API を利用した ROS ラッパ Python プログラムを Web サービスの方の ChatGPT の助けをかりながら作成した様子を紹介します.

OpenAI の文書生成 API 概要

本シリーズ第1回の記事 ChatGPT と ROS – 調査編 でもふれましたが OpenAI の文書生成 API について簡単にまとめますと,「1問1答形式」の Completion API と,「対話した文脈を含むチャット対話形式」の Chat Completion API の2つがあります.

  • OpenAI の文書生成 API
    • Completion API : 1問1答形式
    • Chat Completion API : 文脈を含むチャット対話形式

前回の記事ではこの2つのうち「1問1答」形式の Completion API を利用ました.今回の記事ではもう一方の「チャット対話」形式のインタフェースである Chat Completion API を ROS から利用してみます.

開発・実行環境

今回は Web サービスの ChatGPT に Chat Completion API を使ったプログラムを生成してもらいながら進めましたのでそれも含めて開発・実行環境の構成は次のようになっています.

  • Ubuntu 20.04
  • ROS Noetic
  • OpenAI ChatGPT のアカウントを持っている(今回筆者は ChatGPT-4 を利用)
  • OpenAI API の利用が有効なアカウントを持っている
    • API Key を取得済

ChatGPT でのプログラム生成

まずは ChatGPT の Web サービスに ChatGPT の Python API にアクセスするための Python プログラムを書いてもらいました.

User

ChatGPT の Python API を用いたアクセスプログラムを書いてください.


ChatGPT

まず,OpenAIのPythonクライアントライブラリをインストールする必要があります.次のコマンドでインストールできます.

pip install openai

そして,以下はOpenAIのGPTを使用するための基本的なPythonコードです.この例では,プロンプトとして”Translate the following English text to French: ‘{}'”を使用し,その'{}’の部分に翻訳したい英文を挿入しています.

import openai

openai.api_key = 'your-api-key'

response = openai.ChatCompletion.create(
  model="gpt-4.0-turbo",
  messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Translate the following English text to French: '{}'"}
    ]
)

print(response['choices'][0]['message']['content'])

上記のコードは,APIキーを設定し,特定のモデル(この場合は”gpt-4.0-turbo”)を指定して,ChatCompletion APIを呼び出す基本的な構造を示しています.messagesパラメータは会話の履歴を表し,最初のメッセージは通常,モデルに役割(この場合は”helpful assistant”)を設定するためのシステムメッセージです.ユーザーメッセージはその後に続きます.

注意: ‘your-api-key’の部分は,OpenAIから提供される実際のAPIキーに置き換える必要があります.また,APIの使用は料金が発生しますので,公式ドキュメンテーションを確認して使用制限とコストを理解することが重要です.

なお,GPT-4のリリース後もAPIの基本的な使い方はこれまでと同様ですが,詳細な情報や更新内容についてはOpenAIの公式ドキュメンテーションをご覧ください.

次にこの ChatGPT にアクセスする Python コードを ROS の Service に対応させたプログラムを作成してもらいました.

User

この Python プログラムから ROS の service プログラムラッパーを作成してください.


ChatGPT

ROS (Robot Operating System)は,ロボットのためのフレームワークで,様々なハードウェアやソフトウェアの要素を組み合わせて使うことができます.ここでは,PythonのOpenAI GPT-4クライアントをROSサービスとしてラップする基本的な例を示します.

まず,適切なメッセージタイプを使用するためのsrvファイルを作成します.この例では,リクエストとレスポンスが共に一つの文字列を持つシンプルなサービスを定義します.

# GptService.srv
string input
---
string output

次に,このサービスを実装するPythonのROSノードを作成します.このノードは,指定された文字列を翻訳するサービスを提供します.

#!/usr/bin/env python
import rospy
from openai_ros.srv import GptService, GptServiceResponse
import openai

def handle_gpt_request(req):
    openai.api_key = 'your-api-key'
    
    response = openai.ChatCompletion.create(
        model="gpt-4.0-turbo",
        messages=[
            {"role": "system", "content": "You are a helpful assistant."},
            {"role": "user", "content": "Translate the following English text to French: '{}'".format(req.input)}
        ]
    )

    return GptServiceResponse(response['choices'][0]['message']['content'])

def gpt_service():
    rospy.init_node('gpt_service')
    s = rospy.Service('gpt_service', GptService, handle_gpt_request)
    print("Ready to translate English text to French.")
    rospy.spin()

if __name__ == "__main__":
    gpt_service()

このPythonスクリプトは,ROSノードgpt_serviceを作成し,それがGptServiceサービスを提供するようにします.サービスリクエストが来ると,handle_gpt_request関数が呼び出され,その中でOpenAIのGPT-4クライアントが使われてリクエストされたテキストを翻訳します.

このスクリプトをROSノードとして実行するためには,そのファイルに実行可能なパーミッションを与える必要があります.以下のコマンドで実行可能なパーミッションを与えることができます:

chmod +x gpt_service.py

また,OpenAIのAPIキーを設定する部分では,実際のキーに’your-api-key’を置き換える必要があります.そして,APIの使用は料金が発生しますので,公式ドキュメンテーションを確認して使用制限とコストを理解することが重要です.

なお,上記のコードはあくまで一例であり,具体的な使用シーンや要件によりますので,適宜修正や拡張を行ってください.

ChatGPT に最初に生成してもらった Python プログラムにおいてプロンプトの内容が固定されているため,それを基に生成した ROS ラッパープログラムも固定プロンプトへの応答結果を出すだけになってしまいました.

そこでプロンプトを変更可能なようにプログラムを変更してもらいました.

User

ChatGPT に問うプロンプトを変えられるようにプログラムを変更してください.


ChatGPT

もちろんです.以下に,GPTサービスリクエストにプロンプトを含めるように改変したROSサービスの例を示します.

まず,新たなsrvファイルを作成します.この例では,リクエストにプロンプトとインプットの2つの文字列を持つサービスを定義します.

# GptService.srv
string prompt
string input
---
string output

次に,このサービスを実装するPythonのROSノードを作成します.

#!/usr/bin/env python
import rospy
from openai_ros.srv import GptService, GptServiceResponse
import openai

def handle_gpt_request(req):
    openai.api_key = 'your-api-key'
    
    response = openai.ChatCompletion.create(
        model="gpt-4.0-turbo",
        messages=[
            {"role": "system", "content": "You are a helpful assistant."},
            {"role": "user", "content": "{} '{}'".format(req.prompt, req.input)}
        ]
    )

    return GptServiceResponse(response['choices'][0]['message']['content'])

def gpt_service():
    rospy.init_node('gpt_service')
    s = rospy.Service('gpt_service', GptService, handle_gpt_request)
    print("Ready to handle GPT-4 requests.")
    rospy.spin()

if __name__ == "__main__":
    gpt_service()

このPythonスクリプトは,ROSノードgpt_serviceを作成し,それがGptServiceサービスを提供するようにします.サービスリクエストが来ると,handle_gpt_request関数が呼び出され,その中でOpenAIのGPT-4クライアントが使われてリクエストされたプロンプトとテキストを処理します.

上記のコードを実行する前に,Pythonスクリプトに実行可能なパーミッションを与えることを忘れないでください.

ここまでの ChatGPT の応答で ROS の Python プログラムとして動きそうな感じのソースコードが生成されたように思いましたので実際に実行しながら修正してみることにしました.

ChatGPT が生成したプログラムの修正

今回は ChatGPT と ROS – 文書生成 ROS ラッパー利用編(Completion API) で利用した ROS パッケージ https://github.com/davesarmoury/openai_ros をベースに Chat Completion API を利用する機能を付け加えるかたちで進めました.

ChatGPT が生成した Chat Completion API を利用する ROS Python プログラムを使って Chat Completion API を利用できるよう ROS パッケージに変更を加えた箇所をまとめると次のようになります.

  • openai_chat_node.py の追加
    • ChatGPT が生成したコードからの修正点
      • #!/usr/bin/env python
        • → Python3 に #!/usr/bin/env python3
      • openai.api_key = 'your-api-key'
        • → ROS パラメータから取得する方法に変更
          openai.api_key = rospy.get_param('~key')
      • model="gpt-4.0-turbo",
        • → GPT 3.5 に変更 model="gpt-3.5-turbo",
      • print("Ready to handle GPT-4 requests.")
        • → GPT 3.5 に変更 print("Ready to handle GPT-3.5 requests.")
  • GptService.srv の追加
    • ChatGPT が生成したコードをそのまま利用
  • CMakeLists.txs 内に GptService.srv の記述追加
  • openai_chat.launch の追加
    • 主に OpenAI API Key を ROS パラメータとするために作成

openai_chat_node.py

#!/usr/bin/env python3
import rospy
from openai_ros.srv import GptService, GptServiceResponse
import openai

def handle_gpt_request(req):
#    openai.api_key = 'your-api-key'
    openai.api_key = rospy.get_param('~key')
    
    response = openai.ChatCompletion.create(
#        model="gpt-4.0-turbo",
        model="gpt-3.5-turbo",
        messages=[
            {"role": "system", "content": "You are a helpful assistant."},
            {"role": "user", "content": "{} '{}'".format(req.prompt, req.input)}
        ]
    )

    return GptServiceResponse(response['choices'][0]['message']['content'])

def gpt_service():
    rospy.init_node('gpt_service')
    s = rospy.Service('gpt_service', GptService, handle_gpt_request)
#    print("Ready to handle GPT-4 requests.")
    print("Ready to handle GPT-3.5 requests.")
    rospy.spin()

if __name__ == "__main__":
    gpt_service()

プログラムの本筋の部分は ChatGPT が生成したコードから修正の必要はありませんでした.

GptService.srv

# GptService.srv
string prompt
string input
---
string output

CMakeLists.txt

add_service_files(
  FILES
  Completion.srv
  GptService.srv
)

GptService.srv のサービスが利用できるように CMakeLists.txt に加筆しました.このあたりの修正箇所の洗い出しも ChatGPT に問うてみるのも修正規模が大きい場合にはありかもしれません.

openai_chat.launch

<launch>
  <arg name="key" default="$(env OPENAI_API_KEY)" />
  <arg name="max_tokens" default="256" />
  <arg name="model" default="gpt-4.0-turbo" />

  <node pkg="openai_ros" type="openai_chat_node.py" name="openai_chat" output="screen">
    <param name="key" value="$(arg key)" />
    <param name="max_tokens" value="$(arg max_tokens)" />
    <param name="model" value="$(arg model)" />
  </node>  
</launch>

モデルを GPT-3.5 と GPT-4 で launch オプションで切り替えて使おうかと思っていたのですが,Web と API への課金は別らしく今回は API では GPT-3.5 のみ利用可能な状況でしたので openai_chat_node.py にモデル名を直書きしたまま使ってしまいました.

修正したプログラム実行の様子

roslaunch openai_ros openai_chat.launch を起動してからもう1つのターミナルで ROS サービスで rosservice call /gpt_service '{prompt: "(プロンプト)", input: "(内容)"}'
output: "Mon nom est Robotuser."
のように利用します.

ターミナル1

robotuser@robotuser-PC:~/openai_ws$ source ~/openai_ws/devel/setup.bash
robotuser@robotuser-PC:~/openai_ws$ roslaunch openai_ros openai_chat.launch 
... logging to /home/robotuser/.ros/log/9d61ced2-f54d-11ed-b5ca-c10df8d90fa9/roslaunch-robotuser-PC-41157.log
Checking log directory for disk usage. This may take a while.
Press Ctrl-C to interrupt
Done checking log file disk usage. Usage is <1GB.

started roslaunch server http://robotuser-PC:35595/

SUMMARY
========

PARAMETERS
 * /openai_chat/key: sk-3JDluBbxsNuIhi...
 * /openai_chat/max_tokens: 256
 * /openai_chat/model: gpt-4.0-turbo
 * /rosdistro: noetic
 * /rosversion: 1.16.0

NODES
  /
    openai_chat (openai_ros/openai_chat_node.py)

auto-starting new master
process[master]: started with pid [41165]
ROS_MASTER_URI=http://localhost:11311

setting /run_id to 9d61ced2-f54d-11ed-b5ca-c10df8d90fa9
process[rosout-1]: started with pid [41175]
started core service [/rosout]
process[openai_chat-2]: started with pid [41182]
Ready to handle GPT-3.5 requests.

ターミナル2

robotuser@robotuser-PC:~/openai_ws$ source ~/openai_ws/devel/setup.bash
robotuser@robotuser-PC:~/openai_ws$ rosservice call /gpt_service '{prompt: "Translate following to French:", input: "My name is Robotuser."}'
output: "Mon nom est Robotuser."
robotuser@robotuser-PC:~/openai_ws$ rosservice call /gpt_service '{prompt: "Translate following to Spanish:", input: "My name is Robotuser."}'
output: "Mi nombre es Robotuser."
robotuser@robotuser-PC:~/openai_ws$ rosservice call /gpt_service '{prompt: "Translate following to Japanese:", input: "My name is Robotuser."}'
output: "\u79C1\u306E\u540D\u524D\u306F\u30ED\u30DC\u30C3\u30C8\u30E6\u30FC\u30B6\u30FC\u3067\
  \u3059\u3002"
robotuser@robotuser-PC:~/openai_ws$ 
  • 注)コマンド全体は横スクロールにて表示してください.

このサービス利用例では “My name is Robotuser.” をフランス語,スペイン語,日本語に翻訳するよう各プロンプトを送りました.
日本語への翻訳指示した output が文字コード化していたので Unicode 変換すると次のようになりました.

私の名前はロボットユーザーです.

このように ChatGPT の Web サービスを利用してコードを生成してもらい,OpenAI の Chat Completion API を ROS から利用できるようになりました.

しかし今回のプログラムは Chat Completion API を用いているものの「1問1答」形式の使い方をしていて,それは Completion API を利用している場合と大きく変わらず, “文脈” をふまえた「チャット」形式ではありませんでした.

本シリーズ次回の記事では今回の Chat Completion API を利用する ROS サービスプログラムを文脈をふまえた「チャット」をする ROS プログラムに改造した様子をお伝えする予定です.

著者:yamamoto.yosuke

信州大学の HIRO ロボットソフトウェアが Ubuntu 20.04 + ROS Noetic に対応

先日,長野市にある信州大学の山崎研究室を訪問して Ubuntu 20.04 および ROS Noetic に対応した HIRO ロボットソフトウェアを納品しました.

山崎研究室では HIRO で AI を用いたロボット制御などを行っているとのことで,今回は GPU ボードを搭載したワークステーションに Ubuntu 20.04 および ROS Noetic に対応した HIRO ロボットソフトウェアをインストールしました.

HIRO ロボットは新しいソフトウェアを得て今後も活躍してくれることと思います.


なお, 今回の HIRO とともに TORK では NEXTAGE OPEN も Ubuntu 20.04 および ROS Noetic に対応したロボットソフトウェアの動作確認をしました.

NEXTAGE OPEN や HIRO を Python3 で動かすことや ROS Noetic で使うことにご興味がありましたら,TORK( info@opensource-robotics.tokyo.jp )にお問い合わせいただけたらと思います.


関連記事: 信州大学 山崎研究室でHiroに会いました!

信州大学 山崎研究室でHiroに会いました!

著者:yamamoto.yosuke

パソコン1台で出来るロボットの学習素材集

ROS(ロス/Robot Operating System)の学習は実際にロボットがなくてもロボットのシミュレータが入手できるのでネットワークにつながるパソコンが1台あればできますので結構自習に向いています.この記事では ROS の学習を始める,進めるにあたり必要な情報がある Web へのリンクを中心に紹介します.

大まかに言うと次のインストールを行えば ROS の学習をスタートすることができます.

  • パソコンにオペレーティングシステムの Ubuntu Linux をインストール
  • Ubuntu Linux に ROS をインストール
  • ROS 上で動くロボットソフトウェアのインストール
    • → 紹介 ROS チュートリアル内にて

ROS と Ubuntu Linux のバージョンは後述する ROS 学習のチュートリアルが現時点では ROS Kinetic というバージョンを基本としているので下記の組み合わせをお勧めします.

  • Ubuntu 16.04
  • ROS Kinetic

ROS Melodic は ROS Kinetic と基本的な操作のほとんどは変わらないので ROS Kinetic で学習してから ROS Melodic に移行しても難なく可能です.

 

パソコンへの Ubuntu Linux のインストール

パソコンはどのようなものを使えば良いのか?については下記記事を参考にしてください.

ROS 導入ノートパソコン比較調査

ROS 導入ノートパソコン比較調査

最新高性能パソコンよりも数年型落ちや廉価の機種のほうが Ubuntu Linux をインストールしやすい傾向にあるように思います.

 

Ubuntu Linux への ROS のインストール

下記リンク先に各 ROS のバージョンにおけるインストール手順が書かれています.

また,Ubuntu のバージョンと ROS のバージョンには1対1の対応関係があるので組み合わせを気をつける必要があります.

 

ROS のチュートリアル

各チュートリアルを進めるとそれらの中で ROS シミュレータなどのインストールも行います.

TORK MoveIt チュートリアル

ROS の入門には TORK MoveIt チュートリアルをお薦めします.MoveIt は ROS のマニピュレーションロボット動作計画ソフトウェアです.このチュートリアルでは数種のロボットの ROS シミュレータのインストールや基本的な操作,プログラムでのロボット操作を学習することができます.TORK MoveIt チュートリアルではプログラミング言語に Python を用いていますが,プログラミングの経験がほとんどない人にもプログラムによるロボット操作の体験と学習ができるように構成しています.

ROS を初めて使う方に TORK MoveIt チュートリアルを学習したときのレポートも下記の記事に書いてもらっています.学習過程でいろいろと疑問をもった点などの体験を書いてもらいましたので参考にしてみてください.

初めてのROS(ROSチュートリアルを使って)

 

ROS-Industrial トレーニング(日本語版)

より発展的な ROS プログラミングを学習したい場合は ROS-Industrial トレーニングを行ってみるのも良いでしょう.この教材で取り上げられているプログラミング言語は主に C++ と Python です.C++ によるロボット制御や画像処理,3D ポイントクラウド処理などとそれらの組み合わせのプログラムの学習ができます.

ROS-Industrialのトレーニング教材を日本語訳しました!

 

ROS で質問したいことが出てきたら

ROS Discourse やチュートリアル,パッケージの GitHub Issues に質問を投稿してみてください.

 

入門的な実機マニピュレーションロボット

1台のパソコンだけ,シミュレータだけでなく入門的な実機マニピュレータを利用してみたいと思った方は入門的なマニピュレーションロボット2例の導入検証を行った記事を参考にしてみてください.

ROS 入門向けマニピュレータ導入検証