Campus Tour Guide Robot

Project #2

Topological Map Algorithm

CIS480

 

First let’s establish what information the robot needs in order to function.  Then we determine how the simulator keeps track of that information and what functions the robot can call in order to receive that information from the simulator.  Those functions are, in essence, logical sensors provided to the robot by the simulator.  These, in conjunction with the simulator data structures determine the simulator algorithm.

 

Next we establish the functionality of the robot, in essence, generating its set of  behaviors.  These, then, must be implemented as the robot’s algorithm.

 

The algorithmic description below is based on a functioning program.

 

Robi logical sensors:

senseLoc: What is the identifier of the current location?

sensePaths: How many paths emanating from this intersection?

 

Robi behaviors:

senseLoc: Read location sensor

sensePaths: Read environs sensor

turn(numTicks): Rotate in place numTicks locations.

travel: Go to next point along outpath.

map: An internal behavior (not sent to simulator)

 

Simulator data & data structures (simData):

 

robiLoc: current location of robot

robiDir: outpath # indicating direction toward which robot is heading

simMap: Set of nodes (structures) containing:

          locId

numPaths

          set of neighbors (by id or #)

 

Simulator action:

 

Responses to robot’s execution of behaviors:

senseLoc: Return robiLoc Id; no change to simData.

senseEnv: Return number of outpaths at current location; no change to simData.

turn(n): robiDir (robiDir + n) mod number of outpaths; return nothing.

travel: prevRobiLoc robiLoc

robiLoc robiLoc.neighbor(robiDir)

from-index index-of(prevRobiLoc) {with respect to robiLoc.neighbor array}

robiDir (from-index + 1) mod robiLoc.numPaths

 

Robi data & data structures:

 

myLocName: Id of robot’s location as kept by robot

myLoc: robot’s information about its location

prevLoc: robot’s previous location (as kept by robot)

myDir: robot’s heading, as index into neighbor array

goalDir: direction robot wants to head

numPaths: how many outpaths (neighbors) are at this location

robiMap: Robot’s set of nodes (structures) containing:

          locId

          mapped – Boolean variable indicating mapping status

numPaths

          set of neighbors (by #)

 

Robi control actions:

map:

myLocName senseLoc

numPaths sensePaths

myDir 0

goalDir 0

myLoc makeNewNode(myLocName, numPaths)

travel

doneMapping False

While Not doneMapping

        prevLoc myLoc

        myLocName senseLoc

        numPaths sensePaths

        If prevSeen(myLocName) Then

                myLoc getLoc(myLocName)

                fromDir getFromDir(myLoc, prevLoc)

        Else

                myLoc makeNewNode(myLocName, numPaths)

                fromDir 0

        End If

        myDir (fromDir + 1) Mod numPaths

        robiMap(prevLoc).neighbor(goalDir) myLoc

        robiMap(prevLoc).mapped isMapped(prevLoc)

        If Not robiMap(myLoc).mapped Then

                robiMap(myLoc).neighbor(fromDir) prevLoc

                robiMap(myLoc).mapped isMapped(myLoc)

        End If

        If robiMap(myLoc).mapped Then

                doneMapping gotoClosestInc(myLoc, myDir)

        End If

        If Not doneMapping Then

                goalDir chooseDir(myLoc)

                turn ((goalDir + numP - myDir) Mod numP)

                travel

        End If

Wend

 

makeNewNode(locName, numPaths):

Create new node & store initial info

 

prevSeen(locName):

Boolean – has robot been to this location previously

 

getLoc(locName):

Look up the Id# corresponding to this location’s name

 

getFromDir(thisLoc, prevLoc):

Look up the path # corresponding to the direction from which robot came

 

isMapped(loc):

Boolean – has indicated location been mapped

 

gotoClosestInc(thisLoc, direction):

Starting from current location and direction robot is facing:

        Find the closest unexplored (incomplete) node, if there is one

                Generate a path to it

                Go to that node

                Return False

        But, if no path is found, Return True

 

chooseDir(thisLoc):

Choose the next direction for robot to travel in accordance with this:

        First – assumption is that the location has not been fully mapped

        Second – starting with direction #0, return the first unmapped direction

found.

 


 

errorReport(. . info parameters . . ):

This is designed to be called from places in the program which expect to encounter certain values within specified ranges. 

If that fails to occur call this function sending it information helpful for debugging. 

Write that information to the Debug file.

Halt execution.

 

Comments:

Notice that we have a very stylized robot+simulator.  Nevertheless this structural template can be modified step by step to make an ever more realistic R+S, even to the point of introducing random and intermittent sensor error and moderately faulty actuator performance.  The key is to decompose the robot functions into sensors and actuators and to provide a simulator capable of supplying the designed functionality.  A second essential of implementation is – following the principle of agile programming – to create a working R+S pair at every step of the way.