Calculation funciton cell (cell [0:9]):

This function captures the major intelligence of the demo control.  The function is called by a manager when it finds any node has moved by monitoring the polling cell which holds the current location of the node.  IM1 and IM2's function are slightly different.  We first explain the script for IM1 and then point out the differences between the two.

Explaining IM1's script:

The node ID is firstly obtained and put into a local variable $3 (we could also directly use $$.2 in the computation in the computation).  We then check if the location for this node (node $3) is 0,0 -- the initial position before the first polling result comes back, in which case we simply return without further calculation.  Otherwise we continue our calculation.

In the next step, we calculate (x-x1)^2 +(y-x1)^2 and put the result into $1, where x and y represent the coordinates of the node of concern, and x1, y1 represent the coordinates of node1 (IM1).  We will use x2 and y2 for the coordinates for IM2 (node 2).  We will follow this convention throughout this explanation.

The calculation proceeds according to different situations:

  1. The node is node 1 (IM1): We don't need to do anything.
  2. The node is node 2 and the current join/split state is JOIN:  We need to decide if a split is needed since node 2 could potentially be IM2.  If that is the case we call the split function to accomplish the split procedure; otherwise, there is nothing to be done and we simply return.  The condition for split is to check whether the distance between node 1 and node 2 has exceeded a predefined threshold (set to 100 here).
  3. The node is neither node 1 nor 2:  We need to decide if the node is too far away from IM1 and moves so closer to IM2 that it needs to be handed off.  But we only need to decide that when we are in the SPLIT state (else if [6:0] == 2).  When this is true, we calculate (x-x2)^2 + (y-y2)^2 and put the result in $2.  We then compare this and $1 to decide if the node is closer to IM1 or IM2.  If it is closer to IM2, we need to call the handoff function.  Otherwise we simply return.  There is one more subtlty and that is when IM1 and IM2 are very close but still split, we don't want to hand a node from IM1 to IM2.  We allow this by constraining the handoff to only the case when the node's distance to IM1 exceeds a fixed threshold (set to 80 here).  The handoff function is called with the ID ($3) as the parameter.
Note that split condition is not decided in the above calculation because we have chosen to let IM2 handle that.

IM2's differences from IM1:

While IM1 is responsible for initiating a split, IM2 is responsible for initiating a join by calling the join function cell.  The threshold distance for controlling the join condition is slightly different from that for split.  This threshold is controlled by the split threshold minus a smaller gap.  This design is to prevent the hysterisis situation where the distance between IM1 and IM2 ossilate around the split threshold.

Scripts for Calculation function:

    IM1's calculation function cell (cell [0:9] at IM1):
    init:   // ********** Most important calculation function
            $$.1 = 1;    // init calc result (mgr ID)
            $$.2 = 0;    // init input param (node ID)

    on:
    action:
            $3 = $$.2;

            if ([$3:1].1 == 0 || [$3:1].2 == 0) then
                   break;  // don't use initialization values.
            endif;

            $1 = ([$3:1].1 - [1:1].1)*([$3:1].1 - [1:1].1)
                    + ([$3:1].2 - [1:1].2)*([$3:1].2 - [1:1].2);

            if $3 == 1 then
                   break;
            else if $3 == 2 then
                    if [6:0] == 1
                       && $1 > 100 * 100 then
                           exec [0:10];
                            $$ = 2;
                   endif;
            else if [6:0] == 2 then
                    $2 = ([$3:1].1 - [2:1].1)*([$3:1].1 - [2:1].1)
                            + ([$3:1].2 - [2:1].2)*([$3:1].2 - [2:1].2);
                   if $1 > 80 * 80 && $1 > $2 then
                            [2:10].1 = $3;
                           exec [2:10];
                            $$ = 2;
                   endif;
            endif;
            endif;
            endif;
     

    IM2's calculation function cell (cell [0:9] at IM2):
    init:   // ********** Most important calculation function
            $$.1 = 2;
            $$.2 = 0;
    on:
    action:
            $3 = $$.2;

            if ([$3:1].1 == 0 || [$3:1].2 == 0) then
                   break;  // initialization values are not valid.  Wait until real poll.
            endif;

            $1 = ([$3:1].1 - [1:1].1)*([$3:1].1 - [1:1].1)
                    + ([$3:1].2 - [1:1].2)*([$3:1].2 - [1:1].2);

            if $3 == 1 then
                    break;
            else if $3 == 2 then
                   if $1 <= (100 - 20) * (100 - 20) then
                            $$ = 1;
                           exec [1:10];
                   endif;
            else
                    $2 = ([$3:1].1 - [2:1].1)*([$3:1].1 - [2:1].1)
                            + ([$3:1].2 - [2:1].2)*([$3:1].2 - [2:1].2);
                    if $2 > 80 * 80 && $2 > $1 then
                            [2:10].1 = $3;
                           exec [2:10];
                            $$ = 1;
                   endif;
            endif;
            endif;