⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sensory.cpp

📁 2002年
💻 CPP
📖 第 1 页 / 共 2 页
字号:
				FieldInfo.dir_conf[i] = ClientParam::conf_max;
				if (LastSightTime != time)
					FieldInfo.dir_conf[i] *= Exp(ClientParam::conf_decay, (float)(time -LastSightTime));
			}
		}
	}
	dir_time = time;
	FieldInfo.Update_dirdanger(situation.CurrentTime);
}

void Sensory::Reset(){
	NewSight = false;
	NewSenseInfo = false;
	NewSound = false;
	TwiceSight = false;
}



bool Sensory::AppointUnkPlayer(Player* mp, VisualUnkPlayer* p){
	if(mp == NULL || p == NULL) return false;
	if(mp->IsSamePlayer(*p)){
		if(mp->seen_time() < p->t){
			mp->set_polar(p->seen_rel_angle(), p->seen_distance(), p->t);
			if(p->Is_side_known){ 
				mp->set_arm_tackle(p->armdir, p->tackling, p->t);
			}
			mp->update(p->t);
		}
		DoLog(LOG_UNKPLAYER,"Findnum %d pos(%.2f,%.2f)", mp->InsideNO, mp->pos.x, mp->pos.y);
		p->Recognize();
		return true;
	}else{
		return false;
	}
}

void Sensory::IdentifyUnkPlayers(Time t){
	int i, j;
	float dist, min_dist;
	Vector pos;
	VisualUnkPlayer* p;
	Player* matchp;
	Player* matched_player;

	int num_unknown_theirplayers = Their_Unk_Players.Data(t).Num_datas();
	//Note: when a unk players is identified successfully, it's removed from the unk array immediately
	// so descent order must be kept to make the remove action simplest.
	for(i = num_unknown_theirplayers-1; i >= 0; i--){
		//descent order to reduce update when twice sight
		p = & Their_Unk_Players.Data(t).Data(i);
		matched_player = NULL;
		min_dist = ClientParam::too_different_distance;

		for(j = 0; j < SP_team_size; j ++){
			matchp = & TheirTeam[j];
			if(matchp->IsSeen(t)) continue;
			if(matchp->pos_conf > ClientParam::identify_min_conf || matchp->Is_goalie){
				dist = matchp->pos.disaeolus(p->pos);
				if (dist < min_dist){
					matched_player = matchp;
					min_dist = dist;
				}
			}
		}
		if(AppointUnkPlayer(matched_player, p)) continue;

		matched_player = NULL;
		for(j=0; j<UnknownTheirPlayerList.oldnumplayers; j++){
			matchp = UnknownTheirPlayerList.List[j];
			if(matchp->IsSeen(t)) continue;
			if(matchp->pos_conf > ClientParam::identify_min_conf){
				dist = matchp->pos.disaeolus(p->pos);
				if (dist < min_dist){
					matched_player = matchp;
					min_dist = dist;
				}
			}
		}
		if(AppointUnkPlayer(matched_player, p)) continue;
		UnknownTheirPlayerList.EnList(*p);
	}

	int num_unknown_myplayers = My_Unk_Players.Data(t).Num_datas();
	for(i = num_unknown_myplayers-1; i >= 0; i--){
		p = & My_Unk_Players.Data(t).Data(i);
		matched_player = NULL;
		min_dist = ClientParam::too_different_distance;
		
		for(j = 0; j < SP_team_size; j ++){
			matchp = & MyTeam[j];
			if(matchp->InsideNO == Agent::MyNumber) continue;
			if(matchp->IsSeen(t)) continue;
			if(matchp->pos_conf > ClientParam::identify_min_conf){
				dist = matchp->pos.disaeolus(p->pos);
				if (dist < min_dist){
					matched_player = matchp;
					min_dist = dist;
				}
			}
		}
		if(AppointUnkPlayer(matched_player, p)) continue;

		matched_player = NULL;
		for(j=0; j<UnknownMyPlayerList.oldnumplayers; j++){
			matchp = UnknownMyPlayerList.List[j];
			if(matchp->IsSeen(t)) continue;
			if(matchp->pos_conf > ClientParam::identify_min_conf){
				dist = matchp->pos.disaeolus(p->pos);
				if (dist < min_dist){
					matched_player = matchp;
					min_dist = dist;
				}
			}
		}
		if(AppointUnkPlayer(matched_player, p)) continue;
		UnknownMyPlayerList.EnList(*p);
	}

	/*	Feeled Player Update	*/
	int num_teamlessplayers = Teamless_Players.Data(t).Num_datas();
	for(i = num_teamlessplayers-1; i >= 0; i--){		
		p = & Teamless_Players.Data(t).Data(i);
		matched_player = NULL;
		min_dist = ClientParam::too_different_distance;
		//只处理感知范围内的teamless player
		if (p->seen_distance() > ServerParam::feel_distance) continue;
		
		for(j = 0; j < 2*SP_team_size; j ++){
			matchp = &GetPlayer(j+1);
			if(matchp->InsideNO == Agent::MyNumber) continue;
			if(matchp->IsSeen(t)) continue;
			if(matchp->pos_conf > ClientParam::identify_min_conf){
				dist = matchp->pos.disaeolus(p->pos);
				if (dist < min_dist){
					matched_player = matchp;
					min_dist = dist;
				}
			}
		}
		if(AppointUnkPlayer(matched_player, p)) continue;
		
		min_dist = ClientParam::too_different_distance;
		for(j = 0; j < UnknownTheirPlayerList.oldnumplayers; j++){
			matchp = UnknownTheirPlayerList.List[j];
			if(matchp->IsSeen(t)) continue;
			if(matchp->pos_conf > ClientParam::identify_min_conf){
				dist = matchp->pos.disaeolus(p->pos);
				if (dist < min_dist){
					matched_player = matchp;
					min_dist = dist;
				}
			}
		}
		for(j = 0; j < UnknownMyPlayerList.oldnumplayers; j++){
			matchp = UnknownMyPlayerList.List[j];
			if(matchp->IsSeen(t)) continue;
			if(matchp->pos_conf > ClientParam::identify_min_conf){
				dist = matchp->pos.disaeolus(p->pos);
				if (dist < min_dist){
					matched_player = matchp;
					min_dist = dist;
				}
			}
		}		
		if(AppointUnkPlayer(matched_player, p)) continue;
		
		matched_player = NULL;
		for(j = 0; j < TeamlessPlayerList.oldnumplayers; j++){
			matchp = TeamlessPlayerList.List[j];
			if(matchp->IsSeen(t)) continue;
			if(matchp->pos_conf > ClientParam::identify_min_conf){
				dist = matchp->pos.disaeolus(p->pos);
				if (dist < min_dist){
					matched_player = matchp;
					min_dist = dist;
				}
			}
		}
		
		if(AppointUnkPlayer(matched_player, p)) continue;
		TeamlessPlayerList.EnList(*p);
	}
	//special consideration, find their goalie from teamless player
	if(FieldInfo.IsValidtheirgoalie() && num_teamlessplayers > 0){
		matchp = &TheirPlayer(FieldInfo.theirgoalie);
		p = NULL;
		VisualUnkPlayer* tmp;
		min_dist = 2 * ClientParam::too_different_distance;
		if(!matchp->IsSeen(t) && matchp->IsValidObject()){
			for(i = num_teamlessplayers-1; i >= 0; i--){
				tmp = & Teamless_Players.Data(t).Data(i);
				if(tmp->recognized) continue; 
				if(!PitchInfo.their_penaltyarea.IsWithin(tmp->pos)) continue;
				dist = matchp->pos.disaeolus(tmp->pos);
				if (dist < min_dist){
					p = tmp;
					min_dist = dist;
				}
			}
			if(AppointUnkPlayer(matchp, p)){
				DoLog("find their goalie %.0f, %.0f", p->pos.x, p->pos.y);
			}
		}
	}
	UnknownMyPlayerList.RefreshNumPlayers();
	UnknownTheirPlayerList.RefreshNumPlayers(); 
	TeamlessPlayerList.RefreshNumPlayers();
}

void Sensory::Update_others(Time time){
	if(visualsystem.Vinfo_coming && !sensory.NewSight){
		DoLog(LOG_VDEC,"coming visual haven't come");
	}
	if(auditorysystem.rec_hear_info.IsDataKnown(time-1)){ 
		DoLog(LOG_HEAR, "speaker%d time%d", auditorysystem.rec_hear_info.Data(time-1), time-1);
	}
	ball.Prior_update();
	ball.update(time);// ball info should be updated prior to the other objs

	int i;
	for(i = 0; i < SP_team_size; i ++){
		MyTeam[i].Prior_update(); 
		MyTeam[i].update(time);
	}
	
	for(i = 0; i < SP_team_size; i ++){
		TheirTeam[i].Prior_update(); 
		TheirTeam[i].update(time);
	}

	UnknownTheirPlayerList.Prior_update();
	UnknownMyPlayerList.Prior_update();
	TeamlessPlayerList.Prior_update();

	updated_sight.Reset(); 
	//Unknown Player Identification
	for(Time t = updated_sight_time+1; t<=LastSightTime; t++){
		if(!rec_sight_info.ChkData(t)) continue;
		UpdateUnkPlayers(t);
		IdentifyUnkPlayers(t);

		updated_sight_time = t;
		Self.updated_sight_time=updated_sight_time;
		updated_sight.Add(t); 
	}

	UnknownTheirPlayerList.update(time);
	UnknownMyPlayerList.update(time);
	TeamlessPlayerList.update(time);
	
	/***********************update end********************/
	ball.update_end(); 
	Self.update_end(); 
	for(i = 0; i < SP_team_size; i ++){
		MyTeam[i].update_end();
	}
	for(i = 0; i < SP_team_size; i ++){
		TheirTeam[i].update_end();
	}
	
	UnknownTheirPlayerList.update_end();
	UnknownMyPlayerList.update_end();
	TeamlessPlayerList.update_end();

#ifdef _LOG
	UnknownMyPlayerList.LogList();
	UnknownTheirPlayerList.LogList();
	TeamlessPlayerList.LogList();
#endif
}

//Interface for decision-making module to call
//desire configuration used as reference for switching view modes
void Sensory::SetDesireView(VIEWWIDTH width,VIEWQUALITY quality){
	desire_viewidth = width;
	desire_quality = quality;
	DoRecord("desire width%d, quality%d", width, quality);
}

//called at the time of receiving sight info
//to make sure no duplicate sight info received
void Sensory::Make_ViewModeDecision(){
	VIEWWIDTH width = desire_viewidth;
	VIEWQUALITY quality = desire_quality;
	
	float elapsed_time = stopwatch.MsBetween(SW_CycleStart, LatestTime, SW_Recv_Visualinfo, LatestTime);
		
	bool chv = false;
	if(width == VW_Narrow){	
		bool work = false;
		//估计下次视觉消息来临时间, -2是误差时延的经验值
		DoRecord(LOG_SEE,"elapsed_time %d",elapsed_time);
		if(elapsed_time + SightInterval(width) - 2 >= ServerParam::sense_body_step){
			if(ViewWidth != width){
				change_view(width, quality);
				chv = true;
			}
		}else{
			if(ViewWidth == width || ViewWidth == VW_Wide){
				change_view(VW_Normal, quality);
				chv = true;
			}
			work = true;
		}
		DoRecord(LOG_STOPWATCH, "%d narrow %.1f, work%d, chv%d", LatestTime, elapsed_time, work?1:0, chv?1:0);
	}else if(width != ViewWidth){
		change_view(width, quality);
		chv = true;
	}
	DoRecord(LOG_SEE,"ChangeView(%d) %d",chv,width);

	if(!situation.ClockStopped && !chv){
		float nextsight_time;
		//note: if no change view, the nextviewwidth is just my current viewwidth.
		nextsight_time = elapsed_time + SightInterval(sensory.NextViewWidth);
		Self.NextViewCycle = LatestTime + nextsight_time / ServerParam::simulator_step;
	}
}

//physical command to be called in info proc instead of ctrl proc.
void Sensory::change_view(VIEWWIDTH width, VIEWQUALITY quality){
	char cmd_viewbuf[32];
	char qual_string[8];
	char width_string[8];

	switch (quality){
	case VQ_High: sprintf(qual_string,"high"); break;
	case VQ_Low:  sprintf(qual_string,"low");  break;
	}
	switch (width){
	case VW_Narrow: sprintf(width_string,"narrow"); break;
	case VW_Normal: sprintf(width_string,"normal"); break;
	case VW_Wide:   sprintf(width_string,"wide");   break;
	} 

	sprintf(cmd_viewbuf, "(change_view %s %s)", width_string, qual_string);
	sensory.NextViewWidth = width;
	Network::send_message(cmd_viewbuf, Network::sock);

#ifndef _OffClient
	stopwatch.TimeEvent(SW_Event_ChangeView);
	
#ifdef _LOGMAT
	TIME_T t = stopwatch.GetRawData_Event(SW_Event_ChangeView);	
#ifdef WIN32
	LogMat(LM_Ass, "%d %d %I64d %d %d", Ass_Chview, SW_Event_ChangeView, stopwatch.FormatTime(t), width, quality);
#else // _LINUX
	LogMat(LM_Ass, "%d %d %lld %d %d", Ass_Chview, SW_Event_ChangeView, stopwatch.FormatTime(t), width, quality);
#endif
#endif

	if(!situation.ClockStopped){
		float nextsight_time;
		//note: if no change view, the nextviewwidth is just my current viewwidth.
		nextsight_time = SightInterval(width) - stopwatch.MsFromEvent(SW_Event_ChangeView, SW_CycleStart, LatestTime);

		Self.NextViewCycle=LatestTime + nextsight_time / ServerParam::simulator_step;
	}
#endif
}

bool Sensory::HasFullState(){
#ifdef _Up_FState
	return true;
#else
	return false;
#endif
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -