Robot Soccer Simulator
Симулятор футбола роботов
Руководство пользователя
2008
Содержание
1. Введение. 3
2. Установка и требования к ПК.. 3
2.1 Системные требования к ПК.. 3
2.2 Требования к разработке. 4
2.3 Руководство по установке. 4
3. Руководство пользователя. 5
3.1 Меню.. 6
3.1.1 Главное меню.. 6
3.1.2 Меню Strategies (Стратегии) 7
3.1.3 Меню Time/Score (Время/Счет) 8
3.1.4 Меню игры.. 8
3.1.5 Меню Replay (Повтор) 9
3.2 Начало игры.. 10
4. Руководство по программированию стратегий. 11
4.1 Описание роботов. 11
4.1.1 Команда Синих роботов. 11
4.1.2 Команда Желтых. 12
4.2 Стратегии. 12
4.2.1 Язык описания стратегий. 13
4.2.2 Пример стратегии. 13
4.2.3 Написание собственной стратегии. 21
4.2.4 Основы тригонометрии. 21
5. Регламент чемпионата. 23
5.1 Проведение игр. 23
5.2 Чемпионат. 23
5.3 Рейтинг. 24
6. Официальные правила лиги FIRA. 25
Приложение 1. 32
Приложение 2. 33
Приложение 3. 33
Приложение 4. 35
Приложение 5. 36
Приложение 6. 37
1. Введение
Футбол роботов, высокотехнологичный научный спорт, который был разработан профессором Jong-Hwan Kim из KAIST, (Корейский Технологический Институт) в октябре 1995. Высокий успех при испытании был достигнут за счет изучения и применения высоких технологий из разных областей науки, таких как, анализ изображений, искусственный интеллект, датчики, связь, электронное управление с ограничением по точности, моторы, а также хорошее программное обеспечение и оборудование. С тех пор и до сих пор постоянно растет количество молодых ученых и специалистов, которые в этом участвуют.
Первый международный чемпионат мира роботов футболистов был в KAIST в ноябре 1996, и второй раз была игра в июне 1997 года, там же.
Только после трех лет с рождения роботов-футболистов (5 июня 1997) сформировался и был утвержден союз международных роботов-футболистов из 34 стран (FIRA: Международная ассоциация роботов футболистов). После официальной инаугурации все международные матчи FIRA именовались "FIRA Robot World Cup”.
Энтузиазм к международному чемпионату мира FIRA нарастает каждый день, и теперь, когда футбол роботов произвел большое впечатление, это расширит и повысит уровень международных, научных соревнований.
Цель тренажера Robot Soccer Simulator™ смоделировать работу физических роботов Yujin.
Использование симулятора роботов-футболистов включает в себя разработку стратегий, которые могут использоваться на физических роботах Yujin в будущих соревнованиях чемпионата мира роботов FIRA. Любое другое применения, которое выходит из концепции этой программы - долгожданная премия команде проекта.
2. Установка и требования к ПК
2.1 Системные требования к ПК
Для работы Robot Soccer Simulator компьютер должен соответствовать следующим техническим требованиям:
· Pentium III 600 MHz
· 256 mb RAM
· TNT2 3d Graphics accelerator 32 mb RAM
· 24x CD-ROM
· Разрешение экрана 800 x 600 и больше.
· Direct X 8.0
· 10 мегабайт свободного места на жестком диске
2.2 Требования к разработке
Для написания собственных стратегий вам потребуется любая программная среда способная создавать Dynamic Link Library (DLL), рекомендуется использовать Visual C 6.0 или Borland C Builder 4.0 . Вместе с дистрибутивом устанавливаются проекты стратегий для следующих сред: VC6,. VC2005, BCB4, Delphi7 (c:\strategy\RobotSoccer\Strategy Clear Projects).
2.3 Руководство по установке
Для установки The Robot Soccer Simulator™ запустите самораспаковывающийся архив robosoccer.exe. Содержимое архива должно распаковаться в папку c:\strategy и автоматически должен запустится SoccerMngr, имеющий следующий интерфейс:

В нем нужно указать путь к установленному симулятору: c:\strategy\RobotSoccer\RobotSoccer. exe. И пути к вашим стратегиям, для начало можете указать путь к демо-стратегиям:
c:\strategy\RobotSoccer\Strategy Samples\bin\team1.dll и c:\strategy\RobotSoccer\Strategy Samples\bin\team2.dll
С помощью кнопки «Запустить RSS» можно запустить непосредственно сам симулятор футбола.
Руководство пользователя
При запуске программы Robot Soccer Simulator™ перед вами появится следующий экран:

Это область отображения, меню и информация игры.
Пользователь может выделять роботов и помешать в любую точку на области игрового поля, перед началом игры.
Справа от игрового поля находится меню игры. Пользователь может выбирать определенные пункты для открытия подменю. Также в списке меню отображается время игры и счет.
2.4 Меню
2.4.1 Главное меню
A) Strategies (Стратегии) – пользователь должен щелкнуть здесь, чтобы переместиться в меню и загрузить стратегии для каждой команды роботов. B) Фолы и кнопки выбора(Free Ball, Place Kick, Penalty, Free Kick, Goal Kick) предназначены для рефери. При нарушениях в игре, рефери объявляет фол одной из команд и дает право обладания мячом противоположной команде. C) Start (Старт) - начало игры. D) Time (Время) - текущее время игры. E) Score (Счет) - текущий счет. F) Time/Score (Время/Счет) – при нажатии на эту кнопку пользователь может изменить счет и время игры. G) New Game (Новая игра) - создает новую игру. H) Help – (Помощь) - при нажатии на эту кнопку появляется электронная версия руководства пользователя к игре. |
2.4.2 Меню Strategies (Стратегии)
| Предполагается, что стратегии пишутся в виде отдельных динамических библиотек (DLL), на любом языке (сам симулятор также поддерживает язык Lingo). Файлы со стратегиями помещаются, перед использованием, в каталог C:\strategy\. В поле ввода текста, указываются имена файлов со стратегиями, для Синей и Желтой команд. Стратегии синей команды помещаются в папку c:\strategy\blue\, а для желтой в c:\strategy\Yellow\. A) Нажав на слово LINGO можно выбрать между Lingo (для текстовых файлов) и С++(для DLL). B) Send (Послать) - Как только вы написали имена текстового файла или DLL, при нажатии на кнопку, стратегии загрузятся в игру. C) Open Viewer (Открывает окно просмотра) - позволяет вам видеть переменные и параметры игры. |
2.4.3 Меню Time/Score (Время/Счет)
Если время или счет должны быть изменены по какой-то причине, рефери может использовать это меню, чтобы внести изменения.
A) Time (Время) – рефери может отрегулировать время, он может добавить или вычесть время из игры, можно использовать мелкие интервалы (sec) и более крупные(min).
B) Score (Счет) – изменение счета. Если Рефери считает нужным, по какой-то причине, изменить счет, он должен просто напечатать новое число в поле Счет.
2.4.4 Меню игры

A) Replay (Повтор) – Воспроизводит повтор игры.
B) Pause (Пауза) – приостанавливает просмотр повтора игры.
C) Stop (Остановитесь) – Позволяет вам остановить игру и переводит вас в меню, чтобы принять дальнейшее решение.
2.4.5 Меню Replay (Повтор)
Панель управления воспроизведением, (расположенная на правой части экрана) дает пользователю право выбрать, с какого ракурса рассмотреть повторное воспроизведение
игры.
A) Этот режим показывает перемещение шара по игровому полю и небольшую область вокруг него.
B) Этот режим показывает все игровое поле сверху, воспроизводит игру в обычном ракурсе, так как проходит игра по умолчанию.
C) Этот режим показывает ворота синей команды сверху.
D) Этот режим показывает ворота желтой команды сверху.
E) Этот режим показывает поле параллельно синим воротам.
F) Этот режим показывает поле параллельно желтым воротам.
G. и H. – Оба режима показывают различные виды сбоку, один с синими воротами слева и желтыми справа и другим с синими воротами справа и желтыми слева.
![]()
A) Перематывает воспроизведение в начало игры.
B) Перематывает последние 300 кадров.
C) Norm - Воспроизводит игру на нормальной скорости.
D) Slow - Воспроизводит игру в замедленном движении.
E) Stop Frame - Этот пункт меню позволяет вам сделать стоп кадр. И используя кнопки вперед и назад проследить игру по шагам. Также можно использовать клавиши вперед и назад на клавиатуре. Благодаря этой возможности вы можете воспроизвести игру в режиме замедленного движения и рассмотреть все детали.
F) Exit replay - Выход из режима воспроизведения.
G) No Goal - Выходит из меню воспроизведения и аннулирует гол(если гола не было и воспроизведение было в течении игры, то вы просто выйдите из режима воспроизведения).
2.5 Начало игры
Начать игру весьма просто и это можно сделать по следующим шагами.
1. Начать игру можно запустив c:\strategy\SoccerMngr.exe и нажав в открывшемся окне кнопку “Запуск RSS”.
2. Как только игра загрузилась, нажмите на кнопку “Фокус”, а потом “C++/Lingo”. Убедитесь, что в окне симулятор сменился тип стратегии с Lingo на C++.
3. В окне Soccer Manager укажите в настройках пути к стратегиям для каждой команды в поле ввода и нажмите кнопку “Обновить”.
4. В меню выберите Place Kick и кликните готово. Эта команда укажет игрокам, с какого места начнется игра.
5. Затем в списке выберите команду, которая будет владеть мячом и нажмите готово.
6. Теперь каждая команда расставляет своих игроков на поле согласно правилам Place Kick. То есть, команда нападения может расположить своих игроков в любом месте, в своей части поля и в пределах центра круга, а команда защиты может расположить своих игроков только в своей части поля исключая центр круга. Мяч располагается в центре круга.
7. Чтобы переместить робота, достаточно просто на нем нажать левой кнопкой мыши и, не отпуская ее, переместить робота в нужное место на поле. Также можно вращать роботов, для этого необходимо использовать клавиши курсора (влево и вправо).
8. Как только все роботы находятся на месте, просто нажмите Start, и игра начнется.
В течении игры вы можете использовать меню чтобы принять определенное решение. Можете заново воспроизвести игру, для этого необходимо нажать кнопку Replay, можете остановить игру из-за штрафов, изменить счет или время игры и др. для этого необходимо нажать кнопку Stop и появится меню с вариантами дальнейших решений. Если вы хотите сделать в игре, по какой-либо причине паузу, необходимо нажать на кнопке Pause.
3. Руководство по программированию стратегий
3.1 Описание роботов
На игровом поле размещено 2 команды (синие и желтые), в каждой команде 5 робот по умолчанию: 1 робот – вратарь, 2 защитника и 2 нападающих. Каждый робот имеет два колеса с моторчиками, и все управления сводится к изменению ускорения на этих моторчиках от -125% до 125% (при отрицательном значение ускорения, колесо крутится в противоположную сторону).
3.1.1 Команда Синих роботов.

Это робот – вратарь, его положение возле ворот.
По умолчанию, это робот-защитник, однако, это положение может быть изменено.

По умолчанию, это робот-защитник, однако, это положение может быть изменено.

По умолчанию, это робот-нападающий, однако, это положение может быть изменено.

По умолчанию, это робот-нападающий, однако, это положение может быть изменено.
3.1.2 Команда Желтых

Это робот - вратарь, его положение возле ворот.

По умолчанию, это робот-защитник, однако, это положение может быть изменено.

По умолчанию, это робот-защитник, однако, это положение может быть изменено.

По умолчанию, это робот-нападающий, однако, это положение может быть изменено.
По умолчанию, это робот-нападающий, однако, это положение может быть изменено.
3.2 Стратегии
3.2.1 Язык описания стратегий
Библиотека со стратегией должна содержать минимум 3 функции:
· STRATEGY_API void Create ( Environment *env ); – вызывается при загрузке пользовательской стратегии и может использоваться для инициализации параметров и выделение пользовательской структуры данных.
· STRATEGY_API void Destroy ( Environment *env ); – вызывается при закрытии стратегии и должна использоваться для освобождения памяти выделенной в функции Create.
· STRATEGY_API void Strategy ( Environment *env ); – главная функция, вызывается примерно 60 раз в секунду, с помощью нее осуществляется управление колесами роботов.
Структура Environment содержит:
Robot home[PLAYERS_PER_SIDE]; – массив структур Robot описывающих координаты и ускорения роботов игрока (см. ниже);
OpponentRobot opponent[PLAYERS_PER_SIDE]; – массив структур OpponentRobot описывающих координаты роботов противника (см. ниже)
Ball currentBall, lastBall, predictedBall; – координаты текущего/предыдущего/прогнозируемого положения мяча (predictedBall – нужно вычислять самостоятельно);
Bounds fieldBounds, goalBounds; – координаты прямоугольников описывающие поле и ворота.
long gameState; – указывает текущий типа игры (FREE_BALL, PLACE_KICK…);
long whosBall; – указывает, кому принадлежит мяч в начале игры;
void *userData; – пользовательский указатель может использоваться для хранения каких-либо данных.
Структура Robot/ OpponentRobot содержит:
Vector3D pos; – вектор координат робота;
double rotation; – угол поворота от -180 до +180;
double velocityLeft, velocityRight;(только у структуры Robot) – ускорение левого и правого колеса робота от -125 до +125.
Кроме этого определен ряд констант в дюймах:
FTOP, FBOT – верхняя и нижняя граница поля;.
FRIGHTX, FLEFTX - правая и левая граница поля;
GTOPY, GBOTY - верхняя и нижняя граница ворот;
GRIGHT, GLEFT - правая и левая граница ворот.
3.2.2 Пример стратегии
// Strategy. cpp : Defines the entry point for the DLL application.
//
#include "stdafx. h"
#include "Strategy. h"
#include <math. h>
//Стандартная точка входа в DLL (не изменять)
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
char myMessage[200]; //
void PredictBall ( Environment *env );
void Goalie1 ( Robot *robot, Environment *env );
void NearBound2 ( Robot *robot, double vl, double vr, Environment *env );
void Attack2 ( Robot *robot, Environment *env );
void Defend ( Robot *robot, Environment *env, double low, double high );
//
void MoonAttack (Robot *robot, Environment *env );
// just for testing to check whether the &env->opponent works or not
void MoonFollowOpponent ( Robot *robot, OpponentRobot *opponent );
void Velocity ( Robot *robot, int vl, int vr );
void Angle ( Robot *robot, int desired_angle);
void Position( Robot *robot, double x, double y );
extern "C" STRATEGY_API void Create ( Environment *env )
{
// Здесь можно выделить память под пользовательские данные.
// например env->userData = ( void * ) new MyVariables ();
}
extern "C" STRATEGY_API void Destroy ( Environment *env )
{
// Здесь освобождаем выделенные данные
// например
// if ( env->userData != NULL ) delete ( MyVariables * ) env->userData;
}
extern "C" STRATEGY_API void Strategy ( Environment *env )
{
int testInt = 100;
int k;
switch (env->gameState) // определяем что делать в зависимости от типа игры
{
case 0:
// default
// преследуем противника
MoonFollowOpponent ( &env->home [1], &env->opponent [2] );
MoonFollowOpponent ( &env->home [2], &env->opponent [3] );
MoonFollowOpponent ( &env->home [3], &env->opponent [4] );
MoonAttack ( &env->home [4], env );
Goalie1 ( &env->home [0], env );
break;
case FREE_BALL:
// 3 робота преследуют противника
MoonFollowOpponent ( &env->home [1], &env->opponent [2] );
MoonFollowOpponent ( &env->home [2], &env->opponent [3] );
MoonFollowOpponent ( &env->home [3], &env->opponent [4] );
// 1 аттакует
MoonAttack ( &env->home [4], env );
// вратарь
Goalie1 ( &env->home [0], env );
//
// код ниже работать не будет... даже не пытайтесь....
// изменять можно только ускорение колес
// env->home[0].pos. x = 50;
// env->home[0].pos. y = 0;
// env->home[0].rotation = 20.0;
//
break;
case PLACE_KICK:
MoonAttack ( &env->home [2], env );
break;
case PENALTY_KICK:
switch (env->whosBall)
{
case ANYONES_BALL:
MoonAttack ( &env->home [1], env );
break;
case BLUE_BALL:
MoonAttack ( &env->home [4], env );
break;
case YELLOW_BALL:
MoonAttack ( &env->home [0], env );
break;
}
break;
case FREE_KICK:
FILE * debugfile;
debugfile = fopen("debugfile. txt","a");
for (k=0;k<=4;k++)
fprintf(debugfile, "robot: %d x: %f y: %f z: %f \n",
k, env->opponent[k].pos. x, env->opponent[k].pos. y,
env->opponent[k].pos. z);
fclose(debugfile);
MoonAttack ( &env->home [0], env );
break;
case GOAL_KICK:
MoonAttack ( &env->home [0], env );
break;
}
}
void MoonAttack ( Robot *robot, Environment *env )
{
PredictBall ( env ); // вычисляем где окажется мяч в следующий момент
// вызываем функцию позицирования робота в позиции предполагаемую позицию меча
Position(robot, env->predictedBall. pos. x, env->predictedBall. pos. y);
}
void MoonFollowOpponent ( Robot *robot, OpponentRobot *opponent )
{
// направляем робота в позицию противника
Position(robot, opponent->pos. x, opponent->pos. y);
}
//функции установки ускорения вращения колес
void Velocity ( Robot *robot, int vl, int vr )
{
robot->velocityLeft = vl;
robot->velocityRight = vr;
}
// расчет и установка ускорения колес по заданному углу
void Angle ( Robot *robot, int desired_angle)
{
int theta_e, vl, vr;
theta_e = desired_angle - (int)robot->rotation;
while (theta_e > 180) theta_e -= 360;
while (theta_e < -180) theta_e += 360;
if (theta_e < -90) theta_e += 180;
else if (theta_e > 90) theta_e -= 180;
// проверяем угол, в зависимости от величины выбираем разное ускорение, так как роботы обладают инерцией и при большой ускорении могут «перекрутиться» на больший угол чем нужен
if (abs(theta_e) > 50)
{
vl = (int)(-9./90.0 * (double) theta_e);
vr = (int)(9./90.0 * (double)theta_e);
}
else if (abs(theta_e) > 20)
{
vl = (int)(-11.0/90.0 * (double)theta_e);
vr = (int)(11.0/90.0 * (double)theta_e);
}
Velocity (robot, vl, vr);
}
//расчет и установка ускорения для перемещения робота в заданную позицию
void Position( Robot *robot, double x, double y )
{
int desired_angle = 0, theta_e = 0, d_angle = 0, vl, vr, vc = 70;
double dx, dy, d_e, Ka = 10.0/90.0;
dx = x - robot->pos. x;
dy = y - robot->pos. y;
d_e = sqrt(dx * dx + dy * dy);
if (dx == 0 && dy == 0)
desired_angle = 90;
else
desired_angle = (int)(180. / PI * atan2((double)(dy), (double)(dx)));
theta_e = desired_angle - (int)robot->rotation;
while (theta_e > 180) theta_e -= 360;
while (theta_e < -180) theta_e += 360;
// взависимости от разницы в углах определяем коэффициент ускорения
if (d_e > 100.)
Ka = 17. / 90.;
else if (d_e > 50)
Ka = 19. / 90.;
else if (d_e > 30)
Ka = 21. / 90.;
else if (d_e > 20)
Ka = 23. / 90.;
else
Ka = 25. / 90.;
if (theta_e > 95 || theta_e < -95)
{
theta_e += 180;
if (theta_e > 180)
theta_e -= 360;
if (theta_e > 80)
theta_e = 80;
if (theta_e < -80)
theta_e = -80;
if (d_e < 5.0 && abs(theta_e) < 40)
Ka = 0.1;
vr = (int)(-vc * (1.0 / (1.0 + exp(-3.0 * d_e)+ Ka * theta_e);
vl = (int)(-vc * (1.0 / (1.0 + exp(-3.0 * d_e)Ka * theta_e);
}
else if (theta_e < 85 && theta_e > -85)
{
if (d_e < 5.0 && abs(theta_e) < 40)
Ka = 0.1;
vr = (int)( vc * (1.0 / (1.0 + exp(-3.0 * d_e)+ Ka * theta_e);
vl = (int)( vc * (1.0 / (1.0 + exp(-3.0 * d_e)Ka * theta_e);
}
else
{
vr = (int)(+.17 * theta_e);
vl = (int)(-.17 * theta_e);
}
Velocity(robot, vl, vr);
}
//вычисляем предполагаемые координаты следующего положения меча
void PredictBall ( Environment *env )
{
double dx = env->currentBall. pos. x - env->lastBall. pos. x;
double dy = env->currentBall. pos. y - env->lastBall. pos. y;
env->predictedBall. pos. x = env->currentBall. pos. x + dx;
env->predictedBall. pos. y = env->currentBall. pos. y + dy;
}
//управление вратарем исходя из положения мяча
void Goalie1 ( Robot *robot, Environment *env )
{
double velocityLeft = 0, velocityRight = 0;
double Tx = env->goalBounds. right - env->currentBall. pos. x;
double Ty = env->fieldBounds. top - env->currentBall. pos. y;
double Ax = env->goalBounds. right - robot->pos. x;
double Ay = env->fieldBounds. top - robot->pos. y;
//двигаемся либо вниз либо вверх (скорость левого колеса – скорости правого)
if ( Ay > Ty + 0.9 && Ay > 27 )
{
velocityLeft = -100;
velocityRight = -100;
}
if ( Ay > Ty - 0.9 && Ay < 43 )
{
velocityLeft = 100;
velocityRight = 100;
}
if ( Ay < 27 )
{
velocityLeft = 100;
velocityRight = 100;
}
if ( Ay > 43 )
{
velocityLeft = -100;
velocityRight = -100;
}
//корректировка положения если робота кто-то развернул
double Tr = robot->rotation;
if ( Tr < 0.001 )
Tr = Tr + 360;
if ( Tr > 360.001 )
Tr = Tr - 360;
if ( Tr > 270.5 )
velocityRight = velocityRight + fabs ( Tr - 270 );
else if ( Tr < 269.5 )
velocityLeft = velocityLeft + fabs ( Tr - 270 );
robot->velocityLeft = velocityLeft;
robot->velocityRight = velocityRight;
}
// другой тип атаки
void Attack2 ( Robot *robot, Environment *env )
{
Vector3D t = env->currentBall. pos;
double r = robot->rotation;
if ( r < 0 ) r += 360;
if ( r > 360 ) r -= 360;
double vl = 0, vr = 0;
if ( t. y > env->fieldBounds. top - 2.5 ) t. y = env->fieldBounds. top - 2.5;
if ( t. y < env->fieldBounds. bottom + 2.5 ) t. y = env->fieldBounds. bottom + 2.5;
if ( t. x > env->fieldBounds. right - 3 ) t. x = env->fieldBounds. right - 3;
if ( t. x < env->fieldBounds. left + 3 ) t. x = env->fieldBounds. left + 3;
double dx = robot->pos. x - t. x;
double dy = robot->pos. y - t. y;
double dxAdjusted = dx;
double angleToPoint = 0;
if ( fabs ( robot->pos. y - t. y ) > 7 || t. x > robot->pos. x )
dxAdjusted -= 5;
if ( dxAdjusted == 0 )
{
if ( dy > 0 )
angleToPoint = 270;
else
angleToPoint = 90;
}
else if ( dy == 0 )
{
if ( dxAdjusted > 0 )
angleToPoint = 360;
else
angleToPoint = 180;
}
else
angleToPoint = atan ( fabs ( dy / dx ) ) * 180.0 / PI;
if ( dxAdjusted > 0 )
{
if ( dy > 0 )
angleToPoint -= 180;
else if ( dy < 0 )
angleToPoint = 180 - angleToPoint;
}
if ( dxAdjusted < 0 )
{
if ( dy > 0 )
angleToPoint = - angleToPoint;
else if ( dy < 0 )
angleToPoint = 90 - angleToPoint;
}
if ( angleToPoint < 0 ) angleToPoint = angleToPoint + 360;
if ( angleToPoint > 360 ) angleToPoint = angleToPoint - 360;
if ( angleToPoint > 360 ) angleToPoint = angleToPoint - 360;
double c = r;
double angleDiff = fabs ( r - angleToPoint );
if ( angleDiff < 40 )
{
vl = 100;
vr = 100;
if ( c > angleToPoint )
vl -= 10;
if ( c < angleToPoint )
vr -= 10;
}
else
{
if ( r > angleToPoint )
{
if ( angleDiff > 180 )
vl += 360 - angleDiff;
else
vr += angleDiff;
}
if ( r < angleToPoint )
{
if ( angleDiff > 180 )
vr += 360 - angleDiff;
else
vl += angleDiff;
}
}
NearBound2 ( robot, vl, vr, env );
}
void NearBound2 ( Robot *robot, double vl, double vr, Environment *env )
{
//Vector3D t = env->currentBall. pos;
Vector3D a = robot->pos;
double r = robot->rotation;
if ( a. y > env->fieldBounds. top - 15 && r > 45 && r < 130 )
{
if ( vl > 0 )
vl /= 3;
if ( vr > 0 )
vr /= 3;
}
if ( a. y < env->fieldBounds. bottom + 15 && r < -45 && r > -130 )
{
if ( vl > 0 ) vl /= 3;
if ( vr > 0 ) vr /= 3;
}
if ( a. x > env->fieldBounds. right - 10 )
{
if ( vl > 0 )
vl /= 2;
if ( vr > 0 )
vr /= 2;
}
if ( a. x < env->fieldBounds. left + 10 )
{
if ( vl > 0 )
vl /= 2;
if ( vr > 0 )
vr /= 2;
}
robot->velocityLeft = vl;
robot->velocityRight = vr;
}
//защита
void Defend ( Robot *robot, Environment *env, double low, double high )
{
double vl = 0, vr = 0;
Vector3D z = env->currentBall. pos;
double Tx = env->goalBounds. right - z. x;
double Ty = env->fieldBounds. top - z. y;
Vector3D a = robot->pos;
a. x = env->goalBounds. right - a. x;
a. y = env->fieldBounds. top - a. y;
if ( a. y > Ty + 0.9 && a. y > low )
{
vl = -100;
vr = -100;
}
if ( a. y < Ty - 0.9 && a. y < high )
{
vl = 100;
vr = 100;
}
if ( a. y < low )
{
vl = 100;
vr = 100;
}
if ( a. y > high )
{
vl = -100;
vr = -100;
}
double Tr = robot->rotation;
if ( Tr < 0.001 )
Tr += 360;
if ( Tr > 360.001 )
Tr -= 360;
if ( Tr > 270.5 )
vr += fabs ( Tr - 270 );
else if ( Tr < 269.5 )
vl += fabs ( Tr - 270 );
NearBound2 ( robot, vl, vr, env );
}
3.2.3 Написание собственной стратегии
За основу любой стратегии рекомендуется взять проект из директории c:\strategy\RobotSoccer\Strategy Clear Projects соответствующий вашей среде разработки и скопировать в другую свою папку. Скомпилированные стратегии тестируются с помощью программы Soccer Manager. Для этого в нем нужно указать путь к DLL файлу стратегии (для двух команд можно использовать один и тот же файл DLL) и нажать кнопку «Обновить». Если вы что-то изменили в исходном коде своей стратегии и хотите скомпилировать заново, то перед этим нужно нажать кнопку «Выгрузить», этим вы освободите DLL из контекста процесса симулятора, иначе компилятор выдаст ошибку вида «не возможно записать файл team1.dll, возможно он занят другим процессом».
3.2.4 Основы тригонометрии
Для написания стратегий необходимо обладать некоторыми базовыми понятиями, связанными с геометрией плоскости и тригонометрией.
Игровое поле представляет собой плоскость. Начало координат лежит в левом верхнем углу поля.
Одним из самых важных значений в игре является угол от робота до произвольной точки поля. Это связанно с перемещением робота к мячу. Важно отметить, что углы поворотов роботов в игре измеряются в градусах в пределах от 0 до 180 в первой и второй координатной четверти и от 0 до -180 в третьей и четвертой четверти. Так как известны значения длины перпендикуляра к линии текущего угла поворота робота от желаемой точки и длина до этого перпендикуляра от текущего положения робота, то можно определить тангенс необходимого угла поворота через отношения этих длин (рис. 1).


Рис. 1 – Определение угла до точки
Таким образом, тангенс угла будет определяться следующим выражением:
.
Соответственно для определения угла нужно взять арктангенс от правой части. При этом учитываем, что полученное значение будет измеряться в радианах, поэтому переведем его в градусы:
.
После того как определили угол в треугольнике, необходимо определить угол в игровой системе измерений угла. Следовательно, для первой четверти угол будет таким же a1 = a, для второй a1 = 180 – a, для третьей a1 = -180 + a, для четвертой a1 = 0 – a. Указанные преобразования можно увидеть в тестовой стратегии (функция getangletopoint).
Так же может возникнуть потребность в определении расстояний от одной точки до другой. Пусть точка требуется определить расстояние от точки A(x1, y1) до точки B(x2, y2), оно будет равно:

Если необходимо определить расстояние от точки A(x, y) до прямой, заданной точками P1(x1, y1) и P2(x2, y2), то оно будет равно:

4. Регламент чемпионата
4.1 Проведение игр
Для проведения игр используется предложенный эмулятор кибер-футбола. Соответственно, стратегии должны быть представлены в виде динамически-связываемых библиотек. За каждый игрой наблюдает судья, который фиксирует результаты игр.
В каждой игре предусмотрено две партии, в каждой из которой стратегия используется за разные стороны на игровом поле. Если в процессе игры разница в счете достигла 3 очков, то игра останавливается. Если такой ситуации не возникло, то по истечению двух минут игра останавливается для определения победителя по очкам. Если количество очков одинаково, то проводится серия пенальти для каждой из сторон. В этом случае в игре участвуют только игроки одной команды и вратарь другой. После окончания серии пенальти определяется победитель по большему количеству забитых голов.
В игре могут возникать ситуации, когда игроки блокируют мяч и перемещение мяча прекращается. В таких ситуациях судья вправе в начале игры расставить роботов в отличном от стандартного положении, при этом соблюдая симметрию для каждой команды роботов.
При проведении каждой игра ведется запись. Записи проведенных игр доступны для скачивания на информационном сайте кибер-футбола.
4.2 Чемпионат
Чемпионат позволяет определить лучшую стратегию среди всех участников. В зависимости от схемы проведения турнира можно также определить второе и третье место в чемпионате. Схема проведения чемпионата определяется количеством зарегистрированных участников. В зависимости от этого количества может быть две схемы.
При количестве участников меньше 5 используется схема «каждый с каждым». В этом случае каждая стратегия проигрывается со всеми остальными, при этом за каждую победу начисляется очко. В результате всех игр определяется тройка победителей.
При большем количестве участников используется схема с двойной сеткой. Турнир разделён на две сетки — верхнюю и нижнюю (сетку победителей и сетку проигравших). Все участники начинают турнир в верхней сетке. Участники разбиваются на пары, которые проводят в первом туре игры между собой. Порядок отбора пар может быть либо случайным (по жребию), либо по рейтингам (в этом случае обычно пары составляются по принципу «сильный против слабого», чтобы слабейшие участники отсеялись в первых турах, а сильнейшие играли между собой в конце турнира). При наличии «пустых» участников и отборе по рейтингам технические победы присуждаются наиболее сильным участникам. В результате каждого этапа игр в верхней сетке, стратегии могут перемещаться в двух направлениях: если стратегии выиграла, то она перемещается в следующую ячейку верхней сетки; если стратегия проиграла, то она переходит в нижнюю сетку на соответствующий верхней уровень. Далее проводится этап игр в нижней сетке. Здесь, при выигрыше стратегия двигается вверх по нижней сетке, при проигрыше, стратегия покидает соревнования. В результате, когда проведены все игры в обеих сетках, проводится финал чемпионата. В финале встречаются победители обеих сеток. Для окончательной победы участнику верхней сетки необходимо победить один раз, а участнику нижней два раза. Соответственно, второе место будет у проигравшего в финале. Третье место определяется дополнительной игрой между полуфиналистами обеих сеток.
4.3 Рейтинг
Кроме чемпионата предусмотрен постоянный рейтинг стратегий. Рейтинг представляет собой список, где стратегии идут друг за другом, согласно количеству набранных очков. Пользователь может выбрать любую стратегию из списка для проведения игры, но очки получить может только за игры со стратегиями, близкими к его стратегии по рейтингу.
Выбирать стратегии противника, высылать свои стратегии, следить за состоянием рейтинга стратегий можно на информационном сайте кибер-футбола.
5. Официальные правила лиги FIRA.
Закон 1: Поле и мяч
a) Измерения игровой площадки
Черная, деревянная прямоугольная игровая площадка имеет размер 220см на 180см, также 5см в вышину и 2,5см толщину стен. В углах прямоугольной площадки установлены равнобедренные треугольники 7см на 7см, для того чтобы мяч не был загнан в угол.
b) Маркировки на игровой площадке (Приложение 1)
Игровое поле, должно быть, размечено, как показано в Приложении 1. Круг центра будет иметь радиус 25см.
Дуга, которая является частью штрафной области, будет 25см по линии ворот и 5см перпендикулярно к ней.
Главные линии/дуги (средняя линия, границы области ворот и центральный круг) будут белыми, а линии 3мм толщиной. Положение мяча и позиции робота должны быть отмечены серым цветом.
c) Игровые ворота
Игровые ворота должны быть 40см шириной. Посты и сети не должны обеспечиваться в цели.
d) Линия ворот и вратарская площадка
Линия ворот – линия между стойками ворот, имеет длину 40см.
Вратарская площадка (область обозначены буквой А в Приложение 1) должна включать область, содержащую прямоугольник (50см X 15см перед воротами).
e) Штрафная область
Штрафная область (область обозначена буквой B в Приложение 1) должна включать области, прямоугольник (измеренный 80см X 35см перед воротами) и приложенной дугой (25см параллельно к линии ворот и 5см перпендикуляр к ней).
f) Мяч
Оранжевый мяч для гольфа, с диаметром 42,7 мм и весом 46гр, следует использовать в качестве мяча.
g) Местоположение
Поле должно быть в закрытом помещении.
h) Условие освещения
Освещение на участке соревнований должно быть установлено приблизительно 1 000 люксов.
Закон 2: Игроки
a) Полная система
Матч проводится между двумя командами, каждая должна состоять из пяти роботов. Один из роботов может быть вратарем (Закон 2.(b).2). Также допускаются три “человеческих” члена команды, "менеджер", "инструктор" и "тренер".
b) Роботы
1) Размер каждого робота должен быть 7.5см X 7.5см X 7.5см. Высоту антенны не будут учитывать в рассмотрении размера робота.
I. Верхняя часть робота не должна быть окрашена в оранжевый цвет. На каждом роботе, для его идентификации в команде, должен быть цветной участок либо синего, либо желтого цвета, как назначено организаторами. Все роботы должны иметь (по крайней мере) 3,5см X 3,5 см участок цвета команды, синего или желтого, видимого на их вершине. Цвет идентификации команды может меняться во время игры, для этого используемый цветной участок должен быть съемным. Когда каждому игроку назначен один из двух цветов (желтый или синий), роботы не должны иметь никаких видимых участков тех цветов, которые используются командой противника.
Отметьте: командам рекомендуют подготовить минимум 10 различных цветных участков, кроме синего и желтого, для индивидуальной идентификации робота
II. To enable infrared sensing a robot's sides should be colored light, except at regions necessarily used for robot functionality, such as those for sensors, wheels and the ball catching mechanism. The robots should wear uniforms and the size of which shall be limited to 8cm X 8cm X 8cm.
Позволять инфракрасное ощущение сторон робота должно быть покрашено светом, кроме в областях{регионах}, обязательно используемых для функциональных возможностей робота, типа тех для датчиков, колес и шара{мяча}, ловя механизм. Роботы должны носить униформы и размер которого должен быть ограничен 8cm X 8cm X 8cm.
2) Робот, в пределах собственной области ворот (Закон 1.d.) рассматривается как "вратарь". Роботу-вратарю, позволяется ловить или удерживать мяч только в его собственной области ворот или штрафной области.
3) Каждый робот должен быть полностью независимым, со своим отдельным электромотором. Только при помощи радиосвязи происходит взаимосвязь между главным компьютером и роботом.
4) Роботов допускается оснащать руками, ногами, и т. д., но они должны быть ограничены по размеру (закон 2.b.1), даже после того как все конечности раскрыты. Ни одному из роботов, кроме вратаря, не будет засчитываться, что мяч пойман, если больше чем 30% мяча находится вне поля соприкосновения с роботом, от вершины или от сторон (Приложение 2).
5) В то время как проходит матч, при любом свистке рефери, оператор должен остановить всех роботов, используя коммуникацию между роботами и главным компьютером.
c) Замена игроков
Во время игры разрешается сделать две замены игроков. В перерыве между двумя матчами можно сделать неограниченное количество замен. Когда необходима замена во время игры, заинтересованный менеджер команды должен объявить “перерыв”, и уведомить об этом рефери, и рефери остановит игру в тот же момент. При возобновлении игры, роботы и мяч должны находиться в тех же позициях, что и до прерывания игры.
d) Перерыв
Человек-оператор может объявить перерыв, и уведомить об этом рефери. Каждая команда имеет право на два перерыва в игре, продолжительностью 2 минуты каждый.
Закон 5: Продолжительность Игры
1) Продолжительность игры составляет два периода по 5 минут каждый, между матчами позволяется перерыв в 10 минут. Официальный хронометрист приостановит часы в течении замен, транспортировки травмированных роботов с поля, в течении блокировки времени, а также таких ситуаций когда по усмотрению хронометриста игра должна быть остановлена.
2) Если команда не готова продолжить игру после первого матча и предоставленного перерыва, возможно предоставление дополнительных 5 минут. Если после позволенного дополнительного времени, команда не готова продолжить игру, то она будет дисквалифицирована от игры.
Закон 6: Начало игры
1. Перед началом игры, необходимо разыграть мяч между командами и цвет команды(синий/желтый), для этого бросается монетка. Команде, которая выиграет бросок, будет позволено выбрать цвет (синий/желтый) роботов.
2. Перед началом игры, команде нападения позволяется установить роботов из своей команды произвольно в собственной области и в пределах круга. Тогда как группа защиты размещает роботов в своей области, исключая центр круга.
В начале первого и второго матча, а также когда был забит гол, мяч должен находиться в центре круга, мяч необходимо передавать на сторону своей команды. По сигналу рефери должна начаться игра и все роботы могут двигаться свободно.
3. В начале игры или после того, как был забит гол, игра должна быть начата/продолжена, с позиции роботов как описано в Законе 6.2.
4. После первого матча, команды должны поменяться местами.
Закон 7: Метод Выигрыша
a) Победитель
Гол засчитывается тогда, когда весь мяч пересекает линию ворот.
Победитель игры определяется на основании всех забитых голов.
b) Способ определения победителя в игре, закончившейся ничьей
В случае ничьей, после второй половины игры, победитель будет решен в соответствии со следующей схемой. После перерыва в 5 минут, к игре будет добавлено время, максимум 3 минуты. Чья команда забьет первый гол, та и победит. Если и после сохранилась ничья, каждая команда будет делать штрафные броски. Каждой команде дается возможность 3 раза сделать штрафной удар. На площадке во время штрафного удара находятся вратарь и нападающий. Вратарь находится в пределах вратарской площадки, а позиции футболиста и мяча должны быть согласно Закону 11. После свистка рефери, вратарь может выйти из области вратарской площадки. Даже если, после трех ударов штрафных, победитель не выявился, допускается дополнительное количество ударов до тех пор пока одна из команд не победит. Все штрафные удары бьет один робот и по свистку рефери. Штрафные удары закончатся когда выполнится одно из следующих условий:
1. Вратарь захватывает мяч в области ворот.
2. Мяч выходит из области ворот.
3. Проходит 30 секунд после свистка рефери.
Закон 8: Фолы
Фол будет засчитан в следующих случаях:
1. При столкновении с роботом противоположной команды, преднамеренно или иначе. Когда робот защитник преднамеренно толкает робота противника, свободный удар будет даваться противоположной команде. Разрешают подтолкнуть мяч или игрока противника назад, если игрок находится всегда в контакте с мячом.
2. Разрешают подтолкнуть робота вратаря в область ворот, если мяч - между роботом-нападающим и вратарем. Однако, подталкивание вратаря в ворота вместе с мячом не позволяется. Если робот-нападающий подтолкнет вратаря вместе с мячом в ворота, рефери объявляет удар от ворот.
3. При нападении больше чем одного робота в области ворот противоположной команды, команда получает фол, и вратарь производит удар от ворот. Полагают, что Робот находится в области ворот, если его 50% находятся внутри области.
4. Если в области ворот находится больше чем один робот защитник (считается, что робот находится в области ворот, если он больше чем на 50% находится в ней), исключение составляет ситуация, когда робот находится в области ворот и он не затрагивает игру. Ситуацию оценивает рефери и исходя из ситуации назначает штрафной удар.
5. Фол назначается команде, если один из игроков (кроме вратаря) словил мяч. Также, фол назначается, если робот ведет мяч так, что никакой другой робот не может подойти к мячу.
6. Робот-вратарь должен отдать мяч из области ворот в течении 10 сек. (Закон 1.d.). В случае невыполнения этого условия, противоположной команде будет назначен штрафной удар.
7. При блокировки вратаря в его области ворот, команде предоставляется удар от ворот.
8. Только рефери и одному из членов команды (менеджер, тренер и главный тренер), позволяется дотрагиваться до роботов. Штрафной удар назначается, если без разрешения рефери кто-то коснулся роботов.
9. Если в штрафной области находятся больше трех роботов защитников, то команде назначается штрафной удар. (Считается, что робот находится в области ворот если он больше чем на 50% находится в воротах)
Закон 9: Прерывание Игры
Игра может быть прервана, и замена роботов может произвестись человеком-оператором, только когда:
1. Робот должен быть заменен.
2. Робот упал и блокировал цель.
3. Гол забит, или был фол.
4. Рефери назначает удар от ворот(Закон 12) или свободный мяч (Закон 13).
Закон 10: Свободный удар (Приложение 3)
Когда робот-защитник преднамеренно подталкивает робота противника, свободный удар назначается противоположной команде (Закон 8.1.).
Мяч, для свободного удара (FK), будет помещен в определенное положение на игровой площадке (Приложение 1). Робот, выполняющий удар должен стоять позади мяча. Команда нападения может поместить своих роботов свободно на игровом поле. Двум роботам защитникам позволяется находиться в угловых точках области ворот, а другие два робота должны быть помещены на линии штрафной области. Со свистом рефери, все роботы могут начать перемещаться свободно.
Закон 11: Штрафной удар (Приложение 4)
Штрафной удар может быть назначен в следующих ситуациях.
1. Когда в области ворот находится более чем один защитник. (Закон 8.4.).
2. Если вратарь не отдал мяч со своей области ворот в течении 10 сек. (Закон 8.6.).
3. Когда любой человек касается роботов без разрешения рефери, во время игры (Закон 8.8.).
4. Когда в штрафной области находится более трех защитников. (Закон 8.9.).
Когда рефери назначает штрафной удар(PK), мяч будет помещен в определенную позицию на игровом поле (Приложение 1).
Робот, выполняющий удар должен стоять позади мяча. В половине поля, где выполняется штрафной удар, должны находиться один футболист и вратарь. Вратарь должен находиться на линии ворот. Другие роботы должны находиться во второй половине поля. Размещать роботов можно свободно, но команда нападения имеет предпочтение в расположении роботов. После свистка рефери роботы могут перемещаться свободно. Робот выполняющий штрафной удар может ударить мяч или повести его.
Закон 12: Удар от ворот (Приложение 5)
Удар от ворот назначается в следующих случаях.
1. Когда нападающий игрок подталкивает вратаря в его область ворот, рефери должен объявить удар от ворот, удар совершает вратарь (Закон 8.2.).
2. Нахождение больше чем одного робота в области ворот противоположной команды. Удар от ворот назначается противоположной команде. (Закон 8.3.).
3. Когда робот противника преднамеренно блокирует вратаря в его области ворот (Закон 8.7.).
4. Когда вратарь ловит мяч в своей области ворот.
5. Когда безвыходное положение игры в области ворот длится 10 секунд.
Во время броска от ворот только вратарю разрешается находиться в области ворот. Мяч должен быть помещен в какую-нибудь точку в штрафной области. Во время удара роботы команд должны находиться вне штрафной области. Команда нападения имеет предпочтение в размещении своих роботов на игровой площадке, но это должно соответствовать Закону 8.3.
Команда защиты может разместить своих роботов на своей стороне игрового поля. Игра должна повторно начаться со свистка рефери.
Закон 13: Свободный мяч (Приложение 6)
Рефери объявит свободный мяч, когда происходит безвыходное положение игры в течение 10 секунд вне области ворот.
Свободный мяч разыгрывают в одной из четвертей игрового поля. В этой области должен находится мяч и два игрока, по одному из каждой команды. Игроки помещаются на расстоянии 25см. от мяча, вдоль игрового поля, по разные стороны от него.
Другие роботы (обеих команд) могут быть помещены свободно вне четверти, где разыгрывается свободный мяч, но с правилом, что, команда защиты получит предпочтение в расположении своих роботов. Игра начнется, когда рефери даст сигнал. После свистка все роботы могут перемещаться свободно.
Приложение 1

Приложение 2

Приложение 3

Приложение 4

Приложение 5

Приложение 6





