This document describes the process of writing the BasicPlayer and
BasicCoach on a day-to-day basis. It is meant for me to remember the different
choices that I made in the design and for other people to get an idea of how
the project came to be a reality.
I programmed the assignments for my project and removed many bugs. Some
we're quite serious (invalid object positions and angles). I also wrote a
simple coach, but it is almost trivial. I released the new sourcecode. I won't
spend more time on this software, so if you want to add a feature, request to
become a member of the basicsoccer project group at www.sourceforge.net,
program the extension or fix and release the code.
I spent the last few days implementing my own agent to intercept the
ball, and I found a number of problems with my BasicPlayer. Because debugging
took so long, I decided to write a small visualisation routine to be able to
check some of my code.
I decided that I won't need a coach to implement my own players, so I
dropped it. Furthermore I got the program pasdoc from the internet to make
documentatie. It isn't very good, because to get good documentation you'll get
bad (not very readable) code. So I commented the code the best I could, and
just generated the simple documentation.
While making the documentation, I saw some inconsistencies in the code
that needed to be fixed. Furthermore, because the BasicPlayer is now officially
released, I need a better website. I converted all my code to follow the Object
Pascal Style Guide (I simply use the free formatter by Egbert van Nes). It made
some of the code less readable because now line contains more then 80
characters, but I think it is for the best to adhere to this standard even when
it doesn't look great.
I wrote extra code for the positioning of objects. Not only does the
code now calculate you one position, it also uses its own position to get an
(X,Y) for all movable objects (players and the ball). For seen objects, the
angle and distance is used to calculate the (X,Y) and for unseen objects the
(X,Y) is used to calculate the angle and distance. While I programmed the code,
it became clear to me that I had to reevalute my coordinate system: there was
no logic. I should have given it some extra thought two days ago. I rewrote the
code for getAbsFaceDir, the localization of the player and made some helper
functions for the transfer between absolute and relative angles. Released the
source code version 0.9.1.x.
Because the positioning now works, I programmed a function to calculate
all the angles and distances for the static objects that are not seen (flags
and goalposts). The reactive player now works and I think it is time to release
the first version of the source code (version 0.9.0.x).
I began programming on the code to determine the absolute position of
the player. However, I first wanted to completely understand the algorithm with
the lines and flags. It was not that hard, but for calculating the absolute
angle for the player, I have a difference of Pi for the upper and lower line
with the AT Humboldt 98 code. If I place the player somewhere on the field and
only make a 'turn' and next readout the absolute angle information, my version
just normally walks from 0 to 360 degrees. However, I needed to change the
calculation of the absolute position, so I think the AT Humboldt 98 used a
optimalization. The bottom line is that the absolute positioning now works. The
main difference is that the direction of the player is expressed in degrees
from 0 tot 360 and not from -180 to 180.
After some more serious thought, I decided it would be best to remove
the reference count on the visual objects. If I really need it, it's easily
added, and the code doesn't need to be in there right now. I programmed the
flag and goal definitions, so these can be used to determine the absolute
position of the player.
After a talk with one of my colleagues, I came to the conclusion that
the referencecounter for the visual object wasn't really necessary, because normally
the list returned from getOVList is Free'd before the next see-messages are
processed. However, I'm gonna keep the code it. Maybe somebody will use it for
something useful.
I also implemented a confidence for every visual object. When an object
is seen the last time iteration, the confidence level is 1. Every movable
object has a decay rate from 0.0 to 1.0 to update the confidence every
iteration. This makes sure you can program a player that doesn't chase 'ghost
objects'.
Furthermore, I implemented the minimal send interval (send only one
message for every X milliseconds). This uses the windows.pas GetTickCount.
Therefore, maybe this has to be changed to support Kylix.
Made code to parse all the information in the sense_body message and
processed angle and distance info from normal see messages.
At last I completed enough code to make a simple reactive player. The
player runs to the ball, and kicks it towards the goal. And it works!
The only problem are the immovable objects: I need the absolute positions,
so I can calculate the position of the player, and with that information
calculate which way to dash and kick. But this is for tomorrow.
Because the Visual Object Memory should work, I was ready to program
some tests. However, the soccerserver gave ‘command error’ for every command.
After some searching an debugging, I concluded my UDP implementation was too
simple. The code from Klaus uses a special class to be able to handle changing
ports for UDP/IP. Fortunately, TIdUDPClient from Indy also supports this
technique, and I was able to change my code to handle changing ports. I wrote a
simple test program to let the player dash,turn,dash,turn,etc. The Visual
Object Memory can now be tested.
Worked some time to get the website up and running and adding a counter.
Programmed the see flag messages.
Made a Visual Object Memory list that can be updated. I added an isEqual
function to all TvisualObject descendents, so the list can be easily updated.
Programmed hear and sense_body messages and the see ball, player, line and goal
messages.
I registered my project with SourceForge. Furthermore, I defined the
different TvisualObject classes and started on parsing the received messages. I
decided to use sets (TKindSet) and not C masks (with all the or’s and
stuff), so I rewrote the TvisualObject implementation.
I created a TbasicPlayer object and started defining the different procedures
that should be implemented: turn, dash, etc. I used the C++ API from Emiel
Corten to guide me. I also typed a lot of constants for ball, objects, sides,
etc. Furthermore, I decided to design
the Visual Object Memory with objects, that all descent from TVisualObject.
Also made a send routine, to be able to send commands. Wrote the implementation
of the basic actuator commands.
After another day at the University of Amsterdam, sitting behind an old
Sun Workstation, fighting with emacs and the standard GNU C++ installation, I
just was completely discouraged. I would need to be behind this computer for
many more days, just trying to get my little RoboCup soccerplayer to work. I
used a standard BasicPlayer and BasicCoach library that was written by Emiel
Corten. The API was very well documented, but I wanted to do this project at
home, with my own fast computer and the familiar Windows interface. I decided I
should make my own RoboCup soccer simulator environment in Windows. That
evening, I searched the Internet for some programs (Internet at home is FASTER
than internet at the University: that’s sick!) that I could use. I found a
soccerserver for Windows, and Klaus Dorer had written a soccer monitor and a
basic player and a basic coach. Everything was written in C++, but I wanted to
use Borlands Delphi. With the introduction of the free Kylix for Linux, I knew
many people will switch, because Borlands products are very friendly to the
user, with a great IDE and standard library.
I started analysing the project with the different modules that have to
be programmed. There are the BasicPlayer and the BasicCoach and some helper
modules (for instance the Visual Object Memory). I got the soccerserver,
monitor and basic player (from Klaus) up and running and checked if the program
worked ok. The next step was using the Indy components to try to connect to the
soccerserver using UDP. I wrote a program that sent an ‘init’ and saw it
worked.
-