From: <pat...@us...> - 2015-04-23 01:45:11
|
Revision: 388 http://sourceforge.net/p/simspark/svn/388 Author: patmac369 Date: 2015-04-23 01:45:03 +0000 (Thu, 23 Apr 2015) Log Message: ----------- This commit adds the following new rules and fixes: - Adding new rule requiring that the ball must either touch an opponent, or touch a teammate outside the center circle, before a team taking a kickoff can score. - Adding noise to the beam effector with the amount of noise added controlled by the 'BeamNoiseXY' (in meters) and 'BeamNoiseAngle' (in degrees) values in naosoccersim.rb. Noise is added to beam X and Y values from a uniform distribution within the range [-BeamNoiseXY,BeamNoiseXY] and to beam angle values from a uniform distribution within the range [-BeamNoiseAngle,BeamNoiseAngle]. - Fixing a bug where a player would be incorrectly called for double touching the ball on a kickoff if the player first kicked the ball directly in the opponent's goal from a kickoff, resulting in no goal being awarded and the opposing team being given a kickoff, and then is the next player to touch the ball in the PlayOn playmode after a dropball when the opponent doesn't take their kickoff. Modified Paths: -------------- trunk/rcssserver3d/plugin/soccer/ballstateaspect/ballstateaspect.cpp trunk/rcssserver3d/plugin/soccer/ballstateaspect/ballstateaspect.h trunk/rcssserver3d/plugin/soccer/beameffector/beameffector.cpp trunk/rcssserver3d/plugin/soccer/beameffector/beameffector.h trunk/rcssserver3d/plugin/soccer/soccerruleaspect/soccerruleaspect.cpp trunk/rcssserver3d/plugin/soccer/soccerruleaspect/soccerruleaspect.h trunk/rcssserver3d/rcssserver3d/naosoccersim.rb Modified: trunk/rcssserver3d/plugin/soccer/ballstateaspect/ballstateaspect.cpp =================================================================== --- trunk/rcssserver3d/plugin/soccer/ballstateaspect/ballstateaspect.cpp 2015-03-27 19:39:48 UTC (rev 387) +++ trunk/rcssserver3d/plugin/soccer/ballstateaspect/ballstateaspect.cpp 2015-04-23 01:45:03 UTC (rev 388) @@ -26,6 +26,7 @@ #include <oxygen/agentaspect/agentaspect.h> #include <oxygen/physicsserver/recorderhandler.h> #include <gamestateaspect/gamestateaspect.h> +#include <agentstate/agentstate.h> #include <soccerbase/soccerbase.h> #include <ball/ball.h> @@ -40,6 +41,8 @@ mLastValidBallPos = Vector3f(0,0,0); mGoalState = TI_NONE; mLastAgentCollisionTime = 0; + mCollidingWithLeftTeamAgent = false; + mCollidingWithRightTeamAgent = false; } BallStateAspect::~BallStateAspect() @@ -66,6 +69,9 @@ void BallStateAspect::UpdateLastCollidingAgent() { + mCollidingWithLeftTeamAgent = false; + mCollidingWithRightTeamAgent = false; + // get a list of agents that collided with the ball since the last // update of the recorder and remember the first returned node as // the last agent that collided with the ball. @@ -78,6 +84,26 @@ (agents.front().lock()); mLastAgentCollisionTime = mGameState->GetTime(); + + for (RecorderHandler::TParentList::iterator it = agents.begin(); + it != agents.end(); ++it) { + boost::shared_ptr<oxygen::AgentAspect> agent = + static_pointer_cast<AgentAspect>(it->lock()); + boost::shared_ptr<AgentState> agentState; + if (!SoccerBase::GetAgentState(agent, agentState)) + { + GetLog()->Error() << "ERROR: (SoccerRuleAspect) Cannot" + " get AgentState from an AgentAspect\n"; + } + else { + TTeamIndex team = agentState->GetTeamIndex(); + if (team == TI_LEFT) { + mCollidingWithLeftTeamAgent = true; + } else if (team == TI_RIGHT) { + mCollidingWithRightTeamAgent = true; + } + } + } } // empty the recorder buffer @@ -206,3 +232,16 @@ { return mLastValidBallPos; } + +bool BallStateAspect::GetBallCollidingWithAgentTeam(TTeamIndex team) +{ + if (team == TI_LEFT) { + return mCollidingWithLeftTeamAgent; + } else if (team == TI_RIGHT) { + return mCollidingWithRightTeamAgent; + } else if (team == TI_NONE) { + return !mCollidingWithLeftTeamAgent && !mCollidingWithRightTeamAgent; + } + + return false; +} Modified: trunk/rcssserver3d/plugin/soccer/ballstateaspect/ballstateaspect.h =================================================================== --- trunk/rcssserver3d/plugin/soccer/ballstateaspect/ballstateaspect.h 2015-03-27 19:39:48 UTC (rev 387) +++ trunk/rcssserver3d/plugin/soccer/ballstateaspect/ballstateaspect.h 2015-04-23 01:45:03 UTC (rev 388) @@ -76,6 +76,11 @@ /** updates the reference to the last agent that kicked the ball */ void UpdateLastKickingAgent(boost::shared_ptr<oxygen::AgentAspect> agent); + /** returns if ball is currently colliding with an agent from the given + team + */ + bool GetBallCollidingWithAgentTeam(TTeamIndex team); + protected: /** set up the reference to the ball and field collider */ virtual void OnLink(); @@ -128,6 +133,12 @@ /** then time when the last agent collided with the ball */ TTime mLastAgentCollisionTime; + /** if ball is currently colliding with left team agent */ + bool mCollidingWithLeftTeamAgent; + + /** if ball is currently colliding with right team agent */ + bool mCollidingWithRightTeamAgent; + /** then time when the last agent kicked the ball */ TTime mLastAgentKickTime; Modified: trunk/rcssserver3d/plugin/soccer/beameffector/beameffector.cpp =================================================================== --- trunk/rcssserver3d/plugin/soccer/beameffector/beameffector.cpp 2015-03-27 19:39:48 UTC (rev 387) +++ trunk/rcssserver3d/plugin/soccer/beameffector/beameffector.cpp 2015-04-23 01:45:03 UTC (rev 388) @@ -37,6 +37,8 @@ BeamEffector::~BeamEffector() { + mXYRng.reset(); + mThetaRng.reset(); } #ifdef __APPLE_CC__ @@ -54,7 +56,9 @@ (mAction.get() == 0) || (mBody.get() == 0) || (mGameState.get() == 0) || - (mAgentState.get() == 0) + (mAgentState.get() == 0) || + (mXYRng.get() == 0) || + (mThetaRng.get() == 0) ) { return; @@ -78,10 +82,10 @@ || mGameState->GetPlayMode() == PM_Goal_Right) { Vector3f pos; - pos[0] = beamAction->GetPosX(); - pos[1] = beamAction->GetPosY(); + pos[0] = beamAction->GetPosX() + (*(mXYRng.get()))(); + pos[1] = beamAction->GetPosY() + (*(mXYRng.get()))(); - float angle = beamAction->GetXYAngle(); + float angle = beamAction->GetXYAngle() + (*(mThetaRng.get()))(); // reject nan or infinite numbers in the beam position if ( @@ -181,6 +185,17 @@ mAgentRadius = 0.22f; SoccerBase::GetSoccerVar(*this,"AgentRadius",mAgentRadius); + + mBeamNoiseXY = 0.05f; + SoccerBase::GetSoccerVar(*this, "BeamNoiseXY",mBeamNoiseXY); + + mBeamNoiseAngle = 10.0f; + SoccerBase::GetSoccerVar(*this, "BeamNoiseAngle",mBeamNoiseAngle); + + UniformRngPtr rng1(new salt::UniformRNG<>(-mBeamNoiseXY,mBeamNoiseXY)); + mXYRng = rng1; + UniformRngPtr rng2(new salt::UniformRNG<>(-mBeamNoiseAngle,mBeamNoiseAngle)); + mThetaRng = rng2; } void @@ -189,5 +204,7 @@ mBody.reset(); mGameState.reset(); mAgentState.reset(); + mXYRng.reset(); + mThetaRng.reset(); } Modified: trunk/rcssserver3d/plugin/soccer/beameffector/beameffector.h =================================================================== --- trunk/rcssserver3d/plugin/soccer/beameffector/beameffector.h 2015-03-27 19:39:48 UTC (rev 387) +++ trunk/rcssserver3d/plugin/soccer/beameffector/beameffector.h 2015-04-23 01:45:03 UTC (rev 388) @@ -25,9 +25,13 @@ #include <oxygen/agentaspect/effector.h> #include <oxygen/physicsserver/rigidbody.h> #include <gamestateaspect/gamestateaspect.h> +#include <salt/random.h> class BeamEffector : public oxygen::Effector { +protected: + typedef boost::shared_ptr<salt::UniformRNG<> > UniformRngPtr; + public: BeamEffector(); virtual ~BeamEffector(); @@ -65,8 +69,20 @@ /** the cached field width */ float mFieldWidth; - /** thec cached agent radius */ + /** the cached agent radius */ float mAgentRadius; + + /** random number generator for beam X and Y noise */ + UniformRngPtr mXYRng; + + /** random number generator for beam angle noise */ + UniformRngPtr mThetaRng; + + /** amount of noise added to beam X and Y values */ + float mBeamNoiseXY; + + /** amount of noise added to beam angle value */ + float mBeamNoiseAngle; }; DECLARE_CLASS(BeamEffector); Modified: trunk/rcssserver3d/plugin/soccer/soccerruleaspect/soccerruleaspect.cpp =================================================================== --- trunk/rcssserver3d/plugin/soccer/soccerruleaspect/soccerruleaspect.cpp 2015-03-27 19:39:48 UTC (rev 387) +++ trunk/rcssserver3d/plugin/soccer/soccerruleaspect/soccerruleaspect.cpp 2015-04-23 01:45:03 UTC (rev 388) @@ -76,6 +76,7 @@ mMaxFoulTime(0.0), // maximum time allowed for a player to commit a positional foul before being repositioned mLastKickOffKickTime(0), mCheckKickOffKickerFoul(false), + mAllowKickOffTeamToScore(true), mPenaltyShootout(false) { mFreeKickPos = Vector3f(0.0,0.0,mBallRadius); @@ -1022,6 +1023,9 @@ { mGameState->SetPaused(false); + mCheckKickOffKickerFoul = false; + mAllowKickOffTeamToScore = true; + ClearPlayersBeforeKickOff(idx); // if no player touched the ball for mDropBallTime, we move away @@ -1045,10 +1049,12 @@ if (time > mGameState->GetLastModeChange()) { boost::shared_ptr<GameControlServer> game_control; - if (SoccerBase::GetGameControlServer(*this, game_control) - && game_control->GetAgentCount() > 2) // todo: remove this when there is a "penalty" playmode + if ((SoccerBase::GetGameControlServer(*this, game_control) + && game_control->GetAgentCount() > 2) // todo: remove this when there is a "penalty" playmode + && !mPenaltyShootout) { mCheckKickOffKickerFoul = true; + mAllowKickOffTeamToScore = false; } mLastKickOffKickTime = time; mLastKickOffTaker = agent; @@ -1444,9 +1450,34 @@ if (WasLastKickFromKickOff(agent)) { PunishKickOffFoul(agent); - return false; + // Return true so that we know the ball is in the goal and don't check + // for other conditions such as the ball being out of bounds + return true; } + /* Don't allow goals kicked from inside center circle directly after + kickoff + */ + if (!mAllowKickOffTeamToScore) { + boost::shared_ptr<AgentState> agentState; + if (!SoccerBase::GetAgentState(mLastKickOffTaker, agentState)) + { + GetLog()->Error() << "ERROR: (SoccerRuleAspect) Cannot" + " get AgentState from an AgentAspect\n"; + } + else { + TTeamIndex team = agentState->GetTeamIndex(); + if (idx != team) { + // Team that scored is same team that took kickoff + PunishKickOffFoul(mLastKickOffTaker); + // Return true so that we know the ball is in the goal and + // don't check for other conditions such as the ball being out + // of bounds + return true; + } + } + } + // score the lucky team mGameState->ScoreTeam((idx == TI_LEFT) ? TI_RIGHT : TI_LEFT); mGameState->SetPlayMode((idx == TI_LEFT) ? PM_Goal_Right : PM_Goal_Left); @@ -1478,6 +1509,13 @@ { mGameState->SetPaused(false); + // check that player who took kickoff doesn't touch the ball a second + // time before another agent touches the ball + if (CheckKickOffTakerFoul()) + { + return; + } + // check if the ball is in one of the goals if (CheckGoal()) { @@ -1498,11 +1536,6 @@ } #endif - if (CheckKickOffTakerFoul()) - { - return; - } - // other checks go here... } @@ -1602,6 +1635,28 @@ mLastModeWasPlayOn = false; + if (!mAllowKickOffTeamToScore) { + // Check if requirements/rules have been met for team taking kickoff + // to score + boost::shared_ptr<AgentState> agentState; + if (!SoccerBase::GetAgentState(mLastKickOffTaker, agentState)) + { + GetLog()->Error() << "ERROR: (SoccerRuleAspect) Cannot" + " get AgentState from an AgentAspect\n"; + } + else { + TTeamIndex team = agentState->GetTeamIndex(); + bool ballTouchedByKickOffTeam = + mBallState->GetBallCollidingWithAgentTeam(team); + bool ballTouchedByNonKickOffTeam = + mBallState->GetBallCollidingWithAgentTeam(SoccerBase::OpponentTeam(team)); + salt::Vector2f ball_pos(mBallBody->GetPosition().x(), mBallBody->GetPosition().y()); + bool ballOutsideCenterCircle = ball_pos.Length() > mFreeKickDist; + mAllowKickOffTeamToScore = ballTouchedByNonKickOffTeam || + (ballTouchedByKickOffTeam && ballOutsideCenterCircle); + } + } + switch (playMode) { case PM_BeforeKickOff: Modified: trunk/rcssserver3d/plugin/soccer/soccerruleaspect/soccerruleaspect.h =================================================================== --- trunk/rcssserver3d/plugin/soccer/soccerruleaspect/soccerruleaspect.h 2015-03-27 19:39:48 UTC (rev 387) +++ trunk/rcssserver3d/plugin/soccer/soccerruleaspect/soccerruleaspect.h 2015-04-23 01:45:03 UTC (rev 388) @@ -448,6 +448,8 @@ boost::shared_ptr<oxygen::AgentAspect> mLastKickOffTaker; /** if kickoff taker should be checked for single kick rule */ bool mCheckKickOffKickerFoul; + /** if kickoff taking team has met requirements/rules to score */ + bool mAllowKickOffTeamToScore; /** if in penalty shootout mode */ bool mPenaltyShootout; Modified: trunk/rcssserver3d/rcssserver3d/naosoccersim.rb =================================================================== --- trunk/rcssserver3d/rcssserver3d/naosoccersim.rb 2015-03-27 19:39:48 UTC (rev 387) +++ trunk/rcssserver3d/rcssserver3d/naosoccersim.rb 2015-04-23 01:45:03 UTC (rev 388) @@ -98,6 +98,10 @@ addSoccerVar('ReportScore', true) addSoccerVar('LabelMessages', true) +# Noise added to requested beam positions +addSoccerVar('BeamNoiseXY',0.05) +addSoccerVar('BeamNoiseAngle',10.0) + # auto ref parameters for testing (not for use in competition...) #addSoccerVar('NotStandingMaxTime',10) #addSoccerVar('GoalieNotStandingMaxTime',30) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |