位置や座標などの関数についての詳しい補足


河原林研究室 >> マイクロロボットサッカー日本一への道 >> BasicPiayerとWarldDataについて >> 位置や座標などの関数についての詳しい補足

フィールド

  • コーナーフラグ
  • 味方側コーナーフラグ(左)
    vector_t
    WorldData ::  pv_mycorner_flag1()      //WorldDataクラスのpv_mycorner_flag1メンバ関数の定義
    {
        if (mAgentTeam == TEAM_BLUE){      //見方エージェントチームがTEAM_BLUEなら、
            return mrTopLeftCorner();      //メンバ関数mrTopLeftCornerの値を返す。
        }
        else
            return mrBottomRightCorner();  //それ以外ならメンバ関数mrBottomRightCorner()の値を返す。
    }                                      //ここで返ってくる値は距離と角度
  • 味方側コーナーフラグ(右)
    vector_t
    WorldData ::  pv_mycorner_flag2()      //WorldDataクラスのpv_mycorner_flag2メンバ関数の定義
    {
        if (mAgentTeam == TEAM_BLUE){      //見方エージェントチームがTEAM_BLUEなら、
            return mrBottomRleftCorner();  //メンバ関数mrTopleftCornerの値を返す。
        }
        else
            return mrToprightCorner();     //それ以外ならメンバ関数mrBottomrightCorner()の値を返す。
    }                                      //ここで返ってくる値は距離と角度
  • 敵側コーナーフラグ(左)
    vector_t
    WorldData ::  pv_opcorner_flag1()      //WorldDataクラスのpv_opcorner_flag1メンバ関数の定義
    {
        if (mAgentTeam == TEAM_BLUE){      //見方エージェントチームがTEAM_BLUEなら、
            return mrBottomRightCorner();  //メンバ関数mrBottomRightCornerの値を返す。
        }
        else
            return mrTopLeftCorner();      //それ以外ならメンバ関数mrTopLeftCorner()の値を返す。
    }                                      //ここで返ってくる値は距離と角度
  • 敵側コーナーフラグ(右)
    vector_t
    WorldData ::  pv_opcorner_flag2()      //WorldDataクラスのpv_opcorner_flag2メンバ関数の定義
    {
        if (mAgentTeam == TEAM_BLUE){      //見方エージェントチームがTEAM_BLUEなら、
            return mrTopRightCorner();     //メンバ関数mrTopRightCornerの値を返す。
        }
        else
            return mrBottomLeftCorner();  //それ以外ならメンバ関数 mrBottomLeftCorner()の値を返す。
    }                                     //ここで返ってくる値は距離と角度
    
  • ゴールポール
    • 味方側ゴールポール(左)
      vector_t
      WorldData ::  pv_mygoal_pole1()        //WorldDataクラスのpv_mygoal_pole1メンバ関数の定義
      {
          if (mAgentTeam == TEAM_BLUE){     //見方エージェントチームがTEAM_BLUEなら、
              return mrTopLeftPole();       //メンバ関数mrTopLeftPoleの値を返す。
          }
          else
              return mrBottomRightPole();   //それ以外ならメンバ関数mrBottomRightPoleの値を返す。
      }                                     //ここで返ってくる値は距離と角度
  • 味方側ゴールポール(右)
    vector_t
    WorldData ::  pv_mygoal_pole2()       //WorldDataクラスのpv_mygoal_pole2メンバ関数の定義
    {
        if (mAgentTeam == TEAM_BLUE){     //見方エージェントチームがTEAM_BLUEなら、
           return mrBottomLeftPole();     //メンバ関数mrBottomLeftPoleの値を返す。
        }
        else
            return mrTopRightPole();      //それ以外ならメンバ関数mrTopRightPoleの値を返す。
    }                                     //ここで返ってくる値は距離と角度
  • 敵側ゴールポール(左)
    vector_t
    WorldData ::  pv_opgoal_pole1()       //WorldDataクラスのpv_opgoal_pole1メンバ関数の定義
    {
        if (mAgentTeam == TEAM_BLUE){     //見方エージェントチームがTEAM_BLUEなら、
            return mrTopRightPole();      //メンバ関数mrTopRightPoleの値を返す。
        }
        else {
            return mrBottomLeftPole();    //それ以外ならメンバ関数mrBottomLeftPoleの値を返す。
        }
    }                                     //ここで返ってくる値は距離と角度
  • 敵側ゴールポール(右)
    vector_t
    WorldData ::  pv_opgoal_pole2()       //WorldDataクラスのpv_opgoal_pole2メンバ関数の定義
    {
        if (mAgentTeam == TEAM_BLUE){     //見方エージェントチームがTEAM_BLUEなら、
            return mrBottomRightPole();   //メンバ関数mrBottomRightPoleの値を返す。
        }
        else {
            return mrTopLeftPole();       //それ以外ならメンバ関数mrTopLeftPoleの値を返す。
        }
    }                                     //ここで返ってくる値は距離と角度

(すべてほぼ同じ形のプログラム)

ボールの位置

  • ボールの位置情報は距離と角度が得られる

    #ref(): File not found: "ボール位置情報.JPG" at page "位置や座標などの関数についての詳しい補足"

vector_t
WorldData :: pv_ball()                             //WorlsDataクラスのpv_ballメンバ関数の定義。
{
    vector_t auxBall;                              //vectorクラスのauxBall変数。
    auxBall.angle = mXmlWorldData.mBall.mAngle;    //上のうちのangleに、mXmlWorldData.mBall.mAngleの値を入れる。
    auxBall.length = mXmlWorldData.mBall.mDist;    //上のうちのlengthに、mXmlWorldData.mBall.mDistの値を入れる。
    return auxBall;                                //auxBallの値を入れる。
}                                                  //ここで返ってくる値は距離と角度。

エージェント情報

  • エージェントID
  • 自分のID
    int
    WorldData :: pv_my_id()                            //WorldDataのpv_my_idメンバ関数の定義。
    {
        return mXmlWorldData.mAgentID;                 //←の値を返す
    }
  • 一番近い味方のID
    int
    WorldData :: pv_closest_teammate_to(vector_t v)    //WorldDataのpv_closest_teammate_toメンバ関数の定義。
    {
        vector_t t;                                    //ベクタークラスのtメンバ変数(特殊な変数t)の宣言。(以下ベクターt宣言)
        double min = 9999999;
        int ret = -1, i;
        for (i = 0; i < mXmlWorldData.mMaxAgents/2 ; ++i)
        {                                             //mXmlWorldData.mMaxAgentsの数の半分だけ繰りかえす。
            t = pv_subtract(pv_teammate(i),v);         //tにpv_subtractにpv_teammate(i),vの値を入れた値を返す。
            if (t.length < min && pv_teammate_is_found(i))
            {                                          //もしベクターtのlengthよりもminとpv_teammate_is_found(i)が大きかったら、
                min = t.length;                        //minにベクターtのlengthを入れる。
                ret = i;                               //retにiを入れる。
            }
        }
        return ret;                                    //retの値を返す。
    }
  • 一番近い敵のID
    int
    WorldData :: pv_closest_opponent_to(vector_t v)
    {                                                  //WorldDataのpv_closest_opponent_toメンバ関数の定義。
        vector_t t;                                    //ベクターt宣言。
        double min = 9999999;
        int ret = -1, i;
        for (i = 0; i < mXmlWorldData.mMaxAgents/2; ++i)
        {                                              //mXmlWorldData.mMaxAgentsの値の半分だけ繰り返す。
            t = pv_subtract(pv_opponent(i),v);         //tにpv_subtract(pv_opponent(i),v)の値を入れる。
            if (t.length < min && pv_opponent_is_found(i))
            {                                          //もしtのlengthよりもminとpv_opponent_is_found(i)の値が大きかったら、
                min = t.length;                        //minにlengthの値を入れる。
                ret = i;                               //retにiの値を入れる。
            }
        }
        return ret;                                    //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を先に取得し、この関数に渡す必要がある。
    *ここで返ってくる値は距離と角度

座標系

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

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

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

フィールド座標

  • 上でも説明したように用意されている関数では以下の図のような値を得られる

    #ref(): File not found: "フィールド計算(取得データ).JPG" at page "位置や座標などの関数についての詳しい補足"

  • フィールド座標幅は以下のように計算した。
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);