ブログ

milibのデータ要素アルゴリズム「ZEDA」を見てみる

こんにちは。だいCです。
以前 運動知能研ライブラリ milib の環境構築をしてみました。
今回からライブラリの中身を見ていきたいと思います。

まず最初にmilibの計算の根幹となる「ZEDA」について見ていきたいと思います。

  

1. milib構成におけるZEDAの位置づけ

Z-Labの公開ソフトウェアのページを見ると、milibの構成は以下のようになっているそうです。

milibの構成(Z-Lab参照)

OS上で動作することを考えると、以下のようなイメージだと思っています。

OS上でのmilibの位置づけのイメージ

OSを構成する標準ライブラリやOSをCPU上で動作させるカーネルがmilibの実行環境を支えているイメージです。
milibの対応OSは、milibが依存している標準ライブラリが使用できればどこでも良いかと思います。
milibはユーザランドで動作し、標準ライブラリからOSカーネルのI/Oシステムコールを叩き外部デバイスと連携し現実の物理世界へとアクセスするイメージかと思います。
milibを使用するユーザアプリケーション(図中階層一番上の「Applications」)から見ると、そのように現実の物理世界へアクセスすることもできますし、Roki系ライブラリを駆使してシミュレータを構築し仮想上の物理世界へアクセスすることもできるのかな、と思います。

一番下の階層にいるのがZEDAですね。
ZEDAとは Z Elementary Data Algorithm の略だそうです。milib共通のデータ要素アルゴリズムを構築しているようです。

  

2. ZEDAパッケージのディレクトリ構成

まずはソースコードのパッケージからZEDAライブラリの構成をざっくり見てみましょう。

以前「milib環境を構築してみよう」でクローンされた環境をそのまま見てみます。
自動でクローンされたmilibパッケージのディレクトリ構成は以下のようになっていました。

milib/
├── bin/
├── include/
├── lib/
└── milib-starter/
    ├── README.md
    ├── config
    ├── deb/
    ├── dzco/
    ├── liw/
    ├── neuz/
    ├── roki/
    ├── roki-fd/
    ├── roki-gl/
    ├── scripts/
    ├── zeda/ <-- Here
    ├── zeo/
    ├── zm/
    └── zx11/

「Here」と書いた場所に zeda のソースコードパッケージが配置されています。
milib-starter の中に格納されていたのでした。
zeda/の中身を見てみましょう。{YOUR_DIR} はmilibを配置した自分の好きなディレクトリを指しています。

# 現在zedaディレクトリにいることを確認
$ pwd
{YOUR_DIR}/milib/milib-starter/zeda

tree コマンド等で見ると以下のようなディレクトリ構成になっているようです。

zeda/
├── COPYING
├── GPL-3
├── HISTORY
├── LGPL-3
├── README.ZTK.md
├── README.md
├── config
├── config.org
├── makefile
├── app/
├── doc/
├── example/
├── include/
├── lib/
├── src/
├── test/
└── tools/

README.md がありますね。

  

3. ZEDAのREADME

まずは ZEDA の REAMDE.md を読んでみましょう。
以下、自分の言葉で勝手に日本語に訳してみました。

  

~~~

ZEDA – Elementary Data and Algorithms

Copyright (C) Tomomichi Sugihara (Zhidao) since 1998


[なんですか?これ]

ZEDA頻繁に使用されるデータ構造とアルゴリズムの以下を含むコレクションだよ:

  • ビット演算
  • 配列型演算
  • リスト型演算
  • ツリー型演算
  • ラウンド-ロビン テーブル
  • 文字列型演算
  • コマンドライン オプション操作
  • 一般的な I/O ストリーム
  • 乱数生成器
  • ZTK フォーマット パーサー
  • CSV ファイル操作
  • XML パーサー(libxml2のラッパー)

[インストール / アンインストール方法]

インストール

ZEDAをインストールしたいディレクトリへ移動し、以下を実行してね:

% git clone https://github.com/zhidao/zeda.git
% cd zeda

ヘッダファイル、ライブラリ、ユーティリティを特定のディレクトリにするために、もし必要ならば config ファイルの中の PREFIX を編集してインストールしてね。 (デフォルトのインストール場所: ~/usr)

  • ヘッダファイル: $PREFIX/include/zeda
  • ライブラリファイル: $PREFIX/lib
  • ユーティリティ: $PREFIX/bin

それから, make して install してね。

% make && make install

アンインストール

以下を実行してね:

% make uninstall

これにより $PREFIX/lib/libzeda.so と $PREFIX/include/zeda が削除されるよ。


[つかいかた]

自分の環境変数 PATH と LD_LIBRARY_PATH を設定しておいてね。これは以下を実行するよ:

% export PATH=$PATH:$PREFIX/bin
% export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PREFIX/lib

Bourne shell ファミリー (bash, zsh, etc.) 、または
C shell ファミリー (csh, tcsh, etc.)なら以下のように設定するよ:

% set path = ( $path $PREFIX/bin )
% setenv LD_LIBRARY_PATH $LD_LIBRARY_PATH:$PREFIX/lib

自分の test.c コードをコンパイルしたいときは、例えば、対のような行で動作するよ。

% gcc `zeda-config -L` `zeda-config -I` test.c `zeda-config -l`

[ドキュメント]

http://www.doxygen.org/ から  doxygen  をダウンロードして以下を実行してね:

% make document

HTMLドキュメントが doc/ 以下に生成されるよ。


[お問い合わせ]

zhidao@ieee.org

~~~

  

ふむふむ。

インストールは既に「milib環境を構築してみよう」で実施されているのでスキップしますね。
ドキュメントがあるとのことです。

  

4. コピーライト/ライセンス

zeda/ ディレクトリ内の COPYING を見ると、ZEDAはフリーソフトウェアであり、コピーライトは Tomomichi Sugihara 氏、使用許諾は一部 GPL、LGPLライセンスに基づいているようです。ライセンスによっては複製・改変・使用したもの(派生物含む)を公開・頒布する場合ソースコードの開示義務があるので、オープンソースソフトウェアを商用利用する方はよく注意しておきましょう。

  

5. 環境パスを通しておく

とりあえず、README.md の [つかいかた] に従い、環境パスを通しておきます。
milib/ ディレクトリに置いてある config ファイルの設定を反映しておき、パスを通しておきます。

$ pwd             # milibディレクトリに居ることを確認。
{YOUR_DIR}/milib

$ . ./config      # configファイル内の設定を現在の端末に反映。
$ echo $PREFIX    # 変数PREFIXが反映されていることを確認
{YOUR_DIR}/milib
 
# 環境パスを通す
$ export PATH=$PATH:$PREFIX/bin
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PREFIX/lib 

  

6. ZEDAのdoxygenドキュメント出力

README.mdに書いてあるように、doxygen 形式のドキュメントを出力できるようです。
doxygenをインストールしておきます。

$ sudo apt install doxygen

上記インストールで GraphViz という、関数の呼び出し関係のグラフや UML 図を自動生成してくれるライブラリもインストールしてくれるようです。

README.mdにあるように、make document を実行してドキュメントを doc/ へ出力してみます。

$ pwd  # zeda/に居ることを確認
{YOUR_DIR}/milib/milib-starter/zeda

$ make document
make: *** ターゲット 'document' を make するルールがありません.  中止.

出力できませんでした。
zeda/makefile のルールに document を指定したものは無いようです。
zeda/makefile の中身を見てみると、以下のようなドキュメント出力っぽい記述がありました。

doc:
	@$(MAKEFILEGEN) | make -f - doc

今度は make doc を実行してみます。

$ make doc
make: 'doc' は更新済みです.

はて?
どうやら zeda/ 下で make doc では更新済みとみなされているようです。zeda/makefile を読むと zeda-makefile-gen というスクリプトを実行していて、本スクリプトのヘルプを見てみると( $ zeda-makefile-gen をそのまま実行)、 zeda/doc/ の中で make を実行するようです。しかし失敗していたので、手動で zeda/doc/ 下で make を実行してみました。

$ pwd #  zeda/doc/ に居ることを確認
{YOUR_DIR}/milib/milib-starter/zeda/doc

$ make
warning: Tag `USE_WINDOWS_ENCODING' at line 14 of file `-' has become obsolete.
         To avoid this warning please remove this line from your configuration file or upgrade it using "doxygen -u"
warning: Tag `DETAILS_AT_TOP' at line 30 of file `-' has become obsolete.
         To avoid this warning please remove this line from your configuration file or upgrade it using "doxygen -u"
warning: Tag `SHOW_DIRECTORIES' at line 98 of file `-' has become obsolete.
         To avoid this warning please remove this line from your configuration file or upgrade it using "doxygen -u"
warning: Tag `HTML_ALIGN_MEMBERS' at line 171 of file `-' has become obsolete.
         To avoid this warning please remove this line from your configuration file or upgrade it using "doxygen -u"

--- (後略) ---

warning がいくつか出ていますが、今度はどうやらドキュメント出力に成功したようです。
doc/ 下に以下のような html/ 、 man/ 、 tex/ といった成果物が出力されていました。

zeda/
└── doc/
    ├── dox.conf
    ├── makefile
    ├── html/
    ├── man/
    └── tex/

  

7. ZEDAドキュメント

出力された ZEDAライブラリのdoxygen形式の html/ ドキュメントを以下に上げておきます。

ZEDA Documentation

  

7.1. ZEDAのインクルード依存関係

ZEDAのdoxygenドキュメント出力からファイル構成を視覚的に見ることができます。
zeda.h というヘッダファイルの依存関係グラフを見ると、このファイルがZEDAライブラリをインクルードするための親玉的な存在であることが分かります。

zeda.hの依存関係

  

7.2. ZEDAライブラリの依存関係

以前 milib のインストールを実行した際に、ソースコードがコンパイルされ、ZEDAライブラリが既に出力されています。
ZEDAパッケージの中の lib/ の中に libzeda.so という共有ライブラリがあると思います。

zeda/
└── lib/
    └── libzeda.so

ldd コマンドでこの共有ライブラリの依存関係を見ておきましょう。

$ ldd libzeda.so
	linux-vdso.so.1
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6
	/lib64/ld-linux-x86-64.so.2

上の表示では、各ライブラリのメモリへロードされる時のアドレス表記は省略しています。
依存関係より、Linuxの仮想動的共有オブジェクトのライブラリ、cライブラリ、リンカライブラリという、Linux上でC言語由来の共有ライブラリを動作させるための最低限の構成で成り立っていることが分かります。

  

8. 例 zListClass を読んでみる

ここから少しだけ ZEDAライブラリ のソースコードを味見してみましょう。
例として、配列型演算などもありますがC標準ライブラリでもよく見るようなデータ型は簡単なので、ZEDAのリスト型データ zListClass の定義を見てみます。C++ の STL(Standard Template Library)コンテナで見たことがある人は読みやすいかもしれません。
これは、 zeda_list.h にほぼ定義が書かれています。

ZEDAでは、双方向循環型のリストをデータ型 zListClass として定義してあるようです。
このリスト型のイメージを以下のように描いてみました。

リスト型は複数データを隣同士でつないで簡単に格納/削除できるようにしたものだそうです。
ZEDAでは要素単位はポインタとデータを持ったノードとして定義されます。
ノードは隣のノードの場所を示すポインタを持っています。zListClass では両隣の双方向のポインタを持たせてあり、図のようにリング状に連なっているようです。隣のポインタはそれぞれprevとnextとして示されています。

zListClass の定義を見てみましょう。

#define zListClass(list_t,cell_t,data_t) \
typedef struct __##cell_t{\
  struct __##cell_t *prev, *next;\
  data_t data;\
} cell_t;\
typedef struct __##list_t{\
  int size;\
  cell_t root;\
} list_t

マクロ関数を使用して構造体定義を内包しクラスっぽく定義しています。
list_t はリスト型の定義名で自由に定義できます。
cell_t はノード型の定義名で自由に定義できます。
data_tはデータ型の定義名でintやcharや自分でtypedefして作成したオリジナルのデータ型など自由に入れられます。
見て分かるようにC++のクラスとは異なりコンストラクタやデストラクタはありません。
格納したデータのメモリ解放はクラスオブジェクト生成したあと別途明示的に書く必要があります。
そのため zListDestroy() というマクロ関数が別途解放処理のために定義されてあります。

では zeda_list.h を使用してリスト型データ zListClass をためしてみましょう。
以下、zeda/example/list/ 内のサンプルコードを参考にして、Double型の値をお尻に次々に追加して双方向循環型リスト作成するサンプルを書いてみました。

#include <zeda/zeda_list.h>

int main(void)
{
  /* double型リストの定義 */
  zListClass( DoubleList, DoubleListCell, double);
  DoubleList dl1;

  /* 1つ目のノードを作成 */
  DoubleListCell dc1;
  dc1.data = 1.0;
    /* 1つ目のノードを初期化してルートとしてリストに格納 */
  zListCellInit( &dc1 );
  dl1.root = dc1;
  zListInit( &dl1 );

  /* 以下同様にノードを作成しリストのお尻に格納していく */
  DoubleListCell dc2;
  dc2.data = 2.0;
  zListInsertTail( &dl1, &dc2 );

  DoubleListCell dc3;
  dc3.data = 3.0;
  zListInsertTail( &dl1, &dc3 );

  /* リストの中身を表示 */
  DoubleListCell *dcp;
  zListForEach( &dl1, dcp )
    printf( "value = %lf\n", dcp->data );

  /* Headノードの確認 */
  printf( "value of Head node = %lf\n", zListHead( &dl1 )->data );

  /* Tailノードの確認 */
  printf( "value of Tail node = %lf\n", zListTail( &dl1 )->data );

  /* 最初から順にノード確認 */
  dcp = zListRoot( &dl1 );
  printf( "1st is Root             = %lf\n", dcp->data );
  dcp = zListCellPrev( dcp );
  printf( "2nd previous from Root  = %lf\n", dcp->data );
  dcp = zListCellPrev( dcp );
  printf( "3rd previous from Root  = %lf\n", dcp->data );
  dcp = zListCellPrev( dcp );
  printf( "4th previous from Root  = %lf\n", dcp->data );

  return 0;
}

このサンプルをコンパイルするときの makefile は以下になります。
前述のとおり端末に環境パスが通っていることが前提となります。

INCLUDE=`zeda-config -I`
LIB=`zeda-config -L`
LINK=`zeda-config -l`

CC=gcc
CFLAGS=-ansi -Wall -O3 $(LIB) $(INCLUDE) -funroll-loops

all : zeda_list_sample
% : %.c
	$(CC) $(CFLAGS) -o $@ $< $(LINK)
clean :
	-@rm -f *.o *~ core

これら zeda_list_sample.c と makefile を同じ場所において以下 make を実行します。

$ make

zeda_list_sample という実行ファイルが生成されたと思います。
リストがうまく生成できたか実行してみます。

$ ./zeda_list_sample
value = 3.000000
value = 2.000000
value of Head node = 2.000000
value of Tail node = 3.000000
1st is Root             = 1.000000
2nd previous from Root  = 2.000000
3rd previous from Root  = 3.000000
4th previous from Root  = 1.000000

zListForEach() は最後に格納したお尻から頭へと順にたどっていくようです。ルートは含まないようです。
格納したdoubleのデータ値をもったリストが無事作成できているようです。

  

  

9. 今回はここまで。

ふぅ〜。
milibチャレンジ第一回としてZEDAライブラリについて見てみました。

ZEDAは他にもツリー構造やI/Oストリームなど興味深いデータ定義が実装されているようです。
C++だと何だそんなの簡単そうと浅く思えるものも、Cでプリプロセッサやポインタのテクニックを駆使して実現するのはプログラムのアイデアとして非常に奥深く勉強になります。

中でもZTKフォーマットに関する機能はのちのち重要になってきそうです。
ZTKとは何でしょう?という所も含めて次回以降見ていきたいです。

では。

milib環境を構築してみよう

こんにちは。だいCです。

ロボットのプログラミングしたいよーって人います?
今回からロボットのプログラミングを始めてみようと思います。

自分は「ロボットのプログラミングって何ですか?」って思うことがよくあります。

別にロボットのプログラミングに限った話ではありませんが、
本当に作りたいモノのほんの一部の作業をずっと続けていると、あれ?自分は何がしたかったんだっけ…?と見失うことがたまにあります。やりたいことの迷子になります。

プログラミングも迷子に陥りがちで、
プログラム自体を作りたいモノの一部とみなして「自分はいま〜を作っているゾ!」って思いながらプログラミングしないと作業に埋もれて本来の目的を見失いがちです。
「コードを書いて動かすだけの泥臭いクソつまらない作業をしている」と思った途端、モチベーションはダダ下がりです。自分の人生にとって無駄だと我慢して苦しみながらプログラミングしている人はかわいそうです。
無駄だという計算を走らされ続けて文句もいわず頑張ってくれている計算機もかわいそうです。

ということで、ここでは「ロボットを作るゾ!わーい!」と楽しい気持ちで始めましょう。

 

1. 対象読者

「〜してみよう」と誘っておいてなんですが、人に伝える文章という意味で、読者は以下の知識がある人を前提としています。

  • Linux OSのプログラミング インタフェースの使用経験がある人
  • git、GitHubを使ったことがある人

これらの知識について自分も素人なので恐縮ですが、もし書いてあることに間違いがあれば気軽にコメント頂けると嬉しいです。

 

2. milibってなんですか?

「運動知能研ライブラリ = Motor Intelligence lab. LIBrary」を縮めて「milib」と書いた名前のようです。
自分は「えむ あい りぶ」と読んでいます。

かつて日本には「運動知能研究室」という研究室があったそうです。
このライブラリはその研究室で開発されたものみたいです。
まだ詳しく知りませんが、ロボットのプログラミングにおいて便利かつ強力な計算ライブラリのようです。あまり大きな声では言えませんが、これを解読し使いこなすと、ひょっとすると世界を変えるかもしれない…と一部で噂されているかもしれないようです。

全然よく分からないので、とりあえず使ってみましょう!



3. 環境構築するPC環境

今から環境構築するPC環境をメモしておきます。
OS環境はUbuntu 18.04です。以下コマンドでの確認になります。

3.1. PC

Intel(R) NUC8i7BEH

$ sudo lshw
...
    詳細: デスクトップコンピューター
    製品: NUC8i7BEH (BOXNUC8i7BEH)
    ベンダー: Intel(R) Client Systems
    バージョン: J72992-305
    シリアル: G6BE91500HCB
    幅: 64 bits
...

lshwコマンドの -short オプションでCPU、メモリ、グラフィック等のクラスと詳細をざっくり確認できます。

3.2. CPU

processor      Intel(R) Core(TM) i7-8559U CPU @ 2.70GHz

以下のように/proc/cpuinfoをのぞいても確認できるそうです。

$ cat /proc/cpuinfo

3.3. メモリ

memory         64KiB BIOS
memory         32GiB システムメモリー
memory         16GiB SODIMM DDR4 同期 2400 MHz (0.4 ns)
memory         16GiB SODIMM DDR4 同期 2400 MHz (0.4 ns)
memory         256KiB L1 キャッシュ
memory         1MiB L2 キャッシュ

以下のように /proc/memoinfo をのぞいても確認できるそうです。

$ cat /proc/meminfo
MemTotal:       32749116 kB
...

3.4. グラフィック

display        CoffeeLake-U GT3e [Iris Plus Graphics 655]

lspciコマンドでPCIバス接続されたグラフィック確認することもできるそうです。

$ lspci
...
... VGA compatible controller: Intel Corporation CoffeeLake-U GT3e [Iris Plus Graphics 655] (rev 01)
...

3.5. ディスク

1TBのSSDがささっています。空き容量は700GBくらいあります。

3.6. OSとディストリビューション

$ lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 18.04.6 LTS
Release:	18.04
Codename:	bionic

3.7. カーネル

$ uname -r
5.4.0-72-generic

3.8. コンパイラ

GitHub上でチラリとmilibリポジトリ内のmake関連のコードを覗いてみるとデフォルトでは gcc をコンパイラとしているようです。clang などではないようです。

$ gcc --version
gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.



4. 環境構築のためのパッケージmilib starter

GitHubを見ると、milibを使える環境を自動で構築してくれる「milib-starter」というパッケージを、既に作ってくれているようです。

https://github.com/mi-lib/milib-starter


4.1. milib starter のクローン

まずこのリポジトリを自分のローカルにクローンしてみましょう。

自分はとりあえず 「milib」 というディレクトリを作っておきました。
この中にライブラリ群を入れていこうと思います。

$ mkdir milib  # milibディレクトリを作成
$ cd milib     # milibディレクトリに移動
$ pwd          # パスを確認
/home/{自分の好きなディレクトリ}/milib

milib starter をクローンします。

$ git clone https://github.com/mi-lib/milib-starter.git

クローンできたら中身を確認します。

$ cd milib-starter # クローンしたmilib-starterへ移動
$ pwd              # パスを確認
/home/{自分の好きなディレクトリ}/milib/milib-starter
$ ls               # 中身を確認
README.md  config  deb  scripts

milib starterのディレクトリ構成を見てみましょう。

$ tree
.
├── README.md
├── config
├── deb
│   ├── dzco-dev_1.4.5-debian1_amd64.deb
│   ├── liw-dev_1.2.7-debian1_amd64.deb
│   ├── neuz-dev_0.2.6-debian1_amd64.deb
│   ├── roki-dev_1.6.20-debian1_amd64.deb
│   ├── roki-fd-dev_1.4.4-debian1_amd64.deb
│   ├── roki-gl-dev_1.6.20-debian1_amd64.deb
│   ├── zeda-dev_1.6.16-debian1_amd64.deb
│   ├── zeo-dev_1.10.3-debian1_amd64.deb
│   ├── zm-dev_1.3.22-debian1_amd64.deb
│   └── zx11-dev_1.2.7-debian1_amd64.deb
└── scripts
    ├── milib-install
    ├── milib-rebuild
    └── milib-uninstall

README.mdがありますね。


4.2. milib starter の README

まずはREADME.mdを読んでみます。
以下、自分の言葉で勝手に日本語に訳して書いてみています。

  

milib starter

Copyright (C) Tomomichi Sugihara (Zhidao) since 1998


[なんですか?これ]

このスターターキットにはインストーラ、アンインストーラ、milibを再ビルドするスクリプトが入っているよ。これらは Ubuntu で動くよ(もしくは Debian でもイケるかも。試したことないけど)。

milib はロボットのコントロールやシミュレーションを開発するライブラリを集めたものだよ。ライブラリには以下が含まれるよ:

ZEDA – 初歩的なデータとアルゴリズム
ZM – 手軽な数学ライブラリ
neuZ – ニューラルネットワークのライブラリ
DZco – ディジタル制御のライブラリ
Zeo – Z/幾何学・光学計算ライブラリ
RoKi – ロボット キネティクス ライブラリ(キネマティクスではなくキネマティクス)
ZX11 – Xウインドウシステムのインタフェースライブラリ用ラッバー
LIW – Linuxシステム依存の操作を支援するウィザード
RoKi-GL – ロボット キネティクス ライブラリ: OpenGLによる可視化


[インストール方法 / アンインストール方法]

インストール

もしライブラリのインストール先を特定の場所にする必要があるなら config 内の PREFIX を編集してね。

% milib-install [clone/deb]

コマンドラインでのオプションの意味は以下のようになっているよ。

clone: ライブラリのソースコードをGitHubのリポジトリから取ってくるよ
deb: ディレクトリdeb/以下のDebianパッケージからライブラリをインストールするよ。
もしオプションを省略したら、Git情報なしでソースコードをリポジトリからダウンロードするよ。

アンインストール

以下を実行してね:

% milib-uninstall [deb]

deb オプションはDebianパッケージからインストールしたときだけ有効だよ。


[つかいかた]

もし必要なら自分の環境変数 PATHLD_LIBRARY_PATH を設定しておいてね。
Bourne shell ファミリー (bash, zsh, etc.) なら以下のように設定するよ。

% export PATH=$PATH:$PREFIX/bin
% export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PREFIX/lib

C shell ファミリー (csh, tcsh, etc.)なら以下のように設定するよ:

C shell ファミリー (csh, tcsh, etc.)なら以下のように設定するよ:


[お問い合わせ]

zhidao@ieee.org


ふむふむ。

インストールの選択肢としては、
「GitHubからクローン」か「debパッケージを展開」か「Git情報なしダウンロード」
があるみたいですね。

GitHubには最新版が上がっていそうなので、GitHubからソースコードをクローンして取ってくることにします。
とりあえず、「インストール」に書かれた手順を試してみて、自分が作成しておいた「milib」ディレクトリ内にライブラリ群をクローンしてみましょう。


4.3. milib starterによる自動クローンとインストール

まず「config」ファイルを適当なテキストエディタで開いて、中にある変数 PREFIX に対し自分が作成しておいた「milib/」のパスを書いておきましょう。以下編集後の「config」 ファイルの中身です。

PREFIX=/home/{自分の好きなディレクトリ}/milib 
LIBS="zeda zm neuz dzco zeo roki liw zx11 roki-gl roki-fd"

そして、「 scripts/」 ディレクトリ内にあるシェルスクリプト「milib-install 」でクローンを実行してみます。

$ pwd                    # 現在scriptsディレクトリにいることを確認
/home/{自分の好きなディレクトリ}/milib/milib-starter/scripts

$ ./milib-install clone  # 実行

するとクローンする前に、何やら色々aptパッケージをインストールし始めました。わ〜聞いてないよ〜!
(あとで「milib-install」の中をテキストエディタで覗いてみると、インストールしたのは以下でした)

git wget unzip rename make gcc fakeroot
libxml2-dev xorg-dev libtiff-dev libjpeg-dev freeglut3-dev

そして、最後に以下のメッセージが出てきて終了しました。クローンはできていないようです。

--- (前略) ---
libxml2-dev:amd64 (2.9.4+dfsg1-6.1ubuntu1.4) を設定しています ...
./milib-install: 12: .: Can't open ./config

どうやら config ファイルが置いてある階層から実行しないとダメみたいですね。
scripts ディレクトリの一個上の階層へ戻って、再度スクリプト「milib-install」でクローンを実行してみます。

$ pwd                            # milib-starter/ にいることを確認
/home/{自分の好きなディレクトリ}/milib/milib-starter

$ ./scripts/milib-install clone  # 実行

すると今度は以下のメッセージが出てきて終了しました。クローンはできていないようです。

--- (前略) ---
アップグレード: 0 個、新規インストール: 0 個、削除: 0 個、保留: 3 個。
installing libraries and tools under /home/{自分の好きなディレクトリ}/milib ...
making directory /home/{自分の好きなディレクトリ}/milib/bin ...
making directory /home/{自分の好きなディレクトリ}/milib/include ...
making directory /home/{自分の好きなディレクトリ}/milib/lib ...
Add /home/{自分の好きなディレクトリ}/milib/bin into your PATH by
  export PATH=/home/{自分の好きなディレクトリ}/milib/bin:$PATH
for Bourne shell family (bash, zsh, ksh, etc.), or by
  set path = ( /home/{自分の好きなディレクトリ}/milib/bin $path )
for C shell family (csh, tcsh etc.).

「milib/」 ディレクトリの下を見ると 「bin/」「include/」「lib/」という名前の空のディレクトリが作成されていました。ここがインストール先になるようです。

どうやら README.md の [つかいかた] に書かれていたとおり、これら「bin」「lib」のディレクトリパスを環境変数「PATH」と「LD_LIBRARY_PATH」に追記しておかないとインストールできないようですね。[つかいかた]ってこのスクリプト「milib-install」の使い方のことだったんですかね。てっきりインストール後のライブラリの使い方のことだけかと思っていました。

では以下のように「PATH」と「LD_LIBRARY_PATH」に追記しておきます。

$ pwd                    # milib-starter/ にいることを確認
/home/{自分の好きなディレクトリ}/milib/milib-starter

$ . ./config             # configファイル内の設定を現在の端末に反映。
$ echo $PREFIX           # 変数PREFIXが反映されていることを確認
/home/{自分の好きなディレクトリ}/milib

$ export PATH=$PATH:$PREFIX/bin
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PREFIX/lib

$ echo $PATh             # 確認
--(略)-- :/home/{自分の好きなディレクトリ}/milib/bin

$ echo $LD_LIBRARY_PATH  # 確認
--(略)-- :/home/{自分の好きなディレクトリ}/milib/lib

さてここまで書いてみて再度スクリプト「milib-install」でクローンを実行してみます。

$ ./scripts/milib-install clone

すると今度はクローンし始めました。
と同時にコンパイルまで走り、実行ファイルやライブラリなどを自動でビルドし始めました。

installing libraries and tools under /home/{自分の好きなディレクトリ}/milib ...
/home/{自分の好きなディレクトリ}/milib/bin ... valid path.
/home/{自分の好きなディレクトリ}/milib/lib in LD_LIBRARY_PATH.
cloning zeda ...
Cloning into 'zeda'...

--(中略)--

make[1]: ディレクトリ '/home/{自分の好きなディレクトリ}/milib/milib-starter/zeda' から出ます
/home/{自分の好きなディレクトリ}/milib/milib-starter
cloning zm ...
Cloning into 'zm'...

--(中略)--

make[1]: ディレクトリ '/home/{自分の好きなディレクトリ}/milib/milib-starter/zm' から出ます
/home/{自分の好きなディレクトリ}/milib/milib-starter
cloning neuz ...
Cloning into 'neuz'...

--(中略)--

make[1]: ディレクトリ '/home/{自分の好きなディレクトリ}/milib/milib-starter/neuz' から出ます
/home/{自分の好きなディレクトリ}/milib/milib-starter
cloning dzco ...
Cloning into 'dzco'...

--(中略)--

make[1]: ディレクトリ '/home/{自分の好きなディレクトリ}/milib/milib-starter/dzco' から出ます
/home/{自分の好きなディレクトリ}/milib/milib-starter
cloning zeo ...
Cloning into 'zeo'...

--(中略)--

make[1]: ディレクトリ '/home/{自分の好きなディレクトリ}/milib/milib-starter/zeo' から出ます
/home/{自分の好きなディレクトリ}/milib/milib-starter
cloning roki ...
Cloning into 'roki'...

--(中略)--

make[1]: ディレクトリ '/home/{自分の好きなディレクトリ}/milib/milib-starter/roki' から出ます
/home/{自分の好きなディレクトリ}/milib/milib-starter
cloning liw ...
Cloning into 'liw'...

--(中略)--

make[1]: ディレクトリ '/home/{自分の好きなディレクトリ}/milib/milib-starter/liw' から出ます
/home/{自分の好きなディレクトリ}/milib/milib-starter
cloning zx11 ...
Cloning into 'zx11'...

--(中略)--

make[1]: ディレクトリ '/home/{自分の好きなディレクトリ}/milib/milib-starter/zx11' から出ます
/home/{自分の好きなディレクトリ}/milib/milib-starter
cloning roki-gl ...
Cloning into 'roki-gl'...

--(中略)--

make[1]: ディレクトリ '/home/{自分の好きなディレクトリ}/milib/milib-starter/roki-gl' から出ます
/home/{自分の好きなディレクトリ}/milib/milib-starter
cloning roki-fd ...
Cloning into 'roki-fd'...


--(中略)--

ake[1]: ディレクトリ '/home/{自分の好きなディレクトリ}/milib/milib-starter/roki-fd' から出ます
/home/{自分の好きなディレクトリ}/milib/milib-starter
completed.

標準出力を見てみると、
zedaライブラリだけ app/ ディレクトリがない というエラーが出ているのと、
各ライブラリ共通してclean する時に削除するファイルがない というエラーが出ているのと、
各ライブラリ共通してコンパイルするときに最初は config がない というエラーが出ているようです。
が、これらはインストールにおいて致命的なエラーではなさそうです。

各ライブラリ共通して

  • ライブラリ
  • ヘッダファイル
  • ツール
  • アプリケーション

がインストールされているようです。

また、インストールされたライブラリのバージョンと、依存する各ライブラリのバージョンも標準出力されています。自分の場合、インストールされたものは以下のようです。

インストールされた
ライブラリ
インストールされた
バージョン
依存ライブラリの最低限必要なバージョン
libzeta libzm libneuz libdzco libzeo libroki libliw libzx11 libroki-gl libroki-fd
libzeta 1.6.18
libzm 1.3.22 1.6.4
libneuz 0.2.6 1.6.4 1.3.13
libdzco 1.4.6 1.6.4 1.3.13
libzeo 1.10.3 1.6.4 1.3.13
libroki 1.6.20 1.6.14 1.3.13 1.10.2
libliw 1.2.7
libzx11 1.2.7 1.6.4
libroki-gl 1.6.21 1.6.16 1.3.13 1.9.16 1.6.16 1.2.7 1.2.7
libroki-fd 1.4.4 1.6.4 1.3.13 1.9.16 1.6.16

「milib」ディレクトリに戻ってみて、インストールされたものをざっと確認すると以下のような構成になっていました。

.milib/
├── bin/
│   ├── cad2ztk
│   ├── ...
│   └── zxwatch
├── include/
│   ├── dzco/
│   ├── liw/
│   ├── neuz/
│   ├── roki/
│   ├── roki-fd/
│   ├── roki-gl/
│   ├── zeda/
│   ├── zeo/
│   ├── zm/
│   └── zx11/
├── lib/
│   ├── libdzco.so
│   ├── libliw.so
│   ├── libneuz.so
│   ├── libroki-fd.so
│   ├── libroki-gl.so
│   ├── libroki.so
│   ├── libzeda.so
│   ├── libzeo.so
│   ├── libzm.so
│   └── libzx11.so
└── milib-starter/
    ├── deb/
    ├── dzco/
    ├── liw/
    ├── neuz/
    ├── roki/
    ├── roki-fd/
    ├── roki-gl/
    ├── scripts/
    ├── zeda/
    ├── zeo/
    ├── zm/
    └── zx11/

ソースコード群は milib/ 内に配置するつもりでしたが、結果として milib-starter/ の中に配置されました。
ライブラリをまずは使ってみるだけなので、ディレクトリ構成としてはこちらの方が見やすく、結果オーライだったかもしれません。

サイズも見ておきます。

$ pwd
/home/{自分の好きなディレクトリ}/milib

$ du .
...
79552	.  # kB(キロバイト)

ソースファイルとオブジェクトファイルも含んで80MBくらいのようです。
インストールされたライブラリ達「bin」「include」「lib」のみの合計サイズを見ておくと

$ du --total bin include lib
...
4492	合計

だいたい4.5MBくらいのようです。

ふぅ〜。

ということで環境構築としてソースコードを取ってきてビルドしてライブラリをインストールする所まで出来たようです。
お疲れ様でした。
次回はライブラリを使ってみましょう。

それではまた。

2脚ロボットの要件定義

こんにちは。だいCです。

ここに書いているものは、日頃の自分の考えを整理して後で見直すためのブログになります。

今回のお題は「2脚ロボットの 要件定義」になります。

要件定義とは、

  • ユーザや 利用客側の持っている、「あれが欲しい」「これして欲しい」という製品や、サービス、機能、価格など、利用者からの要望・要求(ニーズ)
  • 作り手や 提供者側の持っている、「(事象やモノ)〜が存在する」「これこれできる」という実現性(シーズ)

の要求と実現性を書き下し、照らし合わせ、
要求が必須かどうかの優先度、再現・理論的な証明・試作・設計・テストができるかどうかの可能性、期間や費用のボリュームと妥当性など 実現度合いを定義して、
「ではこれを〜(何時)〜までに〜(費用)〜で完成 させましょう」
と、商品開発の目標を定かにするフレームワークの一つです。

本記事では、2脚ロボットに限定し、
ざっくり思いつく程度で良いので、要件定義を試みてみます。

Contents

1. ニーズとシーズ

商品開発の前提として、まずはここから話を始めます。
要件定義の要(かなめ)となる、ニーズとシーズについて、自分なりの考えを書いておきます。
あまりに幼稚な内容かもしれませんので、
この1章を飛ばして2章以降から読み進めてもらって構いません。
 

1.1. ニーズ(要求)ベース

ニーズを叶えるための技術を選択
ニーズを叶えるための技術シーズの選択。人と同じ機能を多く持つ技術ほど適用しやすい


商品開発プロジェクトにおいて、企業は顧客の要求をトップダウンに考えて様々な課題を明らかにし、最適な解決方法を提供できるように課題ごとに目標(目的)と計画を決めて効率よく制作を進めることが理想的だと聞きます。
どんな人でも要求が叶えられる事は貴重です。要求実現には対価を支払うだけの価値があります。価値は要求の度合いや実現困難な度合いに応じます。
要求を持った人達は誰でも顧客になり得る可能性があり、顧客それぞれの抱える要求をうまく叶える解決方法を売って実現・提供できれば商売になるということです。拡大解釈すれば、人々の抱える問題は何でも商売になるかもしれないのです。
 

1.1.1. 人々の問題→要求と価値

要求と価格
テキ屋

要求の度合いが大きいほど、高い価値があると書きました。
はてさて要求の度合い、高い価値とは何かと思いますね。
原価企画の考えだと、能力(機能や精度)や品質や信頼性、納期などの要求を考えて、先にその要求に見合う市場価格(予想競争市価)を予測して収益を決めてから、そのあと見合った原価を決めたりするそうです。現行市場に似た製品がある場合には、現行の似た製品の原価(成行原価)を元に、そこからコストダウンの削減額を決めて原価を決めたりするそうです。原価企画の考えだと、この市場価格が価値に当たるという事のようです。
価値工学の考えでは物の原価よりも機能を重視し、価値 = 機能 / 原価 とするそうです、機能はもちろん要求に含まれるものです。
たとえば多くの人々が叶えて欲しいと思う要求・問題ほど高い価値があるとも言えるかもしれません。また、たとえ今は少ない人数の要求でも今後の人類進歩・存亡に関わる問題であれば高い価値があるとみなされるかもしれません。
価値が高いかどうかで、やる/やらないを決めるのはイヤらしいと言われるかもしれませんが、生き残りを賭けた企業にとっては重要な判断材料です。人々の抱える問題を解決することから、企業にとって利益を生む商品につながるという論理は、意思決定の重要な指標になります。
 

1.1.2. 人の問題解決手段としての代理人→人型ロボット

では、人々の抱える問題を解決して欲しいという、まずは漠然とした要求を起点にして、その要求を叶えるための実現手段を考えてみます。まずはあまり悩まず深く考えず要求分析も課題特定もせず詳細もとりあえず置いておきましょう。具体的な実現性(できること、技術的な確証)もまずは無視します。
人々の抱える問題を解決する実現手段として、自分自身の手で解決したい、解決するしかないという場合を除いて、
人の手を雇って代わりに解決してもらうという案が一番シンプルですぐに挙げられます。
「代わりに同じことができる人がいれば…」
とすると代わりに解決してくれる人を用意するにはどうすればよいかという困難が生じます。そこで次に、人の手を借りずに実現する手段はないか?と考えられるでしょう。とりあえず実現性は一旦無視して安易な発想として、ロボットを代用できないか?という案が挙げられそうです。実現性の困難さえ無視できれば手段として安易に挙げられます。様々な場面でロボット適用が挙げられるでしょう。
「代わりに人と同じことができるロボットがあれば…」
人の抱える問題は人に任せるもので、機械で実現可能ならば人と全く同じことができる「人型ロボット」がいればなぁ、、と発想するのは自然だと思います。問題を置き換えやすいと思います。
 

1.1.3. 人型ロボット→専門機械→前提の変更・単純な方法?

しかし実際問題をつきつめて、あーでもないこーでもないと考え試し続けて、満足する解決方法発見にまで至ってみると、結局、問題となる作業や組織、システム自体の前提から無くしてしまえば単純な方法(機能・装置など)だけで解決する、という結論に行き着くかもしれません。単純な方法で解決できれば余計な手間もかからず無駄が少なくて済みます。人型なんて、ましてやロボットなんて全く要らなかった、ということは実際多いと思います。
要求ベースで進めると初めの方は
「ロボットがあれば…」
となって次に
「要求さえ満たせば良い。要求を満たすだけの機能を持った機械があれば…」
となって最終的に
「真の要求さえ満たせば良い。真の要求さえ満たすように前提から変えれば単純な方法で済むんだ」
という結論になります。
この流れを覚えると、初めの「ロボットがあれば…」という考えはもう無くしてしまい、単純な方法・装置はないかを探すラインから企画を練る方が良いように思われます。
確かに、単純な方法・装置であれば低コスト・低リスクでも済むことが多いので、開始からその方法を探すだけに傾倒しても悪くはないと思います。しかし良いとも言い切れません。結果は単純ですが過程はどうでしょうか。実際に単純な方法・装置発見に至るまでどれくらい費やすか、を計算に入れるべきです。要求分析と課題特定と方法探索を繰り返して時間と労力をかけていると、それ自体が長年かかる研究テーマに匹敵します。またターゲットを絞って要求や課題を特定すればするほど適用範囲は狭くなり使用場面も少なくなります。汎用性がなくなり使い回しが効かなくなります。要求する人の数も減ります。多くの人々の抱える問題が対象でなくなると、対価の見込みも限られてきます。
 

1.1.4. 要求における人型ロボット提案のメリット(安易だがシンプルでスリムな発想ができる)

人と同じことができるロボットがいれば、それはそれで単純な方法として済むわけです。ここではロボットは問題解消の実現手段と捉えておきます。
人型ロボットという実現手段を選択するメリットとは何かと言われると、人と似ていて、人と同じ動きができて、人と同じ動きをすぐに教示できてすぐ導入できることがメリットであり、運用がすぐに終了しても、汎用性があるおかげで別の新たな作業へすぐ導入できることがメリットなのです。
別の作業への導入に対応する際、ロボット会社としてはロボットをゼロから作り直したり選択したりする必要はなく、即時導入と汎用性を上げる改良にのみ注力すればいいので、改良開発の方針を決めるのが比較的ラクになるのです。これをカタカナでイイ感じに述べるならば、「シンプルでスリムな発想ができる」のがメリットだと言えるでしょうか。人型ロボットが要求される由来には、このような背景があると考えています。
 

1.2. シーズ(研究・開発)ベース

一方、人々の問題解決の要求をベースとしロボット実現を求める動きとは異なり、一部の人達の創造的欲求からロボットを求める別のモチベーションがあります。
物理・化学・数理現象としてこの世界の新事実を発見したい、発見し知見が得られた成果を利用・応用したい、モデル化したい、制御して望む結果を得たい、新たな技術を具現化したい、というモチベーションです。未知への探究、不可能を可能にする英知・技術的欲求などそれらを集約し体現できる対象としてロボットを求める動きです。
もしうまくいけば問題解決方法として新たな選択肢を与えてくれるわけで、新たな技術やビジネスを生む種(シーズ)となります。ロボットはシーズの塊であり、安易な要求であっても技術的な実現手段としてすぐに候補に挙げられるため、基礎研究や基礎技術開発の試作から応用・実用化転用へと発展していくことが望まれやすいのです。
ロボットの研究者やエンジニアによっては、「自身のゴールは世のため人のため、困った人々のニーズに応えることです」なんて表向きに宣言する人も、内心実はそれが一番のモチベーションではなく、単純に作りたい!世界をもっと知りたい!新しいものを作って自分を満足させたい!という欲求や、技術的困難なモノやまだ世にないモノを作ってドヤ顔したい!すげーって言われたい!という欲求が根源にあったりするのではないかと思います。Yes!Make!Yes!そして…褒めて!もっと褒めて!お金ちょうだい!1兆円!というモチベーションです。
少なくとも自分にはその欲求は少なからずあります。
根源的な欲求は人それぞれだと思いますが、創造的な欲求を満たすミステリーと可能性がロボットにあるおかげで、新たに技術が発展するという考えもあると思います。
 

1.3. ニーズとシーズのマッチング

ニーズとシーズのマッチングのイメージ

 

1.3.1. シーズ側の一方的な製品開発だけではゴミになる?

シーズ側から一方的に「ロボットを作らせてくれー」とロボットを作って、ニーズを持った利用側に「ええやろこれ!欲しいやろ!作ったで!ドヤ!!」と提示しても、要求に合致してなければ利用側からは「要らん!!!」と言われゴミ扱いされてしまいます。研究・開発費を何億円も使って育てた種が一瞬でゴミとして捨てられ結局何も残らなかった、という事例はよくある話です。ロボットは開発費にお金がかかりますが、プロジェクト成果がそれだけの価値があったのか分析されていないことが多いのではないでしょうか。ゴミとされる過程で開発元の組織は荒れまくり身体的にも精神的にも壊れて思考ごと腐ってしまうというのは非常に嘆かわしいことです。腐ったミカンこと、だいCです。
 

1.3.2. 要求を叶えられる要素技術(実現性)はある?

「ロボットよ助けてくれー」というニーズと、「ロボットを作らせてくれー」というシーズを生む動きがうまくマッチすると、ロボットを作る意義が強くなります。お金が行き来して商売として成立し上手く循環すれば継続的な事業になります。作り手側としてロボットの実用化を目指したいのであれば、ニーズとシーズのマッチングの課題に取り組む人が必要なのです。
そもそもシーズがなければ、つまり現状の人型ロボットで実現できるだけの要素技術がなければ絵に描いた餅です。要素技術が確立されていなければ無いものねだりと同じでしょう。一方、開発するにしろ研究するにしろ、ロボットで実現して欲しいという先のニーズが揃っていることも重要だと思います。ニーズに対し、今実用化できるレベルはどこまでなのか?何が技術として必要なのか?を明確にしてくれる人が圧倒的に足りていないと思うのです。そういう方は技術も需要もわかるエジソンみたいな人じゃないかと自分は思っています(エジソンはそんな人じゃない?)。
 

1.3.3. 市場調査とコンセプト検証

何か新しく売れる物を作り初めようとしたことがある人であれば、試作時の検討で経験したことがある人もいるかもしれません。たとえば、すでに市場があると分かっている分野では調査をもとに割と現実的な予測ができます。一方、まだ市場がない未開拓分野の場合、要求分析とコンセプト段階での試作検証が肝心になります。たとえば、完璧ではなくても良いので、コンセプト段階で段ボールで試作モデルを組み、試作モデルを使ってペルソナ(仮定する要求を持ったユーザ)の利用シーンを考えて、ユースケースを洗い出してみます。また、コンセプトを元にアンケート調査も行い、あらゆるターゲット層に当たりをつけて統計的にニーズを調査します。その結果、現時点での試作構想段階ではニーズが無い、要らない、と分かるかもしれません。そしたら諦める、、のではなく、ではどのようになれば欲しいとなるのか?当てはめたシーンは適当か?不十分な点をつきつめて改良点や将来の方向性を見つけ構想を練り直します。そして作りたいものを十分なニーズがあるものへ近づけるための課題に落としていくのです。
どのニーズに当てはめてどの課題を進めるかは作り手次第です。ニーズからの選択ではなく、シーズからの選択です。
 

1.3.4. 試作→試作テスト→先行品の試験販売→改良点調査

ニーズがありそうだとなると、今度は「売れる」につながる商品試作モデルを作って売り「儲る」というサイクルを継続できるようにします。事業となるビジネスモデルを考案・構築していきます。「高確率で儲る」と分かると先行投資をしやすくなり、さらにアルファ版・ベータ版として先行品の生産ができます。先行品ができると特定顧客へ試験販売をして試用してもらい課題調査します。実際に改良点が分かり修正の目処が立ち、同時に商品価値があり利益回収の目処が立つと、量産化・一般販売…と進めても大丈夫だと分かるわけで、さらに量産開発への資金を投じやすくなります。
 

1.3.5. 量産試作→量産テスト→製造→リリース→がっちり

そして実際に量産され、一般向けに販売され世に出回ると、多くの人がニーズを満たしたいと買い求め、ブームが起これば普及し、さらに新たなニーズも生まれるでしょう。社会に普及すると、これを作ったら売れる!という実績が示されるわけです。後追いで参入する者も出てくるでしょう。市場が生まれ、世の中に変革をもたらすことができるかもしれません。
こうしてビジネスとして成長した中で、技術的なハードルをいち早く越えることができ、かつ先行者として市場をつかみ、利益を安定して確保することができれば、資金的に余裕が生まれます。余裕が生まれると、優秀な人材を集め、さらに技術投資して新しいシーズをもっと生むことができるでしょう。
開発費をどんどん使っても回収できるわけで、作り手の「ロボットを作らせてくれー」という願いは大手を振って叶えられ、メーカーの楽園が出来上がるのでした。めでたしめでたし。

と、ここまで書いた内容はあくまで自分の描いた幼稚なサクセスストーリーです。実際はそんなに簡単ではないことは言うまでもありません。
現在産業界を切り拓いている新しい企業は、このような自分達の描く未来予想図の実現に成功しているのだと思います。元々は、新規性があるかも分からない基礎研究・要素技術がきっかけだったかもしれません。しかしその技術において世の中には未だ無い価値を見つけ出すことができて且つニーズがあるのであれば、それは美味しい果実を生む貴重な種(シーズ)であり、果てはメーカーの楽園を築けるチャンスだと思います。もっと企業が挑戦していけば、世の中に希望を与えられると思います。希望がないと、基礎研究・要素技術に携わる人達の心はどんどん腐ってしまうようにも思えます。
 

2. 2脚ロボットを実用化したい

2脚ロボットを実用化したい

 

2.1. 実用化させて欲しい

自分はロボットの会社に勤めているのですが、入社当時からずっと常日頃「売れて使える二足歩行の人型ロボットを作るにはどうずれば良いか」と考え続けています。単純に自分の願望として実用化したいのです。実用化するのが夢なのです。
でも会社としては「作れるかどうかも分からないし使えるか売れるかどうかも分からないものより、まずもっと確実に使えて売れるものを作って売ってくれ」というわけです。目先に見えているニーズや確立された市場に乗れば売れることはある程度分かっているため、優先順位は勝率の高い順・安定順になります。先の見えない新しいロボットを開発するのは金がかかるだけのリスクなのです。ただし誤解がないように。会社の中の人が皆作りたいという意思が無いわけではなく、会社として安定するように仕方なく目の前の市場に目を向けているのです。
「二足歩行の人型ロボットは絶対売れますよ!」と言っても、世に出ている人型ロボットの現状を見られると納得してもらえません。先程描いたような道筋が見えないからです。
「だったら道筋を描かねば…」と考えて自分はこのブログを書いてみてるわけです。どんなプロジェクトでもこのような企画資料を考える人は大変ですよね…と今思ってます。
 

2.2. 要件定義の道筋を立てる

人型ロボットの イメージといえば四肢五体…手足、頭と胴体を 持ったリンク型のロボット。
特に両手両足の 運動に注目してみると、

両手を使って作業をし、両足を使って移動する。

というイメージが湧いてきます。
人型というだけあって、モデルの元となる人の、その見慣れた普段の行動が イメージになっているとも言えるでしょう。
 

2.2.1. 人の代わりに肉体労働をして欲しい

人の手足の作業には、肉体的な負荷を伴う作業がほとんどです。
中でも肉体労働は、手足を使った作業がほとんどといえるでしょう。
現代社会では多くの場面で肉体労働を必要としていることは知っての通りです。
肉体労働は大変だ、知的労働にシフトしよう、と安易に肉体労働を知的労働と比べたり置き換えたりするのは多少疑問があります。逆に、知的労働は大変だ、肉体労働にシフトしよう、と考えても良いでしょう。なぜ肉体労働が大変だといえるのでしょうか?ちょっと考えてみます。
 

2.2.2. 肉体労働の抱える問題

肉体労働の抱えている問題とは何か?を明確にしておきます。
例えば疲労です。日々生活において肉体疲労で余力を失って、精神的余裕が保てずツライという人もきっといるでしょう。過労になると深刻な問題です。
他にも例えば、一人あたりの作業量の物理的な限界です。技術の進歩と暮らしの変化とともに、職種も新たに増え、従来から在る職種においても仕事内容が多様化し、働く人数に対する仕事の作業量も大幅に増えてきた面があります。廃止された職業や仕事も多くあると思いますが、新たに増えた分と比較しても増加傾向にあるのは分かります。一人あたりの肉体労働にはどうしても空間的・時間的な作業量の限界があります。よって現実として作業量が増えたことによって、並行して働く人数も増えなければ、肉体労働には限界が生じるといった問題があります。
また、頭の中だけの作業と異なり、肉体を酷使する作業は労働安全衛生上、常に管理対象となります。場合によっては人命に関わるリスクを伴うため、現場管理の責任は重いという問題もあります。
まとめると、

  1. 疲労
  2. 一人あたりの作業量の限界
  3. 安全衛生管理の負担が大きい

これらが肉体労働につきまわる問題として挙げられます。

2.2.3. ロボット代行による解決の提案

もし社会に人と同じ作業ができるロボットが存在したら、
肉体労働をさせている 現場の責任者達は、労働者達の安全や 衛生管理から解放され、過労や危険回避など責任の重い管理に苦しむことがなくなるし、
肉体疲労で生活に 支障をきたしてた人々も、疲労から解放され 身体的健康を取り戻し、余力を精神面に回し心理状態を安定させ、日々くつろぎながら生活を送ることができるでしょう。

人と同じ2本の手、2本の足を持ったロボット、いわゆる人型ロボットが製品として登場し、代わりにきつい作業や面倒な作業など 色々実現できたなら、非常に簡単で分かりやすい要求実現になるかと思います。先に述べたように、シンプルでスリムな発想で済みます。
 

2.2.4. 人型ロボットなら分かりやすい?人型である理由への疑問

一方、人々の問題解決をベースとして、ロボットが 人型であることへの疑問が次々と湧いてきます。
・人型ロボットへの、要求は一体何なのか?
 ロボットの ユーザは一体誰なのか?
 利用されるのはどんなシーン?ユーザの要求とは?
・人型であることは、機能として本来の 要求に適しているのか?
・人型だから出来る事とは何なのか?人型であることの必然性とは?
・脚は必要か?あんなものは飾りでは?車輪で十分 ではないか?
・1台の売値はいくら?サービスとしての値段は?売れる価格とは?収益は?
・開発費に見合う価値があるのか?先行投資するほどの存続価値があるのか?
・継続的な商売・事業にならないと会社として続かない。一瞬のもの珍しさだけではなく。会社の事業につながる商品としてサイクルできるか?
・では実際、いったいどうやって作るのか?

…いろいろ疑問があり過ぎて、「よし!人型ロボットを 会社で作って儲けよう」なんて易々とOK出せません。これら疑問に目を瞑り「赤字になっても構わない!作りたいから作るんだ!」と、人型ロボットの開発に 全力を駆けて挑戦する…、なんてことができる会社は良いですねー、と思います。でも大部分はそうじゃないと思います。巨額の開発費を投じ製品としてリリースできたし 要求も実現できたけど、ただ赤字になるだけなら やりたくない、それが当然の考え方だと思います。
これら疑問が解消され、「人型ロボットのニーズがある!」「売れる!」「作れば儲かるチャンス!」と経営者達が納得し 確証も持てるようにならないと、作り手側のただ作りたい、という一方的な意思だけじゃ、企画を通すのは難しいです。
 

2.2.5. 人型ロボットの商品開発としての研究テーマ

人型ロボットの研究では、「いったいどうやって作るのか?」という 最後に挙げた難題が最大のテーマになっています。ボトムアップに考えて 要素技術から何か出口を探して考えてみる人も稀にいますが、テーマから逸れるのであまり重要視されません。そもそもテーマ設定時でも、成果が出た時点でも、それでもはっきりその先の出口が見えるわけではないので、何の役に立つかなんて問いを挙げても無闇に課題が増えてしまうだけです。
企業というビジネスの立場ならば、研究成果に目をつけて、課題を持った要素技術の段階でも要求ベースから降ってくる疑問に照らし合わせて、もっと出口の探索に手を出す人がいても良いのでは?と、自分は思います。研究者にまで出口の探索を求めるのは酷であり役割が異なるのではないかと思います。会計上では基礎・応用・工業研究、商品開発とは役割が分けてあり、協力関係のもとに互いに情報共有するものだと聞いていますが。産学連携とかグループ会社や部署間を越えた連携といいつつ、役割を分担し協力する体制が本当にできているのか?縦割の壁ばかりではないか?と疑問に思います。互いにですね。
 

2.2.6. 人型ロボット選定への疑問解消に必要なのは要件定義

さて話を戻して、人型ロボット選定の疑問について、まず少しは解答できそうな、以下の疑問から解消すべきかと思います。

・(要求事項)人型ロボットへの、要求は一体何なのか?
・(実現性)人型だと 一体何ができるのか?

この疑問への解答をもしも作ることができたなら、要求に優先度を振って絞り、それを要件定義とし、皆の認める明確な 製品目標を持って設計フェーズに入れます。
ただ漠然と「人型」としてロボットの 要件定義を始めると、人にして欲しいこと、人の代わりに人ができること、などなど…人にとってできることが沢山あるように、「人型」の中には要件が膨大にあると思います。
(法令や規格、ターゲットや現実的費用など制約条件で絞るのも大変です)
今回は人型ロボットの 手足の中でも足の方、両足だけに絞り要件を 定義したいと思います。
両足、言い換えると2脚です。
2脚の要件定義として、

(要求事項) 人が足を使いたいとき、一体どのようなことが要求されるのか?
(実現性) 2脚だと 一体何が実現できるのか?

について以降考えていきたいと思います。
 

3. ターゲット(は敢えて無し)

製品企画を考える時、ターゲットを絞り、要求を絞り、制約条件を挙げ、実現性を考えて 要件定義するものかと思われます。
例えば工場での使用を想定し、工場の種類の中でも機械類・電子機器の製造工場 で使われること、使用者は期間工のお兄さんやおじさんを想定し、、などなどターゲットを絞れば、要求も実現すべきことも絞られます。
ターゲットを選んで差別化を図る、未踏分野をターゲットにして新たな市場を開拓する、、というのはビジネスの戦略として有効な手段だと思います。
しかしここでは、あえてターゲットを絞らないことにします。
人ができることなら何でも、、「汎用型」と位置づけておきます。
2脚ロボットの汎用性を生かしたいのです。
そもそも2脚の汎用性が何かを明らかにしたい、というのも欲求としてあります。
汎用性を踏まえた上で、その多彩な利用シーンからここなら勝てる!というターゲットを選択させるという方針です。
実のところ、汎用型ロボットの実用分野で、如実に汎用性を示し活用できた事例をあまり見たことがありません。実現課題、実現課題、、とは技術者だけの問題ではありません。ロボット会社の経営者達においても、汎用ロボットに対しビジネスとしての実現課題をクリアにできていません。
多彩な利用シーンはあるものの、そこから選ぼうにもまず、汎用型のロボットが一体どこまで何ができるのか、そもそもの実現性がまず分からない、それに関わる要求も分からない、コストに見合った利用価値がわからないのです。
なので普通は皆、要求分析と検証を続けターゲットを絞り、技術的な課題を絞り、専用機械や治具などを駆使し、特定の作業のみに特化した専門機械を開発する方針に落ち着くのでしょう。
汎用性を生かすには、汎用性と結びつく要求を理解し、実現性を理解し、現実的な活用シーンを描けるかどうかに懸かっていると思います。
  

4. ニーズ(要求事項)

ここから本題のニーズ(要求事項)の洗い出しになります。

足を使う機能としてまず第一に要求されることは「移動」です。
同じ場所で両手を使って作業するデスクワークとは全く異なり、足を使って仕事するならばまず、様々な場所へ「移動」できて欲しいのが当然です。足は飾りではありませんよね(地上では)。
「移動」できた上で、さらに視覚や両手や全身を使った作業も両立して初めて仕事になる、という場合が多いでしょう。運搬など「移動」をしながら行う作業もあります。移動を伴う複合的な作業の要求にどのようなものがあるか挙げてみたいと思います。そしてそれらの作業を果たすため、2脚にどのような機能が要求されるか挙げてみます。
また、「移動」とは簡単に言っても、足を使って移動する環境は様々です。以下では、足を使って移動できて欲しい環境にどのようなものがあるが挙げてみます。
加えて、「脚」や「足」を使い対象物や障害物を操作する機能が欲しい場合もあります。イメージとしてどんなものがあるか見てみましょう。
 

4.1. 主に現地への移動を必要とする作業の代行をして欲しい

何か作業をするとき我々は無意識に「移動」という機能を利用しており
実は「移動」そのものが本来の目的ではない、なんて意識すらしていない


まず「移動」について、以下2点の問いを挙げてみたいと思います。
1. 「移動」の要求の元となる根本的な要求は何か?
2. 「移動」という機能はそもそも必要なのか?
これは一種の思考ゲームだと思います。

「移動」したい、という要求の多くは、そもそも「移動」自体がメインの要求ではなく、「今居る現在地とは別の目的地で、ある目的の作業(用事)を済ませたい」という要求から二次的に派生したものが多いと思います。この要求の実現手段に含まれるものといえます。
この本来の要求が、1.の解答だと考えます。
生物を見渡すと様々な「移動」が見れられます。空を飛んだり水中を泳いだり別の生き物に付着したり寄生したり。移動形態は様々です。生存戦略として「移動」が必要という考えもあります。もし我々人類がテレポーテーションで自分を移動させることができ、サイコキネシスで食料を自分の体に取り入れることができれば、手足は不要となり、異なった姿かたちをしていたかもしれません。場所への「移動」という過程が無くなると「移動」なんてただの無駄なことで暇な人の趣味と言われていたかもしれません。
まあそんな妄想は置いておいて。

もちろん移動自体が目的の場合もあります。
その場合自分自身が実施することに意義があり何かに代行させることはナンセンスでしょう


1.の解答について、移動後のその本来の要求とやらさえ実現できれば「移動」の手段は何でも良い!といってしまえばその通りかもしれません。もちろん手段の中には経路も含まれており、空路で飛ぼうが、陸路で走ろうが何でも良い!となります。

では次いで、とりあえず移動の手段は置いておいて、
「今いる現在地とは別のある目的地で、ある目的の作業(用事)を済ませたい」
というその本来の要求とやらについて考えてみます。
その目的地に本当に移動しないと、目的の用事が本当にできないケースって何があるでしょう?これが本節の冒頭で述べた2.の問いに関連します。
例えば情報交換です。
情報交換って聞くと、皆で集まって会議やおしゃべりするイメージがあります。そしたら、会議室に集まるために移動が必要なのでは?と思いますが、
いえいえ、移動はしなくてもいいでしょう。もはや今ではインターネットを介して遠隔通信でTV会議やチャットでのおしゃべりができますね。おしゃべりの内容が複雑過ぎて直接会わないと伝えるのが難しい場合は置いておいて。
では、会議やおしゃべりという情報交換をするといった目的は、移動という手段がなくても目的自体は達成できますね?
いや、やっぱりちょっと待ってください。
遠隔通信でその目的を達成するということは、その通信を実現するハードウェア、端末のカメラやマイク、ケーブルや無線機、無線塔から電力送線など、その物理的な機器が端末利用者の場所にまで揃っていることが前提にあります。それら物理機器が無いゼロの場所から情報を取ってくるには、まずその場所に機器を設置工事しに行く過程が少なくとも一回以上は必要です。関連して、物理機器が揃っているという前提を実現するには、それらの機器をどこかから調達することが必要になります。
今挙げた例だと、遠隔通信を行う目的を実現するためには前提となる、物理機器の「設置」、「調達」といった目的を達成する必要があります。そしてその目的を達成するためには、「移動」が必要です。

現地への移動を必要とする作業の代行(現地での調達、点検・外観検査、調査)


通信機器に限らず、もっと身近な例だとご飯を食べること、にも当てはまります。我々は生きるために毎日食事を必要とします。食事をするために飲食店へ出かけるならば移動が必要なのは分かります。自宅に居ながらにして食べたい、もしくは自分の好きな場所で食べたいならば、その場所へ持ち合わせるため食料の調達が必要です。近くのスーパーに食料が揃っている環境ならば買出しに行ったり(図中(A)のイメージ)、もしくは出前・デリバリーを頼むなど実現手段があるでしょう。そして、それら食料の設置、調達を行うためには、やはり誰かしらによる「移動」が必要です。

また、ネットワークの発達した現代では移動が必要なさそうな他の例として、大規模なプラント工場、機械工場などで定期的に必要な設備の「点検・検査」が挙げられます(図中(B)のイメージ)。設備の周囲全体をカメラで囲んで遠隔から監視することで、現地に移動しなくても外観検査ができるように思えます。しかし、風化や腐食による設備の物理的な変質を見つけるために、直接指やハンマーで触れて感知するなど、現地での確認が必要な場合もあるでしょう。そのような点検・検査では、検査対象に触れるため、検査範囲に合わせて検査する人がその特定部位まで「移動」することが必要になるかと思います。

他にも、野外の地理や環境の「調査」や「探検」をしたい場合も、やはり「移動」が必要になると思います(図中(C)のイメージ)。

こんな風に一見すると「移動」が必要では無さそうなケースでも、前提を掘り起こすと実は「移動」を必要するという、ある種屁理屈みたいにどこにでも「移動」の必要性を見つけ出せると思います。
「移動」という機能は必要です。これが本節の冒頭で述べた2.の解答になります。

「移動」して、本来の目的である作業を遂行したい。
ロボットに対してだと、「移動」して、目的の作業を代行して欲しい、
これが根本的な要求にまずあると考えます。
 

4.2. 運搬作業を代行して欲しい

運搬作業の例


移動した後、目的の作業をしたい、という場合は多いとは思いますが、
移動しながら、目的の作業をしたい、という場合もあるでしょう。
「運搬」という作業は、まさに移動しながら同時に目的を遂行する作業かと思います。むしろ移動ができなければ成り立たないという場面も多いはずです。

では既存のものから考えて、運搬作業をメインとする仕事って何があるでしょう?

  • ベルボーイ/ベルガールのような荷物持ち
  • ウェイトレス/ウェイターのような配膳/下前
  • 郵便/宅急便のような宅配サービス(料理の宅配?ケータリング?)
  • 物流倉庫での搬送業務
  • 土木工事現場での搬送業務
  • 建設工事現場での搬送業務
  • 長距離移動を伴う運送業務

ちなみに曖昧に「搬送業務」と書いてみましたが、荷揚げや荷下しや積み方まで含めての移動や、大型で重い荷物を運ぶ移動、パレットに載せて運ぶ移動、台車に載せて牽引する移動など形態は様々あります。人は、人力では持ち上げることが無理な荷物に対しては、クレーンやフォークリフト、トラクタなどを利用して搬送を実現しています。
もしロボットが代わりに搬送する場合だと、たとえば大型で力持ちなロボットを適用したり、搬送機械自体がロボットとなり、そのまま荷物を自動で運ぶという方向性もあるかもしれません。
また他にも、ロボットが人と同じサイズで人と同じように搬送機械を操縦して自動で運ぶ、という方向性もあるかもしれません。
ただし先にも述べたように実現できるかどうかはここでは置いておきます。ロボットへの要求に何があるかを挙げることが目的なのです。
 

4.3. 運搬作業の対価は既存の運送サービス料金同等以下にして欲しい

距離・場所・体積・重量・取扱などにより料金が異なる運送・宅配サービス


常日頃から郵便や宅配サービスを一般消費者として利用している人は、荷物の大きさや価格で大体どれくらいの料金がかかるかご存知でしょう。

適正運賃の原価計算の方法をこちらのサイトで分かりやすく例示してくれています。運送原価+附帯作業原価+車両留置原価+高速道路利用料等+その他費用が原価合計となり、そこに収益を加えたものが運賃となるそうです。
 

4.4. 乗り物として移動して欲しい

自分を乗せて乗り物として移動して欲しいイメージ


人にとって「移動」が求められるシーンについて考えた所、たとえもしどこにでも移動できるロボットが登場したとしても、およそ初めの頃は、ロボットに「代わりに目的地へ行ってきて欲しい」という要望もあっても、やはり「自分自身がその場所に行きたい」という要望は必ずあるのではないでしょうか。
その場合、目的地に到達するのが目的であって、過程である経路間の移動は自分の足を使うのは面倒でしんどい、または病気や老化の弱体化や麻痺などで足を使えないかもしれない、何かしらに任せたい、という要望があると予想します。自分の移動を機械に任せたい、つまりロボットへの要求に当てはめるとロボットを「乗り物」として利用できて欲しい、という要求に結びつくと考えられます。
実際、人は昔から移動を牛や馬やロバや犬に任せたり、現代では交通整備された場所であればバイクや自動車を使って運転したり、運転は運転手に任せてタクシーやバス、鉄道、飛行機を利用するなど、乗り物に移動を任せて目的地に到達するということが当たり前になっています。乗り物に乗れば移動できることが当たり前になったので、おそらく人は「乗り物に移動を任せている」という意識はないでしょう。乗れば目的地に着くのは当たり前という認識です。単純に乗り物とは「移動手段」と認識しているのではないでしょうか。
現在乗り物を使用せず移動するシーンといえば、短い距離の移動であったり、交通整備されていない場所、足を使わないと通れない経路の移動が挙げられます。
 

4.5. 足を使わないと通れない経路を、気軽な乗り物として移動して欲しい

四輪車や二輪車では通れず、足を使わないと通れない経路はいくらでもある
自分自身では移動できない場合、今は介護に頼るしかない


足を使わないと通れない経路とは、四輪車や二輪など道路で走る乗り物に乗ったままでは通れない経路です。たとえば、ひび割れた道路、跨げる高さの段差や障害物の多い部屋、まばらな足場、階段、はしご、せまい通路、勾配の急な坂道、山道などなど、探してみるといくらでもあります。そのような不整地とよばれる経路を含む環境で暮らしたり、そのような場所で何かしら作業したいとき、まず自身の足で作業目的の場所へ辿り着くまでの経路を移動できなければいけません。
自分自身で移動できない場合、我々は誰かの助けを必要とします。ここでの助けが必要とは、緊急治療や医療支援が必要というわけではなく、ただ移動ができないという場合です。身内や親戚、友人や知人など誰かしらの助けを得たいが、そのような頼れる人が近くや周りにいない人もいると思います。また、身内や親戚、友人や知人からボランティアとして頻繁に助けを得るのは忍びない、なるべく避けたい、助けを得るならきちんと対価を支払いたい、と思う人も多いと思います。そのような要求に応える1つとして介護サービスがあると思います。曖昧な支援ではなく、きちんと介護内容と成果を明確にし仕事として対価を決め、サービスの提供側と利用側の対等な関係を築いてあれば過剰な気遣いや気苦労をもたずに済むでしょう。
現在、足を使わないと移動できない経路において、自分自身の移動を任せられるモノ・サービスは、障害者用〜とか介護型〜といったり健常者とは異なる扱いを受けるものがほとんどだと思います。健常者と同じ扱いを受けたい人もいるでしょう。できるなら、人の手に依存する介護を利用しなくて済むようにしたい、自身の力(財力)で移動したい、環境のリフォームや乗り物の使用といったモノの使用だけで解決したい、という要求は既にあるはずです。

ここでもし、足を使わないと通れない経路を移動できる乗り物が登場したとしましょう。そしたら選択肢が拡がります。介護を利用しなくて済むようにしたい、乗り物に任せて移動したい、という要求に応えられるはずです。

以上のことから、2脚ロボットへの要求の一つとして「足を使わないといと通れない経路を、気軽な乗り物として移動して欲しい」を挙げておきます。
 

4.6. 交通整備された道路用の乗り物の対価は、既存の交通サービス料金と同等以下にして欲しい

時間、行き先の選択により料金の異なる交通サービス


乗り物が移動できるように線路を敷いたり道路を舗装したり滑走路を作ったり、、現存の移動技術を最大限に実用化させるため、大規模な交通整備を展開してきました。交通整備された環境において、乗り物を利用する交通サービスも発展しています。
交通サービスを利用する側にとって、運賃が無料であればラッキー☆と思いますが、提供する側にとっては用意した環境や乗り物の初期投資や維持費用の回収、従業員の賃金支払いなどサービスを維持する対価として運賃が必要です。
もし新しい乗り物として移動ロボットが登場したとしても、似たような理由で対価は必要でしょう。

利用する側としては、新しい乗り物が既存の交通サービスと同等の移動機能であれば、対価も同等であって欲しいと思います。
では既存の交通サービスを参考に、交通運賃の料金設定は、どのように変わるか少し見てみましょう。以下Wikipediaやらでざっと調べた感じになります。

  行先の自由度 運行時刻の
自由度
移動
範囲目安
速度(km/h) 運賃
タクシー ほぼ固定なし ほぼ固定なし 1km〜 10〜70 1000〜円/km
バス 固定 固定 路線バス500m〜200km 10〜70 200〜1000円
鉄道
路面 固定
固定
2km〜1,000km
10〜20 Wikipedia.運賃
普通
快速
30〜90
特急 50〜110
新幹線 120〜230
飛行機 固定 固定 250km〜2,500km 980〜1111
(マッハ0.8〜0.9)
国内LCL
エコノミー
20,000〜80,000円

 

距離単価では、おそらくバスと鉄道が最も安いといえます。移動時間も含めると飛行機が最もお得に見えます。行き先の自由度と運行時刻の自由度が固定されない分、タクシーは良い値段です。予約席や個人スペースの確保など指標はまだあると思いますが、これを見る限り、例えば5〜10分間1km乗り物として移動するだけで5,000円とか1万円かかるとしたら、それは相場として高過ぎるといえます。京都で人力車に乗るようなエンタメ要素などの付加価値がない限り、価格は上記既存の交通サービスに揃えて欲しいところです。
 

4.7. 足を使わないと通れない経路用の乗り物としての対価は、既存の介護サービス料金同等以下にして欲しい

交通整備された場所での乗り物としての移動は、上記のように既存のモデルを参考にすることができました。
一方、人しか通れない場所ではどうでしょう?現在そのような乗り物は存在しませんよね。

対価の話として介護の妥当な料金設定とは?という疑問が浮かんできます。ベッドからリビングまでの移動を介護してくれたら500円?…なんて料金の決め方はないでしょうが、自動介護サービスへの報酬はいくら?と真面目に考えると難しいものです。既存の介護サービスをそのままスライドすることは妥当でしょうか?介護側の難易度に応じて妥当な価格設定を割り振って欲しいとも思いますが、ヘルパーさんを雇うとしたら、介護保険を使わなければ月20〜30万円とか。保険が適用されても介護認定のレベルによって利用者の負担は異なったりします。専用の集団施設に入れば介護負担がある程度限定されて相応の価格になるそうですが、施設内でしか移動できないなど…料金設定は単純ではなさそうです。くさか里樹氏の漫画「ヘルプマン!」を全巻読んでみると課題があることがよく分かります。なのでここでは簡単に答えは出せないので置いておきます。
 

4.8. 有害汚染区域の中を移動して欲しい

ウイルスや放射能等で汚染された区域で活動するイメージ


放射能や有害ガス、ウィルスにより居住区域が汚染されロックダウンされるといった事が、今や起きないとは言えない時代になってしまいました。人々が避難した後、汚染区域に立ち入る必要が生じた場合、人命を危険に晒さないために、代わりにロボットに出向いてもらいたいという要求は当然あります。
要求としては、人には有害な環境でもロボットには耐えることができて欲しい。その上で移動できて欲しい。となります。
また、最近ではロケットなど宇宙開発の進化が目覚しく、火星や月に辿り着くことも夢では無くなってきています。未知の惑星への宇宙探査が、地球に住む者のために新たな知見を与えたり、新たな地として活用できるチャンスを生むかもしれません。難易度の高さからも人類進歩への貢献度も大きく、潜在的な有用性の高さからも要求は人類全体レベルの規模だと言えます。そのような極限環境へ人の代わりにロボットへ行ってきて欲しい、という要求は同等にあると思います。要求としては、地球上とは異なる大気成分、異なる重力、異なる温度の環境でも耐えることができて欲しい。その上で移動できて欲しい。となります。
 

4.8. 狭い経路を移動して欲しい

狭い洞窟


都会の建物の中など、自然環境ならば洞窟や木々の生茂る山の中など、人が通るのがやっとくらいの狭い経路がたくさんあります。我々が活動する空間はわりと開けた広い場所が多いと思うかもしれませんが、生活する空間は、我々の使い勝手が良いように狭い場所が多いです。特に日本の都市部では密集してて狭い空間が多い印象です。
人が通れる場所であってもそうでなくても通れるのであれば、狭い場所を代わりに移動できて欲しいという要求があると思います。
 

4.9. 強風の中を移動して欲しい

強風は移動主体の全身に風圧をかけるに限らず、環境全てに影響を与え性質を変えてしまう


台風が来たとき我々人間は安全のため外出を避けますよね。強風で身体が煽られて飛ばされるかもしれないし、物が風で飛んできてぶつかるとケガするかもしれません。
物が飛んでくる場合はとりあえず置いておいて、ロボットが風で煽られて飛ばされないように移動できれば、代わりにお願いすることができるわけです。
よって強風の中を人の代わりに移動できて欲しい、という要求を挙げておきます。
 

4.10. 障害物を避けて移動して欲しい

障害物の多い経路


障害物を何と定義するかは場合によると思いますが、とりあえず「移動の妨げになる物」としましょう。
障害物にぶつかっても、さらに環境を破壊しながら経路を変えず突き進んで移動することもできます。しかし人は通常、障害物という環境の破壊が不可能もしくは許可されない場合は、避けて通ります。ロボットにも同様の要求となります。
 

4.10.1. 移動する経路を選択する際、障害物は跨いだり遠回りして環境を壊さず避けて欲しい

障害物を回避する場合、その程度も様々だと思います。距離を大きく空けたり、スレスレで避けたり、一部ぶつかりながら避けたり…。
移動というタスクにおいては邪魔でしかない障害物ですが、元々移動のために存在するわけではないため、障害物などの環境は破壊せず保持して欲しい、という要求が当然あると思います。
環境の保持というと、路面に足跡を残さないで欲しい、特殊な床やモノを経路とするとき踏んで変形させないで欲しい、など要求の難易度も変わります。
 

4.11. 急な段差(崖)を移動して欲しい。

高い崖を登る/降りる
ヤギは崖を登る/降りることができる
人も頑張れば崖を登る/降りることができる
ガジェット刑事なら…
スパイダーマンなら…


日本は火山大国であり島国であるため、山が多く海に囲まれています。隆起や沈降や断層により岩山は形を変え、海岸は波で削られ、急な崖が数多く生まれ現在も存在します。人々は崖のような地域に住んでいたり、趣味でロッククライミング、登山などレクリエイションとして崖のある場所へ移動することもあります。
人が暮らす場所であれば、これまで挙げた例に沿って人の代わりに移動して欲しい、という要求があります。
居住地域でなくても、崖のような危険な場所に出向く人がいて災害などに見舞われて断崖絶壁に取り残されてしまった場合、レスキューする必要があるかもしれません。その場合、危険を冒して人が救助に行かなくても、ロボットの代わりに行ってもらえると助かるでしょう。

↓以降、移動環境について、さらに要素的な要求について挙げてみます。
人工的に限定された技術的ハードルの低い環境から、自然発生し限定されていない技術的ハードルの高い環境まで挙げてみました。
 

4.12. 塗装された床面を移動して欲しい

塗装された床面


塗装された路面とは、塵や凹凸がないように綺麗に整えて、工場での生産のために用意された安定した環境に当たります。工場からお店など、産業においては路面が塗装された環境上での移動が前提となることがあります。
生産を安定させるため、余計に考えないといけない問題は排除してあります。最も技術的なハードルが低くされていると言って良いかもしれません。
 

4.12.1. 塗装された水平な床面を移動して欲しい

4.12.2. 塗装された傾斜のある床面を移動して欲しい

 

4.13. 工場での移動機能の対価は既存のAGVの価格同等以下にして欲しい

工場での使用を想定する場合、現在すでに産業用のAGV(Automated Guided Vehicle:無人搬送車)というモノが市場に出回っているので、それと比較することができます。特に用途・価格帯も調査すれば知ることができます。
すでに市場がある場合、購入者にとって価格は既存のものと同等以下にして欲しいと思うのは当然の要求かと思います。
 

4.14. 舗装された路面を移動して欲しい

舗装された路面1 (コンクリート)
舗装された路面2 (石畳(風?))
舗装された路面3 (アスファルト)

 

4.14.1. 舗装された水平な路面を移動して欲しい

4.14.2. 舗装された傾斜のある路面を移動して欲しい

4.14.3. 舗装された曲面のある路面を移動して欲しい

 

4.15. 濡れている舗装された路面を移動して欲しい

雨で濡れた路面

 

4.16. 凍結した舗装された路面を移動して欲しい

氷結した路面
氷結した路面

 

4.17. 舗装されていない路面を移動して欲しい

人が通れるだけの山道01
舗装されていない路面

 

4.17.1.水平な/傾斜の/曲面のある固く湿った泥土の路面を移動して欲しい

4.17.2. 水平な/傾斜の/曲面のある草の茂った路面を移動して欲しい

草の生えた路面のイメージ

 

4.17.3.水平な/傾斜のある乾いた砂地の路面を移動して欲しい

4.17.4. 石ころだらけの路面を移動して欲しい

石ころだらけの路面(この大きさだと砂利に近い?)のイメージ

 

4.18. 足元の脆い経路を移動して欲しい

4.18.1. 足が沈み込む柔らかい雪道や泥道を移動して欲しい

雪で足の埋もれる路面
雪で足の埋もれる路面

 

4.18.2. 足場の崩れやすい丸太や岩場の上を移動して欲しい

 

4.19. 穴だらけの経路を移動して欲しい

 

4.20. 階段など段差のある経路を移動して欲しい

舗装された傾斜&階段の路面
舗装された傾斜&階段の路面
山道
舗装された道と舗装されていない道を含む山道

 

4.21. 山道や岩道を移動して欲しい

人が通れるだけの山道03
人が通れるだけの山道

 

岩場
ゴツゴツの岩だらけの路面その1
岩場_02
ゴツゴツの岩だらけの路面その2

 

 

以上のように、我々人間が二脚だけで可能な「移動して欲しい」という要求は、簡単に挙げたつもりでも非常にたくさんあることが分かります。
以上に挙げた要求を全て満たすことができれば、汎用的なロボットと言えると思います。
 
 
 

5. シーズ(移動ロボットの実現性)

ここからシーズとなります。実現性といっても現在本当に技術的に実現可能なのかは実は置いてあります。これまで挙げた要求では、ほとんど人の代わりに移動にまつわるものでした。
ニーズベースであれば、各要求を満たす移動さえできれば形はどうでも良いと言えます。
それでは各移動の要求を満たすような移動ロボットの形態が何があるかざっくり挙げてみます。
 

5.1. 移動ロボットの形態

移動手段

移動ロボットの形態には、二脚以外だと例えば以下のような物が挙げられます。

  • 車輪移動型
  • クローラ移動型
  • 多脚移動型
  • 空中移動型(飛行型)

それぞれ得意・不得意はあると思いますが、要求を多く満たすほど汎用性は高いといえます。この中で実現性の技術的ハードルが低そうなもので、技術的に分かりやすそうでかつシンプル(低コスト)なものは、車輪移動でしょうか。安易にそのようなことを書くと怒られるかもしれませんが。
車輪移動では舗装された整地での移動を前提として、複雑な問題を削ぎ落として、それ以外の問題に焦点を当てて取り組むことができるというメリットがあると思います。
 

5.2. 車輪ロボットの形態

車輪の形態

車輪型といっても、そこらの道路で走ってる自動車のような4輪とは限りません。全車輪数、駆動輪の数や配置で変わるとその場で旋回できたり機能がガラッと変わります。上の落書きはパッと自分が挙げられる例となります。

  • 二輪駆動(中央配置)
  • 一輪工藤(玉乗り型)
  • リンク付き車輪型

しかし、これらの車輪型では4章に挙げた要求を全て満たすことができないのは分かると思います。やはり汎用性という潜在能力を持つという意味でも二脚ロボットを選択する意義は大きいと思います。
 

5.3. ハイブリット型の二脚ロボット

2脚とのハイブリッド

他の形態だけが持つメリットは、二脚型には持てないのか?という疑問もあります。
例えば合体型、ハイブリッド型というのも考えてもいいわけですね。
機能を付加できる反面、コストがかさむので、コストに見合うだけの機能の付加価値を定量評価し、ムダかどうか判断する必要があります。
しかしまあ単純に、技樹的には面白そうだと思います。
 

6. シーズ(二脚ロボットの実現性)

6.1. 二脚の移動できる場所

2脚が移動できる場所


二脚ロボットとして現状技術的に実現できるかどうかは置いて、二脚という形態であれば人と同じく上図に挙げたように以下の場所を移動できると期待できます。

  • (A) 高い段差
  • (B) 岩場
  • (C) 濡れた路面
  • (D) 跳躍を必要とするような高い障害物
  • (E) 柔らかい泥土、砂場
  • (F) 狭い通路
  • (G) 壁蹴りで駆け上がる壁
  • (H) 綱渡り
  • (I) 狭いほら穴

これら全ての場所の移動をクリアできること、汎用性を持つことが、二脚の実現性の強みであり、要件になります。

6.2. 二脚が持つ移動形態

2脚ができること1


二脚によって空間・時間において自由に移動できることを例として挙げておきます。もう一度書いておきますが現実で二脚ロボットとして技術的にできるかどうかは置いてあります(しつこいのでもう書きません)。

  • 歩く(足が片方は必ず地面に付いた移動)
  • ジョグ(ゆっくり走る)
  • ダッシュ(すばやく走る)
  • かに歩き
  • 跳躍(足を付いたままでは届かない場所へ飛び移る)
  • 匍匐(ほふく)前進(膝やつま先で蛇のように、にじり歩く)

 

6.3. 二脚ができる移動を伴う作業

2脚ができること2


「移動しながら作業を行う」ということが要求にはありました。
もちろん二脚の実現性に照らし合わせてもできることだと思います。
 

6.4. 二脚ができる移動以外の作業(双腕代わり)

2脚ができること3


二脚をメインとしてできる機能は移動だけなのか?というと、いやもっと可能性はあるぞ!と思います。
例えば、乱暴かもしれませんが、二本の足を双腕として扱ってもいいわけです。

ここからは、二脚の移動以外の機能も考えてみます。
 

6.5. 二脚ができる移動以外の作業(投げる)

2脚ができること4


双腕と似たことができることから、物を投げることも実現性に入れておきます。人はループシュートのように、足で柔らかく掬って投げることができます。
二脚ができることの一つに数えておきましょう。
 

6.6. 二脚ができる移動以外の作業(色々)

2脚ができること5


双腕の代わりになるとのことで、特に脚は腕より力があることを生かして上の図のような作業ができるのではないかと挙げてみました。

  • かかと落としによる杭打ち
  • ハイキックによる布団たたき
  • ドア開け
  • 足踏みによる踏み固め、タップダンスなど

普段手を使って行う作業を、足を使って行うことは「行儀が悪い」と言われます。人からすると行儀の上ですべきではないことだからといって、二脚ロボットも同じようにすべきではないと捉えることはありません。行儀なんて思いもよらないように、たとえば足を足と見えないように、外見上の機械デザインにより工夫すればよいものだと思います。
 

6.7. 二脚移動中の外乱に耐える

外界との接触という問題


ここでいう外乱とは、意図せず入力され目標への制御を邪魔するものを指します。ここでは特に、移動を邪魔するものを指します。

  • (A) 横から押されて外力が加わる
  • (B) 自身で環境に衝突・接触し反力が加わる
  • (C) 重心や慣性モーメントが変化する
    運搬物が中で動いたり、構造が変化して質量分布が変化したりなど

避けられるならばそれでOKですが、どうしてもこれら外乱が加わることがあります。その場合、外乱に耐えて移動を崩さないようにできないといけません。
 

6.8. 人間には難しい二脚だけでの復帰

復帰の問題


二脚ロボットの要求では主に移動できることを前提としてきていましたが、移動が失敗した時のエラーについても対応できていなければいけません。二脚で移動が失敗した時とは、「歩行や走行すべきなのに転倒してしまった場合」と定義しておきます。
転倒してもまた移動再開できるように起きて立ち上がって復帰できて欲しいです。それは基本機能であって欲しいです。が、しかし人間だと二脚だけだと案外転倒状態から起きたり立ち上がるのは難しいものです。やってみると分かります。どこかに手をついて起き上がるのはラクです。なんとか頑張れば、二脚だけでも起き上がることは出来なくはないです。
人で頑張れば出来るのであれば、ロボットであれば二脚だけで起き上がるように作ってあるべきです。参照のモデルの性能の低さは克服しておくべきだと考えます。
 

 

 

ふぅ〜。。とりあえず以上になります。
ここで挙げたものは私がパッと思いついたものになります。
ニーズとシーズを書き出すだけ書き出しただけで、結局何も検証できていないわけですが…。
もちろんこれだけでは、ニーズとシーズの検討には全く不十分です。
けど一度通してやってみると色々と課題や方針が見えてきます。
考え出したらキリがないと思うかもしれませんが、地味に真面目に考え続けることが、実は手っ取り早くて簡単な方法かもしれません。

最初に述べたように、汎用でなければ人型のメリットはないと考えています。
これまでの産業用ロボットは、人の能力のエリアとは異なる「精度」「力強さ」「速度」の三本柱をウリにして発展してきました。従来の産業用ロボットのウリは、人間では届かない能力にあり、働く人間とは勝負の土台が異なっていたのです。
しかし一方最近の各ロボット会社のトレンドとしては、協働ロボット、サービスロボットの分野が(改めて?)注目され、人が持っている能力と被るエリアをターゲットにするようになってきました。ただし人と同程度以下の能力エリアでは、汎用性を示す「器用さ」「多機能」と、さらに「即時導入」の柱がウリになっていないと、人間や専用機械とそのまま勝負しても勝てない、という事がだんだん分かってきています。機能で勝負せず「コスト」だけで勝負に走り買い叩かれて死亡、というルートも見えてきています。
二脚ロボットについても、世の中にはまだ実用化できたモノは存在しませんが、求められていることは同じだと思っています。

上に挙げたすべての要求を一つでも叶えられるよう、技術的な実現性を一つずつクリアし続けることが技術者として重要だと思います。また、一つでも実現できてくれれば、要求を叶える商品としてどんどん世に出して発展していくことが、ロボットの企業としての務めであり醍醐味ではないかと思います。
  
 

それではまた。

もっと速く!の図

ロボットのPTP動作コマンドとその問題

こんにちは。
お久しぶりの投稿です。

今までは剛体の回転運動についてしか書いてませんでした。
ここらで、実際のロボットの動作に少し絡めて
自分の学習の方向性を整理しておきたいと思います。

1. 目的

今回の目的は、以下の2つになります。

  • PTP方式の動作指定によるティーチング・プレイバックにおいて、
    実用上ユーザが求める動作コマンドの入力パラメータ例を挙げる
  • 動作コマンドに照らし合わせ、経路補間、回転運動計算の設計上の課題へと落とし込む

1.1. 目的内の用語

目的に書いてある用語を知っていれば、本節は読み飛ばしてください。

PTP(Pose To PoseまたはPoint To Point)方式とは、
JIS B 0134の用語によると
「ロボットが通過させる指令ポーズだけを指定し,
ポーズ間でたどるべき経路を指定しない制御方式」
のことをいいます。

ロボットを動作させるとき、
移動時間の細かい時間刻みで細かいポーズ変化をいちいち指定するのではなく、
開始点から、経由点、終端点のロボットのポーズと移動時間をざっくり数点指定すれば、
あとは自動で動作を作って補間してくれる方式です。

PTP方式の図
PTP制御方式の図

対して、CP(Countinuous Path)方式というのがあります。
これはJISでは
「ロボットに指令ポーズの間でたどらせる経路を指定する制御方式」
と定義され、ユーザが経路を描いたり何かしら記録して指定し、
きっちり経路上にロボットの手先もしくは全身のポーズを沿わせる方式です。

ユーザがポーズ点だけで指定するのがPTP、
経路を指定するのがCP方式と覚えておきます。

ティーチング・プレイバックとは、

JIS B 0134の用語でいう

教示(ティーチング):
「ロボットのエンドエフェクタ又は模擬機構を
手で又はペンダントを用いて動かし,
ロボットに所望の位置を 1 ステップずつたどらせることによって
プログラムを作成すること」、

プレイバック運転:
「ロボットに,教示プログラミングによって格納したタスクプログラムを
繰り返し実行させる運転方法」

の両方を指しています。

「エンドエフェクタ又は模擬機構って?」
と疑問が重なりますが、ロボットの手のことです。

さらに「ペンダントって?」
と疑問が重なりますが、タブレットみたいな手持ちコントローラを指します。
鉄人28号を操作するために正太郎くんが持ってたあれとかペンダントっぽい気がします。違うか。

さらにさらに「タスクプログラムって?」
と疑問が重なりますが、編集・録画した動画データと同じかと。
記録された動作データのことです。

動作データをプレイバック、
つまり再生してロボットを動作実行させるのですね。
「ちょっと待って。プレイバック、プレイバック」です。違うか。

余談ですが、
ティーチング・プレイバックというロボットの使い方は、
産業用ロボットが出た大昔からずっと変わらず今も主流のままです。

プレイバックは再生するだけなので良いですが、
面倒なのはティーチングです。

「人類は、いつまでタスク(仕事)をロボットに教え続けなければいけないんだ!」

と皆もっと嘆いて

「できらぁっ!」
「いまなんていった?」
「ティーチレスのロボット用ソフトウェアを世に出してやるって言ったんだよ!」

と啖呵切って技術進化に参戦して欲しいです。

できらぁっ!の図
( 出典 ©牛次郎, ビッグ錠『スーパー食いしん坊』)

1.2. 目的の動機

目的を読んでおよそ動機がわかった人は、本節を読み飛ばしてください。

PTP方式の動作指定は
大昔から産業用ロボットで使われている主流な機能です。

PTP方式の機能のない産業用ロボットを販売するロボットメーカーは
おそらく存在しないのではないかと勝手に思っています。
それくらい基本中の基本の機能ではないでしょうか。

では、
ティーチング時、このPTP方式を利用するために、
ユーザに対しどのようなコマンド入力が用意されていれば良いでしょうか?

この疑問が一つ目の目的の動機につながります。
JISにはSLIMというロボット用プログラム言語の規格があり、
動作コマンド(MOVEなど)のインタフェースが定めてありますが、
それで十分か不十分かは
ユースケースをほじくり出してみないとはっきりしません。

また、ユーザ入力のコマンドが定義されたとして、
具体的に計算上どのような問題を解く必要があるでしょうか?

ただし今回は解法までは触れません。
あくまで設計上の課題を明らかにしたいのです。

2. ロボットの動作コマンドの入力パラメータ例

以下にPTP方式で動作するロボットの図を描いてみました。

図中ニョロニョロ描いてある線が
ロボットの手先軌道だと思ってください。

軌道上にいくつか打ってある点が、
ユーザがコマンドのパラメータとして入力した各ポース点です。

PTP動作の図
PTP動作の図


ここではロボットの手先位置姿勢をポーズ点として軌道を描いていますが、
全関節軸の回転角度位置セットを一つのポーズ点として全軸の軌道を扱う場合もあるでしょう。

入力パラメータをユースケースとして考えてみます。

2.1. 目標移動時間による動作指定

PTP方式は、
開始点から、経由点、終端点のロボットのポーズと移動時間を数点指定すれば、
あとは自動で動作を作って補間してくれる方式、
と上の用語説明で書きました。

ならば
・移動時間
・目標のポーズ点
さえ入力パラメータとしてあれば良い気がします。

ということで、1つめの入力パラメータ例は以下になります。

  • 移動時間、目標ポーズ点

ユーザがロボットに与えるコマンド(命令)は
「動け、この移動時間で、この目標ポーズ点へ」
といった感じでしょうか。

目標点と目標点の移動を、
[m/s]、[rad/s]…
といった単位による移動速度で指定したい場合もあるでしょう。
その場合、
開始点と終端点の2点の平均移動速度として速度指定できると嬉しいですね。

・平均移動速度、目標ポーズ点

「平均」移動速度としたのは、
開始点=速度0で停止している状態から、
終端点=速度0で停止した状態へと動作するとき、
あいだに加速と減速が加わり常に速度一定ではないケースを考慮したためです。

小学校で習うように、平均移動速度は移動時間へ容易に変換できます。
(移動時間) = (2つの目標ポーズ点間距離) / (平均移動速度)
なので結局、
移動時間と目標ポーズ点が入力パラメータとして設定可能であれば、
平均移動速度の入力もカバーできることになります。

2.2. 速度比率による動作指定

移動時間をいちいち設定するのは面倒で、
工場でサイクルタイムを気にするユーザは、

「速く!もっと速く!とにかく速く移動してタイムロスを減らすんだ!」

もっと速く!の図
もっと速く!の図

という要望を持つことが大いにあるでしょう。

しかし速くといってもロボットにも限界があるはずです。

ならばユーザの要望は「限界まで速く」になります。

では「限界」とは何に基づいて決まるのでしょう?
例えば以下2つです。

・モータやモータドライバの限界
・安全上の限界

1つめについて、
軸の回転を速くするためモータやモータドライバの回路に電流をどんどん流すと、
ある大きさ以上電流が流れ続けると回路が発熱で壊れてしまう、
といったことがあります。

1つめの「モータやモータドライバの限界」とは、
長時間流しても壊れない程度の電流値、それに対応した最大加速度・速度にしておく、
といった限界です。

モータとモータドライバをこんがり焼く
限界に達したモータとモータドライバがこんがり焼き上がる図

2つめについて、
ロボットがあまり速く動き過ぎると
周囲にある物や人に不意に接触したとき大事故につながる恐れがあります。

2つめの「安全上の限界」とは、
接触しても最悪の事故は避けられる程度の最大速度にしておく、
といった限界です。

安全上の限界のイメージ
安全上の制限速度が必要そうなロボットのイメージ図

余談ですが、
モータやモータドライバの限界に関して、
従来の産業用ロボットは、大出力のモータを選定することで大電流を許容し、
使用する電流値の範囲は定格を超えないよう余裕をもたせ
かつ使用可能な速度・可搬重量の最大範囲を広げる、
というのが普通でした。

ただし大出力に伴いモータも大型かつ大質量になり、
それらを多数装備したロボットは設置場所を手軽に変えられず、
設置スペースや動作軌道も十分配慮しなければいけませんでした。

また安全上の問題に関して、
従来の産業用ロボットでは、
ロボットの周囲に安全柵を設けて人との接触をなるべく防いでいました。

ただしティーチングするにしても
自動運転中のアクシデントに対応するにしても、
ユーザは柵の内外を行ったり来たりしなければならず手軽ではありません。

最近では
これらの課題を克服する新たな形態の産業用ロボット・規格が出てきています。
それに関してはまたいつか書きましょう。

さて話を戻しますが、
「限界」を考慮した速度を指定できるようにするので、
動作コマンドの入力パラーメータとして
移動時間の代わりに限界を100%とした速度比率が用意してあれば、
ユーザの要望は満たされるでしょう。

  • 限界に対する速度比率、目標ポーズ点

ユーザがロボットに与えるコマンド(命令)は
「動け、この速度比率(%)で、この目標ポーズ点へ」
といった感じでしょうか。

2.3. 経由点

2.3.1. 経由点を通る動作を考える

3次元空間上の2つの目標点を補間する方法には、

手先位置のポーズ点だと線形補間、
姿勢(回転方向)のポーズ点だと球面線形補間

といったものがあります。

・位置の点の補間:線形補間(Lerp: Linear interpolate)
・回転方向(姿勢)の補間:球面線形補間(SLerp: Spherical Linear interpolate)

線形補間-球面線形補間の図
線形補間-球面線形補間の図

以前書いた「剛体の運動(2つの姿勢の補間)」は、上記でいう球面線形補間(SLerp)に当たります。

このLerp、SLerpの補間方法は、2つの点の補間を前提としており、開始点と終端点の間を最短距離で結びます。
Lerpだと2つの位置の点を直線状に結び、
SLerpだと2つの姿勢の点を、回転軌道を模した球面の測地線上に沿って結びます。
これが位置姿勢の位置空間軌道になります。

また速度の軌道について、
時間スケールを使い開始点で速度=0で停止した状態から、
終端点で速度=0で停止した状態に至るように補間計算します。

そのため、経由点が含まれても2つの点の間を一回一回加速・減速して停止するようになります。
つまり、経由点で毎回止まるのです。

経由点を使用するユーザの要望はこうでしょう。

「経由点で止まらず動作し続けて欲しい」

経由点で止まって欲しいならば、
2つの目標点間の経路を先のLerp、SLerp によって最短距離(直線、測地線)で結ぶことで実現できます。

止まって欲しくない場合、
実現すると、かわりに目標点間の経路を最短距離の直線、測地線上に結ぶことは難しくなります。

というのは、
同じ方向直線上に経由点が存在するならば問題ありませんが、
経路点で方向が変わると、方向成分の速度の大きさは失われるため、
直線の交点で結ぶと一瞬にしろ必ず経由点で停止することになります。
曲線で結べば常に方向成分は変化しますが速度の大きさを保つことができます。
経路点上で止まらないということは、
方向の変わり目に直線ではない何かしらの曲線で結ぶことになるのです。
高校数学Ⅱ「関数の連続性」で学んだ話を思い出します。

ということで、経由点で止まらない場合、
どのような補間経路が考えられるでしょうか。

2.3.2. 経由点補間の種類

以下図に3つのパターンを挙げてみました。

経由点間を止まらない補間の種類
経由点で止まらない場合の補間の種類

左から1つめの補間タイプは、

・各目標点では動作方向を固定する

というものです。

「経由点を通過するとき、次の目標点方向に向かって動作して欲しい」

といった要望がある場合、この補間方法が使えるでしょう。
次節で挙げますが、
経由点通過時の方向(=目標点速度)をユーザに指定できるように、
入力パラメータを用意しても良いかもしれません。
補間された曲線は、つぎの目標点に近づくにつれ、
固定された動作方向に追従するように回り込んだ形状になります。

左から2つめの補間タイプは、

・動作速度に合わせて直線(測地線)から曲線度合いを増す

というものです。

「経由点を必ず通り通過時の速度はよしなに」

といった場合は、
このタイプの使い勝手が良いかもしれません。

最後の左から3つめの補間タイプは、

・経由点にたどり着く前に次の目標点への動作を始めてしまう

というものです。

前の動作が終わらないうちに次の動作を混ぜて連続動作させるのです。

図には「ショートカット(short-cut)」と書きましたが「合成(blend, mix)」といったりします。
LerpやSLerpの補間が合成される場合、
合成されるまでは直線や測地線上に沿った軌道となります。
なるべく直線性を保った経路が欲しい場合使い勝手が良いかもしれません。

ただし、速度が増すにつれて経路点をショートカットする度合いも増すため、
経由点と速度とのバランス調整をする必要が出て面倒くさい場合もあります。

以上をまとめると、ユーザがロボットに与えるコマンド(命令)の入力パラメータは、

  • 目標点で止まる(Lerp、SLerp)
    ・移動時間(または速度比率)、目標ポーズ点
  • 経由点(経由点で止まらない)
    ・各点間の移動時間(または速度比率)セット、目標経由点セット(複数)、補間の種類

となり、先に挙げた移動時間や速度比率との組み合わせになります。

2.4. 割り込み動作

最後の入力パラメータ例は、割り込み動作についてです。

割り込み動作の図
割り込み動作の図

ある目標点へ移動している途中、
内部/外部センサなど割り込み入力(トリガー)に反応して
目標点や経路を止まらず急遽変更できるのが割り込み動作です。
ユーザがロボットに与える入力パラメータは以下のようになります。

  • (割り込まれる側の元の動作に対し)割り込み動作を許容する/許容しない
  • 監視する割り込み入力(トリガー)の指定
  • トリガーがONになったら発動する割り込み動作(移動時間、目標ポーズ点などのパラメータ)

「移動する物体をキャッチしたい」
といったケースには、
時々刻々と目標点を変えて割り込み動作で追従すれば実現できそうです。

ただし、目標点も移動し続けているのであれば、
目標速度も指定できた方が良さそうです。
よって動作コマンドの入力パラメータに、目標ポーズ点での速度を加えたパターンも挙げておきます。

  • 移動時間(または速度比率)、目標ポーズ点、目標点速度

目標ポーズ点が手先ポーズである場合、
目標点速度を与える代わりに、手先ポーズ点座標の基準座標系自体を移動させるという方法もあります。
入力パラメータは、以下となります。

  • 目標ポーズ点の基準座標系の速度

この基準座標系の速度設定後、

・移動時間(速度度比率)、目標ポーズ点(基準座標系が移動中)

の入力コマンドで、
目標ポーズ点で目標速度を与えることができます。

2.5. PTP動作コマンドの入力パラメータのまとめ

さて以上により、
ユーザがPTP方式の動作コマンドで欲しいと思われる入力パラメータは、
おおかた出揃ったのではないでしょうか?

ここで、まとめておきます。

  1. 目標点に到達するたびに止まる(Lerp、SLerp)
    ・移動時間(または速度比率)、目標ポーズ点
  2. 経由点(で止まらない)
    ・各点間の移動時間(または速度比率)セット、目標経由点セット(複数)、補間の種類
  3. 割り込み動作
    ・(割り込まれる側の元の動作に対し)割り込み動作を許容する/許容しない
    ・監視する割り込み入力(トリガー)の指定
    ・トリガーがONになったら発動する割り込み動作(移動時間、目標ポーズ点などのパラメータ)
  4. 目標点で止まらない
    ・移動時間(または速度比率)、目標ポーズ点、目標点速度

    ・目標ポーズ点の基準座標系の速度
    移動時間(または速度比率)、目標ポーズ点(基準座標系が移動中)

  

3. 設計上の問題

3.1. 【問題1】限界(速度比率100%)の定式化

「限界まで速く」といわれても機械は限界を知りません。
定式化してプログラムを組んで書き込んで上げないと、
ユーザから言われるがままに動き続け、
果ては壊れ、
もしくはケガでは済まない大事故を起こすことだってあります。

「機械は限界を知らない」
「機械は限界を知らない」の図

定式化のために物理モデルを立てる必要があります。

モーターやモータードライバの限界だと
回路保護の観点から
モーターの回転運動と電流と発熱との関係をモデル化する必要があります。

短時間で一気にコゲつくくらいの電流値が一体いくらなのか知る必要があります。

燃えるまでいかなくても高い電流値であれば
時間経過とともに発熱温度が上がり、
基板の冷却装置の伝熱・放熱の限界を超えて壊れてしまうので、
温度上昇を避けられる限界の値がいくらなのか知る必要があります。

安全上の限界だと、
人がロボットのフレームに接触したら停止
つまりゼロ距離で停止するとし、
そこから近距離、遠距離へと距離を変化したときの、
相対的に停止できる各関節軸の回転速度の限界をモデル化する必要があります。

フレームとの距離なので関節一軸だけの問題ではなく、
ロボット全身の衝突モデルを立てる必要があります。

3.2. 【問題2】限界(速度比率100%)と関節-手先の変換

手先のPTP動作をある移動時間セットの経路点セットに沿って実行したいとき、
各関節軸はどのような回転運動をすれば良いでしょうか?

手先の運動と関節角の運動の図
手先の運動と関節角の運動の図

手先の移動速度はゆっくりでも
ある関節軸の回転速度は速くなってしまうことがあります。
手先と各関節軸との運動の変換式を考える必要があります。

また、手先のPTP動作を100%の速度指定で実行したいとき、
先の定式化の話によると、
手先動作の100%限界も各軸モーターの回転運動の制約や衝突モデルの制約に縛られます。
制約式から変換して手先の100%動作を生成する必要があります。

3.3. 【問題3】限界(速度比率100%)と球面上経路点補間

経路点を止まらずに滑らかに補間するとき、
前の章で補間の種類の例を上げてみましたが、
各種類の補間を球面上姿勢方向で実現するには一体どのような計算が必要でしょうか?

ハンドカメラ姿勢の経路点100%補間動作
ハンドカメラ姿勢の経路点100%補間動作の図

止まらずに滑らかに補間するということは、
通過する経路点上で速度を持つということになります。
姿勢の方向変化、姿勢の回転の速度なので、いわゆる姿勢の角速度ですね。

ユーザは時間と方向くらいは指定しても、姿勢の角速度までは直感的に分かりにくいし面倒なので直接指定したくないでしょう。
すると経路上の姿勢の角速度は自動で割り振ってもらう必要があります。

位置空間の点運動と違い、姿勢の運動は複雑です。
速度の限界を関節軸や衝突モデルの制約に基づいて与えるとき、
姿勢の運動に対しどのような形でその制約式が表れるでしょうか?

3.4. 【問題4】割り込み動作を受け入れるシステム

最近のロボットは多数のセンサを監視したり、
脚や双腕や頭部で各部位別々に動作したり、
移動したり、
外部機器と連携したり、、
とマルチタスクであることが当たり前になってきました。

割り込み動作を使用可能にするということは、
ユーザの応用範囲が広がる反面、
ユースケースも増え、
あらゆるパターンに耐えるシステムの設計が求められることになります。
タスク実行の優先度やプリエンプション、リアルタイム処理などのシステム設計時に割り込み動作はあらかじめ考慮される必要があります。

だからといってしかし、
ユーザの割り込み動作の指定をなんでもかんでも許す必要はなく、
「そんなん無理じゃー」
といってエラーで落とす仕様もあって然りだと思います。

ただし割り込み動作がエラーで失敗するときは、
システムの安全性は担保されるべきですし、
後でそのエラー原因や回避方法をなるべくユーザに分かりやすく伝える機能が用意されてあるべきです。

一番よくないのは、中途半端なのに何でもできるように謳った仕様です。
できないならできないと明確に仕様を決めるべきです。
マニュアルにもはっきり書いておくべきです。
ユーザが使ってわけわからん挙動をするロボットは最悪です。
ソフトウェア品質を軽視するヒドい開発体制のメーカーだと非難するべきです。たった少人数で過剰労働させて設計し社内レビューもなく世に出したに違いありません。悪いのは一方的に命令している人間です。ロボットの開発現場の人間が一番ロボットみたいになっ・・・おっと関係ない話でしたね。自分の黒い部分がはみ出していました。

  

4. 今回はここまで

ふぅ〜。
今回はPTP方式の動作コマンドの具体的なユースケースを挙げました。

さらにそのコマンドを実現するために
クリアしなければならない問題も挙げました。

PTP方式のコマンド例はこの限りではないでしょうし、
本問題の解法も一通りではないでしょう。
しかし今回はこれだけ書いたらなんかもう満足したので終わります。

次回からまた、
問題を数式に落とし込んで解いていきたいと思います。

以上です。

剛体の運動(回転と伸縮をもつ運動 ―コリオリの力)

こんにちは。
だいCです。

このブログはノート代わりに使っています。

今回は回転&並進についてノートします。

1. 目的

1つの回転軸まわりの回転と並進が複合した運動における、
質点の位置姿勢の速度・加速度を求める

2. 回転と並進が複合した運動を考える場面

日常だとあまり意識しないかもしれませんが、例えば

  • 乗り物でカーブしながら車線変更するときや、
  • 北半球の気象衛星画像に写った低気圧が反時計回りになっているのを目にしたとき、
  • その他腰を回しながら腕を伸縮するような身体動作をしているとき

など、回転と並進による運動を体感しているみたいですね~。。全然気にしたことなかったですが。

ロボットでも、このような回転&並進による運動の影響は、ユーザーレベルで気にすることはほとんどないと思います。

しかし、ロボットの性能評価や動作設計をおこなう側では、例えば、

  • 複数ある関節軸を同時に動かした時、各関節軸にかかる慣性負荷はどれくらいか
  • 手先に液体等速度や加速度に影響を受ける物体を持たせて運ぶ時、回転と並進を伴う場合、どのような方向に動かせばよいか

などなどモデル化・定式化を考える場面で、さり気なく出てきます。

特に、下の図のようなPolar Robot(極座標型)とよばれる類のロボットは、回転と並進がわかりやすく組み合わされています。

回転と並進が組み合わされた運動をするロボット

ということで、回転と並進が組み合わさると、どのような速度・加速度をもつのか定式化してみましょう。

3. 前提

回転している軸、ここでは軸に限らず回転しているもの全般を指すように、回転系と言っておきましょうか。

回転系の上で、並進運動している座標系に働く速度と加速度を出力とします。

  • 基準座標系を\( \Sigma_{0} \)、回転1と一緒に回る座標系を\( \Sigma_{1} \)、伸縮と一緒に回る座標系を\( \Sigma_{2} \)とします。
  • 入力1:基準座標系\( \Sigma_{0} \)から見た座標系\( \Sigma_{1} \)の位置\( {}^{0}{\bf p}_{1} \)(一定)
  • 入力2:基準座標系\( \Sigma_{0} \)から見た座標系\( \Sigma_{1} \)の姿勢\( {}^{0}{\bf R}_{1} \)
  • 入力3:基準座標系\( \Sigma_{0} \)から見た座標系\( \Sigma_{1} \)の角速度ベクトル\( {}^{0}{\bf \omega}_{1} \) ( 回転軸\({}^{0}{\bf n}_{1} \), 角速度\(\dot{\theta_1}\) )
  • 入力4:基準座標系\( \Sigma_{0} \)から見た座標系\( \Sigma_{1} \)の角加速度ベクトル\( {}^{0}\dot{\bf \omega}_{1} \) ( 回転軸\({}^{0}{\bf n}_{1} \), 角速度\(\ddot{\theta_1}\) )
  • 入力5:座標系\( \Sigma_{1} \)から見た座標系\( \Sigma_{2} \)の位置\( {}^{1}{\bf p}_{2} \)
  • 入力6:座標系\( \Sigma_{1} \)から見た座標系\( \Sigma_{2} \)の姿勢\( {}^{1}{\bf R}_{2} \)(一定)
  • 入力7:座標系\( \Sigma_{1} \)から見た座標系\( \Sigma_{2} \)の並進速度\( {}^{1}{\bf \dot p}_{2} \)
  • 入力8:座標系\( \Sigma_{1} \)から見た座標系\( \Sigma_{2} \)の並進加速度\( {}^{1}{\bf \ddot p}_{2} \)
  • 入力9:座標系\( \Sigma_{2} \)から見た、座標系\( \Sigma_{2} \)と一緒に伸縮する点Pの位置ベクトル\( {}^{2}{\bf p}_{A} \)(一定)
  • 出力1:基準座標系\( \Sigma_{0} \)から見た座標系\( \Sigma_{2} \)の角速度ベクトル\( {}^{0}{\bf \omega}_{2} \)
  • 出力2:基準座標系\( \Sigma_{0} \)から見た座標系\( \Sigma_{2} \)の位置・姿勢の速度\( {}^{0}\dot{\bf p}_{2} \)、\( {}^{0}\dot{\bf R}_{2} \)
  • 出力3:基準座標系\( \Sigma_{0} \)から見た座標系\( \Sigma_{2} \)の角加速度ベクトル\( {}^{0}\dot{\bf \omega}_{2} \)
  • 出力4:基準座標系\( \Sigma_{0} \)から見た座標系\( \Sigma_{2} \)の位置・姿勢の加速度\( {}^{0}\ddot{\bf p}_{2} \)、\( {}^{0}\ddot{\bf R}_{2} \)
  • 回転と伸縮の効果のみ注目したいので重力加速度を無視します。

4. 回転系上での伸縮における位置・姿勢の速度と加速度

座標系\(\Sigma_{0} \)基準の座標系\(\Sigma_{2} \)の位置\( {}^{0}{\bf p}_{2} \)は、入力\( {}^{0}{\bf p}_{1} \)、\( {}^{0}{\bf R}_{1} \)、\( {}^{1}{\bf p}_{2} \)を用いて以下のように求まります。

$$ \begin{array}{rcl}
{}^{0}{\bf p}_{2} &=& {}^{0}{\bf p}_{1} + {}^{0}{\bf p}_{1 \rightarrow 2}  \\
&=& {}^{0}{\bf p}_{1} + {}^{0}{\bf R}_{1}{}^{1}{\bf p}_{2}
\end{array}
$$

座標系\(\Sigma_{0} \)基準の座標系\(\Sigma_{2} \)の姿勢\( {}^{0}{\bf R}_{2} \)は、入力\( {}^{0}{\bf R}_{1} \)、\( {}^{1}{\bf R}_{2} \)を用いて以下のように求まります。

$$ \begin{array}{rcl}
{}^{0}{\bf R}_{2} = {}^{0}{\bf R}_{1} {}^{1}{\bf R}_{2}
\end{array}
$$

以降、この\( {}^{0}{\bf p}_{2} \)、\( {}^{0}{\bf R}_{2} \)の式を用います。

\( {}^{0}{\bf p}_{2} \)を微分して、
入力\( {}^{0}{\bf R}_{1} \)、\( {}^{0}{\bf \omega}_{1} \)、\( {}^{1}{\bf p}_{2} \)、\( {}^{1}{\bf \dot p}_{2} \)を用い、座標系\(\Sigma_{0} \)基準の座標系\(\Sigma_{2} \)の速度\( {}^{0}{\bf \dot p}_{2} \)を表すと以下のようになります。ただし、\( {}^{0}{\bf p}_{1} \)が一定値であるため、その微分値\( {}^{0}{\bf \dot p}_{1} \)は0になります。

$$
\begin{array}{rcl}
{}^{0}{\bf \dot p}_{2} &=& {}^{0}{\bf \dot p}_{1} + {}^{0}{\bf \dot p}_{1 \rightarrow 2} \\
&=& 0 + \frac{\rm d}{\rm dt} \left( {}^{0}{\bf R}_{1}{}^{1}{\bf p}_{2} \right) \\
&=& {}^{0}{\bf \dot R}_{1} {}^{1}{\bf p}_{2} + {}^{0}{\bf R}_{1} {}^{1}{\bf \dot p}_{2} \\
&=& [{}^{0}{\omega}_{1} \times] {}^{0}{\bf R}_{1} {}^{1}{\bf p}_{2} + {}^{0}{\bf R}_{1} {}^{1}{\bf \dot p}_{2} \\
&=& {}^{0}{\bf \omega}_{1}  \times {}^{0}{\bf R}_{1} {}^{1}{\bf p}_{2} + {}^{0}{\bf R}_{1} {}^{1}{\bf \dot p}_{2}
\end{array}
$$

座標系\( \Sigma_{0} \)基準で見た回転する座標系\( \Sigma_{2} \)の姿勢\( {}^{0}{\bf R}_{2} \)の速度\( {}^{0}{\bf \dot R}_{2} \)は、入力\( {}^{0}{\bf R}_{1} \)、\( {}^{1}{\bf R}_{2} \)との関係から微分して以下のように求まります。ただし、\( {}^{1}{\bf R}_{2} \)が一定値であるため、その微分値\( {}^{1}{\dot{\bf R}}_{2} \)は0になります。

$$ \begin{array}{rcl}
{}^{0}\dot{\bf R}_{2} &=& \frac{\rm d}{\rm dt} \left(  {}^{0}{\bf R}_{1} {}^{1}{\bf R}_{2} \right) \\
&=& {}^{0}{\dot{\bf R}}_{1} {}^{1}{\bf R}_{2} + {}^{0}{\bf R}_{1} {}^{1}{\dot{\bf R}}_{2} \\
&=& [{}^{0}{\omega}_{1} \times] {}^{0}{\bf R}_{1} {}^{1}{\bf R}_{2} + 0 \\
&=& {}^{0}{\omega}_{1} \times {}^{0}{\bf R}_{1} {}^{1}{\bf R}_{2} \\
&=& {}^{0}{\omega}_{1} \times {}^{0}{\bf R}_{2}
\end{array}
$$

剛体の運動(回転運動の速度・加速度・躍度)でやったように、
速度を微分することで、点の位置・姿勢の加速度を求めます。

座標系\( \Sigma_{0} \)から見た座標系\( \Sigma_{2} \)の位置の並進加速度は以下のようになります。

$$ \begin{array}{rcl}
{}^{0}\ddot{\bf p}_{2} &=& \
\frac{\rm d}{\rm dt} \left( {}^{0}{\bf \omega}_{1}  \times {}^{0}{\bf R}_{1} {}^{1}{\bf p}_{2} \
+ {}^{0}{\bf R}_{1} {}^{1}{\bf \dot p}_{2} \right) \\
&=& {}^{0}{\bf \dot \omega}_{1}  \times {}^{0}{\bf R}_{1} {}^{1}{\bf p}_{2} \
+ {}^{0}{\bf \omega}_{1}  \times \frac{\rm d}{\rm dt} \left( {}^{0}{\bf R}_{1} {}^{1}{\bf p}_{2} \right) \
+ {}^{0}{\bf \dot R}_{1} {}^{1}{\bf \dot p}_{2} + {}^{0}{\bf R}_{1} {}^{1}{\bf \ddot p}_{2} \\
&=& {}^{0}{\bf \dot \omega}_{1}  \times {}^{0}{\bf R}_{1} {}^{1}{\bf p}_{2} \
+ {}^{0}{\bf \omega}_{1}  \times \left(  {}^{0}{\bf \dot R}_{1} {}^{1}{\bf p}_{2} + {}^{0}{\bf R}_{1} {}^{1}{\bf \dot p}_{2} \right) \
+ [{}^{0}{\bf \omega}_{1} \times ] {}^{0}{\bf R}_{1} {}^{1}{\bf \dot p}_{2} + {}^{0}{\bf R}_{1} {}^{1}{\bf \ddot p}_{2} \\
&=& {}^{0}{\bf \dot \omega}_{1}  \times {}^{0}{\bf R}_{1} {}^{1}{\bf p}_{2} \
+ {}^{0}{\bf \omega}_{1} \
\times \left(  [{}^{0}{\bf \omega}_{1} \times ] {}^{0}{\bf R}_{1} {}^{1}{\bf p}_{2} + {}^{0}{\bf R}_{1} {}^{1}{\bf \dot p}_{2} \right) \
+ [{}^{0}{\bf \omega}_{1} \times ] {}^{0}{\bf R}_{1} {}^{1}{\bf \dot p}_{2} + {}^{0}{\bf R}_{1} {}^{1}{\bf \ddot p}_{2} \\
&=& {}^{0}{\bf \dot \omega}_{1}  \times {}^{0}{\bf R}_{1} {}^{1}{\bf p}_{2} \
+ {}^{0}{\bf \omega}_{1} \times \left( {}^{0}{\bf \omega}_{1} \times {}^{0}{\bf R}_{1} {}^{1}{\bf p}_{2} \right) \
+ {}^{0}{\bf \omega}_{1} \times {}^{0}{\bf R}_{1} {}^{1}{\bf \dot p}_{2} \
+ {}^{0}{\bf \omega}_{1} \times {}^{0}{\bf R}_{1} {}^{1}{\bf \dot p}_{2} + {}^{0}{\bf R}_{1} {}^{1}{\bf \ddot p}_{2} \\
&=& {}^{0}{\bf \dot \omega}_{1}  \times {}^{0}{\bf R}_{1} {}^{1}{\bf p}_{2} \
+ {}^{0}{\bf \omega}_{1} \times \left( {}^{0}{\bf \omega}_{1} \times {}^{0}{\bf R}_{1} {}^{1}{\bf p}_{2} \right) \
+ 2 {}^{0}{\bf \omega}_{1} \times {}^{0}{\bf R}_{1} {}^{1}{\bf \dot p}_{2} \
+ {}^{0}{\bf R}_{1} {}^{1}{\bf \ddot p}_{2} \\
\end{array}
$$

この式のうち、ほとんどの項がこれまでノートした話に出てきていますね。

右辺第一項目は、座標系\(\Sigma_{0}\)から見た座標系\( \Sigma_{2} \)の、回転系の回転方向(接線方向)へ向かう接線加速度、

右辺第二項目は、座標系\(\Sigma_{0}\)から見た座標系\( \Sigma_{2} \)の、回転系の回転軸へ向かう求心加速度になります。

右辺第三項目は、今回初めて出てきます。一体どんな大きさと方向でしょうか、あとで說明します。

右辺第四項目は、座標系\(\Sigma_{0}\)から見た座標系\( \Sigma_{2} \)の、並進運動の加速度です。

一定角速度で回転し、一定並進速度で移動しているとき、第一項の角加速度、第四項の並進加速度は0になりますが、第二項の求心加速度と第三項の加速度は残ります。

また、座標系\( \Sigma_{0} \)から見た座標系\( \Sigma_{2} \)の姿勢の加速度は、以下のようになります。

$$ \begin{array}{rcl}
{}^{0}\ddot{\bf R}_{2} &=&  \frac{\rm d}{\rm dt} \left( {}^{0}{\omega}_{1} \times {}^{0}{\bf R}_{2} \right) \\
&=&  {}^{0}{\dot \omega}_{1} \times {}^{0}{\bf R}_{2} + {}^{0}{\omega}_{1} \times {}^{0}{\bf \dot R}_{2} \\
&=&  {}^{0}{\dot \omega}_{1} \times {}^{0}{\bf R}_{2} + \
{}^{0}{\omega}_{1} \times \left( {}^{0}{\omega}_{1} \times {}^{0}{\bf R}_{2} \right) \\
\end{array}
$$

この式は、同じく剛体の運動(回転運動の速度、加速度、躍度)でまとめたものと同じです。

さて、今回の主役である座標系\( \Sigma_{0} \)から見た座標系\( \Sigma_{2} \)の、位置の加速度\( {}^{0}\ddot{\bf p}_{2} \)の式に現れた
第三項目

$$
2 {}^{0}{\bf \omega}_{1} \times {}^{0}{\bf R}_{1} {}^{1}{\bf \dot p}_{2}
$$

が、一体どのような加速度なのか見てみましょう。

\( {}^{0}{\bf \omega}_{1} \)は、座標系\( \Sigma_{0} \)から見ると回っている座標系\( \Sigma_{1} \)の、回転系の角速度ベクトルです。
その大きさは角速度\( \dot \theta \)、方向は回転軸\({}^{0}{\bf n}_{1} \)方向を指しています。

\( {}^{0}{\bf R}_{1} {}^{1}{\bf \dot p}_{2} \)は、座標系\( \Sigma_{0} \)から見た座標系\( \Sigma_{2} \)の、並進速度方向です。その点での移動方向ですね。

この二つの外積ということは、外積の性質上、両者に垂直な方向、
すなわち回転軸と並進移動方向の両者に垂直な方向に働く加速度になります。

その加速度の方向を、図を交えて具体的に見てみましょう。

環境に固定された基準座標系\( \Sigma_{0} \)から見て、ヨー軸回転しているロボットの回転座標系\( \Sigma_{1} \)があります。
その回転座標系\( \Sigma_{1}  \)上で、姿勢はそのままで、位置だけ並進移動している手先座標系\( \Sigma_{2} \)があるとします。

基準座標系\( \Sigma_{0} \)から見た回転座標系\( \Sigma_{1} \)の、姿勢は\( {}^{0}{\bf R}_{1} \)、回転速度ベクトルは\( {}^{0}{\bf \omega}_{1} \)、
座標系\( \Sigma_{1} \)から見た手先の座標系\( \Sigma_{2} \)の、位置は\( {}^{1}{\bf p}_{2} \)、並進速度のベクトルは\( {}^{1}{\bf \dot p}_{2} \)です。

上記の図では、基準座標系\( \Sigma_{0} \)の位置が、回転座標系\( \Sigma_{1} \)からずれた場所に描いちゃっていますが、両者の位置関係はとりあえず無視してください。

基準座標系\( \Sigma_{0} \)から見ると、手先の並進速度ベクトルは\( {}^{0}{\bf R}_{1} {}^{1}{\bf \dot p}_{2} \)となります。

並進速度ベクトル\( {}^{0}{\bf R}_{1} {}^{1}{\bf \dot p}_{2} \)を分解すると、回転速度ベクトル\( {}^{0}{\bf \omega}_{1} \)(回転軸)に平行な成分と、回転軸に垂直な面上に射影された方向成分に分解できます。

回転速度ベクトル\( {}^{0}{\bf \omega}_{1} \)と並進速度ベクトル\( {}^{1}{\bf \dot p}_{2} \)の外積 \( 2 {}^{0}{\bf \omega}_{1} \times {}^{0}{\bf R}_{1} {}^{1}{\bf \dot p}_{2} \) を、この分解した成分で考えると、回転軸に平行な成分との外積は0になります。そのため、並進速度ベクトルのうち、回転軸に垂直な面上に射影された方向だけ残ります。この残った射影成分を以下のように図示します。

並進速度ベクトル\( {}^{1}{\bf \dot p}_{2} \)の射影成分はベクトルなので、大きさと方向さえ同じならば図のどこに平行移動してもいいので、同一平面上の回転速度ベクトル\( {}^{0}{\bf \omega}_{1} \)(回転軸)へと開始点を平行移動させてみます。

この図に外積 \( 2 {}^{0}{\bf \omega}_{1} \times {}^{0}{\bf R}_{1} {}^{1}{\bf \dot p}_{2} \) を図示してみます。回転速度ベクトル\( {}^{0}{\bf \omega}_{1} \)と並進速度ベクトル\( {}^{0}{\bf R}_{1} {}^{1}{\bf \dot p}_{2} \)の両方に垂直なので、平行移動した並進速度ベクトルが描く回転円に接する方向に、外積のベクトル(赤線)を描けることがわかります。

外積 \( 2 {}^{0}{\bf \omega}_{1} \times {}^{0}{\bf R}_{1} {}^{1}{\bf \dot p}_{2} \) を、開始点を手先位置\( {}^{1}{\bf p}_{2} \)と共に平行移動して戻してやると、以下の図のようになります。

以上の図から分かるように、加速度 \( 2 {}^{0}{\bf \omega}_{1} \times {}^{0}{\bf R}_{1} {}^{1}{\bf \dot p}_{2} \) は、常に並進速度ベクトル\({\bf \dot p}_{2} \)を、回転軸に垂直な平面上へ射影し、さらにその射影方向に対し垂直にとった方向にはたらくことを表しています。

注意が必要なのは、平行移動したことから分かるように、加速度 \( 2 {}^{0}{\bf \omega}_{1} \times {}^{0}{\bf R}_{1} {}^{1}{\bf \dot p}_{2} \) は、位置\( {}^{1} {\bf p}_{2} \)(座標系\(\Sigma_{0}\)における\( {}^{0} {\bf p}_{1 \rightarrow 2} \))から、\(\Sigma_{1}\)の回転円接線方向に向いているわけではないということです。
あくまで並進速度ベクトル \( {}^{1}{\bf \dot p}_{2} \) に垂直な方向であるということを誤解してはいけません。

この加速度 \( 2 {}^{0}{\bf \omega}_{1} \times {}^{0}{\bf R}_{1} {}^{1}{\bf \dot p}_{2} \) は、回転系上で並進移動するときに必要になります。逆に手先座標系\(\Sigma_{2} \)から見ると、逆向きの方向の加速度 \( – 2 {}^{0}{\bf \omega}_{1} \times {}^{0}{\bf R}_{1} {}^{1}{\bf \dot p}_{2} \) がはたらいているように見えます。

この手先座標系\(\Sigma_{2} \)から見た加速度が、質点に対し働くみかけの力を、コリオリの力(Coriolis force)と呼ぶそうです。

この慣性力は、ガスパール=ギュスターヴ・コリオリ(Gaspard-Gustave Coriolis 1792年5月21日 – 1843年9月19日)さんが正式に導出したので、彼の名にちなんでコリオリの力と呼ばれるようになったそうです。物理法則に自分の名前が付くってすごいですよね。

5. まとめ(回転系上での伸縮における位置・姿勢の速度と加速度)

まとめます。

ステップ1. 座標系\(\Sigma_{0} \)基準の座標系\(\Sigma_{2} \)の位置\( {}^{0}{\bf p}_{2} \)、姿勢\( {}^{0}{\bf R}_{2} \)

座標系\(\Sigma_{0} \)基準の座標系\(\Sigma_{2} \)の位置\( {}^{0}{\bf p}_{2} \)を、入力\( {}^{0}{\bf p}_{1} \)、\( {}^{0}{\bf R}_{1} \)、\( {}^{1}{\bf p}_{2} \)を用いて以下のように求めます。

$$ \begin{array}{rcl}
{}^{0}{\bf p}_{2} = {}^{0}{\bf p}_{1} + {}^{0}{\bf R}_{1}{}^{1}{\bf p}_{2} \\
\end{array}
$$

座標系\(\Sigma_{0} \)基準の座標系\(\Sigma_{2} \)の姿勢\( {}^{0}{\bf R}_{2} \)を、入力\( {}^{0}{\bf R}_{1} \)、\( {}^{1}{\bf R}_{2} \)を用いて以下のように求めます。

$$ \begin{array}{rcl}
{}^{0}{\bf R}_{2} = {}^{0}{\bf R}_{1} {}^{1}{\bf R}_{2}
\end{array}
$$

ステップ2. (出力1) 座標系\(\Sigma_{0} \)基準で見た座標系\( \Sigma_{2} \)の位置・姿勢の速度\( {}^{0}\dot{\bf p}_{2} \)、\( {}^{0}\dot{\bf R}_{2} \)

座標系\(\Sigma_{0} \)基準で見た座標系\( \Sigma_{2}\)の位置・姿勢の速度\( {}^{0}\dot{\bf p}_{2} \)、\( {}^{0}\dot{\bf R}_{2} \)を、入力\( {}^{0}{\bf R}_{1} \)、\({}^{1}{\bf p}_{2} \)、ステップ1で求めた\({}^{0}{\bf R}_{2} \)を用いて以下のように求めます。

$$
\begin{array}{rcl}
{}^{0}{\bf \dot p}_{2} &=& {}^{0}{\bf \omega}_{1}  \times {}^{0}{\bf R}_{1} {}^{1}{\bf p}_{2} + {}^{0}{\bf R}_{1} {}^{1}{\bf \dot p}_{2}
\end{array}
$$

$$ \begin{array}{rcl}
{}^{0}\dot{\bf R}_{2} &=& {}^{0}{\omega}_{1} \times {}^{0}{\bf R}_{2}
\end{array}
$$

ステップ3. (出力2) 基準座標系\( \Sigma_{0} \)から見た座標系\( \Sigma_{2} \)の位置・姿勢の加速度\( {}^{0}\ddot{\bf p}_{2} \)、\( {}^{0}\ddot{\bf R}_{2} \)

基準座標系\( \Sigma_{0} \)から見た座標系\( \Sigma_{2} \)の位置・姿勢の加速度\( {}^{0}\ddot{\bf p}_{2} \)、\( {}^{0}\ddot{\bf R}_{2} \)を、入力\( {}^{0}{\bf R}_{1} \)、\({}^{1}{\bf p}_{2} \)、\( {}^{1}\ddot{\bf p}_{2} \)、\({}^{0}{\bf \omega}_{1} \)、\({}^{0}{\bf \dot \omega}_{1} \)、ステップ1.で求めた\\( {}^{0}{\bf R}_{2} \)により、以下のように求めます。

$$ \begin{array}{rcl}
{}^{0}\ddot{\bf p}_{2} &=& \
{}^{0}{\bf \dot \omega}_{1}  \times {}^{0}{\bf R}_{1} {}^{1}{\bf p}_{2} \
+ {}^{0}{\bf \omega}_{1} \times \left( {}^{0}{\bf \omega}_{1} \times {}^{0}{\bf R}_{1} {}^{1}{\bf p}_{2} \right) \
+ 2 {}^{0}{\bf \omega}_{1} \times {}^{0}{\bf R}_{1} {}^{1}{\bf \dot p}_{2} \
+ {}^{0}{\bf R}_{1} {}^{1}{\bf \ddot p}_{2} \\
\end{array}
$$

$$ \begin{array}{rcl}
{}^{0}\ddot{\bf R}_{2} &=& {}^{0}{\dot \omega}_{1} \times {}^{0}{\bf R}_{2} + \
{}^{0}{\omega}_{1} \times \left( {}^{0}{\omega}_{1} \times {}^{0}{\bf R}_{2} \right) \\
\end{array}
$$

6. コリオリの力の実用例

コリオリ式質量流量計

流量計といえば、自分が大学工学部1年で最初に習ったのは、
歯車式、ブローディ(BLODIE)式、ルーツ(ROOTS)式、ドラム式、オーバル式といった容量流量計、
オリフィス・ノズル、ベンチュリ管といった差圧式流量計などでしたが、
コリオリの力を利用したコリオリ式質量流量計というものもあるそうです。

曲がった(部分的に回転カーブした)管の中を通る流量が振動することでコリオリの力を発生させ、2点間の振動の変化をとり質量流量を測定するといった仕組みだそうです。

振動型ジャイロ

回転角速度を計測するジャイロセンサで、回転体上の振動に加わるコリオリの力を利用して回転角速度を測定する振動型ジャイロスコープという計測器があるそうです。

以下の図のように、多摩川精機さんのMEMSセンサには、
「速度を持った質量に角速度が加わると、速度方向と回転軸の両方に直交する方向にコリオリ力が生じる」という原理を使用して回転角速度を測定されているそうです。

TAMAGAWA SEIKI CO. ジャイロセンサについて( http://mems.tamagawa-seiki.com/tec_info/mems_gyro.html )

ふぅ~

コリオリの力というと、
長い振り子の先につけた質量の大きいおもりに働くコリオリの力を観測することでレオン・フーコーさんが地球の自転を証明した話とか、
低気圧の移動がコリオリの力を受けて右回りの渦になる、などスケールの大きな話が例に上がるのですが、
もっと工学寄りで身近なセンサにも使われていることに目を向けたいと思い計測器での利用例を探して挙げました。

回転と伸縮が組み合わさった運動をする物体はすべてコリオリの力を受けます。
台座(または腰軸)が高速回転する回転系上で、手先の物体を高速並進移動させるなど、
ロボットの動力学でも、制御モデルの中にコリオリの力を考えておく必要があるでしょう。

以上です。

剛体の運動(二つの回転軸まわりの運動―ジャイロ効果)

こんにちは。だいCです。

これまで一つの回転軸まわりの回転運動だけ考えてきましたが、
今回からはさらに別の回転や並進運動も複合させた運動についても考えていこうと思います。

いずれは連鎖座標系の速度・加速度としてまとめようと思いますが、
まずは、回転&回転、回転&並進の場合で個別に見ていこうと思います。

今回は回転&回転についてノートします。

1. 目的

二つの回転軸まわりの回転運動における、質点の位置姿勢の速度・加速度を求める

2. 二つの回転軸まわりの回転を考える場面

二つの回転軸まわりの回転を考える場面は、いろいろあると思います。

複数関節軸をもつロボットが各軸同時に動作したときに各関節にかかる速度や加速度を知りたいとき、

順動力学について考えるときなどなど。

今回は例として、以下の図のように直交する二つの回転軸をもつロボットを考えます。

二つの回転軸をもつロボットの関節イメージ

3. 前提

  • 二つの回転を回転1、回転2とします。
  • 基準座標系を\( \Sigma_{0} \)、回転1と一緒に回る座標系を\( \Sigma_{1} \)、回転2と一緒に回る座標系を\( \Sigma_{2} \)とします。
  • 入力1:基準座標系\( \Sigma_{0} \)から見た座標系\( \Sigma_{1} \)の位置\( {}^{0}{\bf p}_{1} \)(一定)
  • 入力2:基準座標系\( \Sigma_{0} \)から見た座標系\( \Sigma_{1} \)の姿勢\( {}^{0}{\bf R}_{1} \)
  • 入力3:基準座標系\( \Sigma_{0} \)から見た座標系\( \Sigma_{1} \)の角速度ベクトル\( {}^{0}{\bf \omega}_{1} \) ( 回転軸\({}^{0}{\bf n}_{1} \), 角速度\(\dot{\theta_1}\) )
  • 入力4:基準座標系\( \Sigma_{0} \)から見た座標系\( \Sigma_{1} \)の角加速度ベクトル\( {}^{0}\dot{\bf \omega}_{1} \) ( 回転軸\({}^{0}{\bf n}_{1} \), 角速度\(\ddot{\theta_1}\) )
  • 入力5:座標系\( \Sigma_{1} \)から見た座標系\( \Sigma_{2} \)の位置\( {}^{1}{\bf p}_{2} \)(一定)
  • 入力6:座標系\( \Sigma_{1} \)から見た座標系\( \Sigma_{2} \)の姿勢\( {}^{1}{\bf R}_{2} \)(一定)
  • 入力7:座標系\( \Sigma_{2} \)から見た、座標系\( \Sigma_{2} \)と一緒に回るある点Pの位置ベクトル\( {}^{2}{\bf p}_{A} \)(一定)
  • 入力8:座標系\( \Sigma_{1} \)から見た座標系\( \Sigma_{2} \)の角速度ベクトル\( {}^{1}{\bf \omega}_{2} \) ( 回転軸\({}^{1}{\bf n}_{2} \), 角速度\(\dot{\theta_2}\) )
  • 入力9:座標系\( \Sigma_{1} \)から見た座標系\( \Sigma_{2} \)の角加速度ベクトル\( {}^{1}\dot{\bf \omega}_{2} \) ( 回転軸\({}^{1}{\bf n}_{2} \), 角速度\(\ddot{\theta_2}\) )
  • 出力1:基準座標系\( \Sigma_{0} \)から見た座標系\( \Sigma_{2} \)の角速度ベクトル\( {}^{0}{\bf \omega}_{2} \)
  • 出力2:基準座標系\( \Sigma_{0} \)から見た座標系\( \Sigma_{2} \)の位置・姿勢の速度\( {}^{0}\dot{\bf p}_{2} \)、\( {}^{0}\dot{\bf R}_{2} \)
  • 出力3:基準座標系\( \Sigma_{0} \)から見た座標系\( \Sigma_{2} \)の角加速度ベクトル\( {}^{0}\dot{\bf \omega}_{2} \)
  • 出力4:基準座標系\( \Sigma_{0} \)から見た座標系\( \Sigma_{2} \)の位置・姿勢の加速度\( {}^{0}\ddot{\bf p}_{2} \)、\( {}^{0}\ddot{\bf R}_{2} \)
  • 二つの回転の効果のみ注目したいので重力加速度を無視します。無重力状態でロボットを動かしているとしましょう。

4. 準備

座標系\(\Sigma_{1}\)基準の座標系\(\Sigma_{2}\)への相対的なベクトルを、座標系\(\Sigma_{0}\)基準に変換すると以下のようになります。

$$
{}^{0}{\bf p}_{1 \rightarrow 2} = {}^{0}{\bf R}_{1} {}^{1}{\bf p}_{2}
$$

角速度ベクトル\(\bf \omega\)についても同じことがいえます。

$$
{}^{0}{\bf \omega}_{1 \rightarrow 2} = {}^{0}{\bf R}_{1} {}^{1}{\bf \omega}_{2}
$$

剛体の運動(回転行列の速度とは)でノートしましたが、
ある位置の点\(\bf p\)とその姿勢\( \bf R \)が角速度ベクトル\(\bf \omega \)で回転すると、その位置と姿勢の速度(\( \dot{\bf p} \), \( \dot{\bf R} \))は以下のように表すことができたのでした。

$$ \begin{array}{rcl}
{\dot {\bf p}} &=&  {\bf \omega} \times {\bf p}
\end{array}
$$

$$ \begin{array}{rcl}
{\dot {\bf R}} &=& [{\bf \omega} \times] {\bf R} \\
&=& {\bf \omega} \times {\bf R}
\end{array}
$$

5. 二つの回転軸まわりの回転における位置・姿勢の速度と加速度

座標系\(\Sigma_{0} \)基準の座標系\(\Sigma_{2} \)の位置\( {}^{0}{\bf p}_{2} \)は、入力\( {}^{0}{\bf p}_{1} \)、\( {}^{0}{\bf R}_{1} \)、\( {}^{1}{\bf p}_{2} \)を用いて以下のように求まります。

$$ \begin{array}{rcl}
{}^{0}{\bf p}_{2} &=& {}^{0}{\bf p}_{1} + {}^{0}{\bf p}_{1 \rightarrow 2}  \\
&=& {}^{0}{\bf p}_{1} + {}^{0}{\bf R}_{1}{}^{1}{\bf p}_{2}
\end{array}
$$

座標系\(\Sigma_{0} \)基準の座標系\(\Sigma_{2} \)の姿勢\( {}^{0}{\bf R}_{2} \)は、入力\( {}^{0}{\bf R}_{1} \)、\( {}^{1}{\bf R}_{2} \)を用いて以下のように求まります。

$$ \begin{array}{rcl}
{}^{0}{\bf R}_{2} = {}^{0}{\bf R}_{1} {}^{1}{\bf R}_{2}
\end{array}
$$

以降、この\( {}^{0}{\bf p}_{2} \)、\( {}^{0}{\bf R}_{2} \)を用います。

準備で述べたとおり、座標系\(\Sigma_{1} \)基準で見た回転する座標系\( \Sigma_{2}\)の相対的な回転速度ベクトル\( {}^{1}{\bf \omega}_{2} \)は、
座標系\(\Sigma_{0} \)基準\( {}^{0}{\bf \omega}_{1 \rightarrow 2} \)に変換すると以下のようになります。

$$
{}^{0}{\bf \omega}_{1 \rightarrow 2} = {}^{0}{\bf R}_{1} {}^{1}{\bf \omega}_{2}
$$

これを用いて、座標系\(\Sigma_{0} \)基準で見た回転する座標系\( \Sigma_{2}\)の回転速度ベクトル\( {}^{0}{\bf \omega}_{2} \)は、ベクトルの合成により以下のように表せます。

$$
{}^{0}{\bf \omega}_{2} = {}^{0}{\bf \omega}_{1} + {}^{0}{\bf \omega}_{1 \rightarrow 2}
$$

準備で述べたとおり、
座標系\( \Sigma_{0} \)基準で見た回転する座標系\( \Sigma_{2} \)上の位置の点\( {}^{0}{\bf p}_{2} \)とその姿勢\( {}^{0}{\bf R}_{2} \)が角速度ベクトル\({}^{0}{\bf \omega}_{2} \)で回転したとき、
その位置と姿勢の速度(\( {}^{0}{\dot{\bf p}}_{2} \), \( {}^{0}{\dot{\bf R}}_{2} \))は、それらの外積で求まるため、以下のように表せます。

$$ \begin{array}{rcl}
{}^{0}{\dot {\bf p}}_{2} &=& {}^{0}{\bf \omega}_{2} \times {}^{0}{\bf p}_{2} \\ 
&=& {}^{0}{\bf \omega}_{2} \times ( {}^{0}{\bf p}_{1} + {}^{0}{\bf p}_{1 \rightarrow 2} + {}^{0}{\bf p}_{2 \rightarrow 2} ) \\
&=& {}^{0}{\bf \omega}_{2} \times {}^{0}{\bf p}_{1 \rightarrow 2} + {}^{0}{\bf \omega}_{2} \times {}^{0}{\bf p}_{2 \rightarrow 2} \\
&=& ( {}^{0}{\bf \omega}_{1} + {}^{0}{\bf \omega}_{1 \rightarrow 2} ) \times {}^{0}{\bf p}_{1 \rightarrow 2} + ( {}^{0}{\bf \omega}_{1} + {}^{0}{\bf \omega}_{1 \rightarrow 2} ) \times {}^{0}{\bf p}_{2 \rightarrow 2} \\
&=& {}^{0}{\bf \omega}_{1} \times {}^{0}{\bf p}_{1 \rightarrow 2}
\end{array}
$$

$$ \begin{array}{rcl}
{}^{0}\dot{\bf R}_{2} &=& {}^{0}{\bf \omega}_{2} \times {}^{0}{\bf R}_{2}
\end{array}
$$

ただし注意が必要な点として、角速度ベクトル \({\bf \omega}_{2}\) によって発生する並進速度 \({}^{0}{\dot {\bf p}}_{2}\) は、位置 \({}^{0}{\bf p}_{2} = {}^{0}{\bf p}_{1} + {}^{0}{\bf p}_{1 \rightarrow 2} + {}^{0}{\bf p}_{2 \rightarrow 2}\) の変位成分のうち角速度ベクトル \({\bf \omega}_{2}\) の回転を受ける成分のみです。 \({}^{0}{\bf p}_{1}\) は回転前の変位であるため関与しません。発生する速度はゼロです。\({}^{0}{\bf p}_{1 \rightarrow 2}\) は、角速度ベクトル \({}^{0}{\bf \omega}_{2}\)のうち \({}^{0}{\bf \omega}_{1}\) の回転を受けますが、 \({}^{0}{\bf \omega}_{1 \rightarrow 2}\) については座標系 \(\Sigma_{2}\) 以降の回転でありこれには関与しません。 \({}^{0}{\bf \omega}_{1 \rightarrow 2}\) の回転を受けるのは \({}^{0}{\bf p}_{2 \rightarrow 2}\) ですが、これは座標系 \(\Sigma_{2}\) 原点であり変位がゼロであるため速度もゼロです。

少し補足になりますが、導出の順序を入れ替えて、\({}^{0}{\bf R}_{2}\)の入力\( {}^{0}{\bf R}_{1} \)、\( {}^{1}{\bf R}_{2} \)との関係から微分して、\({}^{0}{\bf \omega}_{2}\)を導出することもできます。

$$ \begin{array}{rcl}
{}^{0}\dot{\bf R}_{2} &=& \frac{d}{dt} \left(  {}^{0}{\bf R}_{1} {}^{1}{\bf R}_{2} \right) \\
&=& {}^{0}{\dot{\bf R}}_{1} {}^{1}{\bf R}_{2} + {}^{0}{\bf R}_{1} {}^{1}{\dot{\bf R}}_{2} \\
&=& [{}^{0}{\omega}_{1} \times] {}^{0}{\bf R}_{1} {}^{1}{\bf R}_{2} + {}^{0}{\bf R}_{1} [{}^{1}{\omega}_{2} \times]{}^{1}{\bf R}_{2} \\
&=& [{}^{0}{\omega}_{1} \times] {}^{0}{\bf R}_{1} {}^{1}{\bf R}_{2} +  [ \left( {}^{0}{\bf R}_{1}{}^{1}{\omega}_{2} \right) \times] {}^{0}{\bf R}_{1}{}^{1}{\bf R}_{2} \\
&=& [{}^{0}{\omega}_{1} \times] {}^{0}{\bf R}_{2} +  [ {}^{0}{\omega}_{1 \rightarrow 2} \times] {}^{0}{\bf R}_{2} \\
&=& [\left( {}^{0}{\omega}_{1} + {}^{0}{\omega}_{1 \rightarrow 2} \right) \times] {}^{0}{\bf R}_{2} \\
&=& [{}^{0}{\bf \omega}_{2} \times] {}^{0}{\bf R}_{2} \\
&=& {}^{0}{\bf \omega}_{2} \times {}^{0}{\bf R}_{2}
\end{array}
$$

外積と行列の性質から、第三式目から第四式目の変形でだいぶトリッキーな計算をしていますが、第六式目から第七式目の変形より、

$$
{}^{0}{\bf \omega}_{2} = {}^{0}{\bf \omega}_{1} + {}^{0}{\bf \omega}_{1 \rightarrow 2}
$$

と表すことができました。補足終わりです。

剛体の運動(回転運動の速度・加速度・躍度)でやったように、
速度を微分することで、点の位置・姿勢の加速度を求めます。

$$ \begin{array}{rcl}
{}^{0}\ddot{\bf p}_{2} &=& \
{}^{0}{\dot{\bf \omega}}_{2} \times {}^{0}{\bf p}_{2} \
+ {}^{0}{\bf \omega}_{2} \times \left( {}^{0}{\bf \omega}_{2} \times {}^{0}{\bf p}_{2} \right) \\
\end{array}
$$

$$ \begin{array}{rcl}
{}^{0}\ddot{\bf R}_{2} &=& \
{}^{0}{\dot{\bf \omega}}_{2} \times {}^{0}{\bf R}_{2} \
+ {}^{0}{\bf \omega}_{2} \times \left( {}^{0}{\bf \omega}_{2} \times {}^{0}{\bf R}_{2} \right) \\
\end{array}
$$

第二項目は上で求めた\( {}^{0}{\bf \omega}_{2} \)、\( {}^{0}{\bf R}_{2} \)により求められます。加速方向はベクトル\( {}^{0}{\bf \omega}_{2} \)軸に向かう方向で、求心加速度です。

第一項目の角加速度\( {}^{0}{\dot{\bf \omega}}_{2} \)について、さらに、角速度ベクトル\( {}^{0}{\bf \omega}_{2} \)を\( {}^{0}{\bf \omega}_{1} \)、\( {}^{0}{\bf \omega}_{1 \rightarrow 2} \)に分解して求めてみます。

$$ \begin{array}{rcl}
{}^{0}{\dot{\bf \omega}}_{2} \
&=& \
\frac{d}{dt} \left( {}^{0}{\bf \omega}_{1} + {}^{0}{\bf \omega}_{1 \rightarrow 2} \right) \\
&=& \
{}^{0}{\dot{\bf \omega}}_{1} + {}^{0}{\dot{\bf \omega}}_{1 \rightarrow 2} \\
&=& \
{}^{0}{\dot{\bf \omega}}_{1} + \frac{d}{dt} \left( {}^{0}{\bf R}_{1} {}^{1}{\bf \omega}_{2} \right) \\
&=& \
{}^{0}{\dot{\bf \omega}}_{1} + {}^{0}{\dot{\bf R}}_{1} {}^{1}{\bf \omega}_{2} + {}^{0}{\bf R}_{1} {}^{1}{\dot{\bf \omega}}_{2} \\
&=& \
{}^{0}{\dot{\bf \omega}}_{1} + {}^{0}{\bf \omega}_{1} \times {}^{0}{\bf R}_{1} {}^{1}{\bf \omega}_{2} + {}^{0}{\bf R}_{1} {}^{1}{\dot{\bf \omega}}_{2} \\
&=& \
{}^{0}{\dot{\bf \omega}}_{1} + {}^{0}{\bf \omega}_{1} \times {}^{0}{\bf \omega}_{1 \rightarrow 2} + {}^{0}{\bf R}_{1} {}^{1}{\dot{\bf \omega}}_{2} \\
\end{array}
$$

第一項目は、座標系\( \Sigma_{0} \)基準の座標系\( \Sigma_{1} \)の角加速度、
第三項目は、座標系\( \Sigma_{1} \)基準の座標系\( \Sigma_{2} \)の角加速度を、座標系\( \Sigma_{0} \)基準に変換したものといえます。
第二項目は、入力の角速度\( {}^{0}{\bf \omega}_{1} \)と\( {}^{0}{\bf \omega}_{1 \rightarrow 2} \)の外積になっています。回転1と回転2が一定角速度で回転する場合、第一項目、第三項目のような角加速度は0になりますが、第二項目の加速度は残ります。
この第二項目の角加速度\( {}^{0}{\bf \omega}_{1} \times {}^{0}{\bf \omega}_{1 \rightarrow 2} \)の意味について考えてみましょう。

以下の図に、ある点\( {}^{0}{\bf p} \)に働く加速度\( {}^{0}{\bf \omega}_{1} \times {}^{0}{\bf \omega}_{1 \rightarrow 2} \)(図中オレンジ)のイメージを描いてみました。

ジャイロ効果のイメージ

角速度ベクトル\( {}^{0}{\bf \omega}_{1} \)の回転1の運動と、その回転(座標系\( \Sigma_{1} \))上で角速度ベクトル\( {}^{0}{\bf \omega}_{1 \rightarrow 2} \)(座標系\( \Sigma_{0} \)基準)まわりに回転する回転2の運動が合成されて、結果として角速度ベクトル\( {}^{0}{\bf \omega}_{2} \)まわりに回転しているとします。

点Pを合成の角速度ベクトル\( {}^{0}{\bf \omega}_{2} \)まわりに回転するには、図中紫色のベクトル\( {}^{0}{\bf \omega}_{1} \)と青色のベクトル\( {}^{0}{\bf \omega}_{1 \rightarrow 2} \)まわりにそれぞれ回転するための加速度を必要とし、さらに両方の角速度ベクトルに直交するオレンジ色のベクトル軸(奥へと中心を貫通してる矢印)まわりの加速度を必要とします。

この加速度は、図中点Pから出るオレンジ色の矢印によって表されています。
分解すると、図の上方向である回転1の角速度ベクトル\( {}^{0}{\bf \omega}_{1} \)軸方向と、その回転円接線方向にそれぞれ働く加速度が点Pには必要だとわかります。

無重力状態で質量をもった物体が同じ2軸の回転運動をした時、この点Pから出るオレンジ色方向の必要な加速度(力)を与えないと、その反対方向に慣性力が働き、合成された回転の角速度ベクトル\( {}^{0}{\bf \omega}_{2} \)の軸を回転1のベクトル\( {}^{0}{\bf \omega}_{1} \)方向に戻そうとしてしまいます。
すなわち回転2を打ち消す加速度(力)が働きます。
この物理現象をジャイロ効果(gyro effect)と呼ぶそうです。

重力下だと、図中点Pから出るオレンジ色の矢印の、分解した上方向の力と重力が一部相殺され、回転円接線方向のみ残るため、合成された回転の角速度ベクトル\( {}^{0}{\bf \omega}_{2} \)の軸を、ベクトル\( {}^{0}{\bf \omega}_{1} \)軸まわりに回転させる力が働くことがわかります。
これが独楽(こま)などの歳差運動(precession)の原理です。

6. まとめ(二つの回転軸まわりの回転運動における、質点の位置姿勢の速度・加速度)

まとめます。

ステップ1. 座標系\(\Sigma_{0} \)基準の座標系\(\Sigma_{2} \)の位置\( {}^{0}{\bf p}_{2} \)、姿勢\( {}^{0}{\bf R}_{2} \)

座標系\(\Sigma_{0} \)基準の座標系\(\Sigma_{2} \)の位置\( {}^{0}{\bf p}_{2} \)を、入力\( {}^{0}{\bf p}_{1} \)、\( {}^{0}{\bf R}_{1} \)、\( {}^{1}{\bf p}_{2} \)を用いて以下のように求めます。

$$ \begin{array}{rcl}
{}^{0}{\bf p}_{2} = {}^{0}{\bf p}_{1} + {}^{0}{\bf R}_{1}{}^{1}{\bf p}_{2} \\
\end{array}
$$

座標系\(\Sigma_{0} \)基準の座標系\(\Sigma_{2} \)の姿勢\( {}^{0}{\bf R}_{2} \)を、入力\( {}^{0}{\bf R}_{1} \)、\( {}^{1}{\bf R}_{2} \)を用いて以下のように求めます。

$$ \begin{array}{rcl}
{}^{0}{\bf R}_{2} = {}^{0}{\bf R}_{1} {}^{1}{\bf R}_{2}
\end{array}
$$

ステップ2. 座標系\(\Sigma_{0} \)基準で見た座標系\( \Sigma_{1}\)から\( \Sigma_{2}\)への相対的な角速度ベクトル\( {}^{0}{\bf \omega}_{1 \rightarrow 2} \)

座標系\(\Sigma_{0} \)基準で見た座標系\( \Sigma_{1}\)から座標系\( \Sigma_{2}\)への相対的な回転速度ベクトル\( {}^{0}{\bf \omega}_{1 \rightarrow 2} \)を、入力\( {}^{0}{\bf R}_{1} \)、\({}^{1}{\bf \omega}_{2} \)を用いて以下のように求めます。

$$
{}^{0}{\bf \omega}_{1 \rightarrow 2} = {}^{0}{\bf R}_{1} {}^{1}{\bf \omega}_{2}
$$

ステップ3. (出力1) 基準座標系\( \Sigma_{0} \)から見た座標系\( \Sigma_{2} \)の角速度ベクトル\( {}^{0}{\bf \omega}_{2} \)

座標系\(\Sigma_{0} \)基準で見た回転する座標系\( \Sigma_{2}\)の回転速度ベクトル\( {}^{0}{\bf \omega}_{2} \)を、入力\( {}^{0}{\bf \omega}_{1} \)とステップ2.で求めた\( {}^{0}{\bf \omega}_{1 \rightarrow 2} \)のベクトルの合成により、以下のように求めます。

$$
{}^{0}{\bf \omega}_{2} = {}^{0}{\bf \omega}_{1} + {}^{0}{\bf \omega}_{1 \rightarrow 2}
$$

ステップ4. (出力2) 基準座標系\( \Sigma_{0} \)から見た座標系\( \Sigma_{2} \)の位置・姿勢の速度\( {}^{0}\dot{\bf p}_{2} \)、\( {}^{0}\dot{\bf R}_{2} \)

基準座標系\( \Sigma_{0} \)から見た座標系\( \Sigma_{2} \)の位置・姿勢の速度\( {}^{0}\dot{\bf p}_{2} \)、\( {}^{0}\dot{\bf R}_{2} \)を、ステップ1.で求めた\( {}^{0}{\bf p}_{2} \)、\( {}^{0}{\bf R}_{2} \)、ステップ3.で求めた\( {}^{0}{\bf \omega}_{2} \)により、以下のように求めます。

$$ \begin{array}{rcl}
{}^{0}{\dot {\bf p}}_{2} &=&  {}^{0}{\bf \omega}_{2} \times {}^{0}{\bf p}_{2} \\
&=& {}^{0}{\bf \omega}_{1} \times {}^{0}{\bf p}_{1 \rightarrow 2}
\end{array}
$$

$$ \begin{array}{rcl}
{}^{0}\dot{\bf R}_{2} &=& {}^{0}{\bf \omega}_{2} \times {}^{0}{\bf R}_{2}
\end{array}
$$

ステップ5. (出力3) 基準座標系\( \Sigma_{0} \)から見た座標系\( \Sigma_{2} \)の角加速度ベクトル\( {}^{0}\dot{\bf \omega}_{2} \)

基準座標系\( \Sigma_{0} \)から見た座標系\( \Sigma_{2} \)の角加速度ベクトル\( {}^{0}\dot{\bf \omega}_{2} \)を、入力\( {}^{0}{\bf R}_{1} \)、\( {}^{0}{\bf \omega}_{1} \)、\( {}^{0}{\dot{\bf \omega}}_{1} \)、\( {}^{1}{\dot{\bf \omega}}_{2} \)と、ステップ2.で求めた\(  {}^{0}{\bf \omega}_{1 \rightarrow 2} \)により、以下のように求めます。

$$ \begin{array}{rcl}
{}^{0}{\dot{\bf \omega}}_{2} \
&=& \
{}^{0}{\dot{\bf \omega}}_{1} + {}^{0}{\bf \omega}_{1} \times {}^{0}{\bf \omega}_{1 \rightarrow 2} + {}^{0}{\bf R}_{1} {}^{1}{\dot{\bf \omega}}_{2} \\
\end{array}
$$

回転1と回転2が等角速度で回転するとき、\( {}^{0}\dot{\bf \omega}_{2} \)は、以下のように第二項目のジャイロ効果のみになります。

$$ \begin{array}{rcl}
{}^{0}{\dot{\bf \omega}}_{2} \
&=& \
{}^{0}{\bf \omega}_{1} \times {}^{0}{\bf \omega}_{1 \rightarrow 2} \\
\end{array}
$$

ステップ6. (出力4) 基準座標系\( \Sigma_{0} \)から見た座標系\( \Sigma_{2} \)の位置・姿勢の加速度\( {}^{0}\ddot{\bf p}_{2} \)、\( {}^{0}\ddot{\bf R}_{2} \)

基準座標系\( \Sigma_{0} \)から見た座標系\( \Sigma_{2} \)の位置・姿勢の加速度\( {}^{0}\ddot{\bf p}_{2} \)、\( {}^{0}\ddot{\bf R}_{2} \)を、ステップ1.で求めた\( {}^{0}{\bf p}_{2} \)、\( {}^{0}{\bf R}_{2} \)、ステップ3.で求めた\( {}^{0}{\bf \omega}_{2} \)、ステップ5.で求めた\( {}^{0}{\dot{\bf \omega}}_{2} \) により、以下のように求めます。

$$ \begin{array}{rcl}
{}^{0}\ddot{\bf p}_{2} &=& \
{}^{0}{\dot{\bf \omega}}_{2} \times {}^{0}{\bf p}_{2} \
+ {}^{0}{\bf \omega}_{2} \times \left( {}^{0}{\bf \omega}_{2} \times {}^{0}{\bf p}_{2} \right) \\
\end{array}
$$

$$ \begin{array}{rcl}
{}^{0}\ddot{\bf R}_{2} &=& \
{}^{0}{\dot{\bf \omega}}_{2} \times {}^{0}{\bf R}_{2} \
+ {}^{0}{\bf \omega}_{2} \times \left( {}^{0}{\bf \omega}_{2} \times {}^{0}{\bf R}_{2} \right) \\
\end{array}
$$

以上でまとめは終わりです。

7. ジャイロ効果の参考動画

YouTubeを漁るとジャイロ効果に関連する動画はたくさんありますね。ググってすぐ出てきたのをいくつかピックアップしときます。

無重力下の実験動画

NASAの宇宙飛行士Michael E. Fossumさんが、宇宙船での無重力下でジャイロ効果を解説してくれています。
ジャイロ効果により、二つ目の回転が打ち消され、元の回転軸方向に戻ろうとしているのが分かると思います。

3Dモデルで直交2軸回転のジャイロ効果の解説

直感的でわかりやすい動画だったので挙げさせてもらいました。
この動画をアップロードされたJeff Kosmoskiさんは、ググるとKOZM Guitarsというギターのデザイナさんみたいですね。
数式も使わず解説してくれていて、わかりやすいです。

重力下のジャイロ効果いろいろ

重力下のジャイロ効果を応用して、コマの支点に重心位置を合わせたマクスウェルの独楽なんておもちゃもあります。

回転が速いと、支点から重心を結ぶ軸に対し、ジャイロ効果が重力に勝り、その軸を起き上げる方向に力が働き、重心が上に移動する、という現象を逆立ち独楽を分かりやすくして実験してくれてる以下の動画もありました。

あまりこのページでは触れませんが、ジャイロ効果は回転と質量で働く慣性モーメントとして働きます。
逆立ち独楽と同じように、回転している物体が重力を打ち消す現象をわかりやすく試してくれてる動画もありました。
実はこれは、自転車が倒れない仕組みでもあるんですね。

これら不思議な現象も、回転の原理が分かると見てて面白いですね。

リアクションホイール

ジャイロ効果は、宇宙空間の人工衛星の運動制御や、一部移動ロボットの姿勢制御で使われたりします。

最近だとJAXAが三軸姿勢制御モジュールという箱を開発したという記事を見かけたりしましたが、
下にもうちょっと先に記事で見かけたチューリッヒ工科大学(ETH zurich)が開発したCubliを上げておきます。
詳しくはCubliのページで。

このようにジャイロ効果を応用して、機体内部に十分な質量を持ち回転エネルギーをもつ円盤などの回転体(フライホイール)を速度制御して、重心姿勢を制御する装置をリアクションホイールというそうです。

リアクションホイールを使ったロボットといえば、自分の中で一番最初に上がるのは、やはりムラタセイサク君ですね。
「リアクションホイール」という言葉自体、ムラタセイサク君の紹介を見て初めて知った覚えがあります。

ふう、、

今回は、ジャイロ効果の說明をノートしたのですが、関連動画が多めになってしまいました。
他にもブーメランの原理や、ジャイロ効果で遠方まで飛ぶX-Zylo(WMC(William Mark Corporation)製)というおもちゃにも触れたかったのですが、割愛します。

ジャイロ効果の現象は、回転運動の中でも非常に面白い話だと思います。

今回は以上です

剛体の運動(回転運動の速度・加速度・躍度)

こんにちは。だいCです。

 

今回は回転運動によって発生する、直交座標空間上の速度、加速度、躍度についてノートします。

 

1. 目的

一つの回転軸まわりの回転運動における、質点の位置姿勢の速度、加速度、躍度を求める

 

2. 前提

  • 運動対象:ある点Pとします。
  • 基準座標系:\( \Sigma_{0} \)とします。
  • 運動対象の表現:基準座標系\( \Sigma_{0} \)から見た点Pの位置ベクトル\( {}^{0}{\bf p} \)で表現します。
  • 入力1(予め既知の情報):点Pの位置\( {}^{0}{\bf p} \)
  • 入力2(予め既知の情報):角速度ベクトル\( \bf \omega \)(回転軸ベクトル\( \bf n \)、角速度\(\dot{\theta}\) )
  • 入力3(予め既知の情報):角加速度ベクトル\( \dot{\bf \omega} \)(回転軸ベクトル\( \bf n \)、角加速度\(\ddot{\theta}\) )
  • 入力4(予め既知の情報):角躍度ベクトル\( \ddot{\bf \omega} \)(回転軸ベクトル\( \bf n \)、角躍度\( {\theta}^{(3)} \) )
  • 出力1(今回算出する情報):点Pの速度\( {}^{0}\dot{\bf p} \)
  • 出力2(今回算出する情報):点Pの加速度\( {}^{0}\ddot{\bf p} \)
  • 出力3(今回算出する情報):点Pの躍度\( {}^{0}{\bf p}^{(3)} \)

剛体の運動(回転行列の速度とは)で說明しましたが、
\( {}^{0}{\bf p} \)は、基底ベクトル\( {}^{0}{\bf x}_{{}^{0}{\bf e}_{x}}\), \( {}^{0}{\bf y}_{{}^{0}{\bf e}_{y}}\), \( {}^{0}{\bf z}_{{}^{0}{\bf e}_{z}}\)について考えるのと同じです。

 

3. 線形写像―微分

微分して求めていきます。

  • 速度は位置の微分
  • 加速度は速度の微分
  • 躍度は加速度の微分

今回座標系はあまり気にしない話ですが、

一応基準座標系\( O\)を変数左上に記述しておきます。

 

4. 回転運動の速度

回転行列の基底ベクトルの回転速度について考えた時と同じです。

おさらいになりますが、一つの回転軸による回転の角速度ベクトル\( {}^{0}{\bf \omega} \)により、点Pの速度\( {}^{0}{\dot{\bf p}} \)は以下の式で表されます。

$$ \begin{array}{rcl}
{}^{0}{\dot{\bf p}} &=& {}^{0}{\bf \omega} \times {}^{0}{\bf p} \\
&=& [{}^{0}{\bf \omega} \times] {}^{0}{\bf p}
\end{array}
$$

ここで、この速度の方向と大きさについて見てみましょう。

2つのベクトルの外積をとると、

・方向が両ベクトルに直交し且つ掛ける順の右ねじ回転で進む方向となり、

・大きさがその2つのベクトルが張る平行四辺形の面積となるベクトルとなるのでした。

また、大きさ1の回転軸ベクトル\( {}^{0}{\bf n} \)、回転角\( \theta \)により、角速度ベクトルは \( {}^{0}{\bf \omega} = \dot{\theta} {}^{0}{\bf n} \)という定義でした。

以上を踏まえて、速度ベクトル\( {}^{0}{\dot{\bf p}} = {}^{0}{\bf \omega} \times {}^{0}{\bf p} \)の大きさと方向は以下のようになります。

  • 方向は、角速度ベクトル\( {}^{0}{\bf \omega} \)の方向=回転軸ベクトル\( \bf n \)の方向と、回転対象の点Pの位置ベクトル\( {}^{0}{\bf p} \)が直交する方向になります。
  • 大きさは、回転軸\( {}^{0}{\bf n} \)と位置ベクトル\( {}^{0}{\bf p} \)のなす角を\( \alpha \)とすると、
    $$
    |{}^{0}{\bf \omega} \times {}^{0}{\bf p}| = |{}^{0}{\bf \omega}| |{}^{0}{\bf p}| |{\rm sin}\alpha| = |{\dot{\theta} {}^{0}{\bf n} }| |{}^{0}{\bf p}| |{\rm sin}\alpha| = |\dot{\theta}| |{}^{0}{\bf p}| |{\rm sin}\alpha|
    $$
    さらに点Pと回転軸(直線)の距離 \( r := |{}^{0}{\bf p}| {\rm sin}\alpha \) と置くと、結局大きさは\( |\dot{\theta}| |r| \)となります。

 

5. 回転運動の加速度

加速度\( {}^{0}{\ddot{\bf p}} \)は、速度\( {}^{0}{\dot{\bf p}} \)の微分により以下のように求まります。

$$ \begin{array}{rcl}
{}^{0}{\ddot{\bf p}} &=& \frac{d {}^{0}{\dot{\bf p}} }{dt} \\
&=& \frac{d}{dt} \left( {}^{0}{\bf \omega} \times {}^{0}{\bf p} \right) \\
&=& \frac{d}{dt} \left( {}^{0}{\bf \omega} \right) \times {}^{0}{\bf p} + {}^{0}{\bf \omega} \times \frac{d}{dt} \left({}^{0}{\bf p} \right) \\
&=& {}^{0}{\dot{\bf \omega}} \times {}^{0}{\bf p} + {}^{0}{\bf \omega} \times {}^{0}{\dot{\bf p}} \\
&=& {}^{0}{\dot{\bf \omega}} \times {}^{0}{\bf p} + {}^{0}{\bf \omega} \times \left( {}^{0}{\bf \omega} \times {}^{0}{\bf p} \right)
\end{array}
$$

ここで、この加速度\( {}^{0}{\ddot{\bf p}} \)の方向と大きさについて見てみましょう。

まず、右辺の第一項、第二項がどのような方向と大きさを指しているか見てみます。

  1. 右辺第一項\( {}^{0}{\dot{\bf \omega}} \times {}^{0}{\bf p} \)について。
    角速度の微分は\( {}^{0}{\dot{\bf \omega}} =  \ddot{\theta} {}^{0}{\bf n} \)であり、角速度ベクトルに対し方向は、同じ回転軸ベクトル\( {}^{0}{\bf n} \)方向で、大きさが\( \dot{\theta} \)から\( \ddot{\theta} \)に変化したものだとわかります。よって\( {}^{0}{\dot{\bf \omega}} \times {}^{0}{\bf p} \)は、
    ・方向は、前節の速度方向と同じ
    ・大きさは、\( \left| {}^{0}{\dot{\bf \omega}} \times {}^{0}{\bf p} \right| = |\ddot{\theta}| |r| \)
    となります。
    ちなみに、物理学の教科書や金宮先生(Dragomir N, Nenchev先生)の著書「英語で学ぶロボット工学 ― 運動学,動力学と制御」にもありますが、この加速度のことをtrransverse acceleration(横加速度,オイラー加速度,方位加速度,接線加速度)というそうです(みかけの加速度の呼び名と混同しているかもしれません)。
  2. 右辺第二項\( {}^{0}{\bf \omega} \times \left( {}^{0}{\bf \omega} \times {}^{0}{\bf p} \right) \)について。
    ・方向は、前節で見た速度方向と回転軸に直交する方向、さらに言うと軸方向→速度方向へ右ねじに回転させて進む向き、すなわち、点Pから回転軸方向へ垂直に向かう方向となります。
    ・大きさは、\( {}^{0}{\bf \omega} \)と\( \left( {}^{0}{\bf \omega} \times {}^{0}{\bf p} \right) \)のなす角は直交するから\( 90^\circ \)なので、
    $$ \begin{array}{rcl}
    \left| {}^{0}{\bf \omega} \times \left( {}^{0}{\bf \omega} \times {}^{0}{\bf p} \right) \right| &=& |{}^{0}{\bf \omega}| |{}^{0}{\bf \omega} \times {}^{0}{\bf p}| |{\rm sin} 90^\circ| \\
    &=& |\dot{\theta}|\  |\dot{\theta}| |r| \\
    &=& \dot{\theta}^2|r|
    \end{array}
    $$
    となります。
    ちなみにこの加速度は、高校や大学の物理学とかいろんな教科書に出てるようにcentripetal acceleration(求心加速度、向心加速度)というそうです。高校物理だとtransverseの方は習わずこっちしか習わなかったように覚えています。

以上により、

  • 加速度\( {}^{0}{\ddot{\bf p}} \)の方向は、もう言葉で說明するのはキツイので、以下のように図に描いてみました。

    回転運動の加速度\( {}^{0}{\bf p} \)
  • 加速度\( {}^{0}{\ddot{\bf p}} \)の大きさは、右辺第一項、第二項が作る長方形の対角線なので、三平方の定理で出せそうですね。
    大きさについて分解方向で触れている教科書はあるものの、一つに合わせた大きさについて触れているものがないので自己流で以下のように求めました。もし間違ってたらゴメンナサイ。
    $$  \begin{array}{rcl}
    |{}^{0}{\ddot{\bf p}}| &=& \sqrt{ \left| {}^{0}{\dot{\bf \omega}} \times {}^{0}{\bf p} \right|^2 + \left| {}^{0}{\bf \omega} \times \left( {}^{0}{\bf \omega} \times {}^{0}{\bf p} \right) \right|^2 } \\
    &=& \sqrt{ \left( |\ddot{\theta}| |r| \right)^2 + \left( \dot{\theta}^2|r| \right)^2 } \\
    &=& |r| \sqrt{ \ddot{\theta}^2 + \dot{\theta}^4 }
    \end{array} $$

 

6. 回転運動の躍度

躍度\( {}^{0}{{\bf p}^{(3)}} \)は、加速度\( {}^{0}{\ddot{\bf p}} \)の微分により以下のように求まります。

$$ \begin{array}{rcl}
{}^{0}{{\bf p}^{(3)}} &=& \frac{d {}^{0}{\ddot{\bf p}} }{dt} \\
&=&  \frac{d}{dt} \left( {}^{0}{\dot{\bf \omega}} \times {}^{0}{\bf p} + {}^{0}{\bf \omega} \times {}^{0}{\dot{\bf p}} \right) \\
&=& {}^{0}{\ddot{\bf \omega}} \times {}^{0}{\bf p} + {}^{0}{\dot{\bf \omega}} \times {}^{0}{\dot{\bf p}}
+ {}^{0}{\dot{\bf \omega}} \times {}^{0}{\dot{\bf p}} +  {}^{0}{\bf \omega} \times {}^{0}{\ddot{\bf p}}  \\
&=& {}^{0}{\ddot{\bf \omega}} \times {}^{0}{\bf p} + 2{}^{0}{\dot{\bf \omega}} \times {}^{0}{\dot{\bf p}} + {}^{0}{\bf \omega} \times {}^{0}{\ddot{\bf p}} \\
&=& {}^{0}{\ddot{\bf \omega}} \times {}^{0}{\bf p} + 2{}^{0}{\dot{\bf \omega}} \times \left( {}^{0}{\bf \omega} \times {}^{0}{{\bf p}} \right)
+ {}^{0}{\bf \omega} \times
\left( {}^{0}{\dot{\bf \omega}} \times {}^{0}{\bf p} + {}^{0}{\bf \omega} \times \left( {}^{0}{\bf \omega} \times {}^{0}{\bf p} \right) \right) \\
&=& {}^{0}{\ddot{\bf \omega}} \times {}^{0}{\bf p} + 2{}^{0}{\dot{\bf \omega}} \times \left( {}^{0}{\bf \omega} \times {}^{0}{{\bf p}} \right)
+ {}^{0}{\bf \omega} \times
\left( {}^{0}{\dot{\bf \omega}} \times {}^{0}{\bf p}
+ \left( {}^{0}{\bf \omega}^{\rm T} {}^{0}{\bf p} \right) {}^{0}{\bf \omega}\ – \ {}^{0}{\bf \omega}^{2}\ {}^{0}{\bf p}  \right) \\
&=& {}^{0}{\ddot{\bf \omega}} \times {}^{0}{\bf p} + 2{}^{0}{\dot{\bf \omega}} \times \left( {}^{0}{\bf \omega} \times {}^{0}{{\bf p}} \right)
+ {}^{0}{\bf \omega} \times \left( {}^{0}{\dot{\bf \omega}} \times {}^{0}{\bf p} \right )
+ \left( {}^{0}{\bf \omega}^{\rm T} {}^{0}{\bf p} \right) {}^{0}{\bf \omega} \times {}^{0}{\bf \omega}
\ – \ {}^{0}{\bf \omega}^{2}\  {}^{0}{\bf \omega} \times {}^{0}{\bf p} \\
&=& {}^{0}{\ddot{\bf \omega}} \times {}^{0}{\bf p} + 2{}^{0}{\dot{\bf \omega}} \times \left( {}^{0}{\bf \omega} \times {}^{0}{{\bf p}} \right)
+ {}^{0}{\bf \omega} \times \left( {}^{0}{\dot{\bf \omega}} \times {}^{0}{\bf p} \right )
\ – \ {}^{0}{\bf \omega}^{2}\  {}^{0}{\bf \omega} \times {}^{0}{\bf p}
\end{array}
$$

第5式目から第6式目の変形では、外積の公式

$$
{\bf a} \times \left( {\bf b} \times {\bf c} \right) = \left( {\bf a}^{\rm T} {\bf c} \right) {\bf b}\ -\ \left( {\bf a}^{\rm T} {\bf b} \right) {\bf c}
$$

を使っています(これでカッコ部分はスカラーになるので、ベクトルどうしの外積の対象から外してます)。
また、第7式目から第8式目の変形では、同じベクトルどうしの外積はゼロになる性質、

$$
{}^{0}{\bf \omega} \times {}^{0}{\bf \omega} = {\bf 0}
$$

を使っています。

 

 

7. 等角速回転運動(角速度が一定)の場合

角速度が一定だと\( \ddot{\theta} = 0 \)、\({}^{0}\dot{\bf \omega} = {\bf 0}\)になります。

これを踏まえて上述した式を見てみましょう。

高校物理で習ったように、速度、加速度、躍度は次のようになります。

 

7.1. 等角速回転運動のときの速度

上述した\( \dot{{}^{0}{\bf p}}\)と同じ式で表されます。方向も大きさも同じように表せます。

 

7.2. 等角速回転運動のときの加速度

等速回転運動の場合、\({}^{0}\dot{\bf \omega} = {\bf 0}\)になるため、加速度は、回転軸に向かう方向の求心加速度になります。

$$ \begin{array}{rcl}
{}^{0}{\ddot{\bf p}} &=& \frac{d {}^{0}{\dot{\bf p}} }{dt} \\
&=&  {}^{0}{\bf \omega} \times \left( {}^{0}{\bf \omega} \times {}^{0}{\bf p} \right)
\end{array}
$$

  • 方向は回転軸に向かう方向で以下の図のようになります。

    等角速回転運動の加速度\( {}^{0}\ddot{\bf p} \)
  • 大きさは\( \ddot{\theta} = 0 \)より、
    $$
    |{}^{0}{\ddot{\bf p}}| = \dot{\theta}^2|r|
    $$
    です。

7.3. 等角速回転運動のときの躍度

\( \ddot{\theta} = 0 \)、\({}^{0}\dot{\bf \omega} = {\bf 0}\)となるため、躍度は以下のようになります。

$$
{}^{0}{{\bf p}^{(3)}} = \ – \ {}^{0}{\bf \omega}^{2}\  {}^{0}{\bf \omega} \times {}^{0}{\bf p}
$$

  • 方向は\( {}^{0}{\bf \omega} \times {}^{0}{\bf p} \)のマイナス定数倍なので、速度と平行で逆方向の向きになります。
  • 大きさは
    $$ \begin{array}{rcl}
    | {}^{0}{{\bf p}^{(3)}} | &=& | {}^{0}{\bf \omega}^{2} | \left| {}^{0}{\bf \omega} \times {}^{0}{\bf p} \right| \\
    &=& |\dot{\theta}^{2}| |\dot{\theta}||r| \\
    &=& |\dot{\theta}^{3}| |r|
    \end{array}
    $$
    です。

 

 

8. まとめ(一つの回転軸まわりの回転運動における、質点の位置姿勢の速度、加速度、躍度)

8.1. ある点Pの回転運動

まとめます。

ある点Pの回転運動の速度\( {}^{0}{\dot{\bf p}} \)

$$
{}^{0}{\dot{\bf p}} = {}^{0}{\bf \omega} \times {}^{0}{\bf p}
$$

ある点Pの回転運動の加速度\( {}^{0}{\ddot{\bf p}} \)

$$
{}^{0}{\ddot{\bf p}} = {}^{0}{\dot{\bf \omega}} \times {}^{0}{\bf p} + {}^{0}{\bf \omega} \times \left( {}^{0}{\bf \omega} \times {}^{0}{\bf p} \right)
$$

ある点Pの回転運動の躍度\( {}^{0}{{\bf p}^{(3)}} \)

$$
{}^{0}{{\bf p}^{(3)}} = {}^{0}{\ddot{\bf \omega}} \times {}^{0}{\bf p} + 2{}^{0}{\dot{\bf \omega}} \times \left( {}^{0}{\bf \omega} \times {}^{0}{\bf p} \right)
+ {}^{0}{\bf \omega} \times \left( {}^{0}{\dot{\bf \omega}} \times {}^{0}{\bf p} \right )
\ – \ {}^{0}{\bf \omega}^{2}\  {}^{0}{\bf \omega} \times {}^{0}{\bf p}
$$

 

基底ベクトルの回転運動

冒頭に述べたとおり、
ある点Pのベクトル\( {}^{0}{\bf p} \)は、基底ベクトル\( {}^{0}{\bf x}_{{}^{0}{\bf e}_{x}}\), \( {}^{0}{\bf y}_{{}^{0}{\bf e}_{y}}\), \( {}^{0}{\bf z}_{{}^{0}{\bf e}_{z}}\)に置き直しても同じです。

基底ベクトルの回転運動の速度

$$ \begin{array}{rcl}
{}^{0}\dot{\bf x}_{{}^{0}{\bf e}_{x}} &=& {}^{0}{\bf \omega} \times {}^{0}{\bf x}_{{}^{0}{\bf e}_{x}} \\
{}^{0}\dot{\bf y}_{{}^{0}{\bf e}_{y}} &=& {}^{0}{\bf \omega} \times {}^{0}{\bf y}_{{}^{0}{\bf e}_{y}} \\
{}^{0}\dot{\bf z}_{{}^{0}{\bf e}_{z}} &=& {}^{0}{\bf \omega} \times {}^{0}{\bf z}_{{}^{0}{\bf e}_{z}}
\end{array}
$$

基底ベクトルの回転運動の加速度

$$ \begin{array}{rcl}
{}^{0}\ddot{\bf x}_{{}^{0}{\bf e}_{x}} &=& {}^{0}{\dot{\bf \omega}} \times {}^{0}{\bf x}_{{}^{0}{\bf e}_{x}} \
+ {}^{0}{\bf \omega} \times \left( {}^{0}{\bf \omega} \times {}^{0}{\bf x}_{{}^{0}{\bf e}_{x}} \right) \\
{}^{0}\ddot{\bf y}_{{}^{0}{\bf e}_{y}} &=& {}^{0}{\dot{\bf \omega}} \times {}^{0}{\bf y}_{{}^{0}{\bf e}_{y}} \
+ {}^{0}{\bf \omega} \times \left( {}^{0}{\bf \omega} \times {}^{0}{\bf y}_{{}^{0}{\bf e}_{y}} \right) \\
{}^{0}\ddot{\bf z}_{{}^{0}{\bf e}_{z}} &=& {}^{0}{\dot{\bf \omega}} \times {}^{0}{\bf z}_{{}^{0}{\bf e}_{z}} \
+ {}^{0}{\bf \omega} \times \left( {}^{0}{\bf \omega} \times {}^{0}{\bf z}_{{}^{0}{\bf e}_{z}} \right)
\end{array}
$$

基底ベクトルの回転運動の躍度

$$ \begin{array}{rcl}
{}^{0}{\bf x}_{{}^{0}{\bf e}_{x}}^{(3)} &=& {}^{0}\ddot{\bf \omega} \times {}^{0}{\bf x}_{{}^{0}{\bf e}_{x}}
+ 2{}^{0}{\dot{\bf \omega}} \times \left( {}^{0}{\bf \omega} \times {}^{0}{\bf x}_{{}^{0}{\bf e}_{x}} \right)
+ {}^{0}{\bf \omega} \times \left( {}^{0}\dot{\bf \omega} \times {}^{0}{\bf x}_{{}^{0}{\bf e}_{x}} \right )
\ – \ {}^{0}{\bf \omega}^{2}\  {}^{0}{\bf \omega} \times {}^{0}{\bf x}_{{}^{0}{\bf e}_{x}} \\
{}^{0}{\bf y}_{{}^{0}{\bf e}_{y}}^{(3)} &=& {}^{0}\ddot{\bf \omega} \times {}^{0}{\bf y}_{{}^{0}{\bf e}_{y}}
+ 2{}^{0}{\dot{\bf \omega}} \times \left( {}^{0}{\bf \omega} \times {}^{0}{\bf y}_{{}^{0}{\bf e}_{y}} \right)
+ {}^{0}{\bf \omega} \times \left( {}^{0}{\dot{\bf \omega}} \times {}^{0}{\bf y}_{{}^{0}{\bf e}_{y}} \right )
\ – \ {}^{0}{\bf \omega}^{2}\  {}^{0}{\bf \omega} \times {}^{0}{\bf y}_{{}^{0}{\bf e}_{y}} \\
{}^{0}{\bf x}_{{}^{0}{\bf e}_{x}}^{(3)} &=& {}^{0}\ddot{\bf \omega} \times {}^{0}{\bf z}_{{}^{0}{\bf e}_{z}}
+ 2{}^{0}{\dot{\bf \omega}} \times \left( {}^{0}{\bf \omega} \times {}^{0}{\bf z}_{{}^{0}{\bf e}_{z}} \right)
+ {}^{0}{\bf \omega} \times \left( {}^{0}\dot{\bf \omega} \times {}^{0}{\bf z}_{{}^{0}{\bf e}_{z}} \right )
\ – \ {}^{0}{\bf \omega}^{2}\  {}^{0}{\bf \omega} \times {}^{0}{\bf z}_{{}^{0}{\bf e}_{z}} \\
\end{array}
$$

8.3. 姿勢の回転運動

基底ベクトルの回転速度、加速度を図に表すとこんな感じでしょうか(イメージです)。

基底ベクトルの速度、加速度の図

以前、剛体の運動(回転行列の速度とは)にて、
回転行列は、基底ベクトル\( {}^{0}{ \bf  e}_{x} \), \( {}^{0}{ \bf  e}_{y} \), \( {}^{0}{ \bf  e}_{z} \)が回転したベクトル\( {}^{0}{ \bf  x}_{ {}^{0}{ \bf  e}_{x} } \), \( {}^{0}{ \bf  y}_{ {}^{0}{ \bf  e}_{y} } \), \( {}^{0}{ \bf  z}_{ {}^{0}{ \bf  e}_{z} } \)により構成されるとノートしました。

$$
{}^{0}{ \bf R}(t) = \left[ \begin{array}{ccc}
{}^{0}{ \bf  x}_{ {}^{0}{ \bf  e}_{x} }  & {}^{0}{ \bf  y}_{ {}^{0}{ \bf  e}_{y} } & {}^{0}{ \bf  z}_{ {}^{0}{ \bf  e}_{z} }
\end{array} \right]
$$

また、回転行列\( {}^{0}{ \bf R}(t) \)は時刻\( t \)での姿勢を表しているとノートしました。

前述の基底ベクトルの速度、加速度の導出を踏まえると、
一つの回転軸まわりに回転する時の、姿勢の速度\( {}^{0}\dot{ \bf R}(t) \)、加速度\( {}^{0}\ddot{ \bf R}(t) \)、躍度\( {}^{0}{\bf R}^{(3)}(t) \)も同様に表すことができます。

姿勢の速度

$$
{}^{0}\dot{\bf R}(t) = {}^{0}{\bf \omega} \times {}^{0}{\bf R}(t)
$$

 

姿勢の加速度

$$
{}^{0}\ddot{\bf R}(t) = {}^{0}{\dot{\bf \omega}} \times {}^{0}{\bf R}(t) \
+ {}^{0}{\bf \omega} \times \left( {}^{0}{\bf \omega} \times {}^{0}{\bf R}(t) \right)
$$

 

姿勢の躍度

$$
{}^{0}{\bf R}^{(3)}(t) = {}^{0}\ddot{\bf \omega} \times {}^{0}{\bf R}(t)
+ 2{}^{0}{\dot{\bf \omega}} \times \left( {}^{0}{\bf \omega} \times {}^{0}{\bf R}(t) \right)
+ {}^{0}{\bf \omega} \times \left( {}^{0}\dot{\bf \omega} \times {}^{0}{\bf R}(t) \right )
\ – \ {}^{0}{\bf \omega}^{2}\  {}^{0}{\bf \omega} \times {}^{0}{\bf R}(t)
$$

 

 

 

ふぅ~。。

この辺は回転運動の話でよく出る話ですね。

記述の仕方はそれぞれ違うかと思われますが、角加速時と等角速時の両方ちゃんと書いておくと、

「もしこんな加速度で運動させるとき、位置、速度をどう設定して動作軌道をつくるか」

みたいなことを考えるとき役立つと思います。

 

以上です。

剛体の運動(姿勢のオフセット)

こんにちは、だいCです。

剛体の運動について、回転に関する話ばかり書いています。

剛体の運動方向の自由度は、「位置」と「姿勢」の2種類で表現してます。

回転方向の自由度を「姿勢」と呼んでいます。

この「姿勢」という言葉は英語だとorientationですかね。

ロボットの全関節角セットで定まる格好を「姿勢」ということもあります。

こちらは英語だとposeですかね。

ややこしいですね。

今回は、姿勢のオフセットについてノートしていきます。

いきなり姿勢のオフセットといわれても話が見えないので、まず目的を述べる前に、例となるお話を先に書きます。

1. 姿勢のオフセットを考える場面

普通売られているマニピュレータには、操作ソフトも付属しており、

ユーザは手先の位置・姿勢を直交座標空間で操作することができます。

内部では、コントローラが手先位置姿勢から各関節指令角へ自動で変換して動かしてくれます。

ユーザは、手先の運動だけ見て動かせるのです。

イメージとして、下のようなマニピュレータの手先に吸着ハンドが付いている絵を描いてみました。
(3本飛び出してる棒に吸盤みたいなものが付いててそこから吸引するよーな、そんなイメージで描いた絵です。。伝わりにくかったらゴメンナサイ)

マニピュレータの前には、ハンドで把持する物体が置かれています。
(よだれ垂らした直方体みたいなやつがそれです。。)

ユーザは、この手先についた吸着パッドをうまく物体の面に押し当てて、どっか後ろにつながったポンプの空気圧から生じた吸引力により、物体を吸引して掴み取ろうとしています。

吸着ハンドと把持物体(よだれ垂らした顔が描かれたやつ)

ユーザが、手元にコントローラのようなものを持って、直接ジョグ操作(ボタンを押している間ずっと微量ずつ動かせるような操作、ジョギング操作ともいう)をする場合も考えられます。

そうではなく、ここでは、ロボットがビジョンセンサ等を利用し、物体を自動で認識し、自動で物体をつかむことができるソフトが用意されているとします。

下の絵のように、吸着ハンドにビジョンセンサが取り付けられているとします。
(ハンドの真ん中に描き足したのが、ビジョンセンサ(カメラ・レンズのイメージ)のつもりです。。妄想なのでテキトーです)

ビジョンセンサで撮像した物体の映像から、ビジョンの認識技術により物体の位置姿勢を3次元認識できるとします。
(さらっと仮定しましたが、これだけでコンピュータビジョン(画像処理と認識)の難しいお話が出てきます。本題から逸れるので省略します。)

カメラ付きの吸着ハンド

ビジョンソフトは、ロボットのソフトとは別途用意したとします。

ビジョンでは普通、物体の3次元認識の結果を、センサの座標系基準で得られます。
(カメラだと本体内の、レンズ~受光センサ~基板のどこかの位置に仮想的に置かれた座標系です。焦点距離やレンズの歪補正などによって変わりますが、ここではその座標系が予め設定されているものとします)。

ここで、ロボットの手先位置姿勢に対応する座標系を\( \Sigma_{E} \)とします(黒線で描いた座標系)。

ビジョンセンサの座標系を\( \Sigma_{E’} \)とします(オレンジ線で描いた座標系)。

(下付き文字のラベルEは手先=エンドエフェクタEndEffectorを省略してるつもりです。ビジョンセンサを表したラベルE’も、手先の目のようなものだからEyeでもいいですし、ツールToolのTとする場合もありますね。カメラだからCとかでも。もう何でもいいですラベルの対応さえとれれば)

手先とビジョンセンサの座標系が一体化されていて、

両者の座標系が一致するように設計されているイメージを下の絵のように描いてみました。

手先座標系とカメラ座標系の姿勢が一致する

ビジョンセンサから認識された物体の位置姿勢、
ここでは姿勢だけ考えて、物体の姿勢を\( {}^{E’}{\bf R}_{obj} \)とします(objはobjectを省略したラベル)。

\( {}^{E’}{\bf R}_{obj} \)は、座標系\( \Sigma_{E’} \)基準の物体の姿勢を表しているとします。

ビジョンセンサの座標系からみた物体の姿勢\( {}^{E’}{\bf R}_{obj} \)を、手先座標系からみた姿勢\( {}^{E}{\bf R}_{obj} \)へ変換するとき、以下の式で表されます。

$$
{}^{E}{\bf R}_{obj} =  {}^{E}{\bf R}_{E’}  {}^{E’}{\bf R}_{obj}
$$

上式の座標系変換のオペレータ\( {}^{E}{\bf R}_{E’} \)は、

手先座標系\( \Sigma_{E} \)からみたビジョンセンサ座標系\( \Sigma_{E”} \)の位置姿勢でもあります。

上の絵では、両座標系が一致するよう設計されているので、

$$
{}^{E}{\bf R}_{E’} = {\bf I}
$$

( \( {\bf I} \)は単位行列 )

となります。ビジョンセンサ座標系からみた物体の姿勢は、そのまま手先座標系からみた姿勢になっているわけです。

次に、

手先座標系とカメラ座標系の姿勢が一致せず、

下の絵のように、ハンドとは別に、外付けでビジョンセンサ(カメラ)が付いているケースを考えます。

こちらが今回のメインのお話です。

吸着ハンドとは別に外部カメラが外付けされているとき

手先座標系\( \Sigma_{E} \)とビジョンセンサ座標系\( \Sigma_{E”} \)は、下の絵のように姿勢が異なります。

手先座標系とカメラ座標系が一致しない

このように姿勢が異なる場合、物体の位置姿勢に合わせて手先を動かそうとすると、

手先座標系\( \Sigma_{E} \)から見たビジョンセンサの座標系\( \Sigma_{E’} \)の位置姿勢、お題の「姿勢のオフセット」を知る必要があります。

「姿勢のオフセット」と述べてますが、姿勢のずれとか、姿勢の誤差とか、姿勢の一定寸法とか、そんな風に解釈してもらっても構いません。JIS用語だと自分が言う手先とはメカニカルインタフェースのことですね(ラベルではエンドエフェクタにしちゃったけど)。姿勢オフセットはJIS用語だと何でしょう。メーカー定義な感じですかね。

2. 目的

姿勢のオフセット\( {}^{E}{\bf R}_{E’} \)を求める。

3. 姿勢のオフセット

以降、ハンドやビジョンセンサや物体について、全て姿勢だけで考えます。

手先座標系とビジョンセンサ座標系の姿勢が一致している図を描きました。

例のごとく、正規直交基底ベクトル\( {\bf e}_{x} \), \( {\bf e}_{y} \), \( {\bf e}_{z} \)とそれらの先が表面に収まる半径1の球を描いています。

黒い線で描いた座標系が手先座標系\( \Sigma_{E} \)で、

オレンジ色の線で描いたものがビジョンセンサ座標系\( \Sigma_{E’} \)です。

手先座標系とビジョンセンサの座標系の姿勢が一致

以下のように物体の姿勢\( {}^{E’}{\bf R}_{obj} \)を描きました。

手先座標系から見る物体の姿勢も、ビジョンセンサから見る物体の姿勢も同じです。

手先座標系=ビジョンセンサの座標系からみた物体の刺青

次に本題の、手先座標系とビジョンセンサの座標系の姿勢がずれているときを図に描きます。

手先座標系とビジョンセンサの座標系がずれている

さらに物体の姿勢\( {}^{E}{\bf R}_{obj} \)を描きます。

先にも述べましたが、姿勢オフセット\( {}^{E}{\bf R}_{E’} \)は、座標系の相対関係\( \Sigma_{E} \)→\( \Sigma_{E’} \)の座標系変換のオペレータでもあります。

この姿勢オフセット\( {}^{E}{\bf R}_{E’} \)を求める方法を考えてみましょう。

姿勢オフセットがある状態での物体の姿勢

手先座標系\( \Sigma_{E} \)基準で手先をある地点1から地点2に回転移動、もしくは物体を同じ移動量だけ回転したとします。

手先の回転でも物体の回転でも、手先座標系\( \Sigma_{E} \)基準でみると同じ運動として扱えます。

手先の回転運動により、相対的に移動したように見える物体の回転運動も、

手先は移動せず、同じ移動量だけ実際に物体が回転したときの物体の回転運動も

手先座標系\( \Sigma_{E} \)原点から見ると相対的に両方同じになるからです。

(月も太陽も地球から見ると地球のまわりを回って見える現象)

手先座標系\( \Sigma_{E} \)基準で、地点1から2への手先が移動する回転運動オペレータを\( {}^{E}{\bf R}_{obj1 \rightarrow obj2} \)と記述することにします。

地点1の手先座標系\( \Sigma_{E} \)から見た物体の姿勢\( {}^{E}{\bf R}_{obj1} \)、地点2の手先座標系から見た物体の姿勢\( {}^{E}{\bf R}_{obj2} \)により、以下の関係式で表されます。

$$
{}^{E}{\bf R}_{obj2} = {}^{E}{\bf R}_{obj1 \rightarrow obj2} {}^{E}{\bf R}_{obj1}
$$

よって、回転運動のオペレータは、以下のように求まります。

$$
{}^{E}{\bf R}_{obj1 \rightarrow obj2} = {}^{E}{\bf R}_{obj2} {}^{E}{\bf R}_{obj1}^{\rm T}
$$

これが地点1から地点2への手先の回転運動を表しています。

同様にして、ビジョンセンサ座標系\( \Sigma_{E’} \)からみた物体の相対的な移動量は、

回転運動のオペレータ\( {}^{E’}{\bf R}_{obj1 \rightarrow obj2} \)により以下のよう書き表すことができます。

$$
{}^{E’}{\bf R}_{obj1 \rightarrow obj2} := {}^{E’}{\bf R}_{obj2} {}^{E’}{\bf R}_{obj1}^{\rm T}
$$

では、

このビジョンセンサ座標系\( \Sigma_{E’} \)基準の物体の地点1から地点2への回転運動を、

手先座標系基準\( \Sigma_{E} \)基準に座標系変換してみようと思います。

回転運動に座標系変換のオペレータ\( {}^{E}{\bf R}_{E’} \)をかけます。

$$ \begin{array}{rcl}
{}^{E}{\bf R}_{E’}  \left( {}^{E’}{\bf R}_{obj2} {}^{E’}{\bf R}_{obj1}^{\rm T} \right)
&=& {}^{E}{\bf R}_{E’} \left(
{}^{E’}{\bf R}_{E} {}^{E}{\bf R}_{obj2} \left(
{}^{E’}{\bf R}_{E} {}^{E}{\bf R}_{obj1} \right)^{\rm T}
\right) \\
&=& {}^{E}{\bf R}_{obj2} {}^{E}{\bf R}_{obj1}^{\rm T} {}^{E}{\bf R}_{E’} \\
&=& {}^{E}{\bf R}_{obj1 \rightarrow obj2} {}^{E}{\bf R}_{E’}
\end{array}
$$

最終的に以下の式が導けます。

$$
{}^{E}{\bf R}_{E’}  \left( {}^{E’}{\bf R}_{obj2} {}^{E’}{\bf R}_{obj1}^{\rm T} \right)
= {}^{E}{\bf R}_{obj1 \rightarrow obj2} {}^{E}{\bf R}_{E’}
$$

上の式が表す意味は以下のようになります。

$$ \begin{array}{lcl}
{}^{E}{\bf R}_{E’}^{\rm T}
\left( ({\rm ビジョンセンサからみた地点2の物体姿勢}) ( {\rm ビジョンセンサからみた地点1の物体姿勢} )^{\rm T} \right)
&& \\
\ \ \ \ = ({\rm 手先座標系からみた地点1 \rightarrow 2の手先回転運動})
{}^{E}{\bf R}_{E’}
& &
\end{array} $$

式中に日本語で書いた

  1. ビジョンセンサからみた地点1の物体姿勢
  2. ビジョンセンサからみた地点2の物体姿勢
  3. 手先座標系からみた地点1\( \rightarrow \)2の手先回転運動

は、ビジョンの認識機能、ロボットの手先運動制御機能によりそれぞれ計測・取得できるとします。

なので既知の定数として、

1.,2.のビジョン認識機能より計測される\({}^{E’}{\bf R}_{obj2} {}^{E’}{\bf R}_{obj1}^{\rm T} \)の3×3行列を\( {\bf A} \)、

3.のロボットの手先運動制御機能により取得される\( {}^{E}{\bf R}_{obj1 \rightarrow obj2} \)の3×3行列を\( {\bf B} \)、

知りたい姿勢オフセットの3×3行列\( {}^{E}{\bf R}_{E’} \)を\( \bf X \)とおけば、

式は、

$$
{\bf X} {\bf A} = {\bf B} {\bf X}
$$

の形の行列方程式になることがわかります。

あとは、この行列\( \bf X \)を求めて姿勢オフセット\( {}^{E}{\bf R}_{E’} \)を得ることができます。

ここでは、行列方程式解法の詳細は省略します。

ふぅ~、、

落書きみたいな図をいっぱい描いちゃいました。。

この話は、カメラから手先の姿勢オフセットだけでなく、

手先からさらに伸びた上記吸着パッドとか爪とかチャックとかの、ツール先端(TCP:Tool Center Pointと呼ばれる点)の姿勢オフセットを考える時にも有効です。

ただしその場合は、上記ビジョンによる計測だけではなく、ツール先端を計測器具で物理的に計測したり、またはマニピュレータを決まった回転軸と回転角だけ移動させるなど別途拘束条件を設けたりして求めてもいいと思います。

姿勢オフセットの話は、マニピュレータ使用上よく出るのですが、あまりロボット工学の教科書には書かれてませんね。

簡単なようでややこしいです。

物理世界の話をしているけど、仮想的な設定が多いんで、これなんだっけ??ってなっちゃいます。

一度自分の中で消化するまで整理した方がいいですね。

今回は、Dr.の同僚に教えてもらったりして書かせてもらいました。感謝!

まだまだ回転の話は続きますが、、

今回は以上です。

剛体の運動(2つの姿勢の補間)

こんにちは。だいCです。

 

前回「剛体の回転行列の速度とは」で、姿勢の変化は基底ベクトルの移動を表していて、

基底ベクトルの移動の仕方は、回転角の変化\( \Delta \theta \)(\( \theta(t)の軌道計算 \))と回転軸\( \bf n \)に依存する、と書きました。

では、スタートとゴールの2つ姿勢が決まっていて、その間を1つの回転軸で回転移動するとき、間の姿勢はどうなるでしょうか?

回転軸\( \bf n \)はどのような値をとるのでしょうか…?

今回は2つの姿勢の間の姿勢、いわゆる姿勢の補間方法についてノートします。

 

1. 目的

2つの姿勢間を補間する方法を求める。

 

2. イメージ

前回

回転行列で表される姿勢の運動は、xyz軸で構成される正規直交基底の運動であり、xyz軸3本のベクトルは直交したまま球の表面を移動することをノートしました。

では、2つの姿勢間を移動するイメージの絵を描きます。

まず、最初異動する前の姿勢を以下に描きました。

球の表面に3点をとり、同じ球の中心からそれらの点に伸びる3軸が、互いに直交した基底ベクトル3本の組を姿勢として表現します。

よく座標系を表現するときこのような座標軸を描きますね。ここでは、姿勢を表す物体だと思ってください。

最初の開始姿勢

最初の姿勢を\( {\bf R}_0 \)とします。基底ベクトルは\( {\bf e}_{x0} \)、\( {\bf e}_{y0} \)、\( {\bf e}_{z0} \)とします。

この姿勢が点\( O \)を中心として回転し、ある時間経過後、ある姿勢に到達したとします。

到達後の姿勢を下の図ように描き足しました。

これを目標到達姿勢とよび、\( {\bf R}_{g}\)とします。基底ベクトルは\( {\bf e}_{xg} \)、\( {\bf e}_{yg} \)、\( {\bf e}_{zg} \)とします。
(下付き文字を目標=goalだから略してgとしましたが、終端=finishだから略してfと書くこともあります。ここではgとします。)

回転移動後の到達姿勢

開始姿勢\( {\bf R}_0 \)と目標到達姿勢\( {\bf R}_{g} \)への回転移動は、

移動途中に複数の回転軸をとれば、ぐにゃぐにゃいろんな移動方法をとることができます。

ここでは、1つの回転軸だけとり、2つの姿勢間をその軸まわりにだけ回転移動することにします。

1つの回転軸のイメージを下の図のように描いてみます。

2姿勢間を結ぶ1つの回転軸

この1つの回転軸を\( \bf n \)とします。

2つの姿勢間を結ぶ1つの回転軸\( \bf n \)はどのようにして求められるでしょうか?

さらにこの回転軸\( \bf n \)で回転したときの、開始姿勢\( {\bf R}_0 \)と目標到達姿勢\( {\bf R}_{g} \)の間の姿勢\( {\bf R}(t) \)を以下のように描いてみました。

 

2つの姿勢間を1つの回転軸\( \bf n \)まわりで補間した姿勢\( {\bf R}(t)\)

あいだの補間姿勢について、

開始姿勢から移動開始する時刻を0とし、到達姿勢に到達する時刻を1として說明することがあります。

なぜ0から1にするかというと、軌道補間の実装上、話がラクだからです。

開始時刻、到達時刻のとり方なんて無限にありますが、例えば、開始時刻を\(t_0\)、目標到達時刻を\(t_g\)とし、

その間の時刻\( t \)を、たとえば下式のようにパラメータ\( s \)に置き換えてやれば、

$$
s(t) = \frac{t – t_0}{t_g – t_0}
$$

範囲\( [t_0, t_g] \)間の移動を\( [0, 1] \)間の移動、つまり開始点と目標点の間の内分比パラメータの時間変化とすることができるのです。

軌道補間計算を実装するとき、余計な定数の入力文字を考えなくていいのでラクチンです。

これは軌道補間の教科書や論文でもよく見られ、もはや当たり前のように補間を媒介する変数\(s\)は0~1として説明されることもあります。

以降、自分もこのように、\(s\)を補間時刻\(s \in [0, 1]\)として話をすすめることもあるので、ご注意ください。

 

では話を戻して、時刻\( t \)のときの補間姿勢\( {\bf R}(s(t)) \)はどのようにして求まるでしょうか?

 

3. 2つの姿勢間の補間方法

ここで、回転運動を作用する回転行列\( {\bf R}_{0 \rightarrow g} \)と仮において、

開始姿勢\( {\bf R}_{0} \)が、回転運動\( {\bf R}_{0 \rightarrow g} \)の作用によって、目標到達姿勢\( {\bf R}_{g} \)に到達したと考えます。

$$
{\bf R}_{g} = {\bf R}_{0 \rightarrow g} {\bf R}_{0}
$$

この回転行列\( {\bf R}_{0 \rightarrow g} \)は以下のように求まります。

$$
{\bf R}_{0 \rightarrow g} := {\bf R}_{g}{\bf R}^{\rm T}_{0}
$$

この回転行列\( {\bf R}_{0 \rightarrow g} \)が、先程イメージで描いた回転軸\( \bf n \)まわりに \( \theta(s(t_0))(=\theta_0=0) \) から\( \theta(s(t_g))(=\theta_g) \)へ回転する回転運動全体を表しています。

回転行列\( {\bf R}_{0 \rightarrow g} \)にある回転角\( \theta \) ( \( \theta_0(=0) \le \theta \le \theta_g  \) ) を与えると、その回転運動のあいだの1つの姿勢への変換作用\( {\bf R}_{0 \rightarrow g}( \theta ) \)を得ることできます。

回転角\( \theta \)は、入力\( s(t) \)の関数とします。

今回は、\( \theta \)と\( s(t) \)の関係は置いておいて、\( s(t) \)により求まった回転角\( \theta \)を入力として与えることができるとします。

よって、先程まで\( {\bf R}(s(t)) \)と表していた回転行列の姿勢は、開始姿勢\( {\bf R}_{0} \)に対し直接の入力\( \theta \)の関数が作用した姿勢、\( {\bf R}_{0 \rightarrow g}(\theta) {\bf R}_{0} \)と表わせます。

\( \theta \)を入力とすると、上式の\( {\bf R}_{0 \rightarrow g} \)から、\( {\bf R}_{0 \rightarrow g}( \theta ) \)がどのような値になるか求めます。

 

剛体の運動(回転行列と角軸)での内容を使います。

上式で求めた回転行列\( \bf R_{0 \rightarrow g} \)の要素を以下のように置くと、

$$
{\bf R}_{0 \rightarrow g} = \left[ \begin{array}{ccc}
                                                       r_{11} & r_{12} & r_{13} \\
                                                       r_{21} & r_{22} & r_{23} \\
                                                       r_{31} & r_{32} & r_{33}
                                                      \end{array} \right]
$$

回転軸\( \bf n \)は以下のように求まるのでした。これが1つの回転軸\( \bf n \)を求める方法の解答です。

$$
{\bf n}_{\rm id} := \left[ \begin{array}{c}
                                        r_{32}  – r_{23}\\
                                        r_{13}  – r_{31}\\
                                        r_{21}  – r_{12}
                                        \end{array} \right] 
$$

$${\bf n}  := \frac{ {\bf n}_{\rm id} }{ \| {\bf n}_{\rm id} \| }$$

開始姿勢\( {\bf R}_{0} \)の要素を以下のように書くと、

$$
{\bf R}_{0} = \left[ \begin{array}{ccc}
                                r_{0\_11} & r_{0\_12} & r_{0\_13} \\
                                r_{0\_21} & r_{0\_22} & r_{0\_23} \\
                                r_{0\_31} & r_{0\_32} & r_{0\_33}
                                \end{array} \right]
$$

このときの回転角\( \theta_0 \)は、以下のように求まるのでした。

$$
\theta_0 = { \rm atan2 } \left( \frac{1}{2} \| {\bf n}_{\rm id} \|, \frac{r_{0\_11} + r_{0\_22} + r_{0\_33}-1}{2} \right)
$$

同様にして、終端姿勢の回転角\( \theta_g \)も求まります。

補間姿勢の入力回転角\( \theta\)は、\( \theta_0 \)と\( \theta_g \)を元にした軌道補間計算より、予め\(s\)の関数として求めておきます。

ロドリゲスの公式より、入力\( \theta \)のときの回転軸\( {\bf n} \)まわりの姿勢\( {\bf R}(\theta) \)として、補間姿勢\( {\bf R}_{0 \rightarrow g}(t)={\bf R}_{0 \rightarrow g}(\theta) \)が求まります。

$$ {\bf R}_{0 \rightarrow g}(\theta) := {\bf I} + {\rm sin}\theta {\bf[ n\times]} + (1 – {\rm cos}\theta) {\bf[ n\times]}^2 $$

( \( \bf I\)は単位行列、\( \bf[ n\times] \)は\( {\bf n} \)による外積行列 )

最終的に回転作用\( {\bf R}_{0 \rightarrow g}(\theta) \)によって姿勢\( {\bf R}_{0} \)から移動した姿勢\( {\bf R}(s(t)) \)を求めます。

$$
{\bf R}(s(t)) = {\bf R}_{0 \rightarrow g}(\theta) {\bf R}_{0}
$$

以上で、2つ目の問題の解答である、補間姿勢\( {\bf R}(s(t)) \)を求めることできました。

 

4. まとめ

以上をまとめます。

入力
  • 開始姿勢\( {\bf R}_{0} \)
  • 到達姿勢\( {\bf R}_{g} \)
  • 開始時刻\( t_0 \)
  • 終端時刻\( t_g \)
  • 時刻\( t \)
出力
  • 時刻\( t \)のときの補間姿勢\( {\bf R}(s(t)) \)
アルゴリズム
  1. 開始姿勢\( {\bf R}_{0} \)と到達姿勢\( {\bf R}_{g} \)より、2姿勢間の回転運動の作用を表す\( {\bf R}_{0 \rightarrow g} \)を求める。
    $$
    {\bf R}_{0 \rightarrow g} := {\bf R}_{g}{\bf R}^{\rm T}_{0}
    $$

    $$
    \left(
    {\bf R}_{0} = \left[ \begin{array}{ccc}
                                    r_{0\_11} & r_{0\_12} & r_{0\_13} \\
                                   r_{0\_21} & r_{0\_22} & r_{0\_23} \\
                                   r_{0\_31} & r_{0\_32} & r_{0\_33}
                           \end{array} \right], \\
    {\bf R}_{g} = \left[ \begin{array}{ccc}
                                   r_{g\_11} & r_{g\_12} & r_{g\_13} \\
                                   r_{g\_21} & r_{g\_22} & r_{g\_23} \\
                                   r_{g\_31} & r_{g\_32} & r_{g\_33}
                           \end{array} \right], \\
    {\bf R}_{0 \rightarrow g} = \left[ \begin{array}{ccc}
                                                          r_{11} & r_{12} & r_{13} \\
                                                          r_{21} & r_{22} & r_{23} \\
                                                          r_{31} & r_{32} & r_{33}
                                                 \end{array} \right]
    \right)
    $$

  2. 回転行列\( {\bf R}_{0 \rightarrow g} \)より、回転軸\({\bf n}\)を求める。
    $$
    {\bf n}_{\rm id} := \left[ \begin{array}{c}
                                            r_{32} – r_{23} \\
                                            r_{13} – r_{31} \\
                                            r_{21} – r_{12}
                                   \end{array} \right]
    $$

    $${\bf n}  := \frac{ {\bf n}_{\rm id} }{ \| {\bf n}_{\rm id} \| }$$

  3. 開始回転角\( \theta_{0} \)を求める。
    $$ \theta_0 := { \rm atan2 } \left( \frac{1}{2} \| {\bf n}_{\rm id} \|, \frac{r_{0\_11} + r_{0\_22} + r_{0\_33}-1}{2} \right) $$
  4. 終端回転角\( \theta_{g} \)を求める。
    $$ \theta_g := { \rm atan2 } \left( \frac{1}{2} \| {\bf n}_{\rm id} \|, \frac{r_{g\_11} + r_{g\_22} + r_{g\_33}-1}{2} \right) $$
  5. 軌道補間計算により時刻 \( t \)のときの回転角\( \theta(s(t)) \)を求める。
    ここでは軌道補間計算の方法は省略。入出力だけ示す。
    ・入力:開始時刻\(t_0\)、終端時刻\( t_g \)、時刻\( t \)、開始回転角\( \theta_0 \)、終端回転角\( \theta_{g} \)
    ・出力:時刻\(t\)のときの回転角\( \theta(s(t)) \) . 
  6. ロドリゲスの公式より、回転角\( \theta \)のときの回転作用\( {\bf R}_{0 \rightarrow g}(\theta) \)を求める。
    $$ {\bf R}_{0 \rightarrow g}(\theta) :=  {\bf I} + {\rm sin}\theta {\bf[ n\times]} + (1 – {\rm cos}\theta) {\bf[ n\times]}^2 $$
  7. 出力\( {\bf R}(s(t)) := {\bf R}_{0 \rightarrow g}(\theta) {\bf R}_{0} \)を得る。

以上です。

剛体の運動(回転行列の速度とは)

こんにちは。だいCです。

このブログはノート代わりに使わせてもらっています。

前回、回転運動の速度をどのように表すかで、回転行列の速度\( \dot {\bf R}(t) \)を求めました。

「速度が求まってので、次は加速度いってみよー!!」と言いたいところですが、

その前にこの回転行列の速度\( \dot {\bf R}(t) \)が、何なのかをもう少し考えたいと思います。

目的

回転行列の速度\( \dot {\bf R}(t) \)が何かを示す。

回転行列\( \bf R \)の意味

まずそもそも、回転行列\( {\bf R}(t) \)とは、何なのかを考えます。

プログラムとして見ると、\( {\bf R}(t) \)は時刻\( t \)を入力にして行列を返す関数に見えますが、

もう少し内部仕様を掘ってみると、回転行列\( {\bf R } \)の直接の入力は、時刻\( t \)でなく回転角\( \theta \)です。

時刻\( t \)は、回転角を返す関数\( \theta(t) \)の入力です。

この関数\( \theta(t) \)は、内部で軌道計算をします。入出力は以下のようになります。

回転角の関数\( \theta(t) \)

  • 入力:時刻\( t \)
  • 出力:その時刻\( t \)での角度\( \theta \)

回転行列\( {\bf R } \)は、\( {\bf R }(\theta) \)として、以下のように書けます。

回転行列の関数\( {\bf R }(\theta) \)

  • 入力:時刻\( t \)での角度\( \theta \)
  • 出力:その角度\( \theta \)での行列

では、この出力の行列は何を表しているのかを考えます。

回転行列の性質は

広瀬茂男先生の「ロボット工学 ー機械システムのベクトル解析ー」、

川崎晴久先生の教科書「ロボット工学の基礎」、

梶田秀司先生の教科書「ヒューマノイドロボット」を読むと分かりやすいです。

絶対座標系の基底を直交単位ベクトル(いわゆるx軸, y軸, z軸方向の単位ベクトル)を \( {}^{0}{\bf e}_{x} \), \( {}^{0}{\bf e}_{y}\), \( {}^{0}{\bf e}_{z}\)とします。それぞれの座標値は以下のようなります。

$$  \begin{array}{rcl}
{}^{0}{\bf e}_{x} = \left[ \begin{array}{c}
1 \\
0 \\
0
\end{array} \right]
,\ \ \ &
{}^{0}{\bf e}_{y} = \left[ \begin{array}{c}
0 \\
1 \\
0
\end{array} \right]
,\ \ \ &
{}^{0}{\bf e}_{z} = \left[ \begin{array}{c}
0 \\
0 \\
1
\end{array} \right]
\end{array} $$

ここで絶対座標系と書きましたが、絶対座標系とは、、

  • 座標系のボス的存在で、
  • すべての座標の基準となる座標系
  • 空間上の点の座標を数多くの座標系間基準で相対的に表現しまくるのに対し、唯一絶対的な座標表現をするときの基準となる座標系
  • 相対座標系の対称として表顕される座標系

座標系については、別ページにまとめておきます。

今は基準座標系の話をしたいわけではありませんが、

座標表現されたベクトルの座標は必ず、基準座標系が何であるかを把握した上で使用しなければいけません。

特に3Dビジョンや双腕マニピュレータ、移動ロボット等で座標系をバンバン切り替えて操作するときは、間違えると危険です。

1つの絶対座標系を基準に表現しておくと、ややこしい座標系間の相対関係を考えるとき分かりやすくなります。

それでは話を戻して、

絶対座標系の基底を直交単位ベクトル(いわゆるx軸, y軸, z軸方向の単位ベクトル) を\( {\bf e}_{x} \), \( {\bf e}_{y}\), \( {\bf e}_{z}\)としました。

単位ベクトル、つまり大きさが1で、互いに直交する基底(互いに独立)なので、このベクトルを「正規直交基底」と言ったりするそうです。

3次元のベクトル空間は、基準となる座標系の3本の基底ベクトルで表現されます。線形代数の授業ですね。懐かしい。

以降、左上に基準座標系のラベルを書きます。

右下にその基準座標で表された注目する変数のラベルを書きます。

たとえば、あるベクトル\({\bf p} \)は、
座標系\( \Sigma_{A} \)基準の基底ベクトル\( {}^{A}{\bf e}_{x} \), \( {}^{A}{\bf e}_{y} \), \( {}^{A}{\bf e}_{z} \)により、\({}^{A}{\bf p} \)として表現すると、以下のように書きます。

$$ \begin{array}{rcl}
{}^{A}{\bf p} &=&
\left[ \begin{array}{ccc} {}^{A}p_x & {}^{A}p_y & {}^{A}p_z \end{array} \right]^{\rm T} \\
&=&
{}^{A}p_{x}{}^{A}{\bf e}_{x} +
{}^{A}p_{y}{}^{A}{\bf e}_{y} +
{}^{A}p_{z}{}^{A}{\bf e}_{z}
\end{array}
$$

ここで、\( {}^{A}{\bf e}_{x} \), \( {}^{A}{\bf e}_{y}\), \( {}^{A}{\bf e}_{z}\)それぞれの座標は以下のようなります。

$$  \begin{array}{rcl}
{}^{A}{\bf e}_{x} = \left[ \begin{array}{c}
1 \\
0 \\
0
\end{array} \right]
,\ \ \ &
{}^{A}{\bf e}_{y} = \left[ \begin{array}{c}
0 \\
1 \\
0
\end{array} \right]
,\ \ \ &
{}^{A}{\bf e}_{z} = \left[ \begin{array}{c}
0 \\
0 \\
1
\end{array} \right]
\end{array} $$

同様に、このベクトル\({\bf p} \)は

絶対座標系\( \Sigma_{0} \)基準の基底ベクトル\( {}^{0}{\bf e}_{x} \), \( {}^{0}{\bf e}_{y} \), \( {}^{0}{\bf e}_{z} \)により、\({}^{0}{\bf p}\)として表現すると、以下のように書けます。

$$ \begin{array}{rcl}
{}^{0}{\bf p} &=&
\left[ \begin{array}{ccc} {}^{0}p_x & {}^{0}p_y & {}^{0}p_z \end{array} \right]^{\rm T} \\
&=&
{}^{0}p_{x}{}^{0}{\bf e}_{x}
+ {}^{0}p_{y}{}^{0}{\bf e}_{y}
+ {}^{0}p_{z}{}^{0}{\bf e}_{z}
\end{array}
$$

では、座標系の変換を考えたいと思います。

いま、座標系\( \Sigma_{A} \)基準の基底ベクトル\( {}^{A}{\bf e}_{x} \), \( {}^{A}{\bf e}_{y} \), \( {}^{A}{\bf e}_{z} \)を、絶対座標系\( \Sigma_{0} \)基準で見たとき以下のように\( {}^{0}{\bf x}_{{}^{A}{\bf e}_{x}} \), \( {}^{0}{\bf y}_{{}^{A}{\bf e}_{y}} \), \( {}^{0}{\bf z}_{{}^{A}{\bf e}_{x}} \)と表せるとします。

$$ \begin{array}{rcl}
{}^{A}{\bf e}_{x}
& {}^{\Sigma_{A}}\longrightarrow^{\Sigma_{0}} &\ \
{}^{0}{\bf x}_{{}^{A}{\bf e}_{x}} =
\left[ \begin{array}{c}
{}^{0}x_{{}^{A}{\bf e}_{x}x} \\
{}^{0}x_{{}^{A}{\bf e}_{x}y} \\
{}^{0}x_{{}^{A}{\bf e}_{x}z}
\end{array} \right], \\
{}^{A}{\bf e}_{y}
& {}^{\Sigma_{A}}\longrightarrow^{\Sigma_{0}} &\ \
{}^{0}{\bf y}_{{}^{A}{\bf e}_{y}} =
\left[ \begin{array}{c}
{}^{0}y_{{}^{A}{\bf e}_{y}x} \\
{}^{0}y_{{}^{A}{\bf e}_{y}y} \\
{}^{0}y_{{}^{A}{\bf e}_{y}z}
\end{array} \right], \\
{}^{A}{\bf e}_{z}
& {}^{\Sigma_{A}}\longrightarrow^{\Sigma_{0}} &\ \
{}^{0}{\bf z}_{{}^{A}{\bf e}_{z}} =
\left[ \begin{array}{c}
{}^{0}z_{{}^{A}{\bf e}_{z}x} \\
{}^{0}z_{{}^{A}{\bf e}_{z}y} \\
{}^{0}z_{{}^{A}{\bf e}_{z}z}
\end{array} \right],
\end{array}
$$

この変換の関係を使用して、

上記の\( {}^{0}{\bf p} \)を、かなり無理矢理ですが、以下のように式変形します。

特に二段目から三段目、五段目から六段目の式変形は、ふつう導出では出てこない、かなり無理矢理な便宜上の変形です。

$$ \begin{array}{rcl}
{}^{0}{\bf p} &=&
\left[ \begin{array}{ccc} {}^{0}p_x & {}^{0}p_y & {}^{0}p_z \end{array} \right]^{\rm T} \\
&=&
{}^{0}p_{x}{}^{0}{\bf e}_{x}
+ {}^{0}p_{y}{}^{0}{\bf e}_{y}
+ {}^{0}p_{z}{}^{0}{\bf e}_{z}\\
&=&
{}^{A}p_{x}
\left( {}^{0}x_{{}^{A}{\bf e}_{x}x}{}^{0}{\bf e}_{x}
+  {}^{0}x_{{}^{A}{\bf e}_{x}y}{}^{0}{\bf e}_{y}
+ {}^{0}x_{{}^{A}{\bf e}_{x}z}{}^{0}{\bf e}_{z}\right)  \\
&\ &\ +
{}^{A}p_{y}
\left( {}^{0}y_{{}^{A}{\bf e}_{y}x}{}^{0}{\bf e}_{x}
+  {}^{0}y_{{}^{A}{\bf e}_{y}y}{}^{0}{\bf e}_{y}
+ {}^{0}y_{{}^{A}{\bf e}_{y}z}{}^{0}{\bf e}_{z}
\right) \\
&\ &\ +
{}^{A}p_{z}
\left( {}^{0}z_{{}^{A}{\bf e}_{z}x}{}^{0}{\bf e}_{x}
+  {}^{0}z_{{}^{A}{\bf e}_{z}y}{}^{0}{\bf e}_{y}
+ {}^{0}z_{{}^{A}{\bf e}_{z}z}{}^{0}{\bf e}_{z}
\right) \\
&=&
{}^{A}p_{x}
\left[ \begin{array}{c}
{}^{0}x_{{}^{A}{\bf e}_{x}x} \\
{}^{0}x_{{}^{A}{\bf e}_{x}y} \\
{}^{0}x_{{}^{A}{\bf e}_{x}z}
\end{array} \right] +
{}^{A}p_{y}
\left[ \begin{array}{c}
{}^{0}y_{{}^{A}{\bf e}_{y}x} \\
{}^{0}y_{{}^{A}{\bf e}_{y}y} \\
{}^{0}y_{{}^{A}{\bf e}_{y}z}
\end{array} \right] +
{}^{A}p_{z}
\left[ \begin{array}{c}
{}^{0}z_{{}^{A}{\bf e}_{z}x} \\
{}^{0}z_{{}^{A}{\bf e}_{z}y} \\
{}^{0}z_{{}^{A}{\bf e}_{z}z}
\end{array} \right] \\
&=&
{}^{A}p_{x}{}^{0}{\bf x}_{{}^{A}{\bf e}_{x}} +
{}^{A}p_{y}{}^{0}{\bf y}_{{}^{A}{\bf e}_{y}} +
{}^{A}p_{z}{}^{0}{\bf z}_{{}^{A}{\bf e}_{z}} \\
&=&
{}^{A}p_{x} \left[
\left[ \begin{array}{ccc}
{}^{0}x_{{}^{A}{\bf e}_{x}x} &
{}^{0}y_{{}^{A}{\bf e}_{y}x} &
{}^{0}z_{{}^{A}{\bf e}_{z}x}
\end{array} \right]
\left[ \begin{array}{c}
1 \\
0 \\
0
\end{array} \right] \right. \\
&\ &\ \ \ \ \ \ \ \ \ ,
\left.
\left[ \begin{array}{ccc}
{}^{0}x_{{}^{A}{\bf e}_{x}y} &
{}^{0}y_{{}^{A}{\bf e}_{y}y} &
{}^{0}z_{{}^{A}{\bf e}_{z}y}
\end{array} \right]
\left[ \begin{array}{c}
1 \\
0 \\
0
\end{array} \right]
\right. \\
&\ &\ \ \ \ \ \ \ \ \ ,
\left.
\left[ \begin{array}{ccc}
{}^{0}x_{{}^{A}{\bf e}_{x}z} &
{}^{0}y_{{}^{A}{\bf e}_{y}z} &
{}^{0}z_{{}^{A}{\bf e}_{z}z}
\end{array} \right]
\left[ \begin{array}{c}
1 \\
0 \\
0
\end{array} \right]
\right]
\\
&\ & +
{}^{A}p_{y} \left[
\left[ \begin{array}{ccc}
{}^{0}x_{{}^{A}{\bf e}_{x}x} &
{}^{0}y_{{}^{A}{\bf e}_{y}x} &
{}^{0}z_{{}^{A}{\bf e}_{z}x}
\end{array} \right]
\left[ \begin{array}{c}
0 \\
1 \\
0
\end{array} \right] \right. \\
&\ &\ \ \ \ \ \ \ \ \ ,
\left.
\left[ \begin{array}{ccc}
{}^{0}x_{{}^{A}{\bf e}_{x}y} &
{}^{0}y_{{}^{A}{\bf e}_{y}y} &
{}^{0}z_{{}^{A}{\bf e}_{z}y}
\end{array} \right]
\left[ \begin{array}{c}
0 \\
1 \\
0
\end{array} \right]
\right. \\
&\ &\ \ \ \ \ \ \ \ \ ,
\left.
\left[ \begin{array}{ccc}
{}^{0}x_{{}^{A}{\bf e}_{x}z} &
{}^{0}y_{{}^{A}{\bf e}_{y}z} &
{}^{0}z_{{}^{A}{\bf e}_{z}z}
\end{array} \right]
\left[ \begin{array}{c}
0 \\
1 \\
0
\end{array} \right]
\right] \\
&\ & +
{}^{A}p_{z} \left[
\left[ \begin{array}{ccc}
{}^{0}x_{{}^{A}{\bf e}_{x}x} &
{}^{0}y_{{}^{A}{\bf e}_{y}x} &
{}^{0}z_{{}^{A}{\bf e}_{z}x}
\end{array} \right]
\left[ \begin{array}{c}
0 \\
0 \\
1
\end{array} \right] \right. \\
&\ &\ \ \ \ \ \ \ \ \ ,
\left.
\left[ \begin{array}{ccc}
{}^{0}x_{{}^{A}{\bf e}_{x}y} &
{}^{0}y_{{}^{A}{\bf e}_{y}y} &
{}^{0}z_{{}^{A}{\bf e}_{z}y}
\end{array} \right]
\left[ \begin{array}{c}
0 \\
0 \\
1
\end{array} \right]
\right. \\
&\ &\ \ \ \ \ \ \ \ \ ,
\left.
\left[ \begin{array}{ccc}
{}^{0}x_{{}^{A}{\bf e}_{x}z} &
{}^{0}y_{{}^{A}{\bf e}_{y}z} &
{}^{0}z_{{}^{A}{\bf e}_{z}z}
\end{array} \right]
\left[ \begin{array}{c}
0 \\
0 \\
1
\end{array} \right]
\right] \\
&=&
{}^{A}p_{x}
\left[ \begin{array}{ccc}
{}^{0}x_{{}^{A}{\bf e}_{x}x}  & {}^{0}y_{{}^{A}{\bf e}_{y}x}   & {}^{0}z_{{}^{A}{\bf e}_{z}x}  \\
{}^{0}x_{{}^{A}{\bf e}_{x}y}  & {}^{0}y_{{}^{A}{\bf e}_{y}y}   & {}^{0}z_{{}^{A}{\bf e}_{z}y}  \\
{}^{0}x_{{}^{A}{\bf e}_{x}z}  & {}^{0}y_{{}^{A}{\bf e}_{y}z}   & {}^{0}z_{{}^{A}{\bf e}_{z}z}
\end{array} \right]
\left[ \begin{array}{c}
1 \\
0 \\
0
\end{array} \right] \\
&\ & +
{}^{A}p_{y}
\left[ \begin{array}{ccc}
{}^{0}x_{{}^{A}{\bf e}_{x}x}  & {}^{0}y_{{}^{A}{\bf e}_{y}x}   & {}^{0}z_{{}^{A}{\bf e}_{z}x}  \\
{}^{0}x_{{}^{A}{\bf e}_{x}y}  & {}^{0}y_{{}^{A}{\bf e}_{y}y}   & {}^{0}z_{{}^{A}{\bf e}_{z}y}  \\
{}^{0}x_{{}^{A}{\bf e}_{x}z}  & {}^{0}y_{{}^{A}{\bf e}_{y}z}   & {}^{0}z_{{}^{A}{\bf e}_{z}z}
\end{array} \right]
\left[ \begin{array}{c}
0 \\
1 \\
0
\end{array} \right] \\
&\ & +
{}^{A}p_{z}
\left[ \begin{array}{ccc}
{}^{0}x_{{}^{A}{\bf e}_{x}x}  & {}^{0}y_{{}^{A}{\bf e}_{y}x}   & {}^{0}z_{{}^{A}{\bf e}_{z}x}  \\
{}^{0}x_{{}^{A}{\bf e}_{x}y}  & {}^{0}y_{{}^{A}{\bf e}_{y}y}   & {}^{0}z_{{}^{A}{\bf e}_{z}y}  \\
{}^{0}x_{{}^{A}{\bf e}_{x}z}  & {}^{0}y_{{}^{A}{\bf e}_{y}z}   & {}^{0}z_{{}^{A}{\bf e}_{z}z}
\end{array} \right]
\left[ \begin{array}{c}
0 \\
0 \\
1
\end{array} \right] \\
&=&
\left[ \begin{array}{ccc}
{}^{0}x_{{}^{A}{\bf e}_{x}x}  & {}^{0}y_{{}^{A}{\bf e}_{y}x}   & {}^{0}z_{{}^{A}{\bf e}_{z}x}  \\
{}^{0}x_{{}^{A}{\bf e}_{x}y}  & {}^{0}y_{{}^{A}{\bf e}_{y}y}   & {}^{0}z_{{}^{A}{\bf e}_{z}y}  \\
{}^{0}x_{{}^{A}{\bf e}_{x}z}  & {}^{0}y_{{}^{A}{\bf e}_{y}z}   & {}^{0}z_{{}^{A}{\bf e}_{z}z}
\end{array} \right]
\left(
{}^{A}p_{x}{}^{A}{\bf e}_{x} +
{}^{A}p_{y}{}^{A}{\bf e}_{y} +
{}^{A}p_{z}{}^{A}{\bf e}_{z}
\right)
\end{array} $$

最終的に以下のように表せます。

$$
\begin{array}{rcl}
{}^{0}{\bf p} &=&
\left[ \begin{array}{c}
{}^{0}{\bf x}_{{}^{A}{\bf e}_{x}} &
{}^{0}{\bf y}_{{}^{A}{\bf e}_{y}} &
{}^{0}{\bf z}_{{}^{A}{\bf e}_{z}}
\end{array} \right]
\left(
{}^{A}p_{x}{}^{A}{\bf e}_{x} +
{}^{A}p_{y}{}^{A}{\bf e}_{y} +
{}^{A}p_{z}{}^{A}{\bf e}_{z}
\right) \\
&=&
\left[ \begin{array}{c}
{}^{0}{\bf x}_{{}^{A}{\bf e}_{x}} &
{}^{0}{\bf y}_{{}^{A}{\bf e}_{y}} &
{}^{0}{\bf z}_{{}^{A}{\bf e}_{z}}
\end{array} \right]
{}^{A}{\bf p } \\
&=&
{}^{0}{\bf R}_{A}\ {}^{A}{\bf p }
\end{array}
$$

基底ベクトルは座標値だけみると、\( {}^{A}{\bf e}_{x} \)も\( {}^{0}{\bf e}_{x} \)も同じ座標値\( \left[ \begin{array}{ccc} 1 & 0 & 0 \end{array} \right] \) ですが、両者は別モノですね。

座標値を表す座標系空間が異なるということを忘れて同じと思ってしまう時もありますが。

上の式は、座標系\( \Sigma_{A} \)空間上のベクトル\( {}^{A}{\bf p } \)が、\( {}^{0}{\bf R}_{A} \)によって座標系\( \Sigma_{0} \)空間上のベクトル\( {}^{0}{\bf p } \)に変換されていることを表しているのです。

さらに行列\( {}^{0}{\bf R}_{A} \)の中身は、

座標系\( \Sigma_{A} \)の基底ベクトル\( {}^{A}{\bf e}_{x} \), \( {}^{A}{\bf e}_{y} \), \( {}^{A}{\bf e}_{z} \)を、絶対座標系\( \Sigma_{0} \)基準で表したときのベクトル\( {}^{0}{\bf x}_{{}^{A}{\bf e}_{x}} \), \( {}^{0}{\bf y}_{{}^{A}{\bf e}_{y}} \), \( {}^{0}{\bf z}_{{}^{A}{\bf e}_{z}} \)で構成されているのです。

$$
{}^{0}{\bf R}_{A}
=
\left[ \begin{array}{c}
{}^{0}{\bf x}_{{}^{A}{\bf e}_{x}} &
{}^{0}{\bf y}_{{}^{A}{\bf e}_{y}} &
{}^{0}{\bf z}_{{}^{A}{\bf e}_{z}}
\end{array} \right]
$$

このベクトル\( {}^{0}{\bf x}_{{}^{A}{\bf e}_{x}} \), \( {}^{0}{\bf y}_{{}^{A}{\bf e}_{y}} \), \( {}^{0}{\bf z}_{{}^{A}{\bf e}_{z}} \)は、
座標系\( \Sigma_{A} \)原点が絶対座標系\( \Sigma_{0} \)原点からベクトル\( {}^{0}{\bf p}_{A} \)だけ離れていると、
下図のように各ベクトルの大きさは、座標系\( \Sigma_{0} \)から\( \Sigma_{A} \)への並進移動分のベクトル\( {}^{0}{\bf p}_{A} \)がどのような値をとるかによってバラバラです。(手書きで見苦しくて申し訳ないです)

座標系の位置関係

今は回転のみを考えたいので、並進ベクトル\( {}^{0}{\bf p}_{A} \)は無視して、
下図のように座標系\( \Sigma_{A} \)原点が絶対座標系\( \Sigma_{0} \)原点と一致するように考えます。
(これまた手書きで見苦しくて申し訳ないです)

絶対座標系\( \Sigma_{0} \)を、回転軸\( \bf n \)まわりに回転角\( \theta \)だけ回転した座標系が、\( \Sigma_{A} \)と見ることができます。

絶対座標系\( \Sigma_{0} \)から見た座標系\( \Sigma_{A} \)の基底ベクトル\( {}^{A}{\bf e}_{x} \), \( {}^{A}{\bf e}_{y} \), \( {}^{A}{\bf e}_{z} \)は、\( {}^{0}{\bf x}_{{}^{A}{\bf e}_{x}} \), \( {}^{0}{\bf y}_{{}^{A}{\bf e}_{y}} \), \( {}^{0}{\bf z}_{{}^{A}{\bf e}_{z}} \)にそのまま対応するので
各ベクトルの大きさは1になります。

基底ベクトル

行列\( {}^{0}{\bf R}_{A} \)は、
座標系\( \Sigma_{A} \)の基底ベクトル\( {}^{A}{\bf e}_{x} \), \( {}^{A}{\bf e}_{y} \), \( {}^{A}{\bf e}_{z} \)を絶対座標系\( \Sigma_{0} \)基準で表したベクトル\( {}^{0}{\bf x}_{{}^{A}{\bf e}_{x}} \), \( {}^{0}{\bf y}_{{}^{A}{\bf e}_{y}} \), \( {}^{0}{\bf z}_{{}^{A}{\bf e}_{z}} \)で構成されており、
これは座標系\( \Sigma_{A} \)の回転状態、いわゆる姿勢を表しているといえるのです。

(意味1)回転行列は座標系の姿勢を表す

また、先程の式変形で以下のような関係があることを示しました。

$$
{}^{0}{\bf p} = {}^{0}{\bf R}_{A}\ {}^{A}{\bf p }
$$

回転行列\( {}^{0}{\bf R}_{A} \)が、座標系\( \Sigma_{A} \)基準のベクトル\( {}^{A}{\bf p} \)にかかると(作用すると)、座標系\( \Sigma_{A} \)基準のベクトル\( {}^{0}{\bf p} \)に変換されるのでした。

回転行列は、それ自体は座標系の姿勢を表していますが、その座標系基準で表されたベクトルに作用すると、座標系変換の作用を持ちます。

(意味2)回転行列は座標系変換の作用をもつ

ふう、、

回転行列は奥が深い。

でもまだ実は座標系変換だけでなく、もう一つ、回転行列の作用がもつ意味があります。

それが回転運動です。

座標系の基底ベクトルの回転運動

(意味3)回転行列は回転運動の作用をもつ

今まで、座標系を\( \bf A \)というラベルで表してきましたが、これを今度は時間\( t \)に置き換えて考えてみます。

時々刻々と変化する回転運動を、先程まで説明してきた座標系変換のように考えます。

時刻\( t \)のときの絶対座標系\( \Sigma_{0} \)基準でベクトル \( {}^{0}{\bf p}(t) \)だったものが、

時間\( \Delta t \)のあいだ\(\Delta \theta \)回転して

時刻\( t + \Delta \)のときの絶対座標系\( \Sigma_{0} \)基準でベクトル \( {}^{0}{\bf p}(t + \Delta) \)になったとします。

この運動を式で表すと以下のように書けます。

$$
\begin{array}{rcl}
{}^{0_{t+\Delta t}}{\bf p}(t + \Delta t) &=& {}^{0_{t + \Delta t}}{\bf R}_{0_t}( \Delta t ) {}^{0_t}{\bf p}(t) \\
\end{array}
$$

冒頭にも述べましたが、回転行列\( \bf R \)の直接の入力は回転角\( \theta \)です(回転角\( \theta \)の入力が時間t)。

時間\( \Delta t \)のあいだ回転するとき、回転角が\( \Delta \theta \)とすると、上の式は以下のように直せます。

$$
{}^{0_{t + \Delta t}}{\bf p}(t + \Delta t) = {}^{0_{t + \Delta t}}{\bf R}_{0_t}( \Delta \theta) {}^{0_t}{\bf p}(t)
$$

以降、時刻\( t + \Delta t \)のときの絶対座標系\( \Sigma_{0} \)基準という表現は、省略して以下のように書かせてもらいます。

$$
{}^{0}{\bf p}(t + \Delta t) = {}^{0}{\bf R}( \Delta \theta) {}^{0}{\bf p}(t)
$$

絶対座標系\( \Sigma_{0} \)基準の基底ベクトル\( {}^{0}{\bf e}_{x} \), \( {}^{0}{\bf e}_{y} \), \( {}^{0}{\bf e}_{z} \)は、回転角\( \Delta \theta \)に伴って\( {}^{0}{\bf x}_{{}^{0}{\bf e}_{x}}(\Delta \theta) \), \( {}^{0}{\bf y}_{{}^{0}{\bf e}_{y}}(\Delta \theta) \), \( {}^{0}{\bf z}_{{}^{0}{\bf e}_{z}} (\Delta \theta) \)となるので、姿勢の変化は以下のようになります。

$$
{}^{0}{\bf R} (\Delta \theta)
=
\left[ \begin{array}{c}
{}^{0}{\bf x}_{{}^{0}{\bf e}_{x}} (\Delta \theta) &
{}^{0}{\bf y}_{{}^{0}{\bf e}_{y}} (\Delta \theta) &
{}^{0}{\bf z}_{{}^{0}{\bf e}_{z}} (\Delta \theta)
\end{array} \right]
$$

さらにこれら基底ベクトル\( {}^{0}{\bf x}_{{}^{0}{\bf e}_{x}} \), \( {}^{0}{\bf y}_{{}^{0}{\bf e}_{y}} \), \( {}^{0}{\bf z}_{{}^{0}{\bf e}_{z}} \)は、下図のように\( \Delta \theta \)変化すると、原点は同じまま、かつベクトルの大きさは1なので、半径1の球の表面上の点を移動します。

基底ベクトル(緑色)の運動

図にもオレンジの線でいくつか描きましたが、この基底ベクトルの球表面上での移動の仕方は、一様ではありません。

\( \Delta \theta \)の軌道(=\( \theta(t) \)の軌道計算方法)、回転軸方向\( \bf n \)に依存します。

よって、姿勢の変化\( {}^{0}{\bf R}(\Delta \theta) \)も\( \theta(t) \)の軌道、回転軸方向\( \bf n \)に依存することになります。
これは \( \Delta {\bf \omega}  = \Delta t \ {\bf \omega}(t) = \Delta \theta \ {\bf n} \)に依存すると言うこともできます。ロドリゲスの公式を当てはめると姿勢の変化とは\( {}^{0}{\bf R}(\Delta \theta, {\bf n}) \)として以下のように書き表わすこともできます。

$$
\begin{array}{rcl}
{}^{0}{\bf R}(\Delta \theta)
&=&
\left[ \begin{array}{c}
{}^{0}{\bf x}_{{}^{0}{\bf e}_{x}} (\Delta \theta) &
{}^{0}{\bf y}_{{}^{0}{\bf e}_{y}} (\Delta \theta) &
{}^{0}{\bf z}_{{}^{0}{\bf e}_{z}} (\Delta \theta)
\end{array} \right] \\
&=& {}^{0}{\bf R} (\Delta \theta, {\bf n}) \\
&=& {\bf I} + {\rm sin}(\Delta \theta) {\bf[ n\times]} + (1 – {\rm cos}(\Delta \theta)) {\bf[ n\times]}^2 \
\end{array}
$$

\( \Delta t \)時間変化後の姿勢、時刻\( t + \Delta t \)のときの姿勢\( {}^{0}{\bf R}(t + \Delta t )\)は以下のように表せます。

$$
\begin{array}{rcl}
{}^{0}{\bf R} (t + \Delta t)
&=& {}^{0}{\bf R} (\Delta \theta, {\bf n}) {}^{0}{\bf R} (t)
\end{array}
$$

開始時刻\( t_0 \) から \( \Delta t \)ずつ経過して 終端時刻 \( t_f \) まで姿勢の運動は以下のように書き表せることができると言えます。

$$
\begin{array}{rcl}
{}^{0}{\bf R} (t_f)
&=& {}^{0}{\bf R}_{f-1 \rightarrow f}(\Delta t) \cdots {}^{0}{\bf R}_{i \rightarrow i+1}(\Delta t) \cdots {}^{0}{\bf R}_{1 \rightarrow 2}(\Delta t) {}^{0}{\bf R}_{0 \rightarrow 1}(\Delta t) {}^{0}{\bf R}(t_0) \\
&=& {}^{0}{\bf R}(\Delta \theta_f) \cdots {}^{0}{\bf R}(\Delta \theta_i) \cdots {}^{0}{\bf R}(\Delta \theta_2) {}^{0}{\bf R}(\Delta \theta_1) {}^{0}{\bf R}(t_0) \\
&=& {}^{0}{\bf R}(\Delta \theta_f, {\bf n}_f) \cdots {}^{0}{\bf R}(\Delta \theta_i, {\bf n}_i) \cdots {}^{0}{\bf R}(\Delta \theta_2, {\bf n}_2) {}^{0}{\bf R}(\Delta \theta_1, {\bf n}_1) {}^{0}{\bf R}(t_0)
\end{array}
$$

回転行列の速度

以上を踏まえて、回転行列の速度\( {\dot {\bf R}} \)が何かを考えると、

姿勢の速度

と簡単に考えられます。

姿勢は基底ベクトルで構成されていたので、姿勢の速度とは基底ベクトルの速度\( {}^{0}{\dot {\bf x}}_{{}^{0}{\bf e}_{x}} \), \( {}^{0}{\dot {\bf y}}_{{}^{0}{\bf e}_{y}} \), \( {}^{0}{\dot {\bf z}}_{{}^{0}{\bf e}_{z}} \)といえます。

言い換えると、

基底ベクトルの運動方向(球表面上を移動する軌道の接線の傾き)

を表しています。

これらは、回転角の軌道速度\( {\dot \theta}(t) \)、回転軸方向\( \bf n \)に依存します。

この特徴をまとめたものが、角速度ベクトル\( \bf \omega \)だったのですね。

$$
{\bf \omega} = {\dot \theta} {\bf n}
$$

速度\( {\dot {\bf R}} \)の式を見直してみると、

$$ \begin{array}{rcl}
{\dot {\bf R}} &=& {\dot \theta} [{\bf n} \times] {\bf R} \\
&=& [\omega \times] {\bf R}
\end{array}
$$

でした。

回転行列\( {\bf R} \)と、その速度の元となる角速度ベクトル\( \bf \omega \)との外積で得られる行列、

すなわち、基底ベクトルの運動方向

$$
{}^{0}{\dot {\bf x}}_{{}^{0}{\bf e}_{x}} = \omega \times {}^{0}{\bf x}_{{}^{0}{\bf e}_{x}} = {\dot \theta} {\bf n} \times {}^{0}{\bf x}_{{}^{0}{\bf e}_{x}}
$$

$$
{}^{0}{\dot {\bf y}}_{{}^{0}{\bf e}_{y}} = \omega \times {}^{0}{\bf y}_{{}^{0}{\bf e}_{y}} = {\dot \theta} {\bf n} \times {}^{0}{\bf y}_{{}^{0}{\bf e}_{y}}
$$

$$
{}^{0}{\dot {\bf z}}_{{}^{0}{\bf e}_{z}} = \omega \times {}^{0}{\bf z}_{{}^{0}{\bf e}_{z}} = {\dot \theta} {\bf n} \times {}^{0}{\bf z}_{{}^{0}{\bf e}_{z}}
$$

を表していたのでした。

この運動方向は、外積の性質からもいえるように、回転軸\( \bf n \)と各基底ベクトルと垂直に交わる方向になります。

上の図の、球表面に対して接する方向です。

絶対座標系\( \Sigma_{0} \)から見たベクトル\( {}^{0} {\bf p} \)の速度\( {}^{0}{\dot {\bf p}} \)は、角速度ベクトル \( \bf \omega \) により外積の形で表され、さらにその外積ベクトルは、\( {}^{0}{\dot {\bf R}} \)についての方程式から\( {}^{0}{\dot {\bf R}} {}^{0} {\bf R}^{\rm T} \)となることが分かるので、以下の式で表されます。

$$
\begin{array}{rcl}
{}^{0}{\dot {\bf p}} &=& {\bf \omega} \times {}^{0}{\bf p} \\
&=& [{\bf \omega} \times ] {}^{0}{\bf p} \\
&=& {}^{0}{\dot {\bf R}} {}^{0} {\bf R}^{\rm T} {}^{0}{\bf p}
\end{array}
$$

ふう、、

ここまで回転行列を掘り下げるなんて、まぁまずやらないですね。

「だからどうした」と、実際必要性を全く感じない話かもしれません。

途中の式変形とか狂気の沙汰でしたね。

でも、自分でこうやって深いところまで探った後は、現象を多面的に捉えて理解しやすくなるし、制御するときの応用を考えやすくなるので、一度はやっときたいと考えています。

あと、たいていのロボット工学の教科書では、回転行列の以下の性質

  • 姿勢
  • 座標系変換させるオペレータ
  • 回転運動させるオペレータ

を一緒くたに説明してあり、それぞれの意味・利用方法が違うことがわからなくなります(梶田先生の教科書ではきちんと説明してあります)。

なので今後、回転行列を出すときはどれを表しているか十分注意してノートしていきたいです。

以上です。