フィールドと座標系


河原林研究室 >> EcoBe!世界一への道 >> フィールドと座標系

ここでは、「mr-soccer-server2008」に用意されている「soccer_client」の関数を使用したフィールドと座標系についての説明をする。

フィールド

用意されている関数

「soccer_client」に用意されている関数で得ることのできるフィールドでの関しての情報は以下のものがある。

*他にもあるかもしれないが、自分が実際に使用したものをここではあげる。

フィールドフラグ

  • それぞれのフラグは「soccer_client」内の「WorldData?」内に以下のフラグとプログラムが用意されている
  • それぞれの関数内で使用されている返り値は以下の図のような位置を表している。
    フィールド情報.JPG
  • コーナーフラグ
  • 味方側コーナーフラグ(左)
    vector_t
    WorldData ::  pv_mycorner_flag1()
    {
        if (mAgentTeam == TEAM_BLUE){
            return mrTopLeftCorner();
        }
        else
            return mrBottomRightCorner();
    }
    
    *ここで返ってくる値は距離と角度
  • 味方側コーナーフラグ(右)
    vector_t
    WorldData ::  pv_mycorner_flag2()
    {
        if (mAgentTeam == TEAM_BLUE){
            return mrBottomLeftCorner();
        }
        else
            return mrTopRightCorner();
    }
    
    *ここで返ってくる値は距離と角度
  • 敵側コーナーフラグ(左)
    vector_t
    WorldData ::  pv_opcorner_flag1()
    {
        if (mAgentTeam == TEAM_BLUE){
            return mrBottomRightCorner();
        }
        else
            return mrTopLeftCorner();
    }
    
    *ここで返ってくる値は距離と角度
  • 敵側コーナーフラグ(左)
    vector_t
    WorldData ::  pv_opcorner_flag2()
    {
        if (mAgentTeam == TEAM_BLUE){
            return mrTopRightCorner();
        }
        else
            return mrBottomLef*ここで返ってくる値は距離と角度tCorner();
    }
    
    *ここで返ってくる値は距離と角度
  • ゴールポール
    • 味方側ゴールポール(左)
      vector_t
      WorldData ::  pv_mygoal_pole1()
      {
          if (mAgentTeam == TEAM_BLUE){
              return mrTopLeftPole();
          }
          else
              return mrBottomRightPole();
      }
      
      *ここで返ってくる値は距離と角度
  • 味方側ゴールポール(右)
    vector_t
    WorldData ::  pv_mygoal_pole2()
    {
        if (mAgentTeam == TEAM_BLUE){
           return mrBottomLeftPole();
        }
        else
            return mrTopRightPole();
    }
    
    *ここで返ってくる値は距離と角度
  • 敵側ゴールポール(左)
    vector_t
    WorldData ::  pv_opgoal_pole1()
    {
        if (mAgentTeam == TEAM_BLUE){
            return mrTopRightPole();
        }
        else {
            return mrBottomLeftPole();
        }
    }
    
    *ここで返ってくる値は距離と角度
  • 敵側ゴールポール(右)
    vector_t
    WorldData ::  pv_opgoal_pole2()
    {
        if (mAgentTeam == TEAM_BLUE){
            return mrBottomRightPole();
        }
        else {
            return mrTopLeftPole();
        }
    }
    
    *ここで返ってくる値は距離と角度

ボールの位置

  • ボールの位置情報は次の図のように距離と角度が得られる
    ボール位置情報.JPG
vector_t
WorldData :: pv_ball()
{
    vector_t auxBall;
    auxBall.angle = mXmlWorldData.mBall.mAngle;
    auxBall.length = mXmlWorldData.mBall.mDist;
    return auxBall;
}

*ここで返ってくる値は距離と角度

エージェント情報

  • エージェントID
  • 自分のID
    int
    WorldData :: pv_my_id()
    {
        return mXmlWorldData.mAgentID;
    }
  • 一番近い味方のID
    int
    WorldData :: pv_closest_teammate_to(vector_t v)
    {
        vector_t t;
        double min = 9999999;
        int ret = -1, i;
        for (i = 0; i < mXmlWorldData.mMaxAgents/2 ; ++i)
        {
            t = pv_subtract(pv_teammate(i),v);
            if (t.length < min && pv_teammate_is_found(i))
            {
                min = t.length;
                ret = i;
            }
        }
        return ret;
    }
  • 一番近い敵のID
    int
    WorldData :: pv_closest_opponent_to(vector_t v)
    {
        vector_t t;
        double min = 9999999;
        int ret = -1, i;
        for (i = 0; i < mXmlWorldData.mMaxAgents/2; ++i)
        {
            t = pv_subtract(pv_opponent(i),v);
            if (t.length < min && pv_opponent_is_found(i))
            {
                min = t.length;
                ret = i;
            }
        }
        return ret;
    }
  • エージェントの位置
    • 味方の位置
      vector_t
      WorldData :: pv_teammate(int id)
      {
          return mXmlWorldData.getTeamMate(mXmlWorldData.getTeamMate(id)).position;
      }
      
      *これを使う場合、味方のIDを先に取得し、この関数に渡す必要がある。
      *ここで返ってくる値は距離と角度
  • 敵の位置
    vector_t
    WorldData :: pv_opponent(int id)
    {
        return mXmlWorldData.getOpponent(mXmlWorldData.getOpponent(id)).position;
    }
    *これを使う場合、敵のIDを先に取得し、この関数に渡す必要がある。
    *ここで返ってくる値は距離と角度

座標系

上で示した関数で得られる位置情報は距離と角度しか分からない。

よって絶対座標で表せるよう、上で示した関数を使って計算した。

ここではその計算プログラムソースを示す。

フィールド座標

  • 上でも説明したように用意されている関数では以下の図のような値を得られる
    フィールド計算(取得データ).JPG
  • フィールド座標幅は以下のように計算した。
vector_t mycorner1 = gWorldData.pv_mycorner_flag1();
vector_t mycorner2 = gWorldData.pv_mycorner_flag2();
  • X座標幅
p_flg1[0] = mycorner2.length * cos(mycorner2.angle * M_PI / 180.0);
p_flg1[1] = mycorner2.length * sin(mycorner2.angle * M_PI / 180.0);
p_flg2[0] = mycorner1.length * cos(mycorner1.angle * M_PI / 180.0);
p_flg2[1] = mycorner1.length * sin(mycorner1.angle * M_PI / 180.0);
p1 = (p_flg2[0] - p_flg1[0]) * (p_flg2[0] - p_flg1[0]);
p2 = (p_flg2[1] - p_flg1[1]) * (p_flg2[1] - p_flg1[1]);
x = sqrt(p1 + p2);
  • Y座標幅
p_flg1[0] = opcorner1.length * cos(opcorner1.angle * M_PI / 180.0);
p_flg1[1] = opcorner1.length * sin(opcorner1.angle * M_PI / 180.0);
p_flg2[0] = mycorner2.length * cos(mycorner2.angle * M_PI / 180.0);
p_flg2[1] = mycorner2.length * sin(mycorner2.angle * M_PI / 180.0);
p1 = (p_flg2[0] - p_flg1[0]) * (p_flg2[0] - p_flg1[0]);
p2 = (p_flg2[1] - p_flg1[1]) * (p_flg2[1] - p_flg1[1]);
y = sqrt(p1 + p2);

ゴール座標

  • 以下で味方ゴールポールしかあげてないのは自分が作成したプログラムがキーパーだったため使わなかったからである。
  • 敵ゴールポール座標を計算したい場合は、mycornerをopcorner、mygoalをopgoalに変えればよい。
  • まず以下の変数を定義する
    vector_t mycorner1 = gWorldData.pv_mycorner_flag1();
    vector_t mycorner2 = gWorldData.pv_mycorner_flag2();	 
    vector_t opcorner1 = gWorldData.pv_opcorner_flag1();
    vector_t opcorner2 = gWorldData.pv_opcorner_flag2();   
    vector_t mygoal1 = gWorldData.pv_mygoal_pole1();
    vector_t mygoal2 = gWorldData.pv_mygoal_pole2();
    vector_t opgoal1 = gWorldData.pv_opgoal_pole1();
    vector_t opgoal2 = gWorldData.pv_opgoal_pole2();
  • 定義した変数を用いて以下のように計算した
  • 味方ゴールポール(左)
    p_flg1[0] = mycorner2.length * cos(mycorner2.angle * M_PI / 180.0);
    p_flg1[1] = mycorner2.length * sin(mycorner2.angle * M_PI / 180.0);
    p_flg2[0] = mygoal2.length * cos(mygoal2.angle * M_PI / 180.0);
    p_flg2[1] = mygoal2.length * sin(mygoal2.angle * M_PI / 180.0);
    p1 = (p_flg2[0] - p_flg1[0]) * (p_flg2[0] - p_flg1[0]);
    p2 = (p_flg2[1] - p_flg1[1]) * (p_flg2[1] - p_flg1[1]);
    goal_xl = sqrt(p1 + p2);
  • 味方ゴールポール(右)
    p_flg1[0] = mycorner2.length * cos(mycorner2.angle * M_PI / 180.0);
    p_flg1[1] = mycorner2.length * sin(mycorner2.angle * M_PI / 180.0);
    p_flg2[0] = mygoal1.length * cos(mygoal1.angle * M_PI / 180.0);
    p_flg2[1] = mygoal1.length * sin(mygoal1.angle * M_PI / 180.0);
    p1 = (p_flg2[0] - p_flg1[0]) * (p_flg2[0] - p_flg1[0]);
    p2 = (p_flg2[1] - p_flg1[1]) * (p_flg2[1] - p_flg1[1]);
    goal_xr = sqrt(p1 + p2);