#include"m9402.h"
#define S_MAX 20
int kyori;
void sss_io()
{
int data;
void sss_search(void);
static int sss_no;
extern int initial[02];
static int old; /* 読み込んだdataの場所 */
int s_get_data(void); /* dataの読込み */
/* 初期化 */
if(initial[02] == 1)
{
old = 0;
initial[02] = 2;
sss_no = 0;
}
data = s_get_data();
/* sss send */
outportb(TCR2,0xb3); /*Timer enable*/
outportb(PADR2,sss_no); /* 8bit data */
outportb(PACR2,0x28); /* H2 asert */
outportb(PACR2,0x20); /* H2 negate */
sys8(02,old+1,data); /* BBにdataを書き込む */
sys8(02,4,old+1); /* どこのBBの値を変えたか報告 */
sss_search();
old = sss_no;
++sss_no;
}
int s_get_data()
{
float d;
int e;
int data;
int h,m,l;
float f;
int underf;
/* read count data */
h = inportb(CNTR2+2) & 0xff;
m = inportb(CNTR2+4) & 0xff;
l = inportb(CNTR2+6) & 0xff;
/* sss send */
/*outportb(PADR2,sss_no);*/ /* 8bit data */
/* change 3 piece of data to 1 piece data */
data = (h << 16) + (m << 8) +l;
/* calucuration */
d = 34000 * (SSS_LIMIT - data) * 32 / 2; /* 計測距離 */
e = d / (double)8000000; /* 実際の距離 */
kyori=e;
d = d / (double)8000000;
/* 四捨五入 */
f = d - e;
if(f >= 0.5)
e = e + 1;
data = e;
/* under flow check */
underf = inportb(PADR2) & 0x04;
if(underf != 0)
data = 0;
return data;
}
void sss_search(void)
{
int i,j,k;
int rest;
int dist;
int divi;
int diff;
int data;
int direction;
int sss_no; /* 超音波番号 */
int hit; /* get opponent */
int resp; /* response */
int front,left,right; /* data changer */
static int old_divi;
static int d[3][S_MAX+1]; /* data lib */
extern int initial[02]; /* 初期化用変数 */
extern struct pos
{
int x;
int y;
int v;
int theta;
int thetav;
int way;
}
rot_position_i;
/* 初期化 */
if(initial[02] == 2)
direction = 1;
resp = 0x0;
hit = 0;
/* 壁と平行の位置にあるか判別 ただし、指向性は5゜ */
divi = (rot_position_i.theta) / 90;
if(divi != 0)
rest = rot_position_i.theta % (90 * divi);
if(rest > 5)
diff = ((90 - rest) <= 5)? 1 : 0; /* diffが"1"なら平行 */
else if(rest <= 5)
diff = 1;
/* 自分の向き */
for(i = 0 ; i <= 10 ; ++i)
if(divi == 4*i) front =250-rot_position_i.x,right = rot_position_i.y;
else if(divi == (1+4*i)) front =250-rot_position_i.y,left = rot_position_i.x;
else if(divi == (2+4*i)) left = rot_position_i.y,front = rot_position_i.x;
else if(divi == (3+4*i)) front = rot_position_i.y,right = rot_position_i.x;
/* 方向転換したか判別 */
if(old_divi != divi)
direction = 1;
else
direction = 0;
old_divi = divi;
/* dataの補正 */
if(direction != 0)
{
for(i = 0 ; i < 3 ; ++i)
for(j = 0 ; j < S_MAX ; ++j)
switch(i)
{
case 0: d[i][j] = right;
break;
case 1: d[i][j] = front;
break;
case 2: d[i][j] = left;
break;
}
initial[02] = 0;
}
/****** read data ******/
sss_no = sys9(02,4);
data = sys9(02,sss_no+1); /* "data = 0" の時は underflow */
/* 壁と平行の時 */
if(diff == 1)
{
for ( i = 1 ; i <= S_MAX ; ++i)
d[sss_no][i-1] = d[sss_no][i];
d[sss_no][S_MAX] = data;
/* 相手を検索 */
k = 0;
for(i = 1 ; i <= S_MAX ; ++i)
{
if(abs(d[sss_no][i] - d[sss_no][i-1]) < 10)
{
if(k=1)
++hit;
}
else if(abs(d[sss_no][i] - d[sss_no][i-1]) > 25) /* 突然の変化 */
{
if(k = 0)
{
k = 1;
++hit;
}
else
k = 0;
}
}
}
else
{
if(data != 0) /* 壁と平行でないのにdataがある */
++hit;
}
/****** 返す値作成 ********/
if(!hit)
resp = 0;
else
{
resp = resp | 0x8;
resp = resp + sss_no; /************ 改良の余地あり **************/
}
}
開発規約に戻る