@@ -25,6 +25,12 @@ SODLは、簡単な2Dグラフのプロット機能を提供します。
25
25
別々のオブジェクトを描画する事ができます。
26
26
SODLは描画空間を簡単に追加する機能を提供します。
27
27
28
+ #### 機能:根本座標系(ワールド座標系)から見た子オブジェクト位置の取得
29
+ SODLは、連鎖座標系の末端(あるいは中間)に位置するオブジェクトが、
30
+ ワールド座標系原点から見た、どのような位置姿勢に存在しているかを
31
+ 計算して結果を返す機能を座標系オブジェクトのメソッドとして提供します。
32
+ これにより、例えば関節角度を自由に変更した後のロボットハンドの手先位置を
33
+ メソッド呼び出しだけで取得する事ができます。
28
34
29
35
### サンプルコードの解説
30
36
サンプルコードは、ロボットを表示する部分については[ sample_02_6AxRobot] ( #sample_02_6AxRobot ) と同じです。
@@ -162,6 +168,120 @@ Eigen::Vector3f型の3次元空間上の点をプロットデータに追加す
162
168
163
169
時系列グラフの説明は以上です。
164
170
171
+ #### 2. 散布図グラフ
172
+ ```
173
+ //----------------------------------------------------
174
+ // 散布図グラフ(2次元)の作成と描画空間[2]への配置
175
+ //----------------------------------------------------
176
+ // 散布図グラフの作成
177
+ auto scttrGrph = sodl::GraphObj::create(
178
+ "Mouse Drag Trajectory", // オブジェクト名称 = グラフタイトル
179
+ camGrph // 関連付けるカメラ(カメラ投影行列などの設定が済んでいること)
180
+ );
181
+ // ラベルの設定
182
+ scttrGrph->xAxisLabel->text = "X [pix]";
183
+ scttrGrph->yAxisLabel->text = "Y [pix]";
184
+ // 描画空間[2]にグラフを追加
185
+ sodl::drwMngr->AddObjTree_ToDrwSpace(scttrGrph, 2);
186
+ ```
187
+ 散布図グラフの作成手順も時系列グラフと同じです。
188
+ ビューポートとカメラの追加はコードの引用も省略しています。
189
+ 差分は、グラフのインスタンスが` TimeSeriesGraph ` であるか、` GraphObj ` であるか、です。
190
+ ` TimeSeriesGraph ` はデフォルトで古いデータが左に流れて見えなくなるようなプロット範囲をとるのに対し、
191
+ 散布図で用いている` GraphObj ` は、デフォルトで古いデータがいつまでも流れないようなプロット範囲を維持します。だだし、古いデータ自体はやはりメモリの問題でサンプル数が` dataNumMax ` を超えると削除されます。
192
+
193
+ 以降は、プロットデータを作成している箇所を見ていきます。
194
+ 2つの散布図はマウスドラッグ軌跡とロボットの手先の軌跡をそれぞれブロットしています。
195
+
196
+ ##### 2.1 マウスドラッグ軌跡のプロット
197
+ ```
198
+ while(1)
199
+ {
200
+
201
+ (略)
202
+
203
+ //-----------------------------------------------------
204
+ // ドラッグ中のマウス位置X,Yを散布図グラフにプロット
205
+ //-----------------------------------------------------
206
+ scatterGraph_mouseDrag->addData(Eigen::Vector3f(app::mouse_x, app::mouse_y, 0));
207
+
208
+ //-----------------------------------------------------
209
+ // 描画マネージャから描画更新を実行する
210
+ //-----------------------------------------------------
211
+ sodl::drwMngr->drawUpdt();
212
+
213
+ ++count;
214
+ Sleep(10);
215
+ }
216
+
217
+ ```
218
+ メインループでは、単に` app::mouse_x ` , ` app::mouse_y ` をプロットに加えているだけです。
219
+ これらの変数はグローバル変数で、マウスコールバック関数で更新されています。
220
+ コールバック関数を以下に示します。
221
+ ```
222
+ namespace app {
223
+ //================================================================
224
+ //
225
+ // <Summary> GLウィンドウ上でマウスドラッグ時のコールバック
226
+ // <Description>
227
+ //================================================================
228
+ void onMouseDrag(int u, int v)
229
+ {
230
+ mouse_x = u;
231
+ mouse_y = WINDOW_SIZE_Y - v;
232
+ }
233
+ }
234
+ ```
235
+ いたってシンプルです。
236
+ コールバックで得られる値がWindowsのウィンドウ座標系準拠なので
237
+ 画面左上原点の下方向が(+)の座標値となります。
238
+ 一方、グラフプロットの座標系は左下原点の上方向が(+)の座標系としたかったので
239
+ 反転してウィンドウサイズから減算した値を` mouse_y ` に代入しています。
240
+
241
+ 他に、マウスボタンを押したときのコールバック関数` onMouseBtn() ` と
242
+ ボタンを押さずにウィンドウ上をにマウスを乗せて移動させたときのコールバック関数
243
+ ` onMouseHover() ` が何もしない関数として実装されています。
244
+
245
+ ##### 2.2 ロボットの手先軌跡のプロット
246
+ ```
247
+ while(1)
248
+ {
249
+ (略)
250
+
251
+ //-----------------------------------------------------
252
+ // ロボットハンド位置X,Yを散布図グラフにプロット
253
+ //-----------------------------------------------------
254
+ Eigen::Vector3f handPos = J6_Crd->GetTf_root2self().translation();
255
+ scatterGraph_RobotHandXY->addData( handPos );
256
+
257
+ (略)
258
+
259
+ //-----------------------------------------------------
260
+ // 描画マネージャから描画更新を実行する
261
+ //-----------------------------------------------------
262
+ sodl::drwMngr->drawUpdt();
263
+
264
+ ++count;
265
+ Sleep(10);
266
+ }
267
+ ```
268
+ ロボットハンドの手先座標の計算は、メイン関数の中で実装しています。
269
+ ` Eigen::Vector3f handPos = J6_Crd->GetTf_root2self().translation(); `
270
+ の一行です。
271
+ ` J6_Crd ` はロボットの手先を表現している座標系オブジェクト(` CoordChainObj ` のインスタンス)です。
272
+ そして、座標系オブジェクトクラス` CoordChainObj ` のメソッドである` GetTf_root2self() ` は、
273
+ 座標系連鎖を親の親の・・・と辿って、
274
+ 根本までたどり着いた座標系オブジェクトから見た、自分自身までの座標変換
275
+ (言い換えると、自分自身の位置姿勢)を表す` Eigen::Affine3f ` オブジェクトを返します。
276
+ ` Eigen::Affine3f ` から位置情報だけを取り出す` translation() ` をコールして得られた
277
+ ` Eigen::Vector3f ` がワールド座標原点から見たロボットハンドの手先位置として` handPos `
278
+ に代入されます。
279
+
280
+ ` CoordChainObj::GetTf_root2self() ` は使いこなすと強力な座標変換ツールになります。
281
+ また` Eigen::Affine3f ` の扱いを理解することは、それ以上に座標変換の実装を楽にしてくれます。
282
+
283
+ sample_04_DrawGraph の説明は以上です。
284
+
165
285
[ サンプル一覧へ戻る] ( FunctionExplainedWithSamples.md )
166
286
167
287
[ トップページへ戻る] ( README.md )
0 commit comments