7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

はじめてゲームプログラミングで逆運動学を解く

Last updated at Posted at 2022-04-11

はじめに

ロボット工学の基礎の1つと言えば、順運動学と逆運動学です。任天堂スイッチのソフト「はじめてゲームプログラミング」(以下 はじプロ)を使って逆運動学を解きたいと思います。

今回、関節が2つあるアームロボットをゲーム画面上で出現させ、逆運動学と解いて任意の位置にアームの先を移動させます。ロボットアームは2次元平面上を動くようにして、関節は2つのロボットアームとすることで自由度2の簡易的なモデルとしたいと思います。

まず数式

逆運動学の解き方については「優れた解説サイトがたくさんある」ので、バッサリ数式は省略したいのですが、一般的な式のままだとノードンの機能と一致せず、実装ができません。なので用意されている限られたノードンに、式の方を合わせる必要があります。そういう都合上、(自分の勉強も兼ねて)きちんと解いてみたいと思います。

変数の定義

座標系と変数.png

この図と表のように、変数を定義します。

変数 単位 定義
$(x_1, z_1)$ メートル 原点を(0,0)とする座標系における、目標の位置。はじプロでは真上から床を見ると、軸はxとzの座標になっています。
$l_0, l_1$ メートル アームリンクの長さ。固定された根本から順番に0,1と番号を振っています。
$(x_0, z_0)$ メートル アーム0とアーム1の間の関節の位置です。
$\theta_0$ 原点に対するアーム0の角度。反時計回りの方向が正となっています。範囲は-180〜180。
$\theta_1$ アーム0に対するアーム1の角度。そのほかは同上。

順運動学

まず、「関節の角度が決まったら、ロボットアームの先端の位置が決まる」という順運動学の式を書きます。

最初に、$(x_0, z_0)$の式。

\begin{align}

\begin{pmatrix}
x_0 \\
z_0
\end{pmatrix}
&= 
\begin{pmatrix}
l_0 cos \theta_0\\
l_0 sin \theta_0
\end{pmatrix} \\

&= l_0
\begin{pmatrix}
cos \theta_0\\
sin \theta_0
\end{pmatrix} \tag{1} \\

\end{align}

次に、$(x_1, z_1)$の式。

\begin{align}

\begin{pmatrix}
x_1 \\
z_1
\end{pmatrix}
&= 
\begin{pmatrix}
x_0 \\
z_0
\end{pmatrix}
+
l_1
\begin{pmatrix}
cos (\theta_0 + \theta_1)\\
sin (\theta_0 + \theta_1)
\end{pmatrix} \\

&= l_0
\begin{pmatrix}
cos \theta_0\\
sin \theta_0
\end{pmatrix}
+
l_1
\begin{pmatrix}
cos (\theta_0 + \theta_1)\\
sin (\theta_0 + \theta_1)
\end{pmatrix} \tag{2} \\

\end{align}

アーム0に着目すると、$\theta_0$は次のように表せます。

\begin{align}
l_0 tan \theta_0 = \frac{z_0}{x_0} \\

tan \theta_0 = \frac{z_0}{l_0 x_0} \\

\theta_0 = tan^{-1} (\frac{z_0}{l_0 x_0}) \tag{3} \\
\end{align}

同様にアーム1に着目すると、$\theta_1$は次のように表せます。

\begin{align}
l_1 tan \theta_1 = \frac{z_1 - z_0}{x_1 - x_0} \\

tan \theta_1 = \frac{z_1 - z_0}{l_1(x_1 - x_0)} \\

\theta_1 = tan^{-1} (\frac{z_1 - z_0}{l_1(x_1 - x_0)}) \tag{4} \\
\end{align}

逆運動学を解く ①

$\theta_0$を求めるために、$(2)$を変形していきます。

\begin{align}

\begin{pmatrix}
x_1 \\
z_1
\end{pmatrix}
&= l_0
\begin{pmatrix}
cos \theta_0\\
sin \theta_0
\end{pmatrix}
+
l_1
\begin{pmatrix}
cos (\theta_0 + \theta_1)\\
sin (\theta_0 + \theta_1)
\end{pmatrix} \\

\begin{pmatrix}
x_1 - l_0 cos \theta_0 \\
z_1 - l_0 sin \theta_0 
\end{pmatrix}
&= l_1
\begin{pmatrix}
cos (\theta_0 + \theta_1)\\
sin (\theta_0 + \theta_1)
\end{pmatrix}  \tag{2'} \\

\end{align}

両辺を二乗します。

\begin{align}

\begin{pmatrix}
(x_1 - l_0 cos \theta_0)^2 \\
(z_1 - l_0 sin \theta_0)^2 
\end{pmatrix}
&= l_1^2
\begin{pmatrix}
cos^2 (\theta_0 + \theta_1)\\
sin^2 (\theta_0 + \theta_1)
\end{pmatrix} \\

\begin{pmatrix}
x_1^2 - 2l_0 x_1 cos \theta_0 + l_0^2 cos^2 \theta_0 \\
z_1^2 - 2 l_0 z_1 sin \theta_0 + l_0^2 sin^2 \theta_0
\end{pmatrix}
&= l_1^2
\begin{pmatrix}
cos^2 (\theta_0 + \theta_1)\\
sin^2 (\theta_0 + \theta_1)
\end{pmatrix} \\

\end{align}

上下の式を足して、$sin^2 x + cos^2 x = 1$を使って変形します。

\begin{align}

x_1^2 - 2l_0 x_1 cos \theta_0 + l_0^2 cos^2 \theta_0 + z_1^2 - 2 l_0 z_1 sin \theta_0 + l_0^2 sin^2 \theta_0 
&= l_1^2 (cos^2 (\theta_0 + \theta_1) + sin^2 (\theta_0 + \theta_1)) \\

x_1^2 + z_1^2 - 2l_0 (x_1 cos \theta_0 + z_1 sin \theta_0) + l_0^2 (cos^2 \theta_0 + sin^2 \theta_0 )
&= l_1^2 (cos^2 (\theta_0 + \theta_1) + sin^2 (\theta_0 + \theta_1)) \\

x_1^2 + z_1^2 - 2l_0 (x_1 cos \theta_0 + z_1 sin \theta_0) + l_0^2
&= l_1^2 \\

2l_0 (x_1 cos \theta_0 + z_1 sin \theta_0)
&= x_1^2 + z_1^2 + l_0^2 - l_1^2 \\

x_1 cos \theta_0 + z_1 sin \theta_0
&= \frac{x_1^2 + z_1^2 + l_0^2 - l_1^2}{2l_0} \tag{5} \\
\end{align}

$R = \sqrt{a^2 + b^2}$, $α = tan^{-1} \frac{b}{a}$ のとき $a cos x + b sin x = R cos(x - α)$ なので

\begin{align}

x_1 cos \theta_0 + z_1 sin \theta_0
&= \sqrt{x_1^2 + z_1^2} cos (\theta_0 - tan^{-1} \frac{z_1}{x_1})\\

\end{align}

これを $(5)$に代入して

\begin{align}

x_1 cos \theta_0 + z_1 sin \theta_0
&= \frac{x_1^2 + z_1^2 + l_0^2 - l_1^2}{2l_0} \\

\sqrt{x_1^2 + z_1^2} cos (\theta_0 - tan^{-1} \frac{z_1}{x_1})
&= \frac{x_1^2 + z_1^2 + l_0^2 - l_1^2}{2l_0} \\

cos (\theta_0 - tan^{-1} \frac{z_1}{x_1})
&= \frac{x_1^2 + z_1^2 + l_0^2 - l_1^2}{2l_0 \sqrt{x_1^2 + z_1^2}} \\

\theta_0 - tan^{-1} \frac{z_1}{x_1}
&= \pm cos^{-1} \frac{x_1^2 + z_1^2 + l_0^2 - l_1^2}{2l_0 \sqrt{x_1^2 + z_1^2}} \\

\theta_0
&= \pm cos^{-1} \frac{x_1^2 + z_1^2 + l_0^2 - l_1^2}{2l_0 \sqrt{x_1^2 + z_1^2}} + tan^{-1} \frac{z_1}{x_1} \tag{6} \\

\end{align}

これで一旦$\theta_0$が求められました。

逆運動学を解く  ②

次に$\theta_1$を求めるために、$(2')$の2つの式で割ります。

\begin{align}

\frac{z_1 - l_0 sin \theta_0}{x_1 - l_0 cos \theta_0}
&= \frac{l_1 sin (\theta_0 + \theta_1)}{l_1 cos (\theta_0 + \theta_1)} \\

&= tan (\theta_0 + \theta_1) \\

tan (\theta_0 + \theta_1)
&=
\frac{z_1 - l_0 sin \theta_0}{x_1 - l_0 cos \theta_0} \\

\theta_0 + \theta_1
&= tan^{-1}
\frac{z_1 - l_0 sin \theta_0}{x_1 - l_0 cos \theta_0} \\

\theta_1
&= tan^{-1}
\frac{z_1 - l_0 sin \theta_0}{x_1 - l_0 cos \theta_0} - \theta_0 \tag{7} \\

\end{align}

これで$\theta_1$が求められました。

はじプロの角度に関するノードン

用意されている角度に関するノードンは以下の3つです。

名前 機能 入力 出力
角度を位置にノードン
Nodon_Angle_2_Position.png
入力された角度を位置に変換して出力する。$sin$と$cos$の機能。 角度(-180〜180) ・横位置
・縦位置
位置を角度にノードン
Nodon_Pos_2_ang.png
入力された位置を角度に変換して出力する。$tan^{-1}$ の機能。 ・横位置
・縦位置
角度(-180〜180)
角度の差ノードン
Nodon_Angle-Difference.png
入力された2つの角度の差を出力する ・角度1
・角度2

そう、 $\theta_0$ の式の中で使っている$cos^{-1}$のノードンはありません。でも大丈夫。 $cos^{-1}$ を $tan^{-1}$ に変形してやれば、位置を角度にノードン を使えるようになりますね。

直角三角形の辺a,b,cが図のような関係のとき、以下の式が成り立ちます。

直角三角形.png
\begin{align}

\theta
&= cos^{-1} \frac{a}{c} \\

&= tan^{-1} \frac{b}{a} \tag{8} \\

\end{align}

ノードンで表すために式を変形

$(6)$ を $(8)$ のかたちで表すために、 $a, b, c$ を次のようにします。

\begin{align}

a &= x_1^2 + z_1^2 + l_0^2 - l_1^2 \tag{9} \\
c &= 2l_0 \sqrt{x_1^2 + z_1^2} \tag{10} \\
b &= \sqrt{c^2 - a^2} \\

\end{align}

$(6)$ を変形します。

\begin{align}

\theta_0
&= \pm cos^{-1} \frac{a}{c} + tan^{-1} \frac{z_1}{x_1} \\

&= \pm tan^{-1} \frac{b}{a} + tan^{-1} \frac{z_1}{x_1} \\

&= \pm tan^{-1} \frac{\sqrt{c^2 - a^2}}{a} + tan^{-1} \frac{z_1}{x_1} \tag{11} \\

\end{align}

これでノードンで置き換えができる式ができました。

ノードンを使って実装

プログラムのせいり の活用

次に、上記の式をノードンを使って表現していきます。式で使っているたくさんの変数を ワイヤーワープ入口ノードンとワイヤーワープ出口ノードン に置き換えると整理してプログラミングができます。デバッグもしやすい。

Nodon_wire_warp_entery.png

私は以下のようにアサインしました。

変数 ワイヤーワープノードン 説明
$\theta_0$ A 式(11)で求める
$\theta_1$ B 式(7)で求める
$x_1$ X
$z_1$ Z
$l_0$ L 実際に作ったアーム0の長さ
$l_1$ M 実際に作ったアーム1の長さ
$a$ E 式(9)で求める
$c$ F 式(10)で求める

ゲーム画面

ゲーム画面.JPG

ゲーム画面は上から下の床を観る視点に設定しています。中央の(0, 0)の座標にロボットアームの根本(円柱)の中心となるように置きます。

左側に並んでいる8組のノードンたちは、デバッグ用に変数を表示するためのものです。

ロボットアーム

ロボットアーム_全体.JPG
ロボットアーム_左.JPG
ロボットアーム_右.JPG

ノードン 設定
円柱 ふるまい : 見える のみ
いろ : くろ
直方体 0 ふるまい : 見える 動く
大きさ X : 4.00 m
れんけつ面 : X-→中央
いろ : くろ
直方体 1 ふるまい : 見える 動く
大きさ X : 4.00 m
れんけつ面 : X-→X+
いろ : くろ
ふるまい : 見える 動く
れんけつかたさ : バネバネ
れんけつ面 : 中央→X+
いろ : ピンク 

AとBの角度は+ー反転ノードンでプラスマイナスを逆にしています。どうやらヒンジれんけつノードンの回転方向は時計回りになってるようですが、反時計回りにしたいので反転しています。

定数

定数.JPG

アーム0とアーム1の長さを定数ノードンで設定してます。それぞれ4を設定しています。

中間の計算

中間の計算.JPG

ワイヤーワープノードンEとFに入力するための計算です。使っているのはかけ算、引き算、ルートのノードンです。

θ0の計算

θ0の計算.JPG

ワイヤーワープノードンF、E、X、Zを入力し、かけ算、引き算、ルート、位置を角度に のノードンを使って、結果をワイヤーワープノードンAに出力しています。

ボタンAから3つ繋がっている部分は、Aボタン押しで2つ存在する解を切り替える機能を実現しています(デフォルトは+、押すと-)。この流れのノードンの設定は以下のようになっています。

ノードン 設定
ボタン A
マッピング 0-1 → -1-1
+-反転
けいさん x

θ1の計算

θ1の計算.JPG

ワイヤーワープノードンZ、L、A、Xを入力し、角度を位置に、かけ算、引き算、ルート、位置を角度に、角度の差 のノードンを使って、結果をワイヤーワープノードンBに出力しています。

目標のマーカー

目標のマーカー.JPG

アームロボットの根本にある円柱が原点にあるので、これに連結しています。

ノードン 設定
フリースライドれんけつ スライドの移動入力 : XとZ
円柱 ふるまい : 動く
そざい : 無重力
連結面 : Y-→Y+

ランダムに目標点を動かす

ランダムに目標点を動かす.JPG

目標マーカーを1秒間隔でランダムな位置に移動させます。ランダムな半径と角度を変数として、原点から8 m (アーム0とアーム1 の長さの合計)の範囲に目標を置きます。

ノードン 設定
1行目 タイマー 1秒間隔
1行目 ランダム 出力はんい : 0-360
1行目 マッピング 0-360 → -180-180
1行目 角度を位置に
1行目 けいさん X
2行目 ランダム 出力はんい : 0-100
2行目 マッピング 0-100 → 0.01-8
1行目 けいさん X

完成

赤い十字マークがランダムに動き、そこを目標にロボットアームの先端が動きます。モーター音を鳴らしながら、目標に向かって吸い付くようにロボットアームが動いていますね。

アームが静止するまで少しゆらゆら揺れるのが良いですね。はじプロでは慣性モーメントがちゃんとシミュレートされているのが分かります。

7
4
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
7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?