📄 visualsystem.cpp
字号:
#include "visualsystem.h"
#include "strategy.h"
#include "worldmodel.h"
#include "perceptron.h"
#include "skill.h"
#include "agent.h"
#include "log.h"
/*********************** Visual System *****************************************/
VisualSystem::VisualSystem(){
}
void VisualSystem::Raise(VisualObjType otype, AngleDeg angle, float priority){
if(Agent::mediator.ValidRequestAng(angle)){
Agent::mediator.enroll(priority, angle);
DoLog(LOG_VDEC, "A%.0f, P%.3f", angle, priority);
}else{
DoLog(LOG_VDEC, "Rejected A%.0f, P%.3f", angle, priority);
}
}
void VisualSystem::Raise(VisualObjType otype, AngleDeg angle, AngleDeg distribute, float priority){
if(distribute < 2.0f){
Raise(otype, angle, priority);
}else{
Raise(otype, angle, 0.7f * priority);
Raise(otype, angle - distribute, 0.4f * priority);
Raise(otype, angle + distribute, 0.4f * priority);
}
}
void VisualSystem::Raiseplayer(Player& p, float priority){
if(!p.IsValidObject()){
DoLog(LOG_VDEC, "invalid player%d, aborted", p.InsideNO);
return;
}
RingSector* rs = &p.domain.Data(situation.CurrentTime);
if(p.domain.IsDataKnown(situation.CurrentTime) && rs->IsValid()){
Raise(VO_player, rs->angles.Data(0).mean, rs->angles.Data(0).delta + ATan(1.0f/rs->radius.mean), priority);
return;
}
float radius = p.ActiveRadius(situation.CurrentTime);
float dist = Max(p.distance + 0.001f, radius);
float spreadangle = ASin(radius / dist);
if(p.Last_seen_time() != p.original_postime){//hearpos isn't accurate enough.
spreadangle += 10.0f;
}
DoLog(LOG_VDEC, "find %d %.2f", p.InsideNO, priority);
Findforgetobj(VO_player, p.global_angle, spreadangle, priority);
}
/******************/
void VisualSystem::Findforgetobj(VisualObjType otype, AngleDeg angle, AngleDeg distribute, float maxpriority){
AngleDeg tangle = angle - distribute;
float priority;
int i;
for(i = 0; i < 4; i++){
float conf = FieldInfo.DirConf(tangle);
if(conf < 0.9f && !Predictseen(tangle)){
priority = Min(4.0f * (1 - conf), 1.0f);
Raise(otype, tangle, maxpriority * priority * 0.5f);
}
tangle += distribute * 0.666f;
}
}
void VisualSystem::GetActionInf(){
Agent::mediator.Getbestaction(bestaction);
nextselfpos = Self.pos + Self.global_vel;
if(bestaction.GetCMDType() == CMD_dash){
nextselfpos += Polar2Vector(bestaction.GetPower() * Skill::action.Dashrate(), Self.bodyfacing);
}
DoLog(LOG_VDEC,"next self pos(%.2f, %.2f)", nextselfpos.x, nextselfpos.y);
}
bool VisualSystem::Isballbyfeel(){
if(!ball.pos_valid()) return false;
if(ball.distance > ServerParam::feel_distance + ServerParam::ball_speed_max) return false;
if(ball.kickable()) return true;
Vector ballgap = ball.posgap.ChkData(situation.CurrentTime) + ball.velgap.ChkData(situation.CurrentTime);
if((ball.PredictPos(1) - nextselfpos).mod() < ServerParam::feel_distance - ballgap.mod())
return true;
else
return false;
}
void VisualSystem::DoVisualDecision(){
if(Vinfo_coming){
DoLog(LOG_VDEC, "coming visual info (%.0f %.0f)" , NormalizeAngle(Vcominginfo_angle - Vcominginfo_width/2),
NormalizeAngle(Vcominginfo_angle + Vcominginfo_width/2));
}
GetActionInf();
bool canfeelball = Isballbyfeel();
DoViewModeDecision(canfeelball);
Agent::mediator.SetViewRange();
if(FindBall()) return;
//moved out
if(!ClientParam::goalie){
switch(bestaction.GetActionType()){
case Action_pass:
case Action_shoot:
case Action_dribble:
case Action_fastdribble:
case Action_holdball:
case Action_avoidenemy:
case Action_clear://handleball
case Action_passwait:
break;
case Action_interception://interception
break;
case Action_positioning_offense:
case Action_positioning_offside:
break;
case Action_positioning_defense:
break;
case Action_positioning_block:
case Action_positioning_mark:
break;
case Action_none:
default:
break;
}
}else if(ClientParam::goalie){
}
}
bool VisualSystem::FindBall(){
if((Predictconf(ball.global_angle) < 0.8f || (!ball.Isforgot() && ball.pos_conf > 0.5f)) && !situation.ClockStopped){
//just because haven't look at ball
float distribute = ATan2(1.5f * (situation.CurrentTime - ball.original_postime), ball.distance);
distribute = Max(distribute, 20.0f);
Raise(VO_ball, ball.global_angle, 2 * distribute,1.0f);
}else{
DoSeek(1.0f, ball.global_angle);
}
return true;
}
/*****predict next visual inf within current view angle *********/
/***** when clockstopped, prediction is invalid *********/
void VisualSystem::PredictNextSightInf(){
Vinfo_coming = bool(Self.NextViewCycle == situation.CurrentTime && !situation.ClockStopped);
if(Vinfo_coming){
Vcominginfo_angle = Self.headfacing;
Vcominginfo_width = Self.MyViewWidth();
}
}
float VisualSystem::GetPromisingAngle(VisualObjType obj, UNum idx){
MobileObject* mobj = NULL;
if(obj == VO_ball){
mobj = & ball;
}else if(obj == VO_player){
mobj = &GetPlayer(idx);
}
if(mobj != NULL){
if(mobj->pos_conf > ClientParam::min_valid_conf){
//since have't be forgotten, why not look directly
return mobj->global_angle;
}else{//
//return DoSeek(mobj->global_angle, true);
}
}else{
//shouldn't be here;
//return DoSeek(mobj->global_angle, true);
}
return 0;
}
void VisualSystem::DoSeek(float maxpriority, AngleDeg recommendedangle){
int seek_division = 12;
int i;
for(i = 0; i < seek_division; i++){
float angle = recommendedangle + 360.0f/seek_division * i;
float conf = Predictconf(angle);
if(conf > 0.9f) continue;
float priority = 0.3f + 0.3f * (1 - conf);
priority += 0.8f * (float)fabs(i - seek_division/2)/seek_division*2;
Raise(VO_route, angle, priority * maxpriority);
}
}
float VisualSystem::Predictconf(float ang){
if(Predictseen(ang))
return 1.0f;
else
return FieldInfo.DirConf(ang);
}
bool VisualSystem::Predictseen(float ang){
if(Vinfo_coming && fabs(NormalizeAngle(ang - Vcominginfo_angle)) < Vcominginfo_width/2)
return true;
else
return false;
}
/*****是否是新看过的队员,或即将看到他***********/
bool VisualSystem::Isobjconfmax(MobileObject& obj){
if((situation.CurrentTime - obj.original_postime < 2 && obj.IsValidObject())
|| (Predictseen(obj.global_angle) && !obj.Isforgot()))
return true;
else
return false;
}
void VisualSystem::DoViewModeDecision(bool forcenarrow){
if(Self.Is_goalie && situation.IsGoalieKick){
Agent::mediator.SetViewWidth(VW_Wide);
DoLog(LOG_SEE,"wide1");
return;
}
if(ball.distance > 50.0f){
Agent::mediator.SetViewWidth(VW_Wide);
DoLog(LOG_SEE,"wide2");
return;
}else if(ball.distance > 30.0f){
Agent::mediator.SetViewWidth(VW_Normal);
DoLog(LOG_SEE,"normal1");
return;
}
if(forcenarrow){
Agent::mediator.SetViewWidth(VW_Narrow);
if(Self.NextViewCycle - situation.CurrentTime > 1){
DoLog(LOG_SEE,"visualsystem1");
sensory.change_view(VW_Narrow, VQ_High);
}
return;
}
if((ball.PredictPos(1) - nextselfpos).mod() < ServerParam::feel_distance){
Agent::mediator.SetViewWidth(VW_Narrow);
DoLog(LOG_SEE,"visualsystem2");
DoLog(LOG_VDEC, "make up for narrow mode");
return;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -