其实是很久之前写的了,现在拿过来发布一下

Formation after score.

Principle

Formation files are saved in a separate folder with surfix .conf.
Its form is like below:

Formation Static
# move positions when playmode is BeforeKickOff or AfterGoal.
1 Goalie     -49.0   0.0
2 CenterBack -25.0  -7.0
3 CenterBack -25.0   7.0
4 SideBack   -25.0 -15.0
5 SideBack   -25.0  15.0
6 DefensiveHalf -20.0   0.0
7 OffensiveHalf -10.0 -7.0
8 OffensiveHalf -10.0  7.0
9  SideForward  -5.0 -10.0
10 SideForward -5.0  10.0
11 CenterForward -2.0   0.0

This is a static one,a dynamic one is like this:

Formation DelaunayTriangulation 2
Begin Roles
1 Goalie 0
2 CenterBack -1
3 CenterBack 2
4 SideBack -1
5 SideBack 4
6 DefensiveHalf 0
7 OffensiveHalf -1
8 OffensiveHalf 7
9 SideForward -1
10 SideForward 9
11 CenterForward 0
End Roles
Begin Samples 2 45
----- 0 -----
Ball 0 0
1 -50 0
2 -13.63 -5.6
3 -13.9 5.6
4 -13.09 -16.13
5 -13.01 14.51
6 -11.18 -0.36
7 -6.58 -8.2
8 -7.57 8.29
9 -1.26 -11.99
10 -1.8 12.17
11 11.72 0
----- 1 -----
Ball -54.44 -20.73
1 -50 0
2 -47.41 -10.72
3 -45.24 -5.14
4 -50.02 -17.21
5 -45.6 3.88
6 -39.73 -9.8
7 -40.83 -15.77
8 -31.82 3.85
9 -40.78 -29.47
10 -27.69 21.98
11 -14.9 -5.27

You can figure out exact coordinate through a location picture in the user-manual.

In the strategy.cpp ,formation files was first read like this:

const std::string Strategy::BEFORE_KICK_OFF_CONF = "before-kick-off.conf";
const std::string Strategy::NORMAL_FORMATION_CONF = "normal-formation.conf";

Then,a function named read() will check whether formation files is available:

bool
Strategy::read( const std::string & formation_dir )
{
    static bool s_initialized = false;

    if ( s_initialized )
    {
        std::cerr << __FILE__ << ' ' << __LINE__ << ": already initialized."
                  << std::endl;
        return false;
    }
    std::string configpath = formation_dir;
    if ( ! configpath.empty()
         && configpath[ configpath.length() - 1 ] != '/' )
    {
        configpath += '/';
    }

    // before kick off
    M_before_kick_off_formation = readFormation( configpath + BEFORE_KICK_OFF_CONF );
    if ( ! M_before_kick_off_formation )
    {
        std::cerr << "Failed to read before_kick_off formation" << std::endl;
        return false;
    }

    //...

    s_initialized = true;
    return true;

After that,getFormation() will determine which formation to apply according to the worldmode.Mainly the wm.gameMode().type() and wm.gameMode().side()

//
// opponent indirect free kick
//
if ( ( wm.gameMode().type() == GameMode::BackPass_
       && wm.gameMode().side() == wm.ourSide() )
     || ( wm.gameMode().type() == GameMode::IndFreeKick_
          && wm.gameMode().side() == wm.theirSide() ) )
{
    return M_indirect_freekick_opp_formation;
}

Operation

  1. add formation file celebrate-1-L.conf and celebrate-1-R.conf

    Formation Static
    # ---------------------------------------------------------
    # move positions when playmode is AfterGoal.
    1 Goalie     -50.0   0.0
    2 CenterBack -45.0  0.0
    3 CenterBack -40.0   0.0
    4 SideBack   -35.0  0.0
    5 SideBack   -30.0  0.0
    6 DefensiveHalf -25.0   0.0
    7 OffensiveHalf -20.0  0.0
    8 OffensiveHalf -15.0  0.0
    9  SideForward  -10.0  0.0
    10 SideForward -5.0  0.0
    11 CenterForward -1.0   0.0
    # ---------------------------------------------------------
  2. add formation object in strategy.cpp and strategy.h

    //celebrate formation
    static const std::string CELEBRATE_1_L_FORMATION_CONF;
    
    //celebrate formation
    rcsc::Formation::Ptr M_Celebrate_1_L_formation;
  3. add logistic judge in functions

    //in read()
        M_Celebrate_1_L_formation = readFormation( configpath + CELEBRATE_1_L_FORMATION_CONF);
        if ( ! M_indirect_freekick_our_formation )
        {
            std::cerr << "Failed to read celebrate-1-L-formation" << std::endl;
            return false;
        }
    //in getFormation()
        if (wm.gameMode().type() == GameMode::AfterGoal_ && wm.gameMode().side() == wm.ourSide())
        {
            if (wm.time().stopped() <= 20)
            {
                if (wm.ourSide() == LEFT)
                    return M_Celebrate_1_L_formation;
                else
                    return M_Celebrate_1_R_formation;
            }
            if (wm.time().stopped() <= 40)
            {
            }
        }

    You can change your formation at most twice according to rules.So a empty if is left.
    Notice: use wm.time().stopped() to make sure formation get normally in time