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

📄 objects.cpp

📁 2002年
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		DoLog(LOG_UPDATE, "Estimate Ball Moving with (%.2f %.2f) at %d", Vel(time).x, Vel(time).y, time);
	}
}

void MobileObject::estimate_pos(Time time){
	Vector epos = Pos(time -1) + gvel.ChkData(time) / speed_decay + Self.pos_gap.ChkData(time);	
	gpos.Setdata(epos , time);
	pos_conf *= conf_decay;
	pos_time = time;
	if(Self.pos_gap.IsDataKnown(time)){
		coordinate_time = time;
	}
}

//overloaded function, no use
bool MobileObject::Isupdate_heard(){
	if(!heard_pos) return false;
	if(!pos_valid()) return true;
	return true;
}

void MobileObject::update_heard(Time time){
#ifdef	_Up_FState
	isupdateheard = false;
	return ;
#endif	
	isupdateheard = Isupdate_heard();

	if (isupdateheard){
		newpos = true;	
		gpos.Setdata(heardpos_info.data.mean, heardpos_info.time);
		pos_time = heardpos_info.time;
		coordinate_time = pos_time;

		//0.2f 代表双方的定位误差. 当别人喊出一个绝对坐标时,有他的坐标系和自己的坐标系的偏差
		float relateive_delta = heardpos_info.data.delta + CP_coordinate_gap_between_agents;
		relateive_delta -= (heardpos_info.data.mean - Self.pos).mod() * ServerParam::dist_qstep; 
		relateive_delta = Max(relateive_delta, 0.0f);

		original_postime = heardpos_info.time;
		pos_conf = (float)pow(conf_decay, relateive_delta);

		//由于没有喊出original_postime,暂时取消这的更新
		//original_postime = heardpos_info.time;
		
		pos_delta_time = heardpos_info.time;
		pos_deltas.Setdata(heardpos_info.data.delta + CP_coordinate_gap_between_agents, pos_delta_time);
		pos_delta_valid = true;
	}
}

bool MobileObject::inview(Time time){
	if (!IsValidObject()) return false;

	if (pos_time < time){
		estimate(time);
	}
	Vector tmp_pos = (Pos(time) - Self.Pos(time)).Rotate(-Self.Headfacing(time));
	if(tmp_pos.mod() < ServerParam::feel_distance * 0.5f) return true; 
	//DoLog(7,"The Object is assumed to be at rel(%.2f %.2f)", tmp_pos.x, tmp_pos.y);
	float slide_dist = 1.0f / Sin(Self.MyViewAngle(Self.viewwidth.Data(time)));
	tmp_pos -= Vector(slide_dist, 0.0f);
	return bool(fabs(tmp_pos.Angle()) <= Self.MyViewAngle(Self.viewwidth.Data(time)));
}

void MobileObject::forget(){
	forgot = true;
}

bool MobileObject::speed_valid(){
	return bool(speed_conf > min_valid_conf);
}

Vector MobileObject::PredictPos(int cycles){
	Vector predictpos = pos;
	Vector vel = global_vel;
	int i;
	for(i = 0; i < cycles;i++){
		predictpos += vel;
		vel *= speed_decay;
	}
	return predictpos;
}

void MobileObject::PredictPos(Vector p[], int cycles){
	if(cycles <= 0) return;
	Vector vel = global_vel;
	p[0] = pos + vel;
	int i;
	for(i = 1; i < cycles;i++){
		vel *= speed_decay;
		p[i] = p[i-1] + vel;
	}
}

float MobileObject::MinDist(const Vector& tpos){
	float Min_dist = domain.Data(situation.CurrentTime).Dist(tpos - Self.pos);
	Min_dist = Max(Min_dist, pos.dist(tpos) - pos_delta);
	return Min_dist;
}

float MobileObject::Max_posx(){
	float max = pos.x + pos_delta;
	max = Min(max, domain.Data(situation.CurrentTime).Getmax_x() + Self.pos.x);
	return max;
}

float MobileObject::Min_posx(){
	float min = pos.x - pos_delta;
	min = Max(min, domain.Data(situation.CurrentTime).Getmin_x() + Self.pos.x);
	return min;
}

float MobileObject::GetOffsensitivity(){
	return GetOffsensitivity(situation.CurrentTime);
}

float MobileObject::GetOffsensitivity(Time t){
	if(!offsensitivity.IsDataKnown(t)){
		offsensitivity.Setdata(FieldInfo.GetOffensiveSensitivity(Pos(t)), t);
	}
	return offsensitivity.Data(t);
}

float MobileObject::GetDefsensitivity(){
	return GetDefsensitivity(situation.CurrentTime);
}

float MobileObject::GetDefsensitivity(Time t){
	if(!defsensitivity.IsDataKnown(t)){
		defsensitivity.Setdata(FieldInfo.GetDefensiveSensitivity(Pos(t)), t);
	}
	return defsensitivity.Data(t);
}

bool MobileObject::IsLastSeen(){
	return bool(Last_seen_time() == Self.Last_seen_time()) ;
}


/*********************     Ball     **************************/
Ball::Ball(){
	posgap_time = -1;
	velgap_time = -1;
}

void Ball::update_seengap(Time t){
#ifdef _Up_FState
	if(sensory.HasFullState() && acc_vel.IsDataKnown(t)){
		posgap.Setdata(0, t);
		posgap_time = t;
		velgap.Setdata(0, t);
		velgap_time = t;
		return;
	}
#endif

	if(!seenposinfo.IsDataKnown(t)) return;

	Vector t_posgap;
	float headfacingap = 1.5f;
	float dist = seen_distance(t);
	float rposagl = NormalizeAngle(Self.Headfacing(t) +  seen_rel_angle(t));
	float fcosagl = (float)fabs(Cos(rposagl));
	float fsinagl = (float)fabs(Sin(rposagl));
	//相对距离与角度误差
	float dis_gap = 0.05f + 0.513f * dist * ServerParam::dist_qstep/0.9f;
	float agl_gap = Deg2Rad(0.5f + headfacingap);
	//投影到全局坐标上的误差换算
	t_posgap.x = dis_gap * fcosagl + (dist + dis_gap) * agl_gap * fsinagl;
	t_posgap.y = dis_gap * fsinagl + (dist + dis_gap) * agl_gap * fcosagl;
	posgap.Setdata(t_posgap,t);
	
	Vector rpos = Pos(t) - Self.Pos(t);
	DoLog(LOG_UPDATE,"ball rpos(%.4f,%.4f) gap(%.4f %.4f) hafcing %.1f at %d", rpos.x,rpos.y, t_posgap.x, t_posgap.y, Self.Headfacing(t),t);
	posgap_time = t;
	if(seenchinfo.IsDataKnown(t)){
		Vector t_velgap;
	
		//相对速度误差
		t_velgap.x = dis_gap / dist * (float)fabs(seen_distCh(t)) + (dist + dis_gap) * ServerParam::disch_qstep * 0.5f;
		t_velgap.y  = dis_gap * Deg2Rad(seen_dirCh(t)) + (dist + dis_gap) * Deg2Rad(ServerParam::dir_qstep * 0.5f);
		
		t_velgap = t_velgap.Rotate(rposagl);
		t_velgap.x = (float)fabs(t_velgap.x);
		t_velgap.y = (float)fabs(t_velgap.y);
		//旋转rposagl引入的误差
		float tmp = t_velgap.y;
		t_velgap.y += t_velgap.x * agl_gap;
		t_velgap.x += tmp * agl_gap;
		
		//Self的速度误差
		Vector svelgap;
		float rvelagl = NormalizeAngle(Self.Headfacing(t) + Self.SpeedAngle(t));
		fcosagl = (float)fabs(Cos(rvelagl));
		fsinagl = (float)fabs(Sin(rvelagl));
		svelgap.x = (Self.Speed(t) + 0.005f) * agl_gap * fsinagl;
		svelgap.y = (Self.Speed(t) + 0.005f) * agl_gap * fcosagl;
		t_velgap += svelgap;
		velgap.Setdata(t_velgap,t);
		velgap_time = t;

		DoLog(LOG_UPDATE,"ball vel(%.4f,%.4f) gap(%.4f %.4f) selfvel gap(%.2f,%.2f)",Vel(t).x,Vel(t).y,t_velgap.x,t_velgap.y,svelgap.x,svelgap.y);
	}
}

void Ball::estimategap(Time t){
#ifdef _Up_FState
	if(sensory.HasFullState() && acc_vel.IsDataKnown(t)){  
		velgap.Setdata(0, t);
		velgap_time = t;
		posgap.Setdata(0, t);
		posgap_time = t;
		return;
	}

#endif
	Time i;
	Vector gap;
	for(i = velgap_time; i < t; i++){
		gap = (velgap.ChkData(i) + Vector(1,1) * ServerParam::ball_rand * (velgap.ChkData(i).mod() + gvel.ChkData(i+1).mod()/speed_decay)) * speed_decay;
		gap.x = gap.x > max_speed ? max_speed : gap.x;
		gap.y = gap.y > max_speed ? max_speed : gap.y;
		velgap.Setdata(gap, i+1);
		DoLog(LOG_UPDATE,"Estimate velgap (%.3f,%.3f) at %d", velgap.ChkData(i+1).x, velgap.ChkData(i+1).y, i+1);
	}
	velgap_time = t;
	//DoLog(LOG_UPDATE, "Estimate posgap (%.3f,%.3f) at %d(%.2f %.2f %.2f)",posgap.ChkData(posgap_time).x, posgap.ChkData(posgap_time).y, posgap_time, speed_decay, ServerParam::player_rand, ServerParam::player_decay);
	for(i = posgap_time; i < t; i++){
		posgap.Setdata(posgap.ChkData(i) + velgap.ChkData(i+1)/speed_decay + Vector(1,1) * ServerParam::player_rand * Self.Vel(i+1).mod() / ServerParam::player_decay, i+1);
		//DoLog(LOG_UPDATE, "Estimate posgap (%.3f,%.3f) selfvel (%.2f,%.2f) at %d",posgap.ChkData(i+1).x, posgap.ChkData(i+1).y, Self.Vel(i+1).x, Self.Vel(i+1).y, i+1);
	}
	posgap_time = t;
}

void Ball::update_seen(Time time){
/* What's special about ball's updation?
	Collisions, and a more accurate velocity is needed*/
#ifdef _Up_FState
	if(sensory.HasFullState() && acc_pos.IsDataKnown(time)){
		MobileObject::update_seen(time);
		return;
	}
#endif
	if(!seen) return;
	Time last_update_time = Max(update_seen_time, time -2);	
	Vector predictpos, predictvel;
	Vector allowposgap, allowvelgap;
	Vector predictpos_gap, predictvel_gap;
	
	int t;
	for(t = last_update_time + 1; t <= time; t++){
		if(!seenposinfo.IsDataKnown(t)) continue;	
		estimate(t);
		predictpos = Pos(t) - Self.Pos(t);
		DoLog(LOG_UPDATE, "estimate relpos %.2f, %.2f", predictpos.x, predictpos.y);
		predictvel = Vel(t);
		allowposgap = posgap.ChkData(t);
		allowvelgap = velgap.ChkData(t);
		Time last_seen_time = original_postime;
		Time last_seench_time = original_veltime;
		MobileObject::update_seen(t);
		update_seengap(t);
		
		if(seen_distance(t) > 30.0f) continue;
		
		if (seen_distance(t) > (Self.kickable_area+0.04f)){
			Skill::action.ResetKickEffect(t); //then the kick command sent at seen_time must be a fault
		}
		int postime_gap = t - last_seen_time;
		if(postime_gap <= 0){
			DoLog(LOG_UPDATE,"why postime_gap = 0? %d", t);
			continue;
		}
		
		allowposgap += posgap.ChkData(t);
		predictpos_gap = Pos(t) - Self.Pos(t) - predictpos;// - Self.SummarizePosGap(last_seen_time, t);
		DoLog(LOG_UPDATE,"T gap%d, V gap%d, Predictpos Gap(%.2f,%.2f)", postime_gap, t - last_seench_time, predictpos_gap.x, predictpos_gap.y);
		
		bool selfcoll = Self.SelfColl(last_seen_time+1, t);
		float erroridx = 0;
		bool PredictError = IsposError(allowposgap, predictpos_gap, erroridx);
		
		if(seenchinfo.IsDataKnown(t)){
			allowvelgap += velgap.ChkData(t);
			predictvel_gap = Vel(t) - predictvel;
			DoLog(LOG_UPDATE,"predictvel Gap(%.2f,%.2f)",predictvel_gap.x,predictvel_gap.y);
			float verroridx;
			bool PrevelError = IsposError(allowvelgap, predictvel_gap, verroridx);
			if(PredictError || PrevelError){
				erroridx += verroridx;
				DoLog(LOG_UPDATE, "Error Index %.3f",erroridx);
				find_kick = true;
			}else if(predictvel_gap.mod2() > Sqr(0.3f)){
				find_kick = true;
			} 
			error_idx.Setdata(erroridx, t);
			continue;
		}else if(Self.IsMoved(last_seen_time, t)){
			continue;
		}
		if(predictpos.mod() < ServerParam::ball_size + ServerParam::player_size){
			DoLog(LOG_UPDATE, "predict coll, unhandled yet");
		}
		error_idx.Setdata(erroridx, t);
		float sqrconf = max_conf * Sqr(conf_decay);
		float CP_collision_maxdis = 0.75f;
		
		if(!PredictError ){
			if(postime_gap ==1 && !OtherKick(last_seen_time,t) && velgap.IsDataKnown(t) && (posgap.Data(t).mod() + posgap.Data(t-1).mod()) > velgap.Data(t).mod()){
				DoLog(LOG_UPDATE, "estimate maybe more accurate, reset velconf");
				speed_conf = max_conf;
				//wait for estimate
			}else if(selfcoll && postime_gap <= 2){
				DoLog(LOG_UPDATE, "self coll, pos still correct fortunately");
				//wait for estimate
			}else if(!gpos.IsDataKnown(last_seen_time)){
				DoLog(LOG_UPDATE, "last pos is lost, have to estimate");
				//wait for estimate
			}else if(postime_gap<4 && speed_valid()){
				ApplyPosbased_vel(last_seen_time,t,max_conf);
			}else if(postime_gap<6){
				ApplyPosbased_vel(last_seen_time,t,sqrconf);
			}else
				ApplyPosbased_vel(last_seen_time,t,sqrconf * sqrconf);
			
			if(!selfcoll && postime_gap == 1 && seen_distance(t) < 2.0f){
				original_veltime = t - 1;
				DoLog(LOG_UPDATE,"Reliable predict vel at %d", t);
			}
			continue;
		}else{
			find_kick = true;
			DoLog(LOG_UPDATE,"why ball is here, Error Index %.3f at %d", erroridx, t);
		}

		//unmoved posgap limit;
		float dist_moved;
		if(gpos.IsDataKnown(last_seen_time)){
			dist_moved = (gpos.Data(last_seen_time) + Self.SummarizePosGap(last_seen_time, t)).dist(gpos.Data(t)) - allowposgap.mod();
		}else{
			dist_moved = predictpos.dist(gpos.Data(t)) - Vel(t).mod() * postime_gap  - allowposgap.mod();
		}
		if(dist_moved > max_speed * postime_gap){
			DoLog(LOG_UPDATE,"ball is moved");
			gvel.Setdata(0, t);
			vel_time = t;
			if(postime_gap ==1){
				speed_conf = max_conf;
			}else if(postime_gap == 2){
				speed_conf = sqrconf;
			}
		}else if(postime_gap ==1){
			if(OtherKick(last_seen_time)){
				ApplyPosbased_vel(last_seen_time,t,sqrconf);

⌨️ 快捷键说明

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