2013年4月3日水曜日

opencv2.4.4をcygwinでつかってみる(4コマ目) 周期的実行

opencvそれ自体とは無関係ではありますが、linuxを1秒毎に実行させたいので、こちらのページを参考にやってみました.http://www.mech.tohoku-gakuin.ac.jp/rde/contents/linux/control/lcycle.html

サンプルプログラムを動かすと何が起きるか?
おおよそ1秒毎にプログラムがループするようにスケジュールされます.そして下図のような表示がterminal windowに毎秒1行づつ表示されます.
●301とかいうのはプログラム起動後にループした累計回数.
●1.000057Secとかいうのは、スケジュールのインターバルの実測秒で、ピッタンコ1秒じゃなくてわずかですが誤差があります.
●301.035218Secとかいうのは、プログラム起動後の累計秒数.
●0:0:5:1とかいうのは、プログラム起動後の累計日時分秒.

どうなっているか?
●1秒間の遅延を作っている、というか、オレは1秒間だけ眠りたいんで、1秒後に起こしてくれ、とスケジューラに依頼しているのが、usleep(1000*1000); です.単位が1uSecなので100万uSec=1秒となります.なので、完全なる1秒毎割り込みで動かしているわけじゃないのがこのプログラムのイマイチなところです.
●OSが持っている時計を読むことによって、「今何時」という疑問に答える関数がgettimeofday()です.返値の分解能はuSecです.この数値のゼロは1970年なのかどうかはさしあたりどうでもいいので知りません.

他に難しいところはないと思います.

サンプルプログラム   cv_timer.c

#include <stdio.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdlib.h>

unsigned long long GetTick(void) // get time in micro second
{
  struct timeval tv;
  gettimeofday(&tv,NULL);
  return (unsigned long long)tv.tv_sec*1000000+tv.tv_usec;
}

typedef struct { int day, hour, min, sec; } dhms ;

dhms uSec2dhms(unsigned long long uSec) // convert usec to day:hour:min:sec
{
  dhms day;
  unsigned long long Sec = uSec*1e-6;
  day.day =(Sec % (60*60*60*24))/60/60/60;
  day.hour=(Sec % (60*60*60))/60/60;
  day.min =(Sec % (60*60))/60;
  day.sec =Sec % 60;
  return day;
};

int main(int argc,char **argv)
{
  int i;
  dhms day;

  unsigned long long uSec, uSec_1st, uSec_old; // measured time array

  i=0;
  while(1) // timer loop
    {
      if(i==0)
        {
          uSec_1st=GetTick();
          uSec=uSec_1st;
        }
      else
        {
          uSec_old=uSec;
          uSec=GetTick();   // set time to array
          day = uSec2dhms(uSec-uSec_1st);
          printf("%d  interval %f[Sec]   total %f[Sec]   %d:%d:%d:%d[dhms]\n",
                 i,
                 (uSec-uSec_old)*1e-6,
                 (uSec-uSec_1st)*1e-6,
                 day.day, day.hour, day.min, day.sec);
        }
      usleep(1000*1000);   // wait 1 sec
      i++;
    }
  return 0;
}

実行するには、  gcc cv_timer.c  でコンパイルして、a.exeを実行すればいいでしょう.

かしこ


人気ブログランキングへ

0 件のコメント:

コメントを投稿