Nov11’s diary(自宅での開発環境作り )

3Dプリンタと切削加工機で工作した事をアップして行きます

自作したロボットアームを制御する(現実認識を行う)(その1)OpenCVでAR(拡張現実)を行う

自作したロボットアームのエドをVR(仮想現実)上で自由に動かせたので、エドの目を作成する事にした
こちらも、OpenGLと同様に、OpenCVVisual studio C++を使って作成する事にした
OpenCVを使用してのプログラムは、参考にするサイトが色々とあり、OpenGLに比べて、楽に組めた
ただ、OpenCVのバージョン毎のコーディングが違っていて、整理するのに苦労してしまった

んで。手始めに少し前に流行ったAR(拡張現実)を使って、オセロのコマを認識する事にしてみた
注意点は、使用したリソースをプログラム終了時に開放しないと、プログラムが正しく終了しない
また、使用するWebカメラによって、初回取り込みまで一定の時間(1秒程度)経過して取り込まないと正しく取り込めない

[処理手順]
1)オセロのコマの画像を白と黒、それぞれで用意する
2)OpenCVを使って、画像を取り込む
  cvCaptureFromCAMでカメラと接続する
  cvQueryFrameで画像をキャプチャーする
3)コマ(白、黒)のマッチングを行う
  matchTemplateを使用して、画像が含まれているか確認する
  戻り値の認識率が一定の値以上なら、含まれているので、
  認識した位置を使用して、表示を行う

[認識結果]

f:id:Nov11:20161025073353j:plain

[認識している動画]

youtu.be

余談だけど、ドラマ24の「勇者ヨシヒコ」を見ていて思ってしまった事が、このまま、エドにカメラを取り付け、文字が読める様になり、自分で学習出来るようになると、「寄生獣のミギー」、いや「ヒダリー?」みたくなってしまう...
ん~、何かの啓示なのか、これを機会に改名しろと神様が言っている...はずは無いか!
やはり真面目に取り組む為にも、エドで行こう!

なお、ブログの内容を参照して実行した結果に責任は負いかねますので、ご了承下さい

自作したロボットアームを制御する(仮想現実での制御)(その4)計算により関節の角度を求める

自作したロボットアームのエド(2016年06月13日)のCadデータをVisualStudioとOpenGLを使用してVR(仮想現実)で自由に動かせる様になったので、目標位置に対して、各関節の角度を演算により求める事が出来るようにして、目標角度までをアニメーション表示出来るようにもしてみました

ついでに、移動目標が〇だと寂しいので、移動目標を飛行機(本当はヘリコプターにしたかったけど、難しかったので断念しました)にして、ロボットアームvs飛行機って感じのCGが、以下になります

[エド vs 飛行機]

f:id:Nov11:20161015095548j:plain


計算手順は、意外と簡単で、以下のように計算してみました

ロボットアームの基準座標を点P,飛行機の座標を点R,ロボットアームの関節座標を点Qとします
図で表すと、図ー1の様になり、簡略化した物が図ー2となってます
(注意)筆者は、図画工作系の人間なので、数学的表現が微妙となってます

[計算手順]
1)ロボットアームの基準座標と飛行機の座標との水平垂直角度を求める
  空間座標が分かっているので、atan(アークタンジェント)により求める
2)ロボットアームの基準座標と飛行機の座標との直線距離を求める
  「ピタゴラスの定理」で求める
3)点Rの座標を求めて、角度を算出する
  2)で求めた長さと1)で求めた垂直角度から、点Rの座標を求める
  肩から肘(P-Q)の長さ(A)と、肘から掴み(Q-R)の長さ(B)はわかっているので、
  点Pを中心に半径Aの円と点Rを中心に半径Bの円の交点を求めて、点Qとする
  後は、点P、Q、Rの角度を求めれば、計算完了となる
  言葉ではわかりずらいので、図ー3を参照してください

[図ー1]

f:id:Nov11:20161015095652j:plain

[図ー2]

f:id:Nov11:20161015095740j:plain

[図ー3]

f:id:Nov11:20161015095759j:plain

 

んで、計算し動作させると、こんな感じです

youtu.be
やっと、VR(仮想現実)とは言え、任意の空間座標にアームを動かせる様になったので、いよいよ画像認識に取り掛かろうと思うけど、複数の空間座標を通るようにしてからにするか迷うところです
迷う理由は、複数の空間座標を通す為に、3次元の補間計算プログラムを作成しないといけない...
結構大変な作業になりそうなので、悩ましぃとことです

なお、ブログの内容を参照して実行した結果に責任は負いかねますので、ご了承下さい

自作したロボットアームを制御する(仮想現実での制御)(その3)カメラを取り付ける

エド(仮想現実)の手にカメラを取り付けて、エドの主観で仮想空間を見れる様にしてみた
また、エドの指先の空間座標を表示できる様にもして見た
実は、今回の苦労してVR(仮想現実)を作成した目的は、この2つを行いたかったからだ

複数の関節を動かした際に、ロボットアームの指先が、基準点(台座の中心点)から、どれくらいの距離なのかを算出したかったのと、仮想現実で表示内容とWebカメラで撮影した映像をOpenCVで画像処理した物を比較する事によりエドの動作状況をフィードバックさせる事が出来るようにする為だった
また、エドの主観視が出来たことで、抽象的な表現(上下左右など)をエドが認識できる

つまりは、「エドから見て、右上の赤いボールを、左の台に移動させて」が通じる様になるのだ
(右は、第一象限、左は第二象限、上は高さと言う感じです)

後は、音声認識ソフトを使用して、音声によりエドに指示が出せると言う、SF映画などでよく見る光景を作り出す事が出来そうです!
今回のプログラムは、OpenGLとEigenを使用しているので、スマートフォンにも移植しやすいので、スマートフォン音声認識機能を使用すれば、スマートフォン+インカムで、やり取りさせる事が出来る
おぉ~!、まさにSF映画だぁ~!!

[ロボットアームの画面]

f:id:Nov11:20160907110323j:plain
        (アームの先端にカメラと画面右上に空間座標が表示されてます)

[ロボットアームのカメラ動作確認用マーカ]

f:id:Nov11:20160907110354j:plain
        (テーブル上にアルファベットと高さ確認用のマーカを表示しています)

[ロボットアームのカメラに切り替え]

f:id:Nov11:20160907110434j:plain
        (テーブル上のアルファベットと高さ確認用のマーカが表示されています)

んで、エドの主観視した動画を撮ってみました(右上の数値が指先座標です/単位はミリ)

ロボットアームにカメラを取り付け仮想空間を撮影してみた

youtu.b(カクカク動いてますが、操作に慣れていない為です)

この動画でテーブル全面を収める事が出来たので、カメラの取り付け位置は問題ないようです

後は、目的解釈部分と画像認識、音声認識を作成すればVR(仮想現実)シミュレーション完成となる
ここまでで1ヶ月以上掛かった事を考えると、先は長そうだけど、体壊さないように頑張らねばです

今回の主観視を作成していて気付いたのだが、ここまでのプログラムでドックファイトやカーチェイスなどのゲームが作成できるのだ!
体は、少し不自由になったけど、VR(仮想現実)ならそんな制約は無いので、色々と妄想してみよう

最後に、VisualStudioC++とOpenGLの制御手順をまとめてみました

[OpenGLの制御手順]

1)OpenGLのダウンロードする
  ここは、「OpenGL ダウンロード」でググると出てくるので、
  サイトの記述に従いダウンロードする
  Windowsで、「OpenGL32.lib」を使用する場合には、1~3は不要で、
  インクルードを以下のように記述する
  ----------------------------------------------
  #include <windows.h>
  #include <GL/glu.h>
  #include "OpenGL.h"

  #pragma comment (lib, "OpenGL32.lib")
  #pragma comment (lib, "GLU32.lib")
  #pragma comment (lib, "user32.lib")
  #pragma comment(lib, "gdi32.lib")
  ----------------------------------------------

2)Windowsフォームアプリケーションを作成する
  VisualStudioの新しいプロジェクトで、VisualStudio C++
  Windowsフォームアプリケーションを作成する
  VisualStudioは、2010以前を使用すると作成し易くなる

3)OpenGLを配置する
  ヘッダー、ライブラリー、DLLファイルを新規作成した
  フォルダーに配置する

4)OpenGLの設定を行う
  Form1.hのコンストラクタで、描画するコントロール
  デバイスコンテキストを取得し、OpenGLの初期設定を行う
  wglDeleteContext,ReleaseDCなどを設定する

5)Cadデータを読込む
  DesignSpark mechanicalで、OBJファイルを出力しておく
  OBJファイル構成は、ネットに沢山あるので、そちらを参照する

6)カメラ設定を行う
   a)視野を設定
    glMatrixMode( GL_PROJECTION );←ここが無いと変更出来ない
    glLoadIdentity();
    gluPerspective();←引数は、Eigenを使用して求める
   b)カメラの位置、姿勢の設定
    glMatrixMode( GL_MODELVIEW );←ここが無いと変更出来ない
    glLoadIdentity();
    gluLookAt();←引数は、Eigenを使用して求める
   c)バッファのクリア
    glClear();←引数は、ググると出てくる
   d)ライトの設定
    glEnable();←引数は、ググると出てくる
    glLightfv();←引数は、ググると出てくる

7)パーツ表示を行う
  パーツ単位をglPushMatrixとglPopMatrixで挟み込み以下を繰り返す
   a)パーツの移動位置と回転をglTranslatedとglRotatefで指定する
   b)パーツのマテリアルをglMaterialfvで指定する
   c)パーツを構成するポリゴンをglVertex3fvで指定する
    各パーツは、glBeginとglEndで挟み込む
8)全て設定した後に、SwapBuffersを行う

なお、ブログの内容を参照して実行した結果に責任は負いかねますので、ご了承下さい

自作したロボットアームを制御する(仮想現実での制御)(その2)パーツを連動させる

エドの制御を行うために、エドの駆動9パーツを仮想空間に配置し、連動できる様にしてみた
が!、下図の様になってしまい想像通りには、全くさっぱりイメージ通りに表示してくれない!

[失敗イメージ]

f:id:Nov11:20160902141749j:plain

              (手首部分が正しく回転していない)

イメージ通りにいかない原因を調査した結果、OpenGLが予想と違う動きをしている事が分かった
予想と違っていたのは、OpenGLの回転指示関数(glRotatef)でモデルを回転させると、回転軸も追従して回転してくれていると思い込んでいたのだが、回転軸が追従してくれないので下図のように不思議な結果となってしまった

[予想していた回転]

f:id:Nov11:20160902141945j:plain

              (クリックすると拡大表示されます)

[現実の回転結果]

f:id:Nov11:20160902142011j:plain

              (クリックすると拡大表示されます)


んで、この問題を解決する方法をググったら「Quaternion:クォータニオン(四元数)」って単語が出てきたので、クォータニオンが記載されているページを開いた瞬間、ブラウザを閉じてしまった
思わず閉じてしまったホームページには、数式と文字が羅列され、図画工作系の筆者には、あまりにも敷居が高く、その領域に踏み込む事を危険と判断して、勝手にブラウザを閉じてしまったようだ
しかし、ここで諦めるわけにはいけないので、ブラウザを起動し、クォータニオン(四元数)を改めて、ググり恐るおそるクリックすると、やはり数式と文字が羅列されていて、取り付く島もない
何とか、図画工作系の筆者にも分かる様なサイトを見つけて、読み進むが、あっ!と言う間に頭の中を「?」マークが埋め尽くしてしまう…
んで、「ページを開く→「?」マークが頭を埋め尽くす→ブラウザを閉じる→落ち着く」を繰り返すこと3日!何とか取り付く島が出来たので、改めて纏めてみた
結果、OpenGLには、クォータニオンは含まれていないので、OpenGLの回転指示関数(glRotatef)に渡す回転軸を、クォータニオンで求める必要がある事が分かったので、クォータニオンをしてくれる行列演算ライブラリ(Eigen)を使用してプログラムを作成することにした
幸いC++でプログラムを作成していたので、行列演算ライブラリ(Eigen)を組み込む事は簡単だったが、ロボットアームの管理情報を階層化したのでプログラムが再帰構造になり、コンパクトにまとまりはしたが、第三者には解りづらいものになってしまった

しかし、DesignSpark mechanicalでデザインを行い、このプログラムで動作確認を行い、アニメーション形式でのプレゼンテーションでクライアントとのすり合わせを十分取った上で作成する事が出来る環境が整ったことになる
また、このプログラムに簡単な物理法則を組み込めば、デザイン時に警告を出す事も可能になりそうだけど、時間が掛かりそうなので、追々作成する事にして、後は、目的解釈部分を作成すれば完成となる!
もう一息だぁ~!
しかし、物理法則を組み込めば、仮想空間でピタゴラスイッチも可能になりそうって誘惑が筆者を襲ってくるので、この誘惑に負けないように頑張らなければです

[ロボットアームの動作]

youtu.be(操作に慣れていないので、カクカク動いてます)


なお、ブログの内容を参照して実行した結果に責任は負いかねますので、ご了承下さい

 

 

自作したロボットアームを制御する(仮想現実での制御)(その1)OpenGLで描画する

ロボットアームのエドが完成した(2016年06月13日)ので、制御用プログラムを作成する事にした
最初は、演算を行い簡単なワイヤーフレームで動作確認して行こうと考えていたのだが、DesignSpark mechanicalのCadデータを採寸し、別途ワイヤーフレームを構築すると修正対応などの管理が大変になりそうだし、他にも色々な事を想定すると、Cadデータを使用して動作確認をする事にした
んで、ネットでググったら、DirectXOpenGLが良い感じで、結果OpenGLを使用する事にした
OpenGLにした理由は、WindowsLinuxスマートフォンでも動作出来るし、OpenCVとの連携も可能みたいなので、この後に必要となる画像認識につなげて行けるので、OpenGLに決めた
次に、開発言語だが、C/C++C#のどちらするか考えたが、C#は、C/C++のラッパーで供給されていて制限もあるみたいなので、C/C++でプログラムを作成する事にした
んが、この後が、いばらの道となってしまった...
まず、普通にラインなどで描画して、視点移動でグルグル回している物などや、関数の説明はあるのだが、複数のCadデータを読込み、それらを連動させている物を見つけることが出来ない!
その上で、VisualStudioのWindowsフォームアプリケーションベースの物も見つからなく、C#ラッパー版を使用しようかと悩んだが、後々もっと困りそうなので、C/C++版で進める事を決意し、冷静に検索した内容を整理して行くと少しづつ理解できてきたので、簡単にまとめてみた

↓↓↓(以下の内容に変更が有ったので、9月7日のブログで修正しました)↓↓↓

[OpenGLの制御手順]
1)OpenGLのダウンロードする
  「OpenGL ダウンロード」でググると出てくるので、サイトの記述に従いダウンロードする
2)Windowsフォームアプリケーションを作成する
  VisualStudioの新しいプロジェクトで、VisualStudio C++Windowsフォームアプリケーションを作成する
3)OpenGLを配置する
  ヘッダー、ライブラリー、DLLファイルを新規作成したフォルダーに配置する
4)OpenGLの設定を行う
  Form1.hのコンストラクタで、描画するコントロールのデバイスコンテキストを取得し、
  OpenGLの初期設定を行う
  wglDeleteContext,ReleaseDCなどを設定する
5)Cadデータを読込む
  DesignSpark mechanicalで、OBJファイルを出力しておく
  OBJファイル構成は、ネットに沢山あるので、そちらを参照する
6)パーツ表示を行う
  カメラ設定を行う
  パーツ単位をglPushMatrixとglPopMatrixで挟み込み以下を繰り返す
   a)パーツの移動位置と回転をglTranslatedとglRotatefで指定する
   b)パーツのマテリアルをglMaterialfvで指定する
   c)パーツを構成するポリゴンをglVertex3fvで指定する
    各パーツは、glBeginとglEndで挟み込む
  全て設定した後に、SwapBuffersを行う

んで、悪戦苦闘の結果作成した物が以下の感じになった

[OpenGLで表示したCadデータ]

f:id:Nov11:20160625152940j:plain

              (クリックすると拡大表示されます)
上記の画面には、ロボットアームとロボットアーム移動範囲プレートの2つを表示しています

後は、各パーツを連動させる部分と、目的解釈部分を作成すれば、きっと良い感じでエドをVR(仮想現実)で動かす事が出来そうだ

なお、ブログの内容を参照して実行した結果に責任は負いかねますので、ご了承下さい

 

ロボットアームを3Dプリンタと切削加工機で自作する(パーツ作成)(その5)全部完成!

ロボットアーム完成しましたぁ~!!!
まだまだ調整や改良の余地はあるけど、何とか出来上がったです
これから、ロボットアーム専用のドライバーと、制御用アプリケーションを作らねばですね
オセロや将棋の相手をしてもらう為には、画像認識や音声認識も必要となってくるので、まだまだ先は長そうだけど、なんとなぁ~く最後まで出来そうな予感がしてきました

ちなみに、自作したロボットアームの愛称を『エド』にしてみました
名前の由来は、『鋼の錬金術師』の主人公の『エドワード・エルリック』で、とても難しいけど、『エドワード・エルリック』の右手の義手の様に、このロボットアームをベースに改良改善を加えて、筆者の少し動きの悪くなった左腕の補助が出来る様になってくれれば良いなぁ~って思いを込めて、『エド』にしてみました
さぁ~、名前の由来に少しでも近づける様に頑張るぞぉ~!

[ロボットアームの写真]

f:id:Nov11:20160613015815j:plain

なお、ブログの内容を参照して実行した結果に責任は負いかねますので、ご了承下さい

 

ロボットアームを3Dプリンタと切削加工機で自作する(パーツ作成)(その4)肩部分完成!

ロボットアームの台座の垂直回転まで出来ました!
知識不足のせいで、ずいぶんと回り道をしてしまったけど、やっとここまで出来たぁ~!

んで、いつも通り自作したサーボコントローラ(2016年04月25日のブログ)に接続し、ドキドキしながらスイッチをいれ、サーボモータの回転角を指定すると、おぉ~!420gのアームが持ち上がりました
が!、色々と回転角を変化させると、サーボモータからブーンと嫌な音が...
色々と調べると、アームを少ない角度で上方に移動させた場合に異音が発生する事が分かった
どうも、アームの重量により指定角度手前で停止し、小刻みに震えている様なので、一度指定位置より少し上を指定した後に、再度位置指定すると異音が無くなった
ん~、ロボットアームドライバーには、それぞれのサーボモータに意味合いを持たせた上で移動方向に対しての2段階補正を行えるように変更しなければならないようだ
だが取りあえず上手く行ったので、明日から台座の水平回転部分を作成して行こう!
もう少しで完成だぁ~!!

[ロボットアームの写真]

f:id:Nov11:20160609033408j:plain

なお、ブログの内容を参照して実行した結果に責任は負いかねますので、ご了承下さい