ロボット、千葉ロッテマリーンズについていいかげんなことを書きます。
×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
・・・どうも,お久しぶりです.
更新しようという気はあったのですが,どうにもネタがなくて滞りまくりでした.
サボってる間にOpenRTM-aist-1.1.0-RC2がリリースされたので,一応宣伝しときます.
レビューしたいところですが,C++版はだれかやりそうなので,Python版がリリースされたらやります.本当か?
それはさておき,さすがに放置しっぱなしはまずいので,単発企画ですが劣駆動ロボットの制御シミュレーションをやります.
単発企画なので,今回は車の制御や劣駆動マニピュレータの制御を飛ばして,蛇型ロボットの制御をやります.
・・・・とは言っても,非線形制御入門―劣駆動ロボットの技能制御論を参考にしたので,この記事読まずにこの本を読んだ方が良いです.
まず,劣駆動マニピュレータとは,
こんな感じに,非駆動関節のあるマニピュレータのことを言うと思います.
ちなみに,根元が非駆動です.
一方,蛇型ロボットは,
上の劣駆動マニピュレータに,非駆動の並進関節を追加すれば良いことになります.
すなわち,これは劣駆動と言えるかと思います.
今回は以下のような6リンクの蛇型ロボットを制御します.
1リンク目以降は面倒くさいので以下略で.
受動車輪までの長さをlgとすると,各リンクの受動車輪の位置,速度は,
こうなります.
クリックで拡大します.
また,受動車輪は横滑りしないとします.
そんな環境や機構が存在するかは別にして.
受動車輪の車軸方向のベクトルは,
となります.
受動車輪が横滑りしないとき速度ベクトルの車軸方向に0となるはずなので,
となる.
この式をまとめると,
となります.
この式を,
各関節角速度dψと,絶対角の角速度dθの関係式は,
となるので,
と,dψをロボットの入力とすれば先端速度dwを制御できます.
まあ,本当だったら動力学モデルに基づいてなんやかんややるべきでしょうけど,面倒くさいのでdwには目標位置との偏差を入れます.
関節はトルク制御ではなく,速度制御をします.
・・・・・・制御できてない可能性が大なので,間違えても今回のプログラムを研究の参考にしないようにしてください.
今回のプログラムのソースはここからダウンロード出来ます.
プログラムの実行には,PyOpenGL,numpy,pyODEが必要です.
動画も作ってみました.
奥の黒い棒みたいなのが目標位置です.
やっぱり,あんまり参考にはしない方がいいかも.
次回は車両の制御を・・・・する気分ではいます.
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・
更新しようという気はあったのですが,どうにもネタがなくて滞りまくりでした.
サボってる間にOpenRTM-aist-1.1.0-RC2がリリースされたので,一応宣伝しときます.
レビューしたいところですが,C++版はだれかやりそうなので,Python版がリリースされたらやります.
それはさておき,さすがに放置しっぱなしはまずいので,単発企画ですが劣駆動ロボットの制御シミュレーションをやります.
単発企画なので,今回は車の制御や劣駆動マニピュレータの制御を飛ばして,蛇型ロボットの制御をやります.
・・・・とは言っても,非線形制御入門―劣駆動ロボットの技能制御論を参考にしたので,この記事読まずにこの本を読んだ方が良いです.
まず,劣駆動マニピュレータとは,
こんな感じに,非駆動関節のあるマニピュレータのことを言うと思います.
ちなみに,根元が非駆動です.
一方,蛇型ロボットは,
上の劣駆動マニピュレータに,非駆動の並進関節を追加すれば良いことになります.
すなわち,これは劣駆動と言えるかと思います.
今回は以下のような6リンクの蛇型ロボットを制御します.
1リンク目以降は面倒くさいので以下略で.
受動車輪までの長さをlgとすると,各リンクの受動車輪の位置,速度は,
こうなります.
クリックで拡大します.
また,受動車輪は横滑りしないとします.
そんな環境や機構が存在するかは別にして.
受動車輪の車軸方向のベクトルは,
となります.
受動車輪が横滑りしないとき速度ベクトルの車軸方向に0となるはずなので,
となる.
この式をまとめると,
となります.
この式を,
各関節角速度dψと,絶対角の角速度dθの関係式は,
となるので,
と,dψをロボットの入力とすれば先端速度dwを制御できます.
まあ,本当だったら動力学モデルに基づいてなんやかんややるべきでしょうけど,面倒くさいのでdwには目標位置との偏差を入れます.
関節はトルク制御ではなく,速度制御をします.
・・・・・・制御できてない可能性が大なので,間違えても今回のプログラムを研究の参考にしないようにしてください.
今回のプログラムのソースはここからダウンロード出来ます.
プログラムの実行には,PyOpenGL,numpy,pyODEが必要です.
動画も作ってみました.
奥の黒い棒みたいなのが目標位置です.
やっぱり,あんまり参考にはしない方がいいかも.
次回は車両の制御を・・・・する気分ではいます.
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・
PR
どうも,お久しぶりです.
2週間ぶりぐらいですが,更新します.
今回はお知らせと雑談ぐらいですかね.
次回から新企画をやりたいと思いますが,何やるか決まらない.
RTMやるか,マイコンをやるか,はたまた人工知能やるかゲーム製作をやるかは考え中です.
以前のロボットモデリングツールみたいに製作過程を書くだけみたいなのが今のところ有力のような気がします.
・・・・次回の更新がいつになるかはわかりませんが,思いつき次第更新するので,期待せずに待っててください.
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・
2週間ぶりぐらいですが,更新します.
今回はお知らせと雑談ぐらいですかね.
次回から新企画をやりたいと思いますが,何やるか決まらない.
RTMやるか,マイコンをやるか,はたまた人工知能やるかゲーム製作をやるかは考え中です.
以前のロボットモデリングツールみたいに製作過程を書くだけみたいなのが今のところ有力のような気がします.
・・・・次回の更新がいつになるかはわかりませんが,思いつき次第更新するので,期待せずに待っててください.
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・
以前の記事にコメントがあったようなので補足しておきます。
コメントのやりとりのなかで、1つのECで複数のRTCを駆動させるには複合コンポーネントを使うのが手っ取り早いと書きましたが、手っ取り早くない方法をやっておきます。
今回のサンプルはここからダウンロードできます。
今回のサンプルではtest1(DebugのTest1Comp.exe)とtest2(DebugのTest2Comp.exe)を立ち上げて、TestECandComponent.exeを立ち上げるとtest1の実行コンテキストからtest1を解除してtest2の実行コンテキストに関連付けます。
test1、test2はともにonExecuteが呼び出されると"test1"、"test2"と表示します。
test1とtest2は同じ実行周期に設定していますが、test1の方が処理が重く、test1は実行周期を大幅にオーバーするようになっています。
普通にアクティブにすればtest1とtest2は完全に非同期になります。
しかし、TestECandComponent.exeを実行後にアクティブにすると同期になることが試していただければわかると思います。
今回のプログラムを見てみます。
ポイントは、
ExecutionContextList1[0]->remove_component(test1._ptr()); //test1をECから解除
ExecutionContextList2[0]->add_component(test1._ptr()); //test1をtest2のECに関連付け
です。
今回の方法だと自分でプログラムを書かないといけないので面倒くさいですが、RTSEでいちいち操作しなくて良いので一旦作ってしまえば楽かもしれないです。
では、今度こそ2週間ほど休みます。
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・
コメントのやりとりのなかで、1つのECで複数のRTCを駆動させるには複合コンポーネントを使うのが手っ取り早いと書きましたが、手っ取り早くない方法をやっておきます。
今回のサンプルはここからダウンロードできます。
今回のサンプルではtest1(DebugのTest1Comp.exe)とtest2(DebugのTest2Comp.exe)を立ち上げて、TestECandComponent.exeを立ち上げるとtest1の実行コンテキストからtest1を解除してtest2の実行コンテキストに関連付けます。
test1、test2はともにonExecuteが呼び出されると"test1"、"test2"と表示します。
test1とtest2は同じ実行周期に設定していますが、test1の方が処理が重く、test1は実行周期を大幅にオーバーするようになっています。
普通にアクティブにすればtest1とtest2は完全に非同期になります。
しかし、TestECandComponent.exeを実行後にアクティブにすると同期になることが試していただければわかると思います。
今回のプログラムを見てみます。
ポイントは、
ExecutionContextList1[0]->remove_component(test1._ptr()); //test1をECから解除
ExecutionContextList2[0]->add_component(test1._ptr()); //test1をtest2のECに関連付け
です。
今回の方法だと自分でプログラムを書かないといけないので面倒くさいですが、RTSEでいちいち操作しなくて良いので一旦作ってしまえば楽かもしれないです。
では、今度こそ2週間ほど休みます。
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・
今回でこのコーナーは終了です.
どうせ名前だけ変えて似たようなことをやると思いますけど.
さて今回は実践編としてインポートに入力された値からD/Aボードの電圧の出力をするRTCを作りました.
サンプルはここからダウンロード出来ます.
・・・・ただ,今回はCONTEC社製のDA12-16(PCI)というD/Aボードを使ったのですが,付属のライブラリのライセンスがわからないので今回は自分でビルドしてください.
僕がD/Aボードを買ったのではないので定かではないですが,多分ドライバ等をインストールするCDがついてくるはずです.
それでインストールすると,サンプルプログラムがC:\Program Files\CONTEC\API-PAC(W32)\AIOWDM\Sampleあたりに作成されるはずなので,Console\Ao\SingleAoあたりからCaio.hとCAIO.LIBを今回のRTCのVC++のプロジェクトと同じフォルダにコピーすればいけると思います.
自分でプロジェクトを作る場合は,プロパティのリンカ→入力→追加の依存ファイルでCAIO.LIBを追加するだけです.
今回のRTCを作る上で難しそうなのは,全てのチャネルを使うとは限らないところですかね.
既に定義されてるデータ型にも適当なのがないですし.
・・・・・見逃してるだけかもしれないですけど.
そこで今回はコンフィギュレーションでOnを選択したチャネルのデータポートを作成,Offを選択するとデータポートを消すようにしました.
・・・・・正直,僕はあまりデータポートが増えたり減ったりするのは好きではないのですが,このコーナーでは実用性より面白さで作るようにしているので,不満がある人は自分で作り直してください.
配列でやった方が良かったかもしれないです.
あと,コンフィギュレーションで入力電圧の範囲を選択できます.
今回の実験の動画です.
今回は超個人的な事情によりA/Dボードが使えないため,SH7144マイコンでA/D変換してRS-232CでPCに計測結果を送信しています.
・・・RS-232CはRTCを使わずにハイパーターミナルで表示してますが,RTCから出力できた方が良いかもしれません.
動画では,最初にチャネル2のインポートのみがOnになってて,その後チャネル3もOnにしてます.
そして,アクティブにした瞬間チャネル3のデータポートが生成されます.
増えた後にチャネル3のデータポートとテスト出力用のRTCのアウトポートを接続しています.
今回ハイパーターミナルに表示しているのはチャネル3の電圧の計測値です.
アクティブ,非アクティブになった瞬間に0Vにするようにしてるので最初は0Vです.
次に1V,0.5V,1.5V,最後に非アクティブになって0Vに戻ります.
・・・本当は完全に遊びで,SHマイコンが計測した電圧値でモーターの回転速度を変えたりしてるのですが,動画撮るのが面倒くさいので撮ってません.
これで終わりです.
次は何の企画やるかは考え中です.
とりあえず,少なくとも2週間ぐらいは休む予定です.
では,さようなら.
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・
どうせ名前だけ変えて似たようなことをやると思いますけど.
さて今回は実践編としてインポートに入力された値からD/Aボードの電圧の出力をするRTCを作りました.
サンプルはここからダウンロード出来ます.
・・・・ただ,今回はCONTEC社製のDA12-16(PCI)というD/Aボードを使ったのですが,付属のライブラリのライセンスがわからないので今回は自分でビルドしてください.
僕がD/Aボードを買ったのではないので定かではないですが,多分ドライバ等をインストールするCDがついてくるはずです.
それでインストールすると,サンプルプログラムがC:\Program Files\CONTEC\API-PAC(W32)\AIOWDM\Sampleあたりに作成されるはずなので,Console\Ao\SingleAoあたりからCaio.hとCAIO.LIBを今回のRTCのVC++のプロジェクトと同じフォルダにコピーすればいけると思います.
自分でプロジェクトを作る場合は,プロパティのリンカ→入力→追加の依存ファイルでCAIO.LIBを追加するだけです.
今回のRTCを作る上で難しそうなのは,全てのチャネルを使うとは限らないところですかね.
既に定義されてるデータ型にも適当なのがないですし.
・・・・・見逃してるだけかもしれないですけど.
そこで今回はコンフィギュレーションでOnを選択したチャネルのデータポートを作成,Offを選択するとデータポートを消すようにしました.
・・・・・正直,僕はあまりデータポートが増えたり減ったりするのは好きではないのですが,このコーナーでは実用性より面白さで作るようにしているので,不満がある人は自分で作り直してください.
配列でやった方が良かったかもしれないです.
あと,コンフィギュレーションで入力電圧の範囲を選択できます.
今回の実験の動画です.
今回は超個人的な事情によりA/Dボードが使えないため,SH7144マイコンでA/D変換してRS-232CでPCに計測結果を送信しています.
・・・RS-232CはRTCを使わずにハイパーターミナルで表示してますが,RTCから出力できた方が良いかもしれません.
動画では,最初にチャネル2のインポートのみがOnになってて,その後チャネル3もOnにしてます.
そして,アクティブにした瞬間チャネル3のデータポートが生成されます.
増えた後にチャネル3のデータポートとテスト出力用のRTCのアウトポートを接続しています.
今回ハイパーターミナルに表示しているのはチャネル3の電圧の計測値です.
アクティブ,非アクティブになった瞬間に0Vにするようにしてるので最初は0Vです.
次に1V,0.5V,1.5V,最後に非アクティブになって0Vに戻ります.
・・・本当は完全に遊びで,SHマイコンが計測した電圧値でモーターの回転速度を変えたりしてるのですが,動画撮るのが面倒くさいので撮ってません.
これで終わりです.
次は何の企画やるかは考え中です.
とりあえず,少なくとも2週間ぐらいは休む予定です.
では,さようなら.
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・
このコーナーは次回で終了です.
ネタがないのと,毎日更新ができないのと,コメントが全くつかないほど不人気なのが理由です.
とりあえず,次更新したらしばらく休むことにします.
それはさておき,今回はcoilでまた遊んでみようと思います.
サンプルはここからダウンロード出来ます.
まずは,Guardを使ってみます.
m_worker._mutex.lock()の替わりに
coil::Guard<coil::Mutex> guard_(m_worker.mutex_)
を記述することできるみたいです.
後でm_worker._mutex.unlock()で解放しなくても良いみたいですね.
次に,TimeMeasureを使ってみます.
coil::TimeMeasure TM;
TM.tick();
・・・
TM.tack();
printf("%lf\n",TM.getStatistics().max_interval);
printf("%lf\n",TM.getStatistics().mean_interval);
printf("%lf\n",TM.getStatistics().min_interval);
printf("%lf\n",TM.getStatistics().std_deviation);
if(count == 3)TM.reset();
こんな感じで使いました.
tickからtackまでの時間を計測して,最大,平均,最小,標準偏差が出せるようですね.
今回のプログラムでは,3回whileループが回るとリセットするようにしました.
ちなみに実行すると,
task1の回数 1
最大値 0
平均値 0
最小値 0
標準偏差 0
task1の回数 2
最大値 0.203125
平均値 0.101563
最小値 0
標準偏差 0.101563
task1の回数 3
最大値 0.390625
平均値 0.197917
最小値 0
標準偏差 0.159515
リセットしました
task1の回数 4
最大値 0.609375
平均値 0.609375
最小値 0.609375
標準偏差 0
task1の回数 5
最大値 0.796875
平均値 0.703125
最小値 0.609375
標準偏差 0.09375
task1の回数 6
最大値 2
平均値 1.13542
最小値 0.609375
標準偏差 0.616126
みたいな感じになりますね.
リセット直後の4回目では最大,平均,最小値が全て同じになりますね.
最後だけ,2秒間待つようにしてるので標準偏差が大きくなってます.
Asyncも使ってみましたけど・・・・まあ,Async.hに書いてるのとあまり変わらないし別に良いか.
今日はこのぐらいにしときます.
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・
ネタがないのと,毎日更新ができないのと,コメントが全くつかないほど不人気なのが理由です.
とりあえず,次更新したらしばらく休むことにします.
それはさておき,今回はcoilでまた遊んでみようと思います.
サンプルはここからダウンロード出来ます.
まずは,Guardを使ってみます.
m_worker._mutex.lock()の替わりに
coil::Guard<coil::Mutex> guard_(m_worker.mutex_)
を記述することできるみたいです.
後でm_worker._mutex.unlock()で解放しなくても良いみたいですね.
次に,TimeMeasureを使ってみます.
coil::TimeMeasure TM;
TM.tick();
・・・
TM.tack();
printf("%lf\n",TM.getStatistics().max_interval);
printf("%lf\n",TM.getStatistics().mean_interval);
printf("%lf\n",TM.getStatistics().min_interval);
printf("%lf\n",TM.getStatistics().std_deviation);
if(count == 3)TM.reset();
こんな感じで使いました.
tickからtackまでの時間を計測して,最大,平均,最小,標準偏差が出せるようですね.
今回のプログラムでは,3回whileループが回るとリセットするようにしました.
ちなみに実行すると,
task1の回数 1
最大値 0
平均値 0
最小値 0
標準偏差 0
task1の回数 2
最大値 0.203125
平均値 0.101563
最小値 0
標準偏差 0.101563
task1の回数 3
最大値 0.390625
平均値 0.197917
最小値 0
標準偏差 0.159515
リセットしました
task1の回数 4
最大値 0.609375
平均値 0.609375
最小値 0.609375
標準偏差 0
task1の回数 5
最大値 0.796875
平均値 0.703125
最小値 0.609375
標準偏差 0.09375
task1の回数 6
最大値 2
平均値 1.13542
最小値 0.609375
標準偏差 0.616126
みたいな感じになりますね.
リセット直後の4回目では最大,平均,最小値が全て同じになりますね.
最後だけ,2秒間待つようにしてるので標準偏差が大きくなってます.
Asyncも使ってみましたけど・・・・まあ,Async.hに書いてるのとあまり変わらないし別に良いか.
今日はこのぐらいにしときます.
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・