Dynamic Defense Part 1 – Reasoning

June 7th, 2008 by Dave

It has been more than two years since the Dynamic Defense system was designed, but I’ve always meant to document it fully just for the sake of completeness and in the spirit of sharing information.

Dynamic defense was a system that we used on FIRST Team 195 in 2006 to configure and control the autonomous operation of the robot. From this point onward I’m going to assume the reader is familiar with the 2006 game, as well as the game mode flow.

Purpose

The traditional way of controlling the autonomous operation of the robot during FIRST games was always to use switches to select different modes.  This system did allow some flexibility and decisions could be made right up until the robot was dropped on the field before the match, but the decisions that could be made were limited to what had already been considered.

Switch 1 (2*Switch) Switch 2 (1*Switch) Active Mode
OFF OFF 0
OFF ON 1
ON OFF 2
ON ON 3

Using this scheme, it was possible to have many different modes stored and selectable.  It was simple to set the switches equal to a mode number, but not simple to remember exactly what each mode meant.  This was confused further by having a need to select a different stating position, requiring another 2 bits of data to select A, B or C.  There was, however, a workaround for this.  Using an analog selection dial, one was able to choose one of many different numbers on a single input.

these inputs could be placed either on the Operator Interface, or on the robot itself.  Once the inputs were selected, the code inside the robot would look much like this…

// Simplified for the sake of understandability
 
byte mode = (4*switch1) + (2*switch2) + switch1;
 
switch(mode) {
    case 0:
        // code for mode 0
    break;
    case 1:
        // code for mode 1
    break;
    case 2:
        // code for mode 2
    break;
    // .....
}

It’s not complicated, but it isn’t clean either.  Modes often have shared code (for example, 3 modes may have “drive straight 100 ticks” in them, and thus modes could be nicely combined like such…

// Simplified for the sake of understandability
 
byte mode = (4*switch1) + (2*switch2) + switch1;
 
switch(mode) {
    case 0:
        // code for mode 0
    break;
    case 1:
    case 2:
        // code for mode 1 and 2, since they share some of the same features
    break;
    // .....
}

So now two modes are tied together.  What happens when they differ at some point?

// Simplified for the sake of understandability
 
byte mode = (4*switch1) + (2*switch2) + switch1;
 
switch(mode) {
    case 0:
        // code for mode 0
    break;
    case 1:
    case 2:
        // code for mode 1 and 2, since they share some of the same 
 
        if(mode==1) {
            do_something();
        } else {
            do_something_else();
        }
features
    break;
    // .....
}

And what about that starting position selector?

// Simplified for the sake of understandability
 
byte mode = (4*switch1) + (2*switch2) + switch1;
 
switch(mode) {
    case 0:
        // code for mode 0
    break;
    case 1:
    case 2:
        // code for mode 1 and 2, since they share some of the same 
 
        if(mode==1) {
            if(start_pos==A) {
                do_something();
            } else if(start_pos == B) {
                do_something(SOME_CONST);
            } else {
                stop();
            }
        } else {
            if(start_pos==C || start_pos == B) {
                do_something_else();
            } else {
                stop();
            }
        }
features
    break;
    // .....
}

It started nice and simple, but how maintainable is that routine?  No matter how cleanly you try and write it, you end up with code all over the place.  This is what happened in 2005, and I figured there must be a better way.

Risks

Normally a team programmer would open the code loader, and send over a hex file serially which would replace the current program in the ROM.  If this process was interrupted, it would fail and the robot would lose all functionality.  This added increased risk into a last-second code download.  Code downloads could take up to 50 seconds, and a failure would mean the process would have to be repeated.  IFI_Loader (in conjunction with my serial-USB adapter) had also BlueScreened my laptop several times.  Dynamic defense solved this problem by only sending configuration data.  And although not implemented in the initial software, it would have been easy to add a safeguard, and a checksum.

Dynamic Defense was designed to solve these problems, along with others that we didn’t even realize they are problems.  In my next post about DD, I’ll discuss the system in more detail.

Leave a Comment

Please note: Comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.

Recent Posts
IM Me!
Categories
Meta
Archives