#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;	/************ 改良の余地あり **************/
		}
}


開発規約に戻る