📄 sensory.cpp
字号:
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 + -