urgAutoCapture.cpp

00001 /*
00002   URG に自動データ取得機能を追加
00003   Satofumi KAMIMURA
00004   $Id$
00005 */
00006 
00007 #include "urgAutoCapture.h"
00008 #include <stdio.h>
00009 
00010 #if !HAVE_CONFIG_H || HAVE_LIBSDL
00011 #include <SDL.h>
00012 
00013 
00014 int URGAutoCapture::captureThread(void* args) {
00015   URGAutoCapture* obj = (URGAutoCapture*)args;
00016 
00017   bool active = true;
00018   do {
00019     obj->lock();
00020     bool obj_initialized = obj->initialized;
00021     obj->unlock();
00022 
00023     if (obj_initialized) {
00024       unsigned long raw_timestamp = 0;
00025       int back_index = 1 - obj->active_index;
00026       obj->capture_buffer[back_index].ret_value =
00027         obj->URGManualCapture::capture(obj->capture_buffer[back_index].length,
00028                                        obj->next_first, obj->next_last,
00029                                        obj->next_group, *(obj->urg_params),
00030                                        (obj->enableTimestamp)
00031                                        ? &raw_timestamp : NULL);
00032       obj->capture_buffer[back_index].first = obj->next_first;
00033       obj->capture_buffer[back_index].last = obj->next_last;
00034       obj->capture_buffer[back_index].group = obj->next_group;
00035       obj->capture_buffer[back_index].raw_timestamp = raw_timestamp;
00036       obj->capture_buffer[back_index].captured = true;
00037       obj->capture_buffer[back_index].capture_times =
00038         obj->URGManualCapture::getCaptureTimes();
00039 
00040       // バッファの切り替え
00041       obj->capture_buffer[obj->active_index].captured = false;
00042       obj->active_index = back_index;
00043     } else {
00044       SDL_Delay(WaitMsec);
00045     }
00046     obj->lock();
00047     active = obj->active;
00048     obj->unlock();
00049   } while (active);
00050 
00051   return 0;
00052 }
00053 
00054 
00055 void URGAutoCapture::lock(void) {
00056   SDL_LockMutex(mutex);
00057 }
00058 
00059 
00060 void URGAutoCapture::unlock(void) {
00061   SDL_UnlockMutex(mutex);
00062 }
00063 
00064 
00065 void URGAutoCapture::initCaptureBuffer(URGInterface::urgParams_t& params) {
00066   for (int i = 0; i < 2; ++i) {
00067     capture_buffer[i].length = new long [params.sense_steps];
00068     capture_buffer[i].captured = false;
00069     capture_buffer[i].raw_timestamp = 0;
00070     capture_buffer[i].capture_times = 0;
00071 
00072     capture_buffer[active_index].first = -1;
00073     capture_buffer[active_index].last = -1;
00074     capture_buffer[active_index].group = -1;
00075   }
00076   active_index = 0;
00077 }
00078 
00079 
00080 URGAutoCapture::URGAutoCapture(void)
00081   : mutex(SDL_CreateMutex()),
00082     active(true), next_first(-1), next_last(-1), next_group(-1),
00083     initialized(false), active_index(0), urg_params(NULL),
00084     auto_capture_times(0) {
00085   thread = SDL_CreateThread(captureThread, this);
00086 }
00087 
00088 
00089 URGAutoCapture::~URGAutoCapture(void) {
00090 
00091   // スレッドの終了を待つ
00092   lock();
00093   active = false;
00094   unlock();
00095   SDL_WaitThread(thread, NULL);
00096 
00097   // 資源の解放
00098   if (initialized) {
00099     for (int i = 0; i < 2; ++i) {
00100       delete [] capture_buffer[i].length;
00101     }
00102   }
00103   SDL_DestroyMutex(mutex);
00104 }
00105 
00106 
00107 int URGAutoCapture::capture(long length[],
00108                             int first_index, int last_index, int group,
00109                             URGInterface::urgParams_t& params,
00110                             unsigned long* raw_timestamp) {
00111   lock();
00112   next_first = first_index; next_last = last_index; next_group = group;
00113   urg_params = &params;
00114   if (!initialized) {
00115     initCaptureBuffer(params);
00116     initialized = true;
00117   }
00118   unlock();
00119 
00120   int timeout = params.cycle_msec << 2;
00121   bool captured = false;
00122   while (timeout > 0) {
00123     lock();
00124     captured =
00125       capture_buffer[active_index].captured
00126       & (capture_buffer[active_index].first == first_index)
00127       & (capture_buffer[active_index].last == last_index)
00128       & (capture_buffer[active_index].group == group);
00129     if (captured) {
00130       int ret_value = capture_buffer[active_index].ret_value;
00131       for (int i = 0; i < ret_value; ++i) {
00132         length[i] = capture_buffer[active_index].length[i];
00133       }
00134       if (raw_timestamp) {
00135         *raw_timestamp = capture_buffer[active_index].raw_timestamp;
00136       }
00137       auto_capture_times = capture_buffer[active_index].capture_times;
00138       unlock();
00139       return ret_value;
00140     }
00141     unlock();
00142     SDL_Delay(WaitMsec);
00143     timeout -= WaitMsec;
00144   }
00145   return ConnectionDevice::RecvTimeout;
00146 }
00147 
00148 
00149 int URGAutoCapture::getCaptureTimes(void) {
00150   return auto_capture_times;
00151 }
00152 #endif
00153 

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