0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[PyBullet] [強化学習] 2軸ロボットアームの強化学習 Part3 (SARSA法)

0
Last updated at Posted at 2026-06-15

はじめに

PyBullet (Python上で動く物理シミュレータ) を使用して,ロボットアームを可視化して,動かしたい.

前記事では,エージェントの学習方法として "モンテカルロ法" を採用して,PyBullet 内の2軸ロボットアームの強化学習を実装した.

前記事の問題点は,モンテカルロ法が "1エピソード完了後にのみQ値を更新" するため,学習が遅い点である.

本記事では,エージェントの学習方法として "SARSA (TD学習)" を採用する.SARSAは "1ステップごとにQ値を更新" するため,モンテカルロ法よりも学習が速くなる.
グリッパー付きの2軸ロボットアームを使用して,干渉物が存在しない環境下にて,複数のカメラから把持物体の位置を取得して,物体を把持する(下図はPyBullet上のグリッパー付き2軸ロボットアームである).赤枠がグリッパー,緑枠が把持したい物体,青枠がカメラ,青色の球が初期位置である.
2DoF_Random_Agent.png

本記事を実施してできる最終的なものは下記動画の通りである.エージェントの学習方法は "SARSA" である.
下記は,学習中の強化学習による経路生成の動画である.

SARSA_再現フェーズ.gif

下記は,学習後の強化学習による経路生成の動画である.

SARSA_推論.gif

本記事で実装すること

  • エージェントの学習方法は"SARSA"

本記事では実装できないこと (将来実装したい内容)

エージェントの学習手法

  • Q学習
  • DQN
  • Actor-Critic

動作環境

  • macOS Sequoia (バージョン15.5)
  • Python3 (3.13.3)
  • PyBullet (3.25) (物理シミュレータ)
  • Numpy (2.3.0) (数値計算用ライブラリ)

PyBullet のインストール方法

PyBullet のインストール方法については下記にて,説明したため,割愛する.

PyBulletの使用方法

Pythonの物理シミュレータであるPyBulletの使用方法について説明する.
下記リンクのPyBullet公式で調べながら,PyBulletを使用している.

上記リンクを開くと,下図のようなサイトに飛ぶ.使用方法を調べるときは,下図の赤枠内の「PYBULLET QUICKSTART GUIDE」タグをクリックする.
PyBullet公式.png

「PYBULLET QUICKSTART GUIDE」タグをクリックすると,下図のようなドキュメントを見ることができる.基本的には,ドキュメントに記載されている関数の使用方法を見て,ソースコードを作成している.
PyBulletドキュメント.png
PyBulletの関数の引数や戻り値をもっと知りたいのでしたら,上記ドキュメントを見た方がわかりやすいです.

2軸ロボットアームの定義

2軸ロボットアームの定義については下記にて,説明したため,割愛する.

グリッパーの定義

グリッパーの定義については下記にて,説明したため,割愛する.

グリッパー付き2軸ロボットアームのURDF作成

グリッパー付き2軸ロボットアームのURDF作成については下記にて,説明したため,割愛する.

URDFに関しては,下記にて説明したため,割愛する.

カメラによる把持物体の2次元位置を取得

PyBulletでカメラ情報を取得する方法については下記にて,説明したため,割愛する.

強化学習に関して

強化学習は機械学習の一つの種類である.強化学習とは,自分で試行錯誤をしてデータを集め,詰めたデータから良い行動を学習することである.
強化学習のイメージは下図の通りである.

Env_Agent.drawio.png

1:「環境」から「エージェント」に対して,「状態」を渡す
2:「エージェント」が「状態」より,「行動」を選択する
3:「エージェント」から「環境」に対して,「行動」を実行する
4:「環境」が「行動」より,「状態」を更新する
5:「環境」から「エージェント」に対して,「報酬」を渡す
6:「エージェント」が「報酬」より,「学習」する

ここで,用語の定義をする.

用語 用語の定義
エージェント 行動の主体者
環境 エージェントと相互作用を行う対象
状態 エージェントの行動によって置かれるエージェントの状況
行動 エージェントが起こすアクション
報酬 エージェントの行動に対する環境からのフィードバック

本記事での "環境" は "PuBullet上のロボットと環境" である."エージェント" は "ロボットを動かすための頭脳" である.
以下では,本記事で使用する "環境" と "エージェント" を説明していく.

強化学習の環境に関して

強化学習の環境に関しては下記にて,説明したため本記事では割愛する.

強化学習のエージェントに関して

強化学習のエージェントに関して説明する.強化学習の全体像の中で,下図の赤枠で囲んだ「エージェント」を説明する.

Env_AgentAtract.drawio.png

エージェントは,環境から「状態」を受け取り,「行動」を行い,「報酬」を得て,次の「状態」へ遷移する.下記のように1エピソードが完了するまで,「状態(S)」,「行動(A)」,「報酬(R)」,「状態(S)」のループとなる.
$S_{0}, A_{0}, R_{0}, S_{1}, A_{1}, R_{1}, ...$

行動価値関数に関して

行動価値関数については下記にて,説明したため本記事では割愛する.

SARSA (TD学習) に関して

エージェントの学習方法の一種である "SARSA" に関して説明する.

SARSAとは,"State-Action-Reward-State-Action" の頭文字を取った名称である.Q値の更新に使用する5つの要素 $(s_t, a_t, r_t, s_{t+1}, a_{t+1})$ から名付けられており,更新式は以下の通りである.

\displaylines{
Q(s_t, a_t) \leftarrow Q(s_t, a_t) + \alpha \left[ r_t + \gamma Q(s_{t+1}, a_{t+1}) - Q(s_t, a_t) \right] \\
\\
文字の意味は以下の通り.\\
Q ... \text{行動価値関数},\; \alpha ... \text{学習率},\; \gamma ... \text{割引率} \\
s_t ... \text{時刻}t\text{の状態},\; a_t ... \text{時刻}t\text{の行動},\; r_t ... \text{時刻}t\text{の報酬} \\
s_{t+1} ... \text{次の状態},\; a_{t+1} ... \text{次の行動}
}

SARSAは "TD学習 (Temporal Difference Learning)" の一種である.TD学習とは,"1ステップ後の情報を使って価値関数をブートストラップ更新する手法" の総称である.

モンテカルロ法では,更新に収益 $G_t = R_t + \gamma R_{t+1} + \gamma^2 R_{t+2} + \cdots$ (エピソード全体の報酬列) が必要なため,1エピソードが完了するまで更新できない.
SARSAでは,収益 $G_t$ の代わりに "次のQ値" $Q(s_{t+1}, a_{t+1})$ を使うことで,エピソード完了を待たずに1ステップごとにQ値を更新できる.

モンテカルロ法とSARSAの比較を下表にまとめた.

比較項目 モンテカルロ法 SARSA
更新タイミング 1エピソード完了後 1ステップごと
更新に必要な情報 エピソード全体の報酬列 $(s_t, a_t, r_t, s_{t+1}, a_{t+1})$
収束速度 遅い 速い
方策の種類 on-policy on-policy
エピソード終了条件 必須 不要

SARSAは "on-policy" の学習手法である.on-policyとは,"行動の選択に使う方策と,Q値の更新に使う方策が同一である" ことを意味する.具体的には,次の行動 $a_{t+1}$ が "同じ ε-greedy 方策" によって選択されるため,on-policyとなる.

SARSAの学習フローを以下に示す.

1:初期状態 $s_0$ を取得して,ε-greedy方策で最初の行動 $a_0$ を選択する
2:行動 $a_t$ を実行して,報酬 $r_t$ と次の状態 $s_{t+1}$ を得る
3:同じ ε-greedy方策で次の行動 $a_{t+1}$ を選択する
4:$Q(s_t, a_t)$ を更新式で更新する
5:$s_t \leftarrow s_{t+1}$,$a_t \leftarrow a_{t+1}$ として2に戻る

ポイントは,"ループ前に最初の行動を選択する" 点である.モンテカルロ法では,ループ内で行動を選択した後にステップを実行していたが,SARSAでは次の行動 $a_{t+1}$ もループ内で選択する必要があるため,最初の行動 $a_0$ はループ開始前に選択する必要がある.

SARSAの更新式の意味を分解すると下式の通りとなる.

\displaylines{
Q(s_t, a_t) \leftarrow Q(s_t, a_t) + \alpha \left[ r_t + \gamma Q(s_{t+1}, a_{t+1}) - Q(s_t, a_t) \right] \\
\\
\underbrace{r_t + \gamma Q(s_{t+1}, a_{t+1})}_{\text{TD目標値 (1ステップ先の見積もり)}} - \underbrace{Q(s_t, a_t)}_{\text{現在の推定値}} = \underbrace{\delta_t}_{\text{TD誤差}} \\
\\
Q値の更新 = Q値 + \alpha * TD誤差 \\
TD誤差が正なら Q値を増やす(現在の推定より良い状態だった)\\
TD誤差が負なら Q値を減らす(現在の推定より悪い状態だった)
}

このTD誤差 $\delta_t$ を使って,Q値を少しずつ更新することで,学習が進む仕組みである.

行動の選択方法 (ε-greedy法)

行動の選択方法 (ε-greedy法) に関しては下記にて,説明したため本記事では割愛する.

ソースコード一覧

本記事で使用する全ソースコードの一覧を下表にまとめる.フォルダ名が記載されているものは,そのフォルダを作成して,フォルダ内にファイルを保存してください.

URDFファイル

ファイル名 概要
camera_back_to_front.urdf 手前方向(-Y方向)を向いているカメラの定義
camera_front_to_back.urdf 奥行き方向(+Y方向)を向いているカメラの定義
camera_left_to_right.urdf 右方向(+X方向)を向いているカメラの定義
camera_right_to_left.urdf 左方向(-X方向)を向いているカメラの定義
camera_up_to_down.urdf 下方向(-Z方向)を向いているカメラの定義
grasp_object.urdf 把持物体の定義
robot_2dof.urdf グリッパーなし2軸ロボットアームの定義
environment_2dof.urdf 2軸ロボットアームの環境を定義
robot_2dof_hand.urdf グリッパー付き2軸ロボットアームの定義

Pythonファイル

ファイル名 概要
constant.py 定数の定義 (SARSA追加)
main.py 全体的なメイン処理
pybullet_grasp.py PyBulletの把持物体
pybullet_gripper.py PyBulletのグリッパー
pybullet_robot.py PyBulletのロボット
pybullet_camera.py PyBulletのカメラ
pybullet_agent_controller.py PyBulletのエージェント制御 (SARSA対応)
BaseAgent.py PyBulletのエージェントの抽象クラス
RandomAgent.py PyBulletのランダムに動くエージェント
MonteCarloAgent.py PyBulletのモンテカルロ法で学習するエージェント
SarsaAgent.py PyBulletのSARSAで学習するエージェント
pybullet_environment_controller.py PyBulletの強化学習用の環境制御
BaseEnvironment.py PyBulletの強化学習用の環境の抽象クラス
DiscretizeEnvironment.py PyBulletの強化学習用の離散値環境
pybullet_main.py PyBulletのメイン処理 (SARSAループ)

pybullet_main.py の変更点に関して

pybullet_main.py__learning() メソッドをSARSA用に変更した点について説明する.

モンテカルロ法とSARSAの学習ループの違いを下表にまとめた.

比較項目 モンテカルロ法 (part2) SARSA (part3)
最初の行動選択 whileループ内 ループ前に選択
add() の呼び出し add(s, a, r) add(s, a, r, s', a')
Q値の更新タイミング エピソード終了後の update() ステップごとの add()
update() の役割 Q値更新 + ε更新 ε更新のみ

最初の行動をループ前に選択する理由は,SARSAでは "1ステップの実行前後で必ず行動が必要" なためである.具体的には,step(action) の前後に行動が必要となる.step() を呼ぶ前に $a_t$,step() を呼んだ後に $a_{t+1}$ が必要であり,ループ内で step() を最初に呼ぶためには,最初の $a_0$ はループ前に選択しておく必要がある.

SARSAの __learning() の主要部分を抜粋すると以下の通りとなる.

# SARSAは最初の行動をループ前に選択する (s, a, r, s', a' の a に相当)
action = self.__agent.get_action(state)

while not done:
    # 1ステップ実行: (s, a) → (s', r, done)
    next_state, reward, done = self.__env.step(action)

    # 次の行動を選択 (on-policy: 同じε-greedy方策で選択)
    next_action = self.__agent.get_action(next_state)

    # Q値を即時更新: Q(s,a) ← Q(s,a) + α[r + γQ(s',a') - Q(s,a)]
    self.__agent.add(state, action, reward, next_state, next_action)

    # 状態と行動の更新 (s ← s', a ← a')
    state  = next_state
    action = next_action

# エピソード終了: 探索確率 ε の更新 (Q値更新はadd()内で完了済み)
self.__agent.update()

SarsaAgent.py の実装に関して

SarsaAgent.py では,モンテカルロ法 (MonteCarloAgent.py) と比較して,以下の点が異なる.

add() メソッドの引数変更
モンテカルロ法では add(state, action, reward) だったが,SARSAでは (s, a, r, s', a') の5要素が必要なため,add(state, action, reward, next_state, next_action) に変更した.また,モンテカルロ法では add() でメモリにデータを蓄積してエピソード終了後にまとめて更新するのに対して,SARSAでは add() の中でQ値を即時更新する.

\displaylines{
Q(s_t, a_t) \leftarrow Q(s_t, a_t) + \alpha \left[ \underbrace{r_t + \gamma Q(s_{t+1}, a_{t+1})}_{\text{TD目標値}} - Q(s_t, a_t) \right]
}

update() メソッドの役割変更
モンテカルロ法では update() がQ値の更新と ε 更新の両方を担っていたが,SARSAでは update() は ε 更新のみである (Q値更新は add() で完了済み).

パラメータファイル
モンテカルロ法は montecarlo_param.json,SARSAは sarsa_param.json にそれぞれQ値を保存する.学習パラメータ (γ, α, ε など) はモンテカルロ法と同一の値とした.

パラメータ
割引率 γ 0.9
学習率 α 0.1
探索確率の最小値 ε_min 0.1
探索確率の最大値 ε_max 0.9
探索確率の減衰率 0.9999

PyBulletのメイン処理 (pybullet_main.py)

p.connect() 関数の引数である p.DIRECTp.GUI に関しては下記にて,説明したため本記事では割愛する.

PyBulletでロボットを動かす

上記にて,ソースコードを説明した.
main.py ファイルを実施することによって,PyBullet上のロボットを動かしていく.

経路生成の動画

SARSAに動くエージェントによる経路生成の動画を載せる.

動画1:学習時の経路生成の動画

SARSA_再現フェーズ.gif

動画2:学習完了後の経路生成の動画

SARSA_推論.gif

SARSAはモンテカルロ法と比較して,1ステップごとにQ値を更新するため,収束が速くなることが期待される.ただし,学習終了後であっても行動が最適とは限らない.
そのため,次回はSARSAではなく,Q学習を採用することで,行動がより最適となるようにする.

おわりに

本記事では,Pythonを使用して,下記内容を実装しました

  • エージェントの学習方法としてSARSAを採用して,PyBullet 内の2軸ロボットアームの強化学習

次記事では,下記内容を実装していきます.

参考文献

本記事を作成する上で参考にした内容を記載する.

参考記事

参考書籍

  • ゼロから作るDeep Learning ❹ ―強化学習編
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?