servoFreeDemo.cpp

00001 /*
00002   URG センサからのデータ処理 (時刻印による位置を利用)
00003   Satofumi KAMIMURA
00004   $Id$
00005 */
00006 
00007 #include "mRunCtrl.h"
00008 #include "mURGCtrl.h"
00009 #include "vutils.h"
00010 #include "drawCaptures.h"
00011 #include "dumpPlotData.h"
00012 #include "timeUtils.h"
00013 #include <SDL_thread.h>
00014 
00015 using namespace VXV;
00016 
00017 typedef struct {
00018   mURGCtrl* urg;
00019   SDL_mutex* urg_mutex;
00020   SDL_mutex* run_mutex;
00021   TicksPosition* ticks_pos;
00022   SDL_sem* sem;
00023   const char* progname;
00024 } thread_args_t;
00025 
00026 
00027 // URG データの取得スレッド
00028 static int capture_thread(void* args) {
00029   thread_args_t* data = static_cast<thread_args_t*>(args);
00030 
00031   // 少し待ってみる
00032   SDL_Delay(1000);
00033 
00034   // URG データ取得とタイムスタンプを用いた位置補正
00035   while (SDL_SemValue(data->sem) == 0) {
00036 
00037     // URG データの取得
00038     SDL_LockMutex(data->urg_mutex);
00039     int n = data->urg->capture();
00040     SDL_UnlockMutex(data->urg_mutex);
00041     if (n > 0) {
00042       SDL_LockMutex(data->run_mutex);
00043       data->urg->convert(*data->ticks_pos);
00044       SDL_UnlockMutex(data->run_mutex);
00045 
00046       // データ描画
00047       drawCaptures(*data->urg);
00048       outputPlotData(*data->urg, data->progname);
00049     }
00050 
00051     SDL_Delay(10);
00052   }
00053   return 0;
00054 }
00055 
00056 
00057 int main(int argc, char *argv[]) {
00058   try {
00059     mRunCtrl run;
00060     mURGCtrl urg;
00061 
00062     // URG のデータ取得モードは、ManualCapture にしておく
00063     if ((initConnection(&run, argc, argv) < 0) ||
00064         (initConnection(&urg, argc, argv, false) < 0)) {
00065       exit(1);
00066     }
00067     run.set_recvTimeout(1000);
00068 
00069     // タイムスタンプ合わせ
00070     urg.setOwnCrdToObject(&run);
00071     run.adjustSubTreeTicks(GetTicks());
00072     size_t lastAdjust_ticks = GetTicks();
00073 
00074     // 位置と時刻を記録して、指定時刻の位置を補間して返すクラス
00075     TicksPosition ticksPos;
00076 
00077     // URG データ取得スレッドの起動
00078     thread_args_t args;
00079     args.ticks_pos = &ticksPos;
00080     args.urg = &urg;
00081     args.urg_mutex = SDL_CreateMutex();
00082     args.run_mutex = SDL_CreateMutex();
00083     args.sem = SDL_CreateSemaphore(0);
00084     args.progname = argv[0];
00085     SDL_Thread* thread = SDL_CreateThread(capture_thread, &args);
00086 
00087     vmonitor::show();
00088 
00089     // サーボフリー
00090     run.servoCtrl(false);
00091 
00092     enum {
00093       EvaluateSec = 20,         // 動作時間
00094     };
00095     size_t first_ticks = GetTicks();
00096     size_t add_times = 0;
00097     bool demo_moved = false;
00098     while ((GetTicks() - first_ticks) < EvaluateSec * 1000) {
00099 
00100       if ((! demo_moved) && (GetTicks() - first_ticks > 2000)) {
00101         // !!! 補正の動作確認用。2秒後に、動かしてみる
00102         run.rotateToDirection(deg(-90));
00103         demo_moved = true;
00104       }
00105 
00106       // 回転速度がゼロに近ければ、タイムスタンプあわせを行う
00107       // ただし、頻繁な修正を避けるため、前回から5秒以上経過したときのみ
00108       if ((GetTicks() - lastAdjust_ticks) > 5000) {
00109         VXV::Direction rotate_vel = run.getRotateVel();
00110         if (abs(rotate_vel.to_deg()) <= 0) {
00111           lastAdjust_ticks = GetTicks();
00112 
00113           SDL_LockMutex(args.urg_mutex);
00114           run.adjustSubTreeTicks(lastAdjust_ticks);
00115           SDL_UnlockMutex(args.urg_mutex);
00116 
00117           vmonitor::printf("adjust: %d\n", lastAdjust_ticks);
00118         }
00119       }
00120 
00121       // 走行位置の保存
00122       run.getRunPosition();
00123       SDL_LockMutex(args.run_mutex);
00124       ticksPos.add(run.crd_position, run.crd_ticks);
00125       SDL_UnlockMutex(args.run_mutex);
00126       ++add_times;
00127 
00128       SDL_Delay(10);
00129     }
00130 
00131     // 表示用ファイルの出力
00132     outputPlotFile(args.progname);
00133 
00134     printf("add_times: %d\n", add_times);
00135 
00136     // スレッドの終了
00137     SDL_SemPost(args.sem);
00138     SDL_WaitThread(thread, NULL);
00139     SDL_DestroyMutex(args.urg_mutex);
00140     SDL_DestroyMutex(args.run_mutex);
00141     SDL_DestroySemaphore(args.sem);
00142 
00143   } catch (std::exception& e) {
00144     printf("exception: %s\n", e.what());
00145   }
00146   return 0;
00147 }
00148 

Generated on Mon Apr 13 22:52:02 2009 by  doxygen 1.5.7.1