Proposed SpecificationFirst, for motor control, two primitive actions are provided: Move and Turn. These actions provide a combination of simplicity and flexibility, because more complex actions (for instance, moving to, turning toward) can be trivially built thereupon. These actions are also left continuous, because this best matches the complexity of the environments we want to handle. Second, for the sensors, we can provide multiple levels of information. On the lowest level, the animat receives physical feedback upon collision. In a more preventive fashion, the animat perceives visual information about the surroundings. To achieve this, we use line traces that return the first obstacle from the origin. This is a relatively flexible approach. In fact, if necessary, we can extend the line traces to perform a more accurate simulation of movement (for instance, detecting ledges too). As for the mechanism for passing information, the AI is left to query the environment (information pull). This is preferable because the AI can lazily decide what part of the terrain structure it is interested in. When dealing with objects in the environment in Part V, it may be more efficient to broadcast minimal data from the environment (information push). InterfacesRather than drown the issue in wads of mostly inconsequential source code, only the important parts are examined. The full documentation and interface headers are available online. The interfaces with the environment consist of three parts. These parts are conceptually different, but are also separated in the implementation. First, there's the output—as part of the Motion module: void Move( const Vec3f& direction ); void Turn( const Vec3f& orientation ); The Move function attempts to step in a direction relative to the current state. Turn rotates the view to face a particular orientation, expressed relatively to the current one. Second, there is a physical interface—corresponding to the Physics module: bool Collision(); This just returns true if the animat has bumped into something. An alternative—more efficient—approach is to define a simple callback function OnCollision() that gets notified in the same circumstances. Finally, a simulation of a visual interface is also provided so that predictive obstacle avoidance can be attempted. This is part of the Vision module: float TraceWalk( const float angle, const float steps = 4.0f ) const; This procedure tries to walk from the current origin at a particular angle, and returns how far it got without bumping into obstacles. We will improve the functionality of these separate modules in subsequent chapters, as we deem necessary. Code SkeletonTo use these interfaces, it is just a matter of calling the relevant procedures. The particular AI solution used will decide how this is done in practice, but here is a minimal code skeleton containing each of these calls: void Think() { // check for contact bool col = physics->Collision(); // locate any problems straight in front float front_obstacle = vision->TraceWalk( 0.0f ); // decide what actions to call motion->Move( Forward ); if (col || front_obstacle < 2.0f) motion->Turn( orientation ); } The implementation will have to decide whether each of these functions is necessary, and how they fit in the relatively to the AI technique. |