<!-- eStat v3.3.0 -->
<script type="text/javascript">
<!--
var _UJS=0;
//-->
</script>
<script type="text/javascript" src="http://perso.estat.com/js/448048216848.js"></script>
<script type="text/javascript">
<!--
if(_UJS) _estat('448048216848','PAGE_MARQUEE','GROUPE_PAGES_MARQUEES');
//-->
</script>
<noscript>
<a href="http://persos.estat.com/"><img src="http://perso.estat.com/m/00/448048216848?p=PAGE_MARQUEE&c=GROUPE_PAGES_MARQUEES" border="0" alt="marqueur eStat'Perso"></a>
</noscript>
<!-- /eStat -->

RTS3-XP: Code overview

The first versions of RTS3 had no graphic user interface. The parameters values were read in a text file, RTS3.CFG. To modify a value it was necessary to edit the file and to save it under the same name. RTS3.CFG was read automatically during elaboration, without asking a file name to the user.

Graphic interface
To add a graphic interface, I used the JEWL library, available at ftp://ftp.brighton.ac.uk/pub/je/jewl/). The package Commands is an instantiation of the generic procedure JEWL.Windows with the enumerated type RTS3_Commands ( in the Cmd_Types package).
The menus are implemented in the package RTS3_Windows.

With the adjunction of a graphic interface the modification and visualization of the parameters values and others options are made at the beginning of the program by clicking on a menu. The user may accept or modify the values saved in the configuration file. The definitive values of the parameters being unknown until the simulation is started, it is not possible to initialize most parameters at compile time.

To cope with this situation the program is composed of two parts. In the first part, using the JEWL library, the parameters are read and may be modified interactively by the user. The second part (the simulation itself) may now begin but it is not possible to continue with the JEWL library. This is because drawing the creatures as tiny color patches (2 X 2 pixels) could only be done with JEWL on a ‘Canvas’, and I was not able to discover how to set the pen color for that. John English himself did not give me a solution to this problem.
So I continued to use the Adagraph library (http://www.jvdsys.demon.nl/adagraph-0.5e.exe), with almost the same routines as in the previous RT3 versions without graphic interface. When the simulation is finished, the JEWL library is again used to let the user to display or save the results.

To add another salp species (with different parameter values) there is an unavoidable problem: the program must know another parameter set for this second species. It is necessary to add another section in the RTS3.CFG file (previous RTS3.CFG files without this section being now unreadable by the program; the new configuration file is named RTS3-XP.CFG). Once this file is read there should be of course another set of menus and submenus to display and edit the parameters for the second species.
Tailoring RTS3 for more than 2 different species of salps is theoretically easy to do along the same line than the first two, but there will be a limit on the number of counters that may be shown on a single screen line, etc. RTS3-XP cannot be used to simulate simultaneously more than 2 salp species (the default being 1).
To program two species generic packages and procedures are used to read the second set of parameters.

The parameters being read, it is possible to design something more object oriented. This is done by making every salp type a descendent of an ancestor type, Salp_Pattern (in package RTS3_Root). This abstract type is derived for each salp species in package Specific_TYPES. Each salp species has a pointer to its specific parameters.

The first part of the program

During the first part the values read in the configuration file are put into auxiliary variables (with names ending in _Aux or _Span). These variables are displayed inEdit Boxes of the JEWL windows, were they may be modified.

The first part is mainly done in the main procedure RTS3_XP (in file rts3_xp.adb).
Some preliminary computations are made during elaboration: during elaboration of Grid_Constants, the procedure Compute_Video_Parameters establishes the screen parameters according to the current hardware. It also assigns values to the variables V_ and H_Grid_Max which will be used to set the dimensions of the Grid array.

When the program executes, the main procedure, RTS3, first calls the procedure Read_Config_File in the package Simulation_Data. This procedure calls in turn the procedures Read_General_Parameters, Read_SpA_Parameters, Read_SpB_Parameters and Read_Vibilia_Parameters (Read_SpA_Parameters and Read_SpB_Parameters are intantiations of the generic procedure G_Read_Salp_Parameters for Species A and B).

Read_Config_File by default reads the file RTS3-XP.CFG which should exists in the executable directory .

The parameters being read, RTS3 loops waiting for a menu command. Each command brings a new window, where it is possible to inspect or modify the values in the edit boxes. The new (or unchanged) values will be used for the current run. They may be saved either by overwriting RTS3-XP.CFG (in this case the new values become the default values for the next run) or in a new file with any other name –preferably with the extension .cfg. To load this file once RTS3-XP.CFG has been read, simply use the “Change configuration file” submenu of “Parameters”.

Once the user is satisfied with the new values, the second part may take place.

The second part

When the “Simulation > Go” submenu is clicked, RTS3 calls the procedure Execute_RTS3 (in execute_rts3.adb). This procedure is responsible of the second part. It is the true main program.

When this part begins, the procedure Set_Parameters in the package Users_Parameters reads the auxiliary values and assigns them to the variables used during the run.

The rest of the program should not be too difficult to understand owing to the comments and the variables names. The main purpose of Execute_RTS3 is to create one or two tasks to start the salp population(s), and optionally the Vibilia population.

When the tasks finish (either because of the simulation duration is elapsed or the user has interrupted them), the control returns to the JEWL interface where it will be possible to see and save the results, or to find some help.

The most difficult part lies in the creatures tasks.

Remember: each creature ‘structural part’ part is set in Zooid_Pattern record (derived in Oozooid_Pattern and Chain_Pattern varieties). The ‘behavioral component’ lies in a task depending of the Action field of the record. This task is started when the creature is created and loops until its death (and complete decomposition).

Zooids tasks (salps-zooid_processes.adb, with many subunits)

The first oozooid creates its own task with a new statement. The pointer returned is assigned to the field Action of the Zooid_Pattern record of the first oozooid. The task loops during all the life of the zooid. When it is time for the oozooid to reproduce, it calls the Asexual_Multiplication procedure. This procedure makes a new of a Chain_Pattern record (derived from Zooid_Pattern), and assigns the returned pointer to the first oozooid Action field. The task (of the Chain variety) associated with newborn zooid loops similarly during all the chain life, and when it reproduces calls the Asexual_Multiplication procedure, which creates a new zooid of the Oozooid variety. More exactly the chain creates an array of oozooids, each with its own task.
When a task is created, the parent zooid gives the task a pointer to the associated record (the one containing the Action field). This record contains the stage, the weight, the reserves amount, etc. of the zooid, which are thus accessible from the task.

Vibilia tasks (vibilia-vital_process.adb, with many subunits).

Vibilia tasks have a structure somewhat similar to zooids tasks. However, the fact that Vibilia larvae may only develop on a salp host adds new constraints: the adult female (when its state is Seeking_Hosts) should find an adult zooid to deposit its larvae. In RTS3, as a location cannot be occupied by more than 1 creature, a ‘contact’ between the Vibilia and a zooid is defined as follows: when the Vibilia moves to an adjacent location, if its potential destination is occupied by a zooid there is ‘contact’; the Vibilia deposits 1 or several larvae at the zooid location and leaves the zooid to search for another adjacent location.
1) Finding zooids only by chance contact would not be very efficient. It is probable that Vibilia can detect salps at some distance. This distance will be called Search radius. Thus when during a Move the Vibilia potential destination is empty, the 8 (or 4 if Restricted_Orientations = yes) directions radiating from the current location up to a distance of Search radius are checked and the number of zooids along each direction is retained. The new swimming direction of the Vibilia will be the one with the maximum number of detected zooids.
2) The most difficult task now is to get a pointer on the attacked zooid. This is not easy. Because of the hierarchical structure imposed by the HOOD design, zooids and Vibilia have ‘visibility’ on the Space object (i.e. the grid) whereas the Space cannot know anything about the creatures. However, when the Vibilia is ‘in contact’ with a zooid, it has access to its ‘External Appearance’ (when a zooid occupies a location, its External Appearance is shed on the grid). Thus, via the Space, on which it has visibility, the Vibilia can obtain the pointer on the zooid occupying a given location. This makes sense biologically.
3) Zooids and Vibilia are autonomous concurrent entities.To deposit larvae on a zooid there should be some synchronization between the Vibilia and the attacked zooid. At the time of attack the zooid may be engaged in some action (growing, feeding,…) or more likely, owing to perhaps several hundreds tasks to schedule, it does not have currently the focus. An Attacked entry within the zooid task main loop was not found practicable. I arrived at a better solution using a ‘suspension object’: when the Vibilia is ready to deposit its larvae it creates its own suspension object (passing its identity in the discriminant) and waits. When in the course of its daily cycle the zooid ‘discovers’ that it was attacked, it can then awake the Vibilia (whose identity was put in the Vib_ID field of the Zooid_Pattern record).
4) Mutual exclusion is necessary when several larvae simultaneously devour the chain reserves. This is done by including the zooid reserves in a protected object.

Moves

Most of the spatial deployment of the swarm takes place during Moves. A Move is the action to leave a given location to occupy one of the 8 (or 4) adjacent ones around the creature current location. Zooids or Vibilia can only move to empty locations. Zooids moves once every ‘mean day’. When they arrive at a location they filter a certain amount of phytoplankton, depending on their size.

Because they must move quicker than zooids in order to be able to attack them, Vibilia make several Moves (called ‘jumps’) during a mean day. The basic algorithm for Moves is the same for zooids and Vibilia:
- From the current location the 8 (or 4) adjacent destination locations are checked (randomly clockwise or counterclockwise). The first empty location will be the destination for the Move, and its direction becomes the new Simming_Direction.
- If all destinations are not Empty, a flag Possible is set to "False" and the procedure returns. The creature does not move; it will have another chance to leave its current location the next ‘day’. A variable Nb_Of_Move_Retries is then incremented by1. It is reset to 0 when the Move is successful.
- Otherwise if its value becomes greater than a constant Max_Nb_Of_Move_Retries the area is considered overcrowded and the creature is ‘suicided’ (it disappears).

 

Return to home page

(Last modified 2009-02-26)