-
Notifications
You must be signed in to change notification settings - Fork 20
Creating Algorithms (C)
C++ Guides: GAMS Primer | Creating Algorithms | Creating Platforms
GAMS provides an extensible algorithms infrastructure for encoding distributed artificial intelligence. The expressiveness of the algorithm infrastructure is limited only by the functionality of the platforms that the developer has access to. In this wiki, we take a look at how to extend the Base_Algorithm class, the features that GAMS provides to algorithm developers, and the interactions between algorithms and platforms.
The GAMS controller directly calls three algorithm methods during normal execution: analyze, plan, and execute, in that order. Developers will need to provide implementations of each of these methods, and the intentions of these methods are the following:
- analyze: Analyzes the state of the algorithm, the platform, sensor readings, knowledge, or the interactions amongst agents. Usually the results of this analysis are used to either effect better plans or to produce results that a human or another agent might find useful.
- plan: Plans the next step or a sequence of next steps. Most algorithms provided by GAMS only plan one movement at a time. However, more extensive plans are certainly possible, and we do provide some examples of this, e.g., Snake Area Coverage--so named because the pathing looks serpentine.
- execute: Executes the next planned action.
All methods should be non-blocking to allow for platform.sense (), platform.analyze (), and algorithm.analyze () to be called frequently and for updates to the knowledge base to be sent out to other agents or human overseers. If you must use blocking calls, the best way to support them is to create a polling class/infrastructure that launches a thread for the blocking operation and provides a polling mechanism for checking if the blocking operation has completed.
GAMS provides pre-configured variables based on the invocation of init_vars on the Base_Controller. The init_vars function provides the id of the agent along with the estimated number of processes, and this information is used to populate a set of variables in the knowledge base for usage in algorithms and platforms.
The key variables you should know about are the following:
-
self_: the Self class is a self-referencing variable based on the id of the agent.self_->deviceis a container for all variables that begin withdevice.{.id}in the knowledge base (where.idis the id passed in through init_vars).self_->idis an Integer container that directly maps to.idin the knowledge base. -
platform_: The Base_Platformplatform_is a pointer to the current platform (the sensors and actuators facade for controlling the platform). During the execute method for an area coverage algorithm, for instance,platform_->move (Position location)might be called to order the agent to move to a new location. Anything implemented in a platform can be accessed via this handle -
status_: Algorithm status is a set of flags that may be useful for algorithms, especially ones implemented as finite state machines. There are flags here that may be enabled to let other agents know you are deadlocked, waiting, ok, etc. -
sensors_: Sensor is a facade for representing sensor readings, typically over a geographic area. Sensors can be configured with ranges to aid with discretization of search spaces, for instance.
A factory class must be added for each new algorithm. This class must inherit from Algorithm_Factory. The only method that must be overwritten is create. The create method shall check the arguments for reasonable values. If the arguments are valid, then create shall construct the algorithm and return a pointer to it. The Land factory is an example of a factory that does not require any argument checking. The Move factory is an example of a factory that performs argument checking.
The new Algorithm Factory must be added to the Controller Algorithm Factory. There are two options to add new Factory classes. The first option is to add the algorithm to the list of default options in initialize_default_mappings. Resize the aliases variables to the number of commands selected for the new algorithm. Populate the variable. Add the new algorithm with the new factory.
aliases.resize (2); // resize to the number of commands that will be valid
aliases[0] = "uniform random edge coverage"; // populate each field
aliases[1] = "urec";
add (aliases, new area_coverage::Uniform_Random_Edge_Coverage_Factory ()); // actually add these as options
Multiple additions of the same name will overwrite previous additions.
The other option is to use the add function. This allows other algorithms to be added later or subclassing the Controller_Algorithm_Factory.
C++ Guides: GAMS Primer | Creating Algorithms | Creating Platforms