📄 objects.cpp
字号:
DoLog(LOG_UPDATE,"Predict other kick at %.0f",(float)last_seen_time);
}else if(selfcoll){
//wait for estimate
DoLog(LOG_UPDATE,"Error because Self coll");
}else if(last_seench_time < last_seen_time-1 ){
ApplyPosbased_vel(last_seen_time, t, sqrconf );
DoLog(LOG_UPDATE,"Error maybe too old vel");
}else if(seen_distance(t) < CP_collision_maxdis){
Collisionvel(t,sqrconf);
DoLog(LOG_UPDATE,"It must be coll");
}else{
ApplyPosbased_vel(last_seen_time, t, sqrconf);
DoLog(LOG_UPDATE,"Unknown reason");
}
}else if(postime_gap == 2){
if(OtherKick(last_seen_time)){
ApplyPosbased_vel(last_seen_time, t, sqrconf * conf_decay);
DoLog(LOG_UPDATE,"Predict other kick2 at%d", last_seen_time);
}else if(OtherKick(last_seen_time + 1)){
ApplyPosbased_vel(last_seen_time + 1, t, sqrconf * conf_decay);
DoLog(LOG_UPDATE,"Predict other kick3 at%d", last_seen_time+1);
}else if(selfcoll){
//wait for estimate
DoLog(LOG_UPDATE,"Error because Self coll");
}else if(last_seench_time<last_seen_time-1){
ApplyPosbased_vel(last_seen_time, t, sqrconf * conf_decay );
DoLog(LOG_UPDATE,"Error maybe too old vel");
}else{
if(seen_distance(t) > ServerParam::feel_distance){
DoLog(LOG_UPDATE,"too far ,see wrong");
}else{
float dis1 = (Pos(t) - Self.Pos(t)).mod() ;
float dis2 = (Pos(t-1) - Self.Pos(t-1)).mod();
DoLog(LOG_UPDATE,"t%d dis%.2f, t%d dis%.2f", t-1, dis2, t,dis1);
if(dis1 < dis2 && dis1 < CP_collision_maxdis){
Collisionvel(t, sqrconf * conf_decay);
DoLog(LOG_UPDATE,"find coll at t%d", t);
}else if(dis2 < dis1 && dis2 < CP_collision_maxdis){
Collisionvel(t - 1, sqrconf * conf_decay);
DoLog(LOG_UPDATE,"find coll at t%d", t-1);
}else{
if(Skill::action.KickEffect(last_seen_time).mod() > 0 && ball.Pos(last_seen_time).dist2(Self.Pos(last_seen_time)) > 1.0f){
DoLog(LOG_UPDATE,"maybe kick%d invalid", last_seen_time+1);
Skill::action.ResetKickEffect(last_seen_time+1);
}else{
DoLog(LOG_UPDATE,"maybe unfound kick %d", t);
}
ApplyPosbased_vel(last_seen_time, t, sqrconf * conf_decay );
//invalid kick not be clear out. or other Skill::kick haven't been found
}
}
}
}else if(!gpos.IsDataKnown(last_seen_time)){
//wait for estimate
}else if(postime_gap<6){
ApplyPosbased_vel(last_seen_time, t, sqrconf * conf_decay);
}else{
ApplyPosbased_vel(last_seen_time, t, ClientParam::min_valid_conf * conf_decay);
}
}
}
void Ball::ApplyPosbased_vel(Time prevtime,Time latestime,float conf){
bool valid;
Vector evel_posbased;
evel_posbased = posbased_vel_estimate(prevtime, latestime, valid);
if(valid){
gvel.Setdata(evel_posbased, latestime);
vel_time = latestime;
speed_conf = conf;
DoLog(LOG_UPDATE,"t%d, Posbased vel applied", latestime);
}else{
DoLog(LOG_UPDATE,"Why posbased_vel Invalid (%.2f %.2f)", evel_posbased.x, evel_posbased.y);
}
velgap.Setdata(posgap.ChkData(prevtime) + posgap.ChkData(latestime), latestime);
velgap_time = latestime;
DoLog(LOG_UPDATE, "reset velgap (%.2f, %.2f)",velgap.Data(latestime).x, velgap.Data(latestime).y);
}
//decide whether the hear info is useful
bool Ball::Isupdate_heard(){
//no hear info
if(!heard_pos) return false;
if(IsValidObject()){
if(pos.dist(heardpos_info.data.mean) > heardpos_info.data.delta + pos_delta + 2.7f){
DoLog(LOG_HEAR, "Hearbug %d known pos(%.1f, %.1f), delta%.1f while hearing pos(%.1f, %.1f), delta%.1f",
heardpos_info.time, pos.x, pos.y, pos_delta,
heardpos_info.data.mean.x, heardpos_info.data.mean.y, heardpos_info.data.delta);
}
}
DoLog(LOG_HEAR, "ball heard pos(%.1f, %.1f, delta%.1f), delay%d old_delta%.1f",
heardpos_info.data.mean.x, heardpos_info.data.mean.y, heardpos_info.data.delta,
situation.CurrentTime - heardpos_info.time, pos_deltas.Data(pos_delta_time));
if(heardpass.time == heardpos_info.time){
DoLog(LOG_HEAR, "heard passing");
}
//old info is not valid
if(!pos_valid() || !IsValidObject() || Isforgot()){
find_kick = true;
return true;
}
//I have newer info already
if(Last_seen_time() > heardpos_info.time){
if(heardpass.time != heardpos_info.time || seenchinfo.IsDataKnown(Last_seen_time())){
return false;
}else{
//but ball's vel isn't be seen for too far.
find_kick = true;
return true;
}
}
//hear pass info
if(heardpass.time == heardpos_info.time && heardpos_info.time >= Last_seen_time()){
find_kick = true;
return true;
}
//old decision by criver
if (pos_conf > 0.9f || distance < 2.0f){
//it is critical for me, if the confidence of ball is greater than 0.8f and it ball is within 2 meter of my reach
if (heardvel_info.time != heardpos_info.time) return false;
if (ball.global_vel.dist2(heardvel_info.data.mean) < Sqr(0.6f)) return false;
}
//my info is clear enough
if(IsLastSeen() && !OtherKick(update_seen_time)) return false;
if(!IsLastSeen() && (heardvel_info.time - heardvel_info.data.delta) > update_seen_time && IscplayerKnown(update_seen_time)){
//可能刚被人踢过
Vector rel_ball_pos = ball.Pos(update_seen_time) - Self.Pos(update_seen_time);
if(closestrpos(update_seen_time).mod() - rel_ball_pos.mod() * ServerParam::dist_qstep * 0.6f < ServerParam::kickable_area){
if(!find_kick){
estimate(heardvel_info.time);
find_kick = heardvel_info.data.mean.dist2(ball.Vel(heardvel_info.time)) > Sqr(0.6f);
}
return true;
}
}
//convert hear delta to pos gap in my system
float relateive_delta = heardpos_info.data.delta + CP_coordinate_gap_between_agents;
estimategap(heardpos_info.time);
if(Sqr(relateive_delta) < posgap.Data(heardpos_info.time).mod2()){
//rude deal
find_kick = true;
return true;
}else{
return false;
}
//有一点还没有判断清楚, 如果听到的位置时间比自己已知的新, 虽然delta>posgap,
//但如果中间曾被人踢过,应尽量采用听到的.
}
void Ball::update_heard(Time time){
MobileObject::update_heard(time);
if(isupdateheard){
//take care, here we set player's iscontrolball
int No;
for(No = 1; No <= SP_team_size; No++){
MyPlayer(No).Set_Iscontrolball_Fromheard(heardpos_info.time);
TheirPlayer(No).Set_Iscontrolball_Fromheard(heardpos_info.time);
UnknownTheirPlayerList.Set_IsControlball_FromHeard(heardpos_info.time);
UnknownMyPlayerList.Set_IsControlball_FromHeard(heardpos_info.time);
TeamlessPlayerList.Set_IsControlball_FromHeard(heardpos_info.time);
}
updated_holder = true;
if (heard_vel && heardvel_info.data.delta <= VelDelay() ){
//如果听到的位置精确度更高,不妨认为速度的也更高
gvel.Setdata(heardvel_info.data.mean, heardvel_info.time);
vel_time = heardvel_info.time;
speed_conf = (float)pow(conf_decay, int(heardvel_info.data.delta));
original_veltime = heardvel_info.time - int(heardvel_info.data.delta);
newvel = true;
DoLog(LOG_HEAR, "ball vel %d, (%.1f,%.1f)", heardvel_info.time,
heardvel_info.data.mean.x, heardvel_info.data.mean.y);
}
}
}
void Ball::Prior_update(){
find_kick = false;
updated_holder = false;
}
void Ball::update_end(){
MobileObject::update_end();
if(Last_seen_time() < Self.Last_seen_time() && distance < ServerParam::feel_distance){
if(ball.Pos(Self.Last_seen_time()).dist(Self.Pos(Self.Last_seen_time())) + ball.posgap.ChkData(Self.Last_seen_time()).mod() < ServerParam::feel_distance){
forget();
}
}
pos_delta = posgap.ChkData(situation.CurrentTime).mod();
if(distance > ClientParam::kickable_area || !pos_valid() || !IsValidObject()){
kick_able = false;
}else if(Last_seen_time() >= Self.Last_seen_time()){
kick_able = true;
}else if(pos_delta > 2.0f){
kick_able = false;
}else if(ball.Pos(Self.Last_seen_time()).dist(Self.Pos(Self.Last_seen_time())) +
ball.posgap.ChkData(Self.Last_seen_time()).mod() > ServerParam::feel_distance){
kick_able = true;
}else{
kick_able = false;
}
if(distance < ClientParam::kickable_area && !kick_able){
if(!pos_valid()) DoLog(LOG_UPDATE, "kick disable for pos invalid");
else if(!IsValidObject()) DoLog(LOG_UPDATE, "kick disable for Rs invalid");
else{
DoLog(LOG_UPDATE, "kick disable for ball( %d) is unseen at %d", Last_seen_time(), Self.Last_seen_time());
}
}
theirgoalangle = (PitchInfo.theirgoal - pos).Angle();
mygoalangle = (PitchInfo.mygoal - pos).Angle();
DoLog(LOG_UPDATE, "ball pos(%.2f, %.2f), vel(%.2f, %.2f)", pos.x, pos.y, global_vel.x, global_vel.y);
}
void Ball::Collisionvel(Time time,float conf){
Vector vel = Skill::action.SummarizeKickeffectVel(Vel(vel_time),vel_time,time,speed_decay,max_speed);
gvel.Setdata(vel * -0.1f, time);
vel_time = time;
speed_conf = conf;
DoLog(LOG_UPDATE,"coll handle t%.0f,v(%.2f,%.2f)",(float)time,Vel(time).x,Vel(time).y);
}
bool Ball::OtherKick(Time time){
if(IscrposKnown(time)){
if(closestrpos(time).mod() < ServerParam::kickable_area + 0.05f )
return true;
}
return false;
}
bool Ball::OtherKick(Time prevtime,Time lastime){
for(Time t=prevtime;t<=lastime;t++){
if(OtherKick(t)) return true;
}
return false;
}
bool Ball::IsposError(Vector allowposgap, Vector predictgap,float& gapmod){
if(fabs(predictgap.x) > allowposgap.x || fabs(predictgap.y) > allowposgap.y){
gapmod = fabs(predictgap.x) > allowposgap.x ? Sqr((float)fabs(predictgap.x)-allowposgap.x) : 0;
gapmod += fabs(predictgap.y) > allowposgap.y ? Sqr((float)fabs(predictgap.y)-allowposgap.y) : 0;
gapmod = (float)sqrt(gapmod / allowposgap.mod());
return true;
}else{
gapmod = 0;
return false;
}
}
Vector Ball::posbased_vel_estimate(Time prev_time, Time last_time, bool& valid){
/* estimate by postion difference */
valid = false;
Vector gap = Pos(last_time) - Pos(prev_time);
Vector evel;
gap -= Self.SummarizePosGap(prev_time, last_time);
DoLog(LOG_UPDATE,"prev pos (%.2f %.2f) last pos (%.2f %.2f) gap (%.2f %.2f)", Pos(prev_time).x, Pos(prev_time).y,
Pos(last_time).x, Pos(last_time).y, gap.x, gap.y);
//if (gap.mod() < (float)fabs(last_time - prev_time) * max_speed){
Vector kickeffectpos = Skill::action.SummarizeKickeffectPos(prev_time, last_time, speed_decay);
evel = (gap - kickeffectpos) * (1 - speed_decay) / (1 - Exp(speed_decay, (float)(last_time - prev_time)));
//evel is now that at time prev_time
if(evel.mod() > max_speed){
evel = evel / evel.mod() * max_speed;
}
evel = Skill::action.SummarizeKickeffectVel(evel, prev_time, last_time, speed_decay, max_speed);
valid = true;
return evel;
}
void Ball::estimate(Time time){
MobileObject::estimate(time);
estimategap(time);
}
void Ball::estimate_pos(Time time){
MobileObject::estimate_pos(time);
}
void Ball::CollisionHandle(Time time){
DoLog(LOG_UPDATE,"Coolisionhandle");
estimate_pos(time);
if (speed_valid()){
Vector rpos = Pos(time) - Self.Pos(time);
float r = ServerParam::ball_size + ServerParam::player_size;
float d = rpos.mod();
if (d>=r) return;
AngleDeg th = float(fabs(NormalizeAngle(rpos.Angle() - Self.Bodyfacing(time -1) - 180.0f)));
float l1 = d * Cos(th);
float h = d * Sin(th);
float cosp = h / r;
float sinp = (float)sqrt(1.0 - Sqr(cosp));
float l2 = r * sinp;
gpos.Data(time) += Vel(time) *float( speed_decay * (-(l1+l2) / Max(Vel(time).mod() * speed_decay, 0.000001f)));
gvel.Data(time) *= -0.1f;
vel_time = time;
speed_conf = min_valid_conf / Sqr(conf_decay);
}
}
bool Ball::catchable(){
if(Self.Is_goalie)
return bool(pos_conf > 0.8f && distance < ServerParam::catch_area_l && PitchInfo.my_penaltyarea.IsWithin(Self.pos) && Skill::action.cancatch(situation.CurrentTime));
else
return bool(pos_conf > 0.8f && distance < ServerParam::catch_area_l && PitchInfo.my_penaltyarea.IsWithin(pos) && Skill::action.cancatch(situation.CurrentTime));
}
bool Ball::shootable(){
return bool(FieldInfo.shootablearea.IsWithin(pos) && kickable());
}
bool Ball::kickable(const Vector& selfpos){
return bool(pos_valid() && ball.pos.dist2(selfpos) < Sqr(Self.kickable_area ));
}
bool Ball::catchable(const Vector& selfpos){
return bool(pos_valid() && pos.dist2(selfpos) < Sqr(ServerParam::catch_area_l) && PitchInfo.my_penaltyarea.IsWithin(selfpos) && Skill::action.cancatch(situation.CurrentTime));
}
bool Ball::shootable(const Vector& ballpos){
return FieldInfo.shootablearea.IsWithin(ballpos);
}
void Ball::Setball_CPlayer(UNum idx,Vector pos,Time time){
if(idx > 0 && idx <= 2*SP_team_size)
ClosestPlayer.Setdata(idx, time);
else
ClosestPlayer.Setdata(idx, time-1);
ClosestRPos.Setdata(pos-Pos(time),time);
}
bool Ball::IsOtherKick(){
if(IsOtherKick(situation.CurrentTime) || IsOtherKick(situation.CurrentTime - 1)){
return true;
}else
return false;
}
bool Ball::IsOtherKick(Time t){
if(error_idx.IsDataKnown(t) && error_idx.Data(t) > 0.01f )
return true;
else
return false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -