| || |
Information related to the development of the airtraffic program. Look
here also for random development rants; It's my scetchboard for
Airtraffic is written in Python. Why? it's easy, it codes fast, it's
Object Oriented, doesn't have memory issues and is just plain
readable. Took me 2 months to write half a client in C++ to then just
re-write it in 1 week with python, knowing nothing of python when I
But the speed I hear you say.. we all know that 90% of the
time the 10% of the code is being executed, and guess what, we can
just write those 10% in C or C++ when performance becomes a problem,
while in the mean time we have a very fast way to build the other
90% of the program.
Other cool thing would be that, with a bit of effort ATC specialists
(that generally don't generate code for a living) could get enough of
a hang of the language and go beyond just giving advice, and actually
supply code. Something that would never happen, if coded in C++.
After mucking around with custom networking protocols, I realized all
I was doing was building yet an other RPC. Which is silly (I am too
lazy for that). So i just used Corba (in the form of the Orbit orb)
with python and didn't have to worry about inventing my own RPC
anymore :). Result is that we can concentrate on working on the sim,
and not trying to fix some home-grown RPC copy. Besides, if someone
thinks of a better client, or wants to write one for his favorite
OS, that's just a matter of implementing the IDLs.
Having everything dynamic is all nice and dandy. Except that when you
change something, there's no compiler to warn you for strange code or
typos. Until it blows up in your face, that is. So, the code already has
a bunch of Unit tests that can be ran by doing:
5.3 Unit Tests
in the test/ directory. These tests are really helpful to
verify what things got broken when mucking around with the code. Write
'em and use 'em!.
I have chosen to use GTK/Gnome for the User Interface of the client. As far
as I am concerned GTK vs. QT are just different roads to the same goal
and we had to choose one. I use GTK/Gnome because it is what i am most
familiar with and I use the gnome desktop.
5.4 User Interface
I don't like the work of manually writing UIs and what I like even
less, is having to mess around with computer generated code, just to
have it all overwritten/invalidated because some button was moved
around. so I decided to use libglade (it takes the glade XML file,
and builds the GUI at runtime). It works like a charm.
The client program (the ``airtraffic-client'' cvs module). This
is responsible for the user interface, but not more then that. It is a
terminal/a data-displayer. It shouldn't have to do much fancy
5.5 The client
The server program (the ``airtraffic'' cvs module). This does most of
the work and runs on the server (obviously).
5.6 The server
The main calculations in the simulation get done by the Simulation
Server (also just called the ``server''). This new is then made
available to the connected clients for which it is relevant.
The one airtraffic program has various distinct functions (when
started up with different command-line options):
- Simulation Server
- This is the program that does the interfacing
with the airtraffic-client. It keeps the simulation data and does the
calculations (for the moment, maybe that will become a different
- Meta Server
- This is a server that keeps track of the Simulation
Servers that are available for use to a user. The idea is to make one
global server where all Simulation servers announce their presence so
that people can see what servers are running.
- ticker server
- Because the orbit orb blocks all
threading in python *sigh*. They say it's going to get fixed, but
until then, this server gives a ``update'' message to the simulation
server, so that it knows it has to process it's data (update plane
positions, etc). It's a hack, but it works for the moment.
I am thinking of renaming the ticker-server to ``reality'') server, so
that all the calculations go into a separate process that updates the
data in the Simulation Server every game cycle (ATM thats 1sec). It
seems like a good idea, since that would make SimServer have only one
task (getting data to the clients), and let me free to implement all
kinds of stuff in the new server without having to touch the client
interface part of the project.
Downside of this is that much information needs to be in memory
twice (in the reality- and in the sim-server) Maybe a way to
avoid that, is to used shared memory or something of the sort. That
does make it all more complex, thou, and a downside is that it makes
it impossible for the reality- and sim-server to be on different
physical boxes. Maybe I'll try to fix this when it becomes a problem
Data files in the XML are parsed at the startup of the
servers. These files contain the definitions of the properties of the
various plane types, sceneries etc.
The data given to the client by the server is low-level data
stating the situation of the planes at the moment. The information
the client sends to the server is high-level, requesting a heading and
height or other changes. The server keeps full control of the
planes. A client never gives information on plane objects, it can only
request changes to the server.
5.7 Data flow
All the information that changes as the game progresses is send to the
client via a Corba interface with the simserver. This information
includes: Contains among other things: The current locations and
statuses of all planes, airport and runway information, etc.
5.7.1 Dynamic Simulation Information
My idea is to let the simserver Corba simserver live on port 13222
The information on the region of the server that doesn't change as the
game progresses. Airport and runways locations, terrains, Static Plane
Information (defining how the different types of aircraft will
behave), etc. The idea is to dump this kind of information into XML
files that the clients can either download at the beginning of the
simulation (as far as they don't have it already with the
airtraffic-client distribution), or they can download it as needed.
5.7.2 Static Simulation Information
One idea is that if a simsever automaticly generates at startup some
scenery it writes this information to a XML file that the clients then
in turn download via HTTP. This tiny HTTP server would listen to port
Information on the Corba client server interface.
Object is for the client to get information on running (and public)
sim-servers in the world. For this it uses the interfaces defined in
meta.idl. There is a bootstrapping problem here, since the client
needs to know at least one metaserver to get the list of all other
server. My idea is that clients get the corba IOR from
5.8.1 Meta -- Clients
After the client has the IOR of the meta server if can interrogate it,
via the Meta::Client interface about the available simulations.
- Client uses the getServerList(version) method to get a
list of IORs of sim-servers that the meta-server knows about1. The client
now has sufficent information to connect to a simserver.
- However it can use the getServerData(serverIor) to get
more information on a simserver before connecting to it. Information
could be things like type of simulation running, number of current
players, etc. Basicly information that would interest the users for
deciding which Sim Server to pick for starting a simulation run.
- To solve the problem that people are unaware of new software
versions (to no fault of their own). So an other method that the
Meta::Client interface provides is the LatestVersion()
one. This simply returns the latest version of the software that the
meta server knows about. If it is newer the software the client is
running, a kind message would pop-up for the user, telling him/her that
they can do a upgrade.
The idea is that anybody who wants to can start their own simserver
can do so. As with the client there's a bootstrap issue. So again, the
simserver can get the Meta server's IOR. This time from:
5.8.2 Meta -- SimServers
All interfacing with Meta goes via the Meta::Server interface that is
also described in the meta.idl file.
- The first command is the annouce(SimServer, ServerData)
method. This returns a identifier (a random 30bit number at the moment) that
uniquely identifies the sim-server to Meta. SimServer is the structure
that the meta client shows to the clients when they get the list of
available server; While ServerData is the data that Meta knows about
when client requests more information on the server.
- If a sim-server shuts down it can notify the meta server via the
retract(id) method. This cleans the sim-server from
the meta server records.
- Strange things happen to software, and simserver may go down
without retracting them self from Meta. For this reason meta servers
are expected to trigger the ping(id) Every 5 minutes would be a
fine time to ping the meta server. If the meta server hasn't heard
from the SimServer in 15 minutes it will assume it is no longer
working and remove it from the listings.
- finally pingData(id, ServerData) does the same as ping,
but it also updates the information Meta has about the simserver. The
idea is not to keep Meta synced in real-time with the sim-server but
giving an update every 5minutes seems reasonable. Also if would be
useful to, if the maximum capacity of the sim-server is reached it
could send a pingData() to notify Meta server and prevent more
people from trying to connect.
Of course the meta server is something that people in a local-network
would want to setup for themselfs, so the sim-server is also the meta
server, just give the airtraffic -meta on the command line
and put the resulting meta-client.idl and
meta-server.idl into some place where the clients and
sim-servers know where to reach it.
As standard the simserver will announce it's presence to
the global meta-server and then it will become visible to clients
world-wide. There might be good reasons that you do not which this,
and a simple command-line option will inhibit it from announcing or
announce to a local meta-server.
This is the main connection of the simulation from the user point of
view. To start the connection the user does a connect(nick)
call on the SimServer::Sim interface. This returns an
identification token (a random number) to the client, which will be
used to identify the user in future connections. disconnect()
does the expected, and releases user related resources from the
5.8.3 SimServer - Client
The basic idea here, is to have a subscription interface. To put it in
an other way: The client gets a list of objects via
getSimObjList() that are known in the simulation, and it can
decide (via subscribe()) to monitor them, or not. The SimServer
keeps track of whom is monitoring what. Every once in a while (a few
seconds) the client requests an update (getUpdate(userId)), and
the SimServer sends back the data of objects that the client was
monitoring, and have changed.
To send commands to the planes, the Client uses
Next: 6 User Documention
Up: AirTraffic documentation
Previous: 4 Contributing
Copyright © 2001 Marijn Vriens
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License.
Last change: 2002-02-18