📄 objects.cpp
字号:
#include "objects.h"
#include "worldmodel.h"
#include "perceptron.h"
#include "skill.h"
#include "log.h"
ObjectUpdate::ObjectUpdate(){
pos_time = -1;
}
void ObjectUpdate::set_polar(AngleDeg ang,Time time){
//do not exchange the order of the next two statements
seenposinfo.Setdata(Vector(seenposinfo.Data(seentime).x, ang), time);
seentime = Max(seentime, time);
seen = true;
}
void ObjectUpdate::set_polar(AngleDeg ang,float d,Time time){
seenposinfo.Setdata(Vector(d, ang), time);
seen = true;
if(seentime < time){
seentime = time;
sdtime = time;
seen_times.Add(time);
}else if(seentime > time){
int i,j;
for(i=seen_times.Num_datas()-2; i>=0; i--){
if(seen_times.Data(i) == time) return;
if(seen_times.Data(i) < time){
break;
}
}
i++;
seen_times.Add(time);
for(j=seen_times.Num_datas()-1; j>i; j--){
seen_times.Data(j) = seen_times.Data(j-1);
}
seen_times.Data(j) = time;
}else{
if(seen_times.IsEmpty()){
seen_times.Add(time);
}
}
}
void ObjectUpdate::set_conf_param(float max,float decay,float min){
max_conf = max;
conf_decay = decay;
min_valid_conf = min;
}
void ObjectUpdate::set_objtype(ObjType objtype){
this->objtype = objtype;
}
/******************************* Object **************************/
Object::Object(){
pos_conf = 0;
global_angle = 0;
}
void Object::set_pos(float X,float Y,bool rotate){
if (!rotate)
pos = Vector(X,Y);
else
pos = Vector(-X,-Y);
}
void Object::set_global_angle(AngleDeg ang,bool rotate){
if(!rotate)
global_angle = ang;
else
global_angle = NormalizeAngle(180 + ang);
}
bool Object::pos_valid(){
return bool(pos_conf >= min_valid_conf);
}
/**************************Mobile Object Update Process************************/
MobileUpdate::MobileUpdate(){
coordinate_time = -1;
heard_pos = false;
heard_vel = false;
pos_delta_valid = false;
}
void MobileUpdate::estimate_pos_delta(Time t){
if(!pos_delta_valid) return;
while(pos_delta_time < t){
pos_deltas.Setdata(pos_deltas.Data(pos_delta_time) + max_speed, pos_delta_time+1);
pos_delta_time ++;
}
}
void MobileUpdate::Parse_HearPos(TimedData<NoiseVector>& hearpos){
if(!heard_pos){
heardpos_info = hearpos;
heard_pos = true;
}else if(hearpos.data.delta >= hearpos.data.delta){
//the second hear info is more valuable
heardpos_info = hearpos;
}
}
void MobileUpdate::Parse_HearVel(TimedData<NoiseVector>& hearvel){
if(!heard_vel){
heardvel_info = hearvel;
heard_vel = true;
}else if(hearvel.data.delta >= hearvel.data.delta){
//the second hear info is more valuable
heardvel_info = hearvel;
}
}
void MobileUpdate::set_speed_param(float max,float decay){
max_speed = max;
speed_decay = decay;
}
void MobileUpdate::set_chinfo(float distChng,float dirChng,Time time){
seenchinfo.Setdata(Vector(distChng, dirChng), time);
}
/*************************** Mobile Object *********************/
MobileObject::MobileObject(){
Object::Object();
speed_conf = 0;
speed_conf = 0;
global_vel = 0;
update_seen_time = -1;
seentime = -1;
sdtime = -1;
}
Vector MobileObject::Pos(Time time){
return gpos.IsDataKnown(time) ? gpos.Data(time) : pos;
}
int MobileObject::PosDelay(){
return situation.CurrentTime - original_postime;
}
int MobileObject::VelDelay(){
return situation.CurrentTime - original_veltime;
}
Vector MobileObject::Vel(Time time){
return gvel.IsDataKnown(time) ? gvel.Data(time) : global_vel;
}
float MobileObject::ActiveRadius(Time time){
return pos_deltas.ChkData(time);
}
void MobileObject::update_end(){
if(newpos){
forgot = false;
}
#ifndef _Up_FState
if(sensory.NewSight && !seen && inview(sensory.LastSightTime) && distance < ServerParam::team_far_length){
DoLog(LOG_UPDATE, "forget obj (%.2f %.2f)", pos.x, pos.y);
forget();
}
#endif
pos = Pos(situation.CurrentTime);
rel_pos = pos - Self.pos;
global_angle = rel_pos.Angle();
distance = rel_pos.mod();
if (domain.IsDataKnown(situation.CurrentTime))
{
RingSector * rs = &(domain.Data(situation.CurrentTime));
if (objtype == OBJ_Player && rs->IsValid() && //valid player and valid domain
!rs->IsWithin(global_angle, distance) //pos is out of domain
&& rel_pos.mod() < ServerParam::team_far_length * 0.9f){ //too far player needn't care
/*
if(ball.kickable()){
DoLog("ctrller adjust");
}
//player pos correction based on domain, move from outside into the edge of domain
DoLog("move player %d into domain mean%.1f delta%.1f, former dir%.1f",
((Player*) this)->InsideNO,
rs->angles.Data(0).mean,
rs->angles.Data(0).delta,
global_angle);
*/
//distance correction
if (distance > rs->radius.sup()){
distance = rs->radius.sup();
}else if (distance < rs->radius.inf()){
distance = rs->radius.inf();
}
if(!rs->IsWithin(global_angle)){
//angle correction, it's assumed to lies in the first sector of domain.
float da = NormalizeAngle(global_angle - rs->angles.Data(0).mean);
if (da > rs->angles.Data(0).delta){
global_angle = NormalizeAngle(rs->angles.Data(0).sup());
}else if(da < - rs->angles.Data(0).delta){
global_angle = NormalizeAngle(rs->angles.Data(0).inf());
}
}
rel_pos = Polar2Vector(distance, global_angle);
pos = Self.pos + rel_pos;
//DoLog("from (%.1f, %.1f) to (%.1f, %.1f)", Pos(situation.CurrentTime).x, Pos(situation.CurrentTime).y, pos.x, pos.y);
}
}
global_vel = Vel(situation.CurrentTime);
speed = global_vel.mod();
vel_angle = global_vel.Angle();
//yjy
pos_delta = pos_deltas.Data(situation.CurrentTime);
seen = false;
isupdateheard = false;
seen_times.Reset();
heard_pos = false;
heard_vel = false;
}
//
void MobileObject::Prior_update(){
newpos = false;
updated_seen = false;
newvel = false;
}
void MobileObject::update(Time time){
update_seen(time);
update_heard(time);
//if(IsValidObject()){
estimate(time);
pos = Pos(sensory.LastSightTime);
rel_pos = pos - Self.Pos(sensory.LastSightTime);
distance = rel_pos.mod();
//}
}
void MobileObject::update_seen(Time time){
#ifdef _Up_FState
if(sensory.HasFullState() && acc_vel.IsDataKnown(time)){
gvel.Setdata(acc_vel.Data(time), time);
gpos.Setdata(acc_pos.Data(time), time);
pos_time = time;
coordinate_time = time;
vel_time = time;
speed_conf = max_conf;
pos_conf = max_conf;
update_seen_time = time;
original_postime = time;
original_veltime = time;
updated_seen = true;
newpos = true;
newvel = true;
pos_delta_valid = true;
pos_deltas.Setdata(0,time);
pos_delta_time = time;
rel_pos = gpos.Data(time) - Self.Pos(time);
domain.Data(time).Set(rel_pos.mod(), 0, rel_pos.Angle(), 0);
domain.TimedData(time).time = time;
}
#else
//没有新的视觉消息, 直接返回
if(seen){
//将收到的视觉信息,按时间依次更新 (一般1条或2条视觉信息)
Vector pos, rel_vel, rpos;
int i = 0, t = 0;
for(; i<seen_times.Num_datas(); i++){
t = seen_times.Data(i);
/* Position */
rpos = Polar2Vector(seen_distance(t), seen_rel_angle(t));
pos = rpos.Rotate(Self.Headfacing(t)) + Self.Pos(t);
estimate(t -1);
gpos.Setdata(pos, t);
/*****************/
float seegap = Sqr(seen_distance(t)*ServerParam::dist_qstep*0.5f) + Sqr(seen_distance(t)*ServerParam::dir_qstep*0.5f );
pos_deltas.Setdata((float)sqrt(seegap), t);
/* Velocity */
if (seenchinfo.IsDataKnown(t)){
newvel = true;
rpos.Normalize();
rel_vel.x = seen_distCh(t) * rpos.x - (seen_dirCh(t) * PI / 180.0f * seen_distance(t) * rpos.y);
rel_vel.y = seen_distCh(t) * rpos.y + (seen_dirCh(t) * PI / 180.0f * seen_distance(t) * rpos.x);
rel_vel = rel_vel.Rotate(Self.Headfacing(t));
gvel.Setdata(Self.Vel(t) + rel_vel, t);
vel_time = t;
speed_conf = max_conf;
original_veltime = t;
}
}
updated_seen = true;
newpos = true;
update_seen_time = t;
pos_time = t;
coordinate_time = t;
pos_conf = max_conf;
original_postime = t;
pos_delta_time = t;
pos_delta_valid = true;
forgot = false;
}
#endif
}
void MobileObject::estimate(Time time){
//if(!IsValidObject()) return;
Time t;
if(vel_time < pos_time - 5){//for unknown player, maybe no old vel;
vel_time = pos_time;
gvel.Setdata(0, vel_time);
speed_conf = 0;
}
for(t = vel_time; t < pos_time; t ++){
estimate_vel(t + 1);
}
if(sensory.LastSightTime > coordinate_time && coordinate_time > 0 && gpos.IsDataKnown(coordinate_time)){
float posconfbk = pos_conf;
for(t = coordinate_time; t < pos_time; t++){
estimate_pos(t + 1);
}
pos_conf = posconfbk;
}
for(t = pos_time; t < time; t ++){
estimate_vel(t + 1);
estimate_pos(t + 1);
}
}
void MobileObject::estimate_vel(Time time){
Vector evel = gvel.ChkData(time -1);
if (objtype == OBJ_Ball)
evel += Skill::action.KickEffect(time -1);
if (evel.mod() > max_speed){
evel = evel / evel.mod() * max_speed;
}
evel *= speed_decay;
gvel.Setdata(evel, time);
speed_conf *= conf_decay;
vel_time = time;
if (objtype == OBJ_Ball){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -