From: <he...@us...> - 2011-04-20 23:19:33
|
Revision: 268 http://simspark.svn.sourceforge.net/simspark/?rev=268&view=rev Author: hedayat Date: 2011-04-20 23:19:27 +0000 (Wed, 20 Apr 2011) Log Message: ----------- Implementing a fix for goal counting problem based on Luis's suggestion and Mahdi's work. Modified Paths: -------------- trunk/rcssserver3d/ChangeLog trunk/rcssserver3d/plugin/soccer/soccerruleaspect/soccerruleaspect.cpp trunk/rcssserver3d/plugin/soccer/soccerruleaspect/soccerruleaspect.h Modified: trunk/rcssserver3d/ChangeLog =================================================================== --- trunk/rcssserver3d/ChangeLog 2011-04-20 23:14:35 UTC (rev 267) +++ trunk/rcssserver3d/ChangeLog 2011-04-20 23:19:27 UTC (rev 268) @@ -1,3 +1,12 @@ +2011-04-21 Hedayat Vatankhah <hed...@gm...> + + * plugin/soccer/soccerruleaspect/soccerruleaspect.h: + * plugin/soccer/soccerruleaspect/soccerruleaspect.cpp (SoccerRuleAspect::CheckGoal): + - if goal recorder's cannot detect any goals, geometrically check to + make sure that no goal is actually happened. Thanks to Luis for starting + the effort and Mahdi for the initial code for calculating where the ball + crosses the goal geometrically. + 2011-03-28 Hedayat Vatankhah <hed...@gm...> * rcssmonitor3d/rcssmonitor3d.rb: Modified: trunk/rcssserver3d/plugin/soccer/soccerruleaspect/soccerruleaspect.cpp =================================================================== --- trunk/rcssserver3d/plugin/soccer/soccerruleaspect/soccerruleaspect.cpp 2011-04-20 23:14:35 UTC (rev 267) +++ trunk/rcssserver3d/plugin/soccer/soccerruleaspect/soccerruleaspect.cpp 2011-04-20 23:19:27 UTC (rev 268) @@ -63,7 +63,7 @@ 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 + mMin3PlDistance(0), // min dist for third closest of team before being repositioned mMaxTouchGroupSize(1000), mMaxFaultTime(0.0) // maximum time allowed for a player to commit a positional fault before being repositioned { @@ -83,23 +83,23 @@ mBallBody->Enable(); } -/* Uses only Ball and Players positions and detects overcrowind near ball and areas and +/* 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 +void SoccerRuleAspect::AutomaticSimpleReferee(TPlayMode playMode) { // Reset counters before kickoff if (playMode == PM_BeforeKickOff) - { + { ResetFaultCounter(TI_LEFT); ResetFaultCounter(TI_RIGHT); } 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 + 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 AnalyseTouchGroups(TI_LEFT); AnalyseTouchGroups(TI_RIGHT); // Only apply rules during play-on @@ -108,7 +108,7 @@ ClearPlayersAutomatic(TI_LEFT); // enforce standing and not overcrowding rules for left team ClearPlayersAutomatic(TI_RIGHT); // enforce standing and not overcrowding rules for right team } - + // Reset touch groups ResetTouchGroups(TI_LEFT); ResetTouchGroups(TI_RIGHT); @@ -116,18 +116,18 @@ } -void +void SoccerRuleAspect::ResetFaultCounterPlayer(int unum, TTeamIndex idx) { - playerGround[unum][idx] = 0; - playerNotStanding[unum][idx] = 0; + 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; + prevPlayerInsideOwnArea[unum][idx] = 0; + playerInsideOwnArea[unum][idx] = 0; + playerFaultTime[unum][idx] = 0; } -void +void SoccerRuleAspect::ResetFaultCounter(TTeamIndex idx) { for(int t=1; t<=11; t++) { @@ -136,54 +136,54 @@ } // Process agent state: standing, sitted, laying down, ... -void +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 + //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]++; + { + 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]++; + playerGround[unum][idx]++; } //increase player standing or at least trying... Reset ground if (pos.z() >= middleZVal) { - playerStanding[unum][idx]++; + 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 (playerStanding[unum][idx] > 0.5 / 0.02) { + playerNotStanding[unum][idx] = 0; } } // 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++) + 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++) +// 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; +// cout << endl; // } } @@ -202,7 +202,7 @@ ownGoalPos = Vector3f(-mFieldLength/2.0, 0.0, 0.0); else ownGoalPos = Vector3f(mFieldLength/2.0, 0.0, 0.0); - + boost::shared_ptr<oxygen::Transform> agent_aspect; SoccerBase::TAgentStateList::const_iterator i; @@ -210,45 +210,45 @@ 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; + 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()) + + 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()) + + 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; + closestPlayer[idx] = unum; } // save player inside area state in previous cycle - prevPlayerInsideOwnArea[unum][idx] = playerInsideOwnArea[unum][idx]; + 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())) || + 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; + playerInsideOwnArea[unum][idx] = 1; //goalie is not repositioned when inside own area... if (unum == 1) - { - distGArr[unum][idx] = 0.0; - } + { + distGArr[unum][idx] = 0.0; + } } else playerInsideOwnArea[unum][idx] = 0; @@ -256,7 +256,7 @@ // 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 @@ -290,7 +290,7 @@ SoccerBase::TAgentStateList agent_states; if (! SoccerBase::GetAgentStates(*mBallState.get(), agent_states, idx)) return; - + SoccerBase::TAgentStateList::const_iterator i; for (i = agent_states.begin(); i != agent_states.end(); i++) { @@ -307,31 +307,31 @@ 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)) + // 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]++; } // I am the second closest player but i am too near the ball (and not the goalie) - else if(unum != 1 && closestPlayerDist[idx2] < mMinOppDistance && - distArr[unum][idx] <= mMin2PlDistance + 0.01 && ordArr[unum][idx] == 2 ) + else if(unum != 1 && closestPlayerDist[idx2] < mMinOppDistance && + distArr[unum][idx] <= mMin2PlDistance + 0.01 && ordArr[unum][idx] == 2 ) { playerFaultTime[unum][idx]++; } - // Too many players inside my own penalty area and Im am the last one to enter or + // 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 else if((numPlInsideOwnArea[idx] > mMaxPlayersInsideOwnArea && unum != 1 && playerInsideOwnArea[unum][idx] == 1 && - (prevPlayerInsideOwnArea[unum][idx] == 0 || + (prevPlayerInsideOwnArea[unum][idx] == 0 || (prevPlayerInsideOwnArea[1][idx] == 0 && playerInsideOwnArea[1][idx] == 1 && mMaxPlayersInsideOwnArea + 1 == ordGArr[unum][idx])))) { playerFaultTime[unum][idx]++; } // I am a field player and on the ground for too much time - else if (unum != 1 && playerGround[unum][idx] > mGroundMaxTime / 0.02) + else if (unum != 1 && playerGround[unum][idx] > mGroundMaxTime / 0.02) { playerFaultTime[unum][idx]++; } @@ -346,7 +346,7 @@ playerFaultTime[unum][idx]++; } // I am the goalie and I and not standing for too much time - else if (unum == 1 && playerNotStanding[unum][idx] > mGoalieNotStandingMaxTime / 0.02) + else if (unum == 1 && playerNotStanding[unum][idx] > mGoalieNotStandingMaxTime / 0.02) { playerFaultTime[unum][idx]++; } @@ -354,11 +354,11 @@ { playerFaultTime[unum][idx]=0; } - } + } } -salt::Vector3f SoccerRuleAspect::RepositionOutsidePos(salt::Vector3f posIni, int unum, TTeamIndex idx) +salt::Vector3f SoccerRuleAspect::RepositionOutsidePos(salt::Vector3f posIni, int unum, TTeamIndex idx) { salt::Vector3f pos; // Choose x side based on team @@ -396,12 +396,12 @@ 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); + salt::Vector3f new_pos = RepositionOutsidePos(ballPos, unum, idx); //Calculate my Reposition pos outside of the field - SoccerBase::MoveAgent(agent_aspect, new_pos); + 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; + //cout << "*********Player Repos Num: " << unum << " Team: " << team << " Pos: " << new_pos << endl; } } } @@ -1025,9 +1025,35 @@ { // check if the ball is in one of the goals TTeamIndex idx = mBallState->GetGoalState(); + if (idx == TI_NONE) { - return false; + const salt::Vector3f ballPos = mBallBody->GetPosition(); + const float xDist2Goal = fabs(ballPos.x()) - mGoalBallLineX; + + // check if ball is completely out of the field + if (xDist2Goal < 0) + return false; + + salt::Vector3f normBVel = mBallBody->GetVelocity(); + // ball should be inside the field recently (assumes that the simulation + // step size is smaller than 1 second) + if (ballPos.x() - normBVel.x() > mGoalBallLineX) + return false; + + normBVel.Normalize(); + double velCos = normBVel.x(); + double dist = xDist2Goal / velCos; + salt::Vector3f crossPoint = ballPos - normBVel * dist; + + if (fabs(crossPoint.y()) < mGoalWidth / 2.0 && + crossPoint.z() < mGoalHeight) + { + if (ballPos.x() < 0) + idx = TI_LEFT; + else + idx = TI_RIGHT; + } } // score the lucky team @@ -1231,7 +1257,7 @@ << playMode << "\n"; break; } - + // Simple Referee AutomaticSimpleReferee(playMode); } @@ -1281,6 +1307,7 @@ SoccerBase::GetSoccerVar(*this,"FieldLength",mFieldLength); SoccerBase::GetSoccerVar(*this,"FieldWidth",mFieldWidth); SoccerBase::GetSoccerVar(*this,"GoalWidth",mGoalWidth); + SoccerBase::GetSoccerVar(*this,"GoalHeight",mGoalHeight); SoccerBase::GetSoccerVar(*this,"FreeKickDistance",mFreeKickDist); SoccerBase::GetSoccerVar(*this,"FreeKickMoveDist",mFreeKickMoveDist); SoccerBase::GetSoccerVar(*this,"GoalKickDist",mGoalKickDist); @@ -1291,9 +1318,9 @@ float penaltyLength, penaltyWidth; SoccerBase::GetSoccerVar(*this,"PenaltyLength",penaltyLength); SoccerBase::GetSoccerVar(*this,"PenaltyWidth",penaltyWidth); - + // auto ref parameters - SoccerBase::GetSoccerVar(*this,"NotStandingMaxTime",mNotStandingMaxTime); + SoccerBase::GetSoccerVar(*this,"NotStandingMaxTime",mNotStandingMaxTime); SoccerBase::GetSoccerVar(*this,"GoalieNotStandingMaxTime",mGoalieNotStandingMaxTime); SoccerBase::GetSoccerVar(*this,"GroundMaxTime",mGroundMaxTime); SoccerBase::GetSoccerVar(*this,"GoalieGroundMaxTime",mGoalieGroundMaxTime); @@ -1324,6 +1351,8 @@ -(penaltyWidth + mGoalWidth)/2.0), Vector2f(-mFieldLength/2.0, (penaltyWidth + mGoalWidth)/2.0)); + + mGoalBallLineX = mFieldLength / 2.0 + mBallRadius; } void @@ -1753,7 +1782,7 @@ SoccerBase::TAgentStateList agent_states; if (SoccerBase::GetAgentStates(*mBallState.get(), agent_states, TI_NONE)) { - + SoccerBase::TAgentStateList::const_iterator i; for (i = agent_states.begin(); i != agent_states.end(); ++i) (*i)->UnSelect(); @@ -1768,7 +1797,7 @@ if (SoccerBase::GetAgentStates(*mBallState.get(), agent_states, TI_NONE) && agent_states.size() > 0) { boost::shared_ptr<AgentState> first = agent_states.front(); - + SoccerBase::TAgentStateList::const_iterator i; for (i = agent_states.begin(); i != agent_states.end(); ++i) { @@ -1784,7 +1813,7 @@ return; } } - + // No agent selected, select first first->Select(); } Modified: trunk/rcssserver3d/plugin/soccer/soccerruleaspect/soccerruleaspect.h =================================================================== --- trunk/rcssserver3d/plugin/soccer/soccerruleaspect/soccerruleaspect.h 2011-04-20 23:14:35 UTC (rev 267) +++ trunk/rcssserver3d/plugin/soccer/soccerruleaspect/soccerruleaspect.h 2011-04-20 23:19:27 UTC (rev 268) @@ -45,7 +45,7 @@ { public: typedef std::list<boost::shared_ptr<AgentState> > TAgentStateList; - + public: SoccerRuleAspect(); virtual ~SoccerRuleAspect(); @@ -64,13 +64,13 @@ \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 */ @@ -80,7 +80,7 @@ */ void ClearPlayersAutomatic(TTeamIndex idx); - /** Calculates distance arrays needed for repositioning players + /** Calculates distance arrays needed for repositioning players */ void CalculateDistanceArrays(TTeamIndex idx); @@ -99,18 +99,18 @@ */ void ResetFaultCounterPlayer(int unum, TTeamIndex idx); - /**Analyse Faults from players and increase fault counter of offending players + /**Analyse Faults from players and increase fault counter of offending players */ void AnalyseFaults(TTeamIndex idx); /** Check whether too many agents are touching */ void AnalyseTouchGroups(TTeamIndex idx); - + /** Reset the touch groups */ void ResetTouchGroups(TTeamIndex idx); - + /** Automatic Referee that clears players that violate the rules */ void AutomaticSimpleReferee(TPlayMode playMode); @@ -138,19 +138,19 @@ void ClearPlayersWithException(const salt::Vector3f& pos, float radius, float min_dist, TTeamIndex idx, boost::shared_ptr<AgentState> agentState); - /** + /** * get the size of field, i.e. length and width - * - * + * + * * @return the length and width */ salt::Vector2f GetFieldSize() const; - - + + void ResetAgentSelection(); - + void SelectNextAgent(); - + void ClearSelectedPlayers(); protected: @@ -238,7 +238,7 @@ */ void ClearPlayers(const salt::AABB2& box, float min_dist, TTeamIndex idx); - /** + /** * clear the player before kick off, if the team is the kick off * side, the robots can be on his own half and the center circle, * otherwise the robots can only be on his own half except the @@ -247,7 +247,7 @@ * @param idx the team which kick off */ void ClearPlayersBeforeKickOff(TTeamIndex idx); - + protected: /** reference to the body node of the Ball */ boost::shared_ptr<oxygen::RigidBody> mBallBody; @@ -277,6 +277,10 @@ float mFieldWidth; /** the goal width (in meters) */ float mGoalWidth; + /** the goal height (in meters) */ + float mGoalHeight; + /** the absolute x coordinate of the goal which ball should pass (in meters) */ + float mGoalBallLineX; /** the point on the field where we do the kick in, free kick etc. */ salt::Vector3f mFreeKickPos; /** the distance opponents have to keep during free kicks, kick ins etc. */ @@ -295,28 +299,28 @@ //FCP 2010 - New Parameters (added by FCPortugal for Singapure 2010) /** max time player may be sitted or laying down before being repositioned */ - int mNotStandingMaxTime; + int mNotStandingMaxTime; /** max time player may be on the ground before being repositioned */ - int mGroundMaxTime; + int mGroundMaxTime; /** max time goalie may be sitted or laying down before being repositioned */ - int mGoalieNotStandingMaxTime; + 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; + float mMin2PlDistance; /** min dist for third closest of team before being repositioned */ - float mMin3PlDistance; + float mMin3PlDistance; /** min dist for closest Opponent to ball in order to use repositions for the second and third player*/ - float mMinOppDistance; + float mMinOppDistance; /** maximum number of players of the defending team that may be inside own penalty area */ - int mMaxPlayersInsideOwnArea; + int mMaxPlayersInsideOwnArea; /** maximum number of players that may be in a single touch group */ int mMaxTouchGroupSize; /** maximum time allowed for a player to commit a positional fault before being repositioned */ - int mMaxFaultTime; + 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 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 @@ -329,7 +333,7 @@ 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 */ + /* FCP 2010 - New Parameters */ // areas where opponents are not allowed in certain play modes /** bounding box for the right half of the field */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |