沼津高専 電子制御工学科

技術調査報告書(超音波センサ)

MIRS0404-TECH-0002

改訂記録

版数

作成日

作成者

承認

改訂内容

A01

2004.07.19

大胡 真司

石川 健太

初版


目次

 


1.     目的

 

このドキュメントは、MIRS-0404-TEST-0003(技術調査書)での超音波の調査が実際のMIRS競技においての技術を調査していなかったため、改めて調査を行ったその報告書である。

 

2.     調査内容

1.      MIRS静止時

ここでは、MIRSが静止しているときに超音波センサがポストをどのくらいの距離まで感知するのかを調査する。
調査方法として、MIRSをある地点に置き、まずポストをMIRSから200mmに置いたのちにuss_testを実行し、超音波センサが正確な距離を計測しているか調査する。正確に計測しているならばポストを徐々にMIRSから遠ざけていってそのたびに正確に計測しているか調査し、正確に計測できなくなったときの距離もまた調査する。また、その超音波センサのポスト位置の計測返り値がどのくらいの精度かも調査する。

 

2.      MIRS回転時

次にここでは、MIRSがある地点で360°回転しているときに超音波センサがポスト間での距離をどのくらいの精度で計測できるのかを調査する。
調査方法として、センサーマップにおけるuss_2とuss_4を超音波センサでの計測データをテキストファイルに書きこめるように改良したuss_testのプログラム(のちにそのプログラムは挙げることにする)で動かす。ここでMIRSは別のコンソールで360°回転しているようにしておく。そして下図のような場所で距離を計測し、どのくらいの精度で計測できるのか調査する。
また、次にMIRS回転時にMIRS静止時の距離計測範囲の最大値と同じ位置にポストを置き、同様の方法で超音波センサでの計測が可能か、またどのくらいの精度かを調査する。

 

 

3.     調査結果

1.      MIRS静止時

 MIRSが静止している状態で調査した結果、

 まず、200mm以下は前提として測れないとされていたが、実際にuss_testでは計測は可能だったが精度がとても悪かったため、200mm以下での距離計測にこの超音波センサは用いることができない事が改めてわかった。
 次に、超音波センサで計測できる最大距離は、1500mmであり、またその返り値は1500±20mmであった。よってこの超音波センサの計測誤差は±1.3%である。つまり、MIRSの競技場は、3.6m×3.6mなので静止していればほとんど競技場の全範囲でポストの距離計測が可能である。
最後に、超音波センサでのポストの距離計測範囲を図示すると以下のようになる。

2.      MIRS回転時

 MIRSが360°回転している状態で調査した結果、

 まずここで、標準機の動作確認で用いたuss_testを改良したプログラムを下に示す。

 
#include <stdio.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <pthread.h>
 
#include "uss.h"
 
int uss_data;
 
 
void *uss_transmit(int *uss_no)
{
        struct timeval tv;
        struct uss_msg_struct uss_msg;
 
     int cmd;
     int n;
        fd_set rfds;
        int retval;
        int fd0, ctl;
     int bufsize=10;
     int buf[bufsize];
 
        uss_msg.command=1; /* Shot */
        uss_msg.number=*uss_no;
        cmd = *uss_no;
 
     //printf("uss_no =%d\n",cmd);
 
        if ((fd0 = open("/dev/rtf2", O_RDONLY)) < 0) {
                fprintf(stderr, "Error opening /dev/rtf2\n");
                exit(1);
        }
 
        if ((ctl = open("/dev/rtf1", O_WRONLY)) < 0) {
                fprintf(stderr, "Error opening /dev/rtf1\n");
                exit(1);
        }
 
        while(1) {
                        if (write(ctl, &uss_msg, sizeof(uss_msg)) < 0){
                                fprintf(stderr, "uss_transmit:now sending commands to uss%d.\n", cmd);
                                continue;
                        }
                        FD_ZERO(&rfds);
                        FD_SET(fd0, &rfds);
                        tv.tv_sec = 0;
                        tv.tv_usec = 100000;
 
                        retval = select(FD_SETSIZE, &rfds, NULL, NULL, &tv);
                        if (retval > 0) {
                                if (FD_ISSET(fd0, &rfds)) {
                                        n = read(fd0, buf, bufsize - 1);
                                        buf[n] = 0;
                                        uss_data = buf[0];
                                        break;
                                }
                        }
                        else {
                                uss_data = 999;
                                break;
                        }
 
        }
     close(fd0);
     close(ctl);
        pthread_exit(0);
}
 
int main()
{
 
        pthread_t uss_task;
        pthread_attr_t attr_uss;
     struct sched_param sched_param;
 
 
     int uss_no;
     int comand;
     int ret,i,j;
        FILE *fp;
 
        pthread_attr_init (&attr_uss);
        sched_param.sched_priority = 21;
     pthread_attr_setschedpolicy(&attr_uss, SCHED_RR);
        pthread_attr_setschedparam(&attr_uss, &sched_param);
 
     comand = 1;
     //uss_no=1;
     fp=fopen("/homes/home16/ohgo/mirs_std_v1.0/uss/uss_scale.txt","a");
     //for(i=0;i<2;i++){  while(1){   //for(j=3;j><4;j++){   for(j=2;j><5;j=j+2){    uss_no=j;            ret=pthread_create( &uss_task, &attr_uss, (void*)uss_transmit, &uss_no);    ret=pthread_join(uss_task,NULL);    printf("uss[%d] = %d\n",uss_no,uss_data);    fp=fopen("/homes/home16/ohgo/mirs_std_v1.0/uss/uss_scale.txt","a");    fprintf(fp,"%d\n",uss_data);    fclose(fp);    usleep(100000);   }  }  return 0; } >

 

 そして、手順通りにtestを行ってできたテキストファイル(見やすいように改良し、また参考にならないデータは省略した)は下のようになる。

 
1593
549
 
1613
710
 
1199
433
 
1161
1581
 
539
1627
 
507
1193
 
526
1165
 
1052
1122
 
1007
477
 
982
511
 
995
1032
 
1598
1029
 
1236
1019
 
1199
1569
 
1156
1582
 
523
1647
 
497
1189
 
488
1174
 
1028
1143
 
484
1119
 

 

 上のデータを見てみると、ポストの距離を計測できたときのデータは 500±30mmぐらいのデータになっている。よって誤差は±4%となった。しかし、MIRS静止時の最大距離計測距離の1500mmで同様にプログラムを動かすと1500mmジャストの返り値のときもあれば1500±300mmの返り値のときもあり、その誤差は±20%もあった。つまりポストの距離が遠ければ遠いほどその誤差は大きくなってしまうことが調査の結果、わかった。
 パーセント上で見ればかなりひどい精度で計測している。よって、MIRSが回転しているときは、この超音波センサの計測データのみでポストの距離を決めてしまうのは得策ではない。
 そのために、MIRS0404では、超音波センサだけでなくポストの座標データは光学式マウスも併用してデータを決めているのである。