A fundamental nature of an AAA system is that it is agent based, with the agents being physically, computationally, and algorithmically modular. This central philosophy radically impacts the nature of programming a AAA system:
- There is no central factory "brain" and thus there is no single program for an entire AAA factory. Rather, the factory program is completely distributed across the agents, with each agent having its own program which must reliably execute without access to any central or global database.
- There is no central coordinator, so programs must interact using standard protocols to negotiate over resources and order factory operations.
- We must be able to robustly specify cooperative real-time behavior, thus the agent behavior is specified within a novel programming model.
Agent programs are used both to guide the run-time execution of an agent and describe its simulated behavior while the factory system is being developed and debugged within the AAA simulation environment. Because of the distributed nature of the AAA system, these programs do not have access to the databases held by the interface tool during simulation. For the minifactory instance of AAA, the following is a pair of sample programs, one for a manipulator, and one for a courier, which will cause a part -- received by the manipulator from a bulk feeder -- to be placed on a sub-assembly carried by a courier.
Sample manipulator program
# Agent class definition class Program(ManipProgram): # Binding method def bind(self): # bind a bulk feeder self.feeder = self.bindDescription("ShaftFeeder") # bind product information self.product = self.bindPrototype("ShaftB") # Execution method def run(self): while 1: # convenience function for getting a # product from a feeder self.getPartFromFeeder(self.product, self.feeder) # Wait for a courier to rendezvous # with the manipulator for feeding partner = self.acceptRendezvous("Feeding") # and transfer the product to the courier self.transferGraspedProduct(partner) # instantiate the applet program = Program()
Sample courier program
# "Applet" class definition class Program(CourierProgram): # Binding method def bind(self): # superclass has some binding to do CourierProgram.bind(self) # Bind to a particular manipulator self.source = self.bindAgent("FeederManip") # Bind to a particular factory area self.corridor = self.bindArea("CorridorA") # Execution method def run(self): # initialize the movement self.startIn(self.corridor) # block until manipulator is ready self.initiateRendezvous(self.source, "Feeding") # move into the workspace self.moveTo(self.sourceArea) # coordinate with manipulator to # get product from it self.acceptProduct() # The coordinated maneuver is done self.finishRendezvous("Loading") # move out of the workspace self.moveTo(self.corridor, blocking=1) # instantiate the applet program = Program()
In order to facilitate completely distributed agent programs, AAA agent programs take the form of applets, i.e., they are instances of classes (in Python rather than Java) which have predefined methods. The two most important methods for an agent program applet, such as the one in these examples, are
- run - which specifies the agent program content
- bind - which specified what factory resources the program needs to operate
The agent program content, i.e., the run method, involves communicating with other agents (see Agent protocols section) and specifying agent behaviour (See programming model section).
The bind method is what enables an agent to run without recourse to a central database. For example in the sample courier program the courier must "know" how to contact and locate the manipulator named "FeederManip". This is done in its bind method. When an agent runs in simulation within the AAA interface tool, the bind method can just link the simulated courier directly to the description of the simulated manipulator named "FeederManip" found in the simulation database, but when a program is downloaded to a physical agent, the courier's bind method is invoked in order to package up a database of the factory entities which that program applet uses in its run method, including a description of how to contact and locate the real agent named "FeederManip" in this factory. This database is sent to the agent with the program applet so that the agent does not have to contact a central database to resolve questions it has about factory entities.
Just as there is no central database that agents can rely on during factory operations, there is no central coordinator to organize and direct the agents. Each agent must be programmed to coordinate with its peers to effect the appropriate product flow and assembly operations. In order to achieve this coordination, agents must know and understand common communications protocols. We identify several different types of protocols within our factory, such as built-in protocols that every agent must provide in order to make possible safe factory operations, and extensible protocols that are specific to a particular instantiation of AAA or a particular solution approach.
A built-in protocol is one that will be necessary for any agent in any AAA system to produce and understand. For example, there cannot be any central arbiter parceling out resources in any AAA system, so every agent has built-in the ability to negotiate with other agents over resource reservation. Agents must have this ability to negotiate for resources in order to ensure safe factory operations.
Using minifactory as an example AAA system, the primary shared resource that our agents negotiate over currently is space on the platen. In the picture above, the green and purple rectangles are reserved corridors for courier motion and the orange square is the workspace for a manipulator. We assume that a courier will only go where it says it will go, and that there are no "outside'' influences which fail to reserve the resources they consume. These assumptions --- which are reasonable in the highly structured, very stable, and well known minifactory environment --- allow us to dispense with the inter-agent perception systems that would be necessary to implement completely "reactive'' motion, in which agents would be required to observe other agents' positions and intentions (either with sensors or by querying) prior to taking action. The low cost and predictable behavior obtained through the use of a reservation system far outweighs the risk of our assumptions being violated and the minor efficiency losses which will inevitably be incurred. Reservation areas will usually have semantic meaning, such as the corridors for courier motion or the manipulator workspace in the above example, but also include safe parking spots or product buffer areas.
We foresee using a similar distributed reservation system to arbitrate the consumption of more abstract resources such as vibration, noise, thermal, or optical emissions.
One more protocol that all agents share is the protocol for defining and extending semantic protocols. A particular semantic protocol may not be in use by all agents, but agents can negotiate to confirm whether they share the same semantic protocols before proceeding with operations.
For example, in our current approach to programming agents in minifactory, we view the agent programs as having two types of interactions, the rendezvous between a courier and a manipulator in which the manufacturing process is performed and information about the process is exchanged, and the gross courier motion, in which couriers move from rendezvous to rendezvous without colliding. Keeping the couriers from colliding into each other results from using the built-in geometry resource negotiating protocols, but deciding in what order couriers may rendezvous with manipulators, i.e. distributed factory scheduling, is the domain of an extensible protocol. An example of this protocol can be seen in the sample courier program which initiates a rendezvous to be accepted as specified in the sample manipulator program.
Most industrial robot programming languages are based on standard computer languages, with the addition of special primitives, constructs, and libraries to support the physical control of a robot. These languages are usually targeted at the control of a single robot, and do not inherently provide support for a program which must be distributed across many different robots. While this model can be effective for "trade-show'' or "laboratory'' demonstrations of a single robot, it leads to significant complications when a robot must be integrated and coordinate with its neighbors in an actual factory.
Fundamentally, these approaches to robot programming make a distinction between the continuous domain of control theory and the discrete domain of event management. We choose to place this distinction at a slightly higher level and make it a more formal abstraction barrier than most. Traditionally, the continuous, state-based view is relegated to running controllers, with all decisions about which controllers to run and when to run them made by systems using a discrete, event based view. Instead we make use of continuous mechanisms to guide the transitions between controllers as well as to run the controllers themselves, freeing the agent programs to deal with the more relevant and abstract problem of deciding what to do and how to do it.
Rather than ask the program to generate trajectories through the free configuration space of the agent, the program is responsible for decomposing the free configuration space into overlapping regions and parameterizing controllers associated with each region. A hybrid control system is then responsible for switching or sequencing between the control policies associated with this decomposition to achieve a desired overall goal. For example, in the two-dimensional state space shown here, if the agent starts in any of the regions, it will be eventually guided to the goal point in R4.
The script defined by the applet's run method deploys these control policies and then monitors the progress through callback functions. The scripting level has no responsibility for real-time controller sequencing. The hybrid control executive accepts the deployments from the scripting level, and automatically sequences specific control policies. A properly specified set of control policies can ensure semi-global safe operation with automatic local fault recovery and persistent goal-seeking behavior.