From: <he...@us...> - 2010-05-23 07:34:31
|
Revision: 204 http://simspark.svn.sourceforge.net/simspark/?rev=204&view=rev Author: hedayat Date: 2010-05-23 07:34:24 +0000 (Sun, 23 May 2010) Log Message: ----------- Applied the simple referee patch Modified Paths: -------------- trunk/rcssserver3d/ChangeLog trunk/rcssserver3d/plugin/soccer/soccerruleaspect/soccerruleaspect.cpp trunk/rcssserver3d/plugin/soccer/soccerruleaspect/soccerruleaspect.h trunk/rcssserver3d/rcssserver3d/naosoccersim.rb Modified: trunk/rcssserver3d/ChangeLog =================================================================== --- trunk/rcssserver3d/ChangeLog 2010-05-19 17:15:37 UTC (rev 203) +++ trunk/rcssserver3d/ChangeLog 2010-05-23 07:34:24 UTC (rev 204) @@ -1,3 +1,11 @@ +2010-05-23 Hedayat Vatankhah <he...@gr...> + + * rcssserver3d/naosoccersim.rb: + * plugin/soccer/soccerruleaspect/soccerruleaspect.h: + * plugin/soccer/soccerruleaspect/soccerruleaspect.cpp: + - Added the simple referee patch from FCPortugal team (thanks to + Luis Paulo Reis) + 2010-02-28 Marian Buchta <mar...@gm...> * cmake/FindBoost.cmake: Modified: trunk/rcssserver3d/plugin/soccer/soccerruleaspect/soccerruleaspect.cpp =================================================================== --- trunk/rcssserver3d/plugin/soccer/soccerruleaspect/soccerruleaspect.cpp 2010-05-19 17:15:37 UTC (rev 203) +++ trunk/rcssserver3d/plugin/soccer/soccerruleaspect/soccerruleaspect.cpp 2010-05-23 07:34:24 UTC (rev 204) @@ -53,10 +53,19 @@ mFirstCollidingAgent(true), mNotOffside(false), mLastModeWasPlayOn(false), - mUseOffside(true) + mUseOffside(true), + mDropBallTime(15), + mNotStandingMaxTime(1000), // max time player may be sitted or laying down before being repositioned + mGoalieNotStandingMaxTime(1000), // max time goalie may be sitted or laying down before being repositioned + mGroundMaxTime(1000), // max time player may be on the ground before being repositioned + mGoalieGroundMaxTime(1000), // max time goalie (pl number 1) may be on the ground before being repositioned + mMaxPlayersInsideOwnArea(1000), // maximum number of players of the defending team that may be inside own penalty area + mMinOppDistance(0), // min dist for closest Opponent to ball in order to use repositions for 2nd, 3rd player + mMin2PlDistance(0), // min dist for second closest of team before being repositioned + mMin3PlDistance(0), // min dist for third closest of team before being repositioned + mMaxFaultTime(0.0) // maximum time allowed for a player to commit a positional fault before being repositioned { mFreeKickPos = Vector3f(0.0,0.0,mBallRadius); - } SoccerRuleAspect::~SoccerRuleAspect() @@ -72,7 +81,272 @@ mBallBody->Enable(); } +/* Uses only Ball and Players positions and detects overcrowind near ball and areas and +players innappropriate behavior (laying on the ground or not walking for too much time) */ +void +SoccerRuleAspect::AutomaticSimpleReferee(TPlayMode playMode) +{ + if (playMode != PM_PlayOn) { + ResetFaultCounter(TI_LEFT); ResetFaultCounter(TI_RIGHT); //only using automatic refereing in PlayOn + } + else { + CalculateDistanceArrays(TI_LEFT); // Calculates distance arrays for left team + CalculateDistanceArrays(TI_RIGHT); // Calculates distance arrays for right team + AnalyseFaults(TI_LEFT); // Analyses simple faults for the left team + AnalyseFaults(TI_RIGHT); // Analyses simple faults for the right team + ClearPlayersAutomatic(TI_LEFT); // enforce standing and not overcrowding rules for left team + ClearPlayersAutomatic(TI_RIGHT); // enforce standing and not overcrowding rules for right team + } +} + + +void +SoccerRuleAspect::ResetFaultCounterPlayer(int unum, TTeamIndex idx) +{ + playerGround[unum][idx] = 0; + playerNotStanding[unum][idx] = 0; + playerStanding[unum][idx] = 5/0.02; // Considers player has been standing for some time in playoff + prevPlayerInsideOwnArea[unum][idx] = 0; + playerInsideOwnArea[unum][idx] = 0; + playerFaultTime[unum][idx] = 0; +} + +void +SoccerRuleAspect::ResetFaultCounter(TTeamIndex idx) +{ + for(int t=1; t<=11; t++) { + ResetFaultCounterPlayer(t,idx); + } +} + +// Process agent state: standing, sitted, laying down, ... +void +SoccerRuleAspect::processAgentState(salt::Vector3f pos, int unum, TTeamIndex idx) +{ + float groundZVal = 0.15; //bellow this player is on the ground + float middleZVal = 0.25; //abovce this player is standing (or trying...) + + //increase player not standing if it is not in upward position and inside of field + if (pos.z() < middleZVal && fabs(pos.y())< mFieldWidth/2 + 0.1) { + playerNotStanding[unum][idx]++; + playerStanding[unum][idx]=0; //player not standing + } + + //increase player near ground if it is very low and inside of field + if (pos.z() < groundZVal && fabs(pos.y())< mFieldWidth/2 + 0.1) { + playerGround[unum][idx]++; + } + + //increase player standing or at least trying... Reset ground + if (pos.z() >= middleZVal) { + playerStanding[unum][idx]++; + playerGround[unum][idx]=0; + } + + //Player standing for some cycles (0.5 seconds) reset not standing count + if (playerStanding[unum][idx] > 0.5/0.02) { + playerNotStanding[unum][idx]=0; + } + +// if (playerGround[unum][idx] > 0/0.02) +// cout << "On the Ground Unum" << unum << " Team: " << idx << " Time: " << playerGround[unum][idx] << +// " z= " << pos.z() << endl; //debug +} + +// Calculates ordering on a distance vector +void SoccerRuleAspect::SimpleOrder(float dArr[][3], int oArr[][3], TTeamIndex idx) +{ + for(int t1=1; t1<=10; t1++) + for(int t2=t1+1; t2<=11; t2++) + if (dArr[t1][idx] >= dArr[t2][idx]) oArr[t1][idx]++; else oArr[t2][idx]++; + +// DEBUG +// if (dArr[1][idx]<1000.0) { +// cout << "Team: " << idx << " --> "; +// for(int t1=1; t1<=6; t1++) +// if (dArr[t1][idx]<5.0) cout << t1 << " o:" << oArr[t1][idx] << " d: " << dArr[t1][idx] << " | "; +// cout << endl; +// } +} + +// Calculate Distance arrays and ordering to the ball and own goal +void SoccerRuleAspect::CalculateDistanceArrays(TTeamIndex idx) +{ + if (idx == TI_NONE || mBallState.get() == 0) return; + std::list<boost::shared_ptr<AgentState> > agent_states; + if (! SoccerBase::GetAgentStates(*mBallState.get(), agent_states, idx)) return; + + salt::Vector3f ballPos = mBallBody->GetPosition(); + salt::Vector3f ownGoalPos = Vector3f(-mFieldLength/2.0, 0.0, 0.0); + if (idx==TI_RIGHT) ownGoalPos = Vector3f(mFieldLength/2.0, 0.0, 0.0); //own goal position + boost::shared_ptr<oxygen::Transform> agent_aspect; + std::list<boost::shared_ptr<AgentState> >::const_iterator i; + + numPlInsideOwnArea[idx] = 0; closestPlayer[idx]=1; closestPlayerDist[idx]=1000.0; + for(int t=1; t<=11; t++) { + distArr[t][idx]=1000.0; ordArr[t][idx]=1; distGArr[t][idx]=1000.0; ordGArr[t][idx]=1; + } + + for (i = agent_states.begin(); i != agent_states.end(); ++i) { + SoccerBase::GetTransformParent(**i, agent_aspect); + Vector3f agentPos = agent_aspect->GetWorldTransform().Pos(); + int unum = (*i)->GetUniformNumber(); + distArr[unum][idx] = sqrt((agentPos.x()-ballPos.x())*(agentPos.x()-ballPos.x()) + + (agentPos.y()-ballPos.y())*(agentPos.y()-ballPos.y())); + distGArr[unum][idx] = sqrt((agentPos.x()-ownGoalPos.x())*(agentPos.x()-ownGoalPos.x()) + + (agentPos.y()-ownGoalPos.y())*(agentPos.y()-ownGoalPos.y())); + + // determine closest player + if (distArr[unum][idx] < closestPlayerDist[idx]) { + closestPlayerDist[idx] = distArr[unum][idx]; closestPlayer[idx] = unum; + } + + // save player inside area state in previous cycle + prevPlayerInsideOwnArea[unum][idx] = playerInsideOwnArea[unum][idx]; + + // determine number of players inside area and set inside area state of player + if (idx == TI_LEFT && mLeftPenaltyArea.Contains(Vector2f(agentPos.x(), agentPos.y())) || + idx == TI_RIGHT && mRightPenaltyArea.Contains(Vector2f(agentPos.x(), agentPos.y()))) { + numPlInsideOwnArea[idx]++; + playerInsideOwnArea[unum][idx] = 1; + + //goalie is not repositioned when inside own area... + if (unum == 1) { + distGArr[unum][idx] = 0.0; + } + } + else playerInsideOwnArea[unum][idx] = 0; + + // Process agent state: standing, sitted, laying down, ... + processAgentState(agentPos, unum, idx); + } + + // compute rank of distance to ball + SimpleOrder(distArr, ordArr, idx); + // compute rank of distance to own goal + SimpleOrder(distGArr, ordGArr, idx); +} + +// Analyse Faults and Creates Fault Time Array +void SoccerRuleAspect::AnalyseFaults(TTeamIndex idx) +{ + TTeamIndex idx2; if (idx == TI_LEFT) idx2 = TI_RIGHT; else idx2 = TI_LEFT; //Other team + for(int unum=1; unum<=11; unum++) { + + //I am the third closest player but i am too near the ball (and not the goalie) + if ( unum!=1 && closestPlayerDist[idx2] < mMinOppDistance && + (distArr[unum][idx] <= mMin3PlDistance+0.01 && ordArr[unum][idx] == 3)) + { + playerFaultTime[unum][idx]++; //increase player fault time + //cout << "Min3Dist " << mMin3PlDistance << " activated - player " << unum << " to be repositioned \n"; + } + else + //I am the second closest player but i am too near the ball (and not the goalie) + if( unum!=1 && closestPlayerDist[idx2] < mMinOppDistance && + distArr[unum][idx] <= mMin2PlDistance+0.01 && ordArr[unum][idx] == 2 ) + { + playerFaultTime[unum][idx]++; //increase player fault time + //cout << "Min2Dist " << mMin2PlDistance << " activated - player " << unum << " to be repositioned \n"; + } + else + // too many players inside my own penalty area and Im am the last one to enter or + // the last one to enter was the goalie and I am the one further away from own goal + if( (numPlInsideOwnArea[idx] > mMaxPlayersInsideOwnArea && unum !=1 && playerInsideOwnArea[unum][idx] == 1 && + (prevPlayerInsideOwnArea[unum][idx] == 0 || + prevPlayerInsideOwnArea[1][idx] == 0 && + playerInsideOwnArea[1][idx] == 1 && + mMaxPlayersInsideOwnArea + 1 == ordGArr[unum][idx]))) + { + playerFaultTime[unum][idx]++; //increase player fault time + //cout << "MaxPlInPenalty " << mMaxPlayersInsideOwnArea << " activated - player " + // << unum << " to be repositioned " << " ord " << ordGArr[unum][idx] << "\n"; + } + else + //I am a field player and on the ground for too much time + if ( unum!=1 && playerGround[unum][idx] > mGroundMaxTime/0.02 ) + { + playerFaultTime[unum][idx]++; //increase player fault time + //cout << "GroundMaxTime " << mGroundMaxTime << " activated - player " + // << unum << " to be repositioned " << "\n"; + } + else + // I am a field player and I am not standing for too much time + if( unum!=1 && playerNotStanding[unum][idx] > mNotStandingMaxTime/0.02 ) + { + playerFaultTime[unum][idx]++; //increase player fault time + //cout << "StandMaxTime " << mNotStandingMaxTime << " activated - player " + // << unum << " to be repositioned " << "\n"; + } + + else + //I am the goalie and I am on the ground for too much time + if ( unum==1 && + playerGround[unum][idx] > mGoalieGroundMaxTime/0.02 ) + { + playerFaultTime[unum][idx]++; //increase player fault time + //cout << "GoalieGroundMaxTime " << mGoalieGroundMaxTime << " activated - player " + // << unum << " to be repositioned " << "\n"; + } + else + //I am the goalie and I and not standing for too much time + if ( unum == 1 && playerNotStanding[unum][idx] > mGoalieNotStandingMaxTime/0.02) + { + playerFaultTime[unum][idx]++; //increase player fault time + //cout << "GoalieStandMaxTime " << mGoalieNotStandingMaxTime << " activated - player " + // << unum << " to be repositioned " << "\n"; + } + else { + playerFaultTime[unum][idx]=0; //reset player fault time + } + + } +} + + +salt::Vector3f SoccerRuleAspect::RepositionOutsidePos(salt::Vector3f posIni, int unum, TTeamIndex idx) +{ + salt::Vector3f pos; + float fac=1.0; + if (unum > 6) unum = 7 -unum; //because of teams that use numbers 7-11 + if (posIni.y()<1.5) fac = 1.0; else fac = -1.0; //for visualization purposes + if (idx==TI_LEFT) pos = Vector3f(-(7-unum)*0.6, 6.5*fac, 1.0); + else pos = Vector3f((7-unum)*0.6, 6.5*fac, 1.0); + //cout << "*********Player Repos Num: " << unum << " Team: " << idx << " Pos: " << pos << endl; + return pos; +} + + +// Clear Players that are violating the rules void +SoccerRuleAspect::ClearPlayersAutomatic(TTeamIndex idx) +{ + if (idx == TI_NONE || mBallState.get() == 0) return; + + std::list<boost::shared_ptr<AgentState> > agent_states; + if (! SoccerBase::GetAgentStates(*mBallState.get(), agent_states, idx)) return; + + salt::Vector3f ballPos = mBallBody->GetPosition(); + + boost::shared_ptr<oxygen::Transform> agent_aspect; + std::list<boost::shared_ptr<AgentState> >::const_iterator i; + + for (i = agent_states.begin(); i != agent_states.end(); ++i) { + SoccerBase::GetTransformParent(**i, agent_aspect); + Vector3f agentPos = agent_aspect->GetWorldTransform().Pos(); + int unum = (*i)->GetUniformNumber(); + if (playerFaultTime[unum][idx] > mMaxFaultTime/0.02) { + // I am not a very good soccer player... I am violating the rules... + salt::Vector3f new_pos = RepositionOutsidePos(ballPos, unum, idx); + //Calculate my Reposition pos outside of the field + SoccerBase::MoveAgent(agent_aspect, new_pos); + //Oh my God!! I am flying!! I am going outside of the field + ResetFaultCounterPlayer(unum, idx); + //cout << "*********Player Repos Num: " << unum << " Team: " << team << " Pos: " << new_pos << endl; + } + } +} + +void SoccerRuleAspect::ClearPlayers(const salt::Vector3f& pos, float radius, float min_dist, TTeamIndex idx) { @@ -855,6 +1129,9 @@ << playMode << "\n"; break; } + + // Simple Referee + AutomaticSimpleReferee(playMode); } void @@ -912,7 +1189,20 @@ float penaltyLength, penaltyWidth; SoccerBase::GetSoccerVar(*this,"PenaltyLength",penaltyLength); SoccerBase::GetSoccerVar(*this,"PenaltyWidth",penaltyWidth); + + // auto ref parameters + SoccerBase::GetSoccerVar(*this,"NotStandingMaxTime",mNotStandingMaxTime); + SoccerBase::GetSoccerVar(*this,"GoalieNotStandingMaxTime",mGoalieNotStandingMaxTime); + SoccerBase::GetSoccerVar(*this,"GroundMaxTime",mGroundMaxTime); + SoccerBase::GetSoccerVar(*this,"GoalieGroundMaxTime",mGoalieGroundMaxTime); + SoccerBase::GetSoccerVar(*this,"MaxPlayersInsideOwnArea",mMaxPlayersInsideOwnArea); + SoccerBase::GetSoccerVar(*this,"MinOppDistance",mMinOppDistance); + SoccerBase::GetSoccerVar(*this,"Min2PlDistance",mMin2PlDistance); + SoccerBase::GetSoccerVar(*this,"Min3PlDistance",mMin3PlDistance); + //SoccerBase::GetSoccerVar(*this,"MaxFaultTime",mMaxFaultTime); + + // cout << "MaxInside " << mMaxPlayersInsideOwnArea << endl << endl; // set up bounding boxes for halfs and goal areas // the right and the left half are intentionally oversized towards the sides and Modified: trunk/rcssserver3d/plugin/soccer/soccerruleaspect/soccerruleaspect.h =================================================================== --- trunk/rcssserver3d/plugin/soccer/soccerruleaspect/soccerruleaspect.h 2010-05-19 17:15:37 UTC (rev 203) +++ trunk/rcssserver3d/plugin/soccer/soccerruleaspect/soccerruleaspect.h 2010-05-23 07:34:24 UTC (rev 204) @@ -64,7 +64,49 @@ \param pos position where the ball should be dropped- */ void DropBall(salt::Vector3f pos); + + /** Calculates the out of the field reposition pos for a given agent with unum and team idx + Agents are repositioned outside of the field near the mid field line on the opposite yy side + regarding the ball position + */ + salt::Vector3f RepositionOutsidePos(salt::Vector3f initPos, int unum, TTeamIndex idx); + + /** Calculates the inside field reposition pos for a given agent with unum and team idx + Agents are repositioned at distance from the ball, that is, at: plpos + (plpos-ballpos).normalize()*dist + */ + //salt::Vector3f RepositionInsidePos(salt::Vector3f initPos, int unum, TTeamIndex idx, float distance); + /** New rules for repositioning players that commit faults + */ + void ClearPlayersAutomatic(TTeamIndex idx); + + /** Calculates distance arrays needed for repositioning players + */ + void CalculateDistanceArrays(TTeamIndex idx); + + /** Calculates ordering on a distance vector */ + void SimpleOrder(float dArr[][3], int oArr[][3], TTeamIndex idx); + + /** Agent state concerining standing, laying down on the ground are processed + */ + void processAgentState(salt::Vector3f pos, int unum, TTeamIndex idx); + + /** Reset the fault time counter for all players and also other counters + */ + void ResetFaultCounter(TTeamIndex idx); + + /** Reset the fault time counter for a given player + */ + void ResetFaultCounterPlayer(int unum, TTeamIndex idx); + + /**Analyse Faults from players and increase fault counter of offending players + */ + void AnalyseFaults(TTeamIndex idx); + + /** Automatic Referee that clears players that violate the rules + */ + void AutomaticSimpleReferee(TPlayMode playMode); + /** broadcast a said message to all players \param message said message- \param pos positon of the player- @@ -95,6 +137,7 @@ * @return the length and width */ salt::Vector2f GetFieldSize() const; + protected: /** rereads the current soccer script values */ @@ -203,21 +246,15 @@ /** the radius of the Ball */ float mBallRadius; - /** the length of the pause after a goal */ float mGoalPauseTime; - /** the length of the pause after the ball left the field */ float mKickInPauseTime; - /** the length of one game half */ float mHalfTime; - /** the time we wait before dropping the ball in play modes where only - one team can touch the ball - */ + one team can touch the ball */ float mDropBallTime; - /** the point above the ground, where the ball left the field */ salt::Vector3f mLastValidBallPos; /** the field length (in meters) */ @@ -241,6 +278,43 @@ float mWaitBeforeKickOff; /** flag if we want to play only one half of the match */ bool mSingleHalfTime; + + //FCP 2010 - New Parameters (added by FCPortugal for Singapure 2010) + /** max time player may be sitted or laying down before being repositioned */ + int mNotStandingMaxTime; + /** max time player may be on the ground before being repositioned */ + int mGroundMaxTime; + /** max time goalie may be sitted or laying down before being repositioned */ + int mGoalieNotStandingMaxTime; + /** max time goalie (player number 1) may be on the ground before being repositioned */ + int mGoalieGroundMaxTime; + /** min dist for second closest of team before being repositioned */ + float mMin2PlDistance; + /** min dist for third closest of team before being repositioned */ + float mMin3PlDistance; + /** min dist for closest Opponent to ball in order to use repositions for the second and third player*/ + float mMinOppDistance; + /** maximum number of players of the defending team that may be inside own penalty area */ + int mMaxPlayersInsideOwnArea; + /** maximum time allowed for a player to commit a positional fault before being repositioned */ + int mMaxFaultTime; + /* Useful arrays for dealing with agent state an faults */ + salt::Vector3f playerPos[12][3]; //Players Positions - not used + int playerGround[12][3]; //Time Players are on the ground + int playerNotStanding[12][3]; //Time Players are not standing (head up for more than 0.5s) + int playerInsideOwnArea[12][3]; //Player is inside own area + int prevPlayerInsideOwnArea[12][3]; //Player was inside own area last cycle + int playerStanding[12][3]; //Time Players are standing + float distArr[12][3]; //Distance array to ball (left/right team) + int ordArr[12][3]; //Distance order of players (left/right team) + float distGArr[12][3]; //Distance array to own goal (left/right team) + int ordGArr[12][3]; //Distance order of players to own goal (left/right team) + int playerFaultTime[12][3]; //Time player is commiting a positional fault + int numPlInsideOwnArea[3]; //Number of players inside own area + int closestPlayer[3]; //Closest Player from each team + float closestPlayerDist[3]; //Closest Player distance to ball from each team + /* FCP 2010 - New Parameters */ + // areas where opponents are not allowed in certain play modes /** bounding box for the right half of the field */ salt::AABB2 mRightHalf; Modified: trunk/rcssserver3d/rcssserver3d/naosoccersim.rb =================================================================== --- trunk/rcssserver3d/rcssserver3d/naosoccersim.rb 2010-05-19 17:15:37 UTC (rev 203) +++ trunk/rcssserver3d/rcssserver3d/naosoccersim.rb 2010-05-23 07:34:24 UTC (rev 204) @@ -62,10 +62,30 @@ addSoccerVar('RuleGoalPauseTime',3.0) addSoccerVar('RuleKickInPauseTime',1.0) addSoccerVar('RuleHalfTime',5.0 * 60) -addSoccerVar('RuleDropBallTime',30) +addSoccerVar('RuleDropBallTime',15) addSoccerVar('SingleHalfTime', false) addSoccerVar('UseOffside',false) +# auto ref parameters FCP 2010 +addSoccerVar('NotStandingMaxTime',30) +addSoccerVar('GoalieNotStandingMaxTime',60) +addSoccerVar('GroundMaxTime',15) +addSoccerVar('GoalieGroundMaxTime', 30) +addSoccerVar('MaxPlayersInsideOwnArea',3) +addSoccerVar('MinOppDistance',0.8) +addSoccerVar('Min2PlDistance',0.4) +addSoccerVar('Min3PlDistance',1.0) + +# auto ref parameters for testing (not for use in competition...) +#addSoccerVar('NotStandingMaxTime',10) +#addSoccerVar('GoalieNotStandingMaxTime',30) +#addSoccerVar('GroundMaxTime', 5) +#addSoccerVar('GoalieGroundMaxTime', 5) +#addSoccerVar('MaxPlayersInsideOwnArea',2) +#addSoccerVar('MinOppDistance',1.0) +#addSoccerVar('Min2PlDistance',0.6) +#addSoccerVar('Min3PlDistance',1.5) + # recorders addSoccerVar('BallRecorder',"Ball/geometry/recorder") addSoccerVar('LeftGoalRecorder',"leftgoal/GoalBox/BoxCollider/recorder") This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |