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

📄 soccerruleaspect.cpp

📁 robocup rcssserver 运行防真机器人足球比赛所用的服务器端
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*-   this file is part of rcssserver3D   Fri May 9 2003   Copyright (C) 2002,2003 Koblenz University   Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group   $Id: soccerruleaspect.cpp,v 1.33 2008/02/24 10:18:09 rollmark Exp $   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; version 2 of the License.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include "soccerruleaspect.h"#include <salt/random.h>#include <zeitgeist/logserver/logserver.h>#include <oxygen/agentaspect/agentaspect.h>#include <oxygen/physicsserver/body.h>#include <oxygen/sceneserver/scene.h>#include <oxygen/gamecontrolserver/gamecontrolserver.h>#include <soccer/soccerbase/soccerbase.h>#include <soccer/gamestateaspect/gamestateaspect.h>#include <soccer/ballstateaspect/ballstateaspect.h>#include <soccer/agentstate/agentstate.h>using namespace oxygen;using namespace boost;using namespace std;using salt::Vector2f;using salt::Vector3f;SoccerRuleAspect::SoccerRuleAspect() :    SoccerControlAspect(),    mBallRadius(0.111),    mGoalPauseTime(3),    mKickInPauseTime(1),    mHalfTime(2.25 * 60),    mFreeKickDist(9.15),    mFreeKickMoveDist(15.15),    mAutomaticKickOff(false),    mWaitBeforeKickOff(1.0),    mSingleHalfTime(false),    mSayMsgSize(20),    mAudioCutDist(50.0),    mUseOffside(true),    mFirstCollidingAgent(true),    mNotOffside(false),    mLastModeWasPlayOn(false){    mFreeKickPos = Vector3f(0.0,0.0,mBallRadius);}SoccerRuleAspect::~SoccerRuleAspect(){}voidSoccerRuleAspect::MoveBall(const Vector3f& pos){    mBallBody->SetPosition(pos);    mBallBody->SetVelocity(Vector3f(0,0,0));    mBallBody->SetAngularVelocity(Vector3f(0,0,0));}voidSoccerRuleAspect::MoveAgent(shared_ptr<Transform> agent_aspect, const Vector3f& pos){    SoccerBase::MoveAgent(agent_aspect, pos);}voidSoccerRuleAspect::ClearPlayers(const salt::Vector3f& pos, float radius,                               float min_dist, TTeamIndex idx){    if (idx == TI_NONE || mBallState.get() == 0) return;    std::list<boost::shared_ptr<AgentState> > agent_states;    if (! SoccerBase::GetAgentStates(*mBallState, agent_states, idx))        return;    salt::BoundingSphere sphere(pos, radius);    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);        // if agent is too close, move it away        Vector3f new_pos = agent_aspect->GetWorldTransform().Pos();        Vector3f test_pos = new_pos;        test_pos[2] = pos[2];        // DEBUG        //cerr << "testing position (" << test_pos[0] << "," << test_pos[1] << ")" << endl;        if (sphere.Contains(test_pos))        {            float dist = salt::UniformRNG<>(min_dist, min_dist + 2.0)();            if (idx == TI_LEFT)            {                if (pos[0] - dist < -mFieldLength/2.0)                {                    new_pos[1] = pos[1] < 0 ? pos[1] + dist : pos[1] - dist;                } else {                    new_pos[0] = pos[0] - dist;                }            } else {                if (pos[0] + dist > mFieldLength/2.0)                {                    new_pos[1] = pos[1] < 0 ? pos[1] + dist : pos[1] - dist;                } else {                    new_pos[0] = pos[0] + dist;                }            }            MoveAgent(agent_aspect, new_pos);        }    }#if 0    if (idx == TI_NONE || mBallState.get() == 0) return;    std::list<boost::shared_ptr<AgentState> > agent_states;    if (! SoccerBase::GetAgentStates(*mBallState, agent_states, idx))        return;    salt::BoundingSphere sphere(pos, radius);    boost::shared_ptr<oxygen::Transform> transform_parent;    boost::shared_ptr<oxygen::Body> agent_body;    std::list<boost::shared_ptr<AgentState> >::const_iterator i;    for (i = agent_states.begin(); i != agent_states.end(); ++i)    {        SoccerBase::GetTransformParent(*(*i), transform_parent);        // call GetAgentBody with matching AgentAspect        SoccerBase::GetAgentBody(transform_parent, agent_body);        // if agent is too close, move it away        Vector3f new_pos = agent_body->GetPosition();        if (sphere.Contains(new_pos))        {            float dist = salt::UniformRNG<>(min_dist, min_dist + 2.0)();            if (idx == TI_LEFT)            {                if (pos[0] - dist < -mFieldLength/2.0)                {                    new_pos[1] = pos[1] < 0 ? pos[1] + dist : pos[1] - dist;                } else {                    new_pos[0] = pos[0] - dist;                }            } else {                if (pos[0] + dist > mFieldLength/2.0)                {                    new_pos[1] = pos[1] < 0 ? pos[1] + dist : pos[1] - dist;                } else {                    new_pos[0] = pos[0] + dist;                }            }            new_pos[2] = 1.0;            MoveAgent(agent_body, new_pos);        }    }#endif}voidSoccerRuleAspect::ClearPlayers(const salt::AABB2& box,                               float min_dist, TTeamIndex idx){    if (idx == TI_NONE || mBallState.get() == 0) return;    std::list<boost::shared_ptr<AgentState> > agent_states;    if (! SoccerBase::GetAgentStates(*mBallState, agent_states, idx))        return;    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);        // if agent is too close, move it away        Vector3f new_pos = agent_aspect->GetWorldTransform().Pos();        if (box.Contains(Vector2f(new_pos[0], new_pos[1])))        {            if (idx == TI_LEFT)            {                new_pos[0] = box.minVec[0] -                    salt::UniformRNG<>(min_dist, min_dist + 2.0)();            } else {                new_pos[0] = box.maxVec[0] +                    salt::UniformRNG<>(min_dist, min_dist + 2.0)();            }            MoveAgent(agent_aspect, new_pos);        }    }#if 0    if (idx == TI_NONE || mBallState.get() == 0) return;    std::list<boost::shared_ptr<AgentState> > agent_states;    if (! SoccerBase::GetAgentStates(*mBallState, agent_states, idx))        return;    boost::shared_ptr<oxygen::Transform> transform_parent;    boost::shared_ptr<oxygen::Body> agent_body;    std::list<boost::shared_ptr<AgentState> >::const_iterator i;    for (i = agent_states.begin(); i != agent_states.end(); ++i)    {        SoccerBase::GetTransformParent(*(*i), transform_parent);        // call GetAgentBody with matching AgentAspect        SoccerBase::GetAgentBody(transform_parent, agent_body);        // if agent is too close, move it away        Vector3f new_pos = agent_body->GetPosition();        if (box.Contains(Vector2f(new_pos[0], new_pos[1])))        {            if (idx == TI_LEFT)            {                new_pos[0] = box.minVec[0] -                    salt::UniformRNG<>(min_dist, min_dist + 2.0)();            } else {                new_pos[0] = box.maxVec[0] +                    salt::UniformRNG<>(min_dist, min_dist + 2.0)();            }            new_pos[2] = 1.0;            MoveAgent(agent_body, new_pos);        }    }#endif}voidSoccerRuleAspect::DropBall(){    DropBall(mBallBody->GetPosition());}voidSoccerRuleAspect::DropBall(Vector3f pos){    salt::Vector2f ball_pos(pos.x(), pos.y());    // we do not drop the ball within the penalty area    if (mLeftPenaltyArea.Contains(ball_pos))    {        pos[0] = mLeftPenaltyArea.maxVec[0];        pos[1] = pos.y() < 0 ?            mLeftPenaltyArea.minVec[1] : mLeftPenaltyArea.maxVec[1];    }    else if (mRightPenaltyArea.Contains(ball_pos))    {        pos[0] = mRightPenaltyArea.minVec[0];        pos[1] = pos.y() < 0 ?            mRightPenaltyArea.minVec[1] : mRightPenaltyArea.maxVec[1];    }    MoveBall(pos);    ClearPlayers(pos, mFreeKickDist, mFreeKickMoveDist, TI_LEFT);    ClearPlayers(pos, mFreeKickDist, mFreeKickMoveDist, TI_RIGHT);    mGameState->SetPlayMode(PM_PlayOn);}voidSoccerRuleAspect::UpdateBeforeKickOff(){    // get game control server to check agent count    static shared_ptr<GameControlServer> game_control;    if  (game_control.get() == 0)    {        game_control = shared_dynamic_cast<GameControlServer>            (GetCore()->Get("/sys/server/gamecontrol"));        if (game_control.get() == 0)        {            GetLog()->Error() << "(SoccerRuleAspect) Error: can't get GameControlServer.\n";            return;        }    }    // if no players are connected, just return    if (! game_control->GetAgentCount()) return;    // before the game starts the ball should stay in the middle of    // the playing field    Vector3f pos(0,0,mBallRadius);    MoveBall(pos);    ClearPlayers(mRightHalf, 1.0, TI_LEFT);    ClearPlayers(mLeftHalf, 1.0, TI_RIGHT);#if 0    //    // TODO: this has to be tested (compiles and no crashes at least)    mInOffsideLeftPlayers.clear();    mInOffsideRightPlayers.clear();#endif    if (mAutomaticKickOff && mGameState->GetModeTime() > mWaitBeforeKickOff)    {        mGameState->KickOff();    }}voidSoccerRuleAspect::UpdateKickOff(TTeamIndex idx){    ClearPlayers(mRightHalf, 1.0, TI_LEFT);    ClearPlayers(mLeftHalf, 1.0, TI_RIGHT);    ClearPlayers(Vector3f(0,0,0), mFreeKickDist, mFreeKickMoveDist,                 SoccerBase::OpponentTeam(idx));    // if no player touched the ball for mDropBallTime, we move away    // all players and set the play mode to play on    if (mDropBallTime > 0 &&        mGameState->GetModeTime() > mDropBallTime)    {        // Drop the ball at its current position.        // This should always be (0,0) during kickoff.        DropBall(mBallBody->GetPosition());        return;    }    // after the first agent touches the ball move to PM_PLAYON    shared_ptr<AgentAspect> agent;    TTime time;    if (! mBallState->GetLastCollidingAgent(agent,time))    {        return;    }    if (time > mGameState->GetLastModeChange())    {        mGameState->SetPlayMode(PM_PlayOn);    }}voidSoccerRuleAspect::UpdateKickIn(TTeamIndex idx){#if 1    // do nothing for the duration of mKickInPauseTime    if (mGameState->GetModeTime() < mKickInPauseTime)    {        return;    }    // move away opponent team    ClearPlayers(mFreeKickPos, mFreeKickDist, mFreeKickMoveDist,                 SoccerBase::OpponentTeam(idx));    // if no player touched the ball for mDropBallTime, we move away    // all players and set the play mode to play on    if (mDropBallTime > 0 &&        mGameState->GetModeTime() > mDropBallTime)    {        DropBall(mFreeKickPos);        return;    }    // after the first agent touches the ball move to PM_PLAY_ON. the    // time when the agent last touches the ball must be after the    // change to the KickIn mode    shared_ptr<AgentAspect> agent;    TTime time;    if (! mBallState->GetLastCollidingAgent(agent,time))    {        GetLog()->Error() << "ERROR: (SoccerRuleAspect) " << "no agent collided yet\n";        return;    }    TTime lastChange = mGameState->GetLastModeChange();    if (time > lastChange)    {        mGameState->SetPlayMode(PM_PlayOn);        GetLog()->Error() << "ERROR: (SoccerRuleAspect) " << "Set Playmode to playon\n";    } else    {        // move the ball back on the ground where it left the playing        // field        MoveBall(mFreeKickPos);    }#endif}//-----------------------------------voidSoccerRuleAspect::UpdateFreeKick(TTeamIndex idx){#if 1    // do nothing for the duration of mKickInPauseTime    if (mGameState->GetModeTime() < mKickInPauseTime)    {        return;    }//---------------    salt::Vector2f ball_pos(mFreeKickPos.x(), mFreeKickPos.y());    // we do not drop the ball within the penalty area    if (mLeftPenaltyArea.Contains(ball_pos))    {        mFreeKickPos[0] = mLeftPenaltyArea.maxVec[0];        mFreeKickPos[1] = mFreeKickPos.y() < 0 ?            mLeftPenaltyArea.minVec[1] : mLeftPenaltyArea.maxVec[1];    }    else if (mRightPenaltyArea.Contains(ball_pos))    {        mFreeKickPos[0] = mRightPenaltyArea.minVec[0];        mFreeKickPos[1] = mFreeKickPos.y() < 0 ?            mRightPenaltyArea.minVec[1] : mRightPenaltyArea.maxVec[1];    }    MoveBall(mFreeKickPos);//--------------------------    // move away opponent team    ClearPlayers(mFreeKickPos, mFreeKickDist, mFreeKickMoveDist,                 SoccerBase::OpponentTeam(idx));    // if no player touched the ball for mDropBallTime, we move away    // all players and set the play mode to play on    if (mDropBallTime > 0 &&        mGameState->GetModeTime() > mDropBallTime)    {        DropBall(mFreeKickPos);        return;    }    // after the first agent touches the ball move to PM_PLAY_ON. the    // time when the agent last touches the ball must be after the    // change to the KickIn mode    shared_ptr<AgentAspect> agent;    TTime time;    if (! mBallState->GetLastCollidingAgent(agent,time))    {        GetLog()->Error() << "ERROR: (SoccerRuleAspect) " << "no agent collided yet\n";        return;    }    TTime lastChange = mGameState->GetLastModeChange();    if (time > lastChange)    {        mGameState->SetPlayMode(PM_PlayOn);        GetLog()->Error() << "ERROR: (SoccerRuleAspect) " << "Set Playmode to playon\n";    } else    {        // move the ball back on the ground where it left the playing        // field        MoveBall(mFreeKickPos);    }#endif}//-----------------------------------voidSoccerRuleAspect::UpdateGoalKick(TTeamIndex idx){

⌨️ 快捷键说明

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