Citation
Planning for preservation of open space in the Colorado Front Range urbanization corridor

Material Information

Title:
Planning for preservation of open space in the Colorado Front Range urbanization corridor
Creator:
Wheeler, Douglas
Place of Publication:
Denver, CO
Publisher:
University of Colorado Denver
Publication Date:
Language:
English
Physical Description:
93 leaves : maps, forms ; 28 cm

Subjects

Subjects / Keywords:
Open spaces -- Colorado ( lcsh )
Open spaces ( fast )
Colorado ( fast )
Genre:
bibliography ( marcgt )
theses ( marcgt )
non-fiction ( marcgt )

Notes

Bibliography:
Includes bibliographical references (leaves 91-93).
General Note:
Submitted in partial fulfillment of the requirements for the degree, Master of Planning and Community Development, College of Architecture and Planning
Statement of Responsibility:
by Douglas Wheeler.

Record Information

Source Institution:
|University of Colorado Denver
Holding Location:
|Auraria Library
Rights Management:
All applicable rights reserved by the source institution and holding location.
Resource Identifier:
11930378 ( OCLC )
ocm11930378
Classification:
LD1190.A78 1984 .W4345 ( lcc )

Downloads

This item has the following downloads:


Full Text
RULE-BASED FEATURE IDENTIFICATION FOR
INDOOR TOPOLOGICAL MAPPING USING
ULTRASONIC SENSORS
by
John Osber Wetherbie HI
B.S., University of California at Los Angeles, 1984
A thesis submitted to the
University of Colorado at Denver
in partial fulfillment
of the requirements for the degree of
Master of Science
Computer Science
1999


This thesis for the Master of Science
degree by
John Osber Wetherbie HI
has been approved
by
Date


Wetherbie HI, John Osber (M.S., Computer Science)
Rule-Based Feature Identification for Indoor Topological Mapping Using Ultrasonic Sensors
Thesis directed by Assistant Professor Christopher E. Smith
ABSTRACT
The goal of this study is to develop a method for identifying indoor features such as
corridors, alcoves, and T junctions suitable for use in mapping, localization, and navigation.
This study differs from the majority of work in the area of feature identification due to the
focus on detecting large-scale features, e.g., corridors, alcoves, etc., instead of small-scale
features such as comers, edges, and planes. A set of feature patterns are used to represent the
real world features to be identified. Each feature pattern contained a set of rules that are
matched against sonar observations taken by a mobile robot. Sonar readings are taken at
specified distance intervals by the robot and matched against the rule sets of the various
patterns. The rules are very simple and involve comparing a sonar range reading to one or
two threshold values. This simplicity leads to reduced computational complexity and to a
more flexible and extensible feature identification algorithm. The pattern which has the
highest percentage of its rules satisfied by the sonar data is selected as the current feature.
Tests are conducted to identify single features alone and a series of features that would
normally be seen by a robot traversing an indoor environment. Results demonstrate that
in


the proposed methodology successfully identifies all features in the feature set.
Misidentifications can occur at the transitions between features in some cases. These events
are reduced by using filtered data for feature identification instead of raw sonar data.
This abstract accurately represents the contents of the candidates thesis. I recommend its
publication.
IV


DEDICATION
This thesis is dedicated to my wife Michele, our two sons, Andrew and Ryan, and to
the loving memory of my mother.


ACKNOWLEDGEMENTS
I would like to thank several people for their contributions to this thesis effort. My
thanks to my advisor, Chris Smith, for his help in coming up with the topic for this research
and his continued guidance during the time it took to complete this work. My greatest thanks
goes to my family. First to my wife Michele, who made sure I had the evenings and
weekends I needed to complete this research. Next to Andrew, who was very good about
letting Daddy use the computer when he needed to study. Finally to Ryan, who mostly played
quietly and did not put my thesis in his mouth once.


CONTENTS
Chapter
1. Introduction.....................................................................1
1.1 Background......................................................................1
1.2 Problem Statement..............................................................4
1.3 Overview.......................................................................4
2. Related Work....................................................................5
2.1 Overview.......................................................................5
2.2 Grid-Based Representations.....................................................7
2.3 Topological Representations...................................................14
2.4 Feature Identification........................................................20
3. Approach.......................................................................28
3.1 Overview.......................................................................28
3.2 Ultrasonic Sensors............................................................29
3.2.1 Theory.......................................................................29
3.2.2 Polaroid 600 Ultrasonic Sensor...............................................32
3.3 Robot.........................................................................34
3.4 Software......................................................................36
3.4.1 Feature Set..........:......................................................39
3.4.2 Rules........................................................................46
vii


4. Results
51
4.1 Overview........................................................................51
4.2 Results of Individual Feature Identification....................................51
4.2.1 Corridor..................................................................... 52
4.2.2 Four Way Intersection.........................................................54
4.2.3 Up T Intersection.............................................................58
4.2.4 Across T Intersection........................................................60
4.2.5 L Intersection................................................................63
4.2.6 Alcove........................................................................66
4.2.7 Dual Alcove.....:.............................................................68
4.2.8 Corridor End............................................,.....................70
4.2.9 Alcove End......................:.......i.....................................72
4.2.10 Dual Alcove End..............................................................74
4.3 Results of Multiple Feature Identification......................................76
4.4 Summary of Results..............................................................83
5. Conclusions......................................................................88
5.1 Evaluation......................................................................88
5.2 Future Work....................................................................89
5.3 Summary.........................................................................91
viii


Appendix
A. Computer Program............................................................92
B. Program Output and Configuration File......................................221
References................................................................... 241
IX


FIGURES
Figure
1.1 Map to Nearest Copier............................................................1
2.1 A Simple Grid-Based Representation..............................................7
2.2 Basic Sensor Model..............................................................9
2.3 A Simple Topological Map.......................................................15
2.4 Staggered Hallway...............................:.............................19
2.5 Sonar Transmitter and Receiver................................................21
2.6 Angle of Incidence for Planes and Comers......................................22
3.1. Sonar Transducer Lobes....................:...................................30
3.2 Cross Section of a Sonar Beam..................................................31
3.3 Sonar Ring of the Scout Robot................................................ 33
3.4 Arrangement of the Sonar Sensors............................................. 33
3.5 Nomadic Technologies Scout Robot...............................................35
3.6 System Configuration...........................................................36
3.7 Flow of the C++ Program........................................................38
3.8 Indoor Feature Set.............................................................40
3.9 Predicted Sonar Data for a Corridor............................................41
3.10 Predicted Sonar Data for a Four Way Intersection..............................41
3.11 Predicted Sonar Data for an Up T Intersection.................................42
x


3.12 Predicted Sonar Data for an Across T Intersection..................................42
3.13 Predicted Sonar Data for a L Intersection..........................................43
3.14 Predicted Sonar Data for an Alcove.................................................43
3.15 Predicted Sonar Data for a Dual Alcove.............................................44
3.16 Predicted Sonar Data for a Corridor End............................................44
3.17 Predicted Sonar Data for an Alcove End.............................................45
3.18 Predicted Sonar Data for a Dual Alcove End.........................................45
3.19 match Function from FrontLongRule..................................................50
4.1 Sonar Plot for a Corridor...........................................................52
4.2 Predicted and Actual Sonar Data for a Corridor......................................53
4.3 Sonar Plot for a Four Way Intersection..............................................55
4.4 Predicted and Actual Sonar Data for a Four Way Intersection.........................56
4.5 Sonar Plot for an Up T Intersection.................................................58
4.6 Predicted and Actual Sonar Data for an Up T Intersection............................59
4.7 Sonar Plot for an Across T Intersection.............................................61
4.8 Predicted and Actual Sonar Data for an Across T Intersection........................62
4.9 Sonar Plot for a L Intersection.....................................................63
4.10 Predicted and Actual Sonar Data for a L Intersection...............................64
4.11 Sonar Plot for an Alcove...........................................................66
4.12 Predicted and Actual Sonar Data for an Alcove......................................67
xi


4.13 Sonar Plot for a Dual Alcove...................................................68
4.14 Predicted and Actual Sonar Data for a Dual Alcove..............................69
4.15 Sonar Plot for a Corridor End..................................................70
4.16 Predicted and Actual Sonar Data for a Corridor End.............................71
4.17 Sonar Plot for an Alcove End...................................................72
4.18 Predicted and Actual Sonar Data for an Alcove End..............................73
4.19 Sonar Plot for a Dual Alcove End...............................................74
4.20 Predicted and Actual Sonar Data for a Dual Alcove End..........................75
4.21 Map of Multiple Feature Environment............................................77
4.22 A Portion of the Multiple Feature Environment.....1............................78
4.23 Sonar Plot for Multiple Feature Environment....................................79
4.24 Robot Detecting a Corridor End Instead of an Up T...............................84
4.25 Robot Unable to Differentiate an Up T from a Dual Alcove........................85
4.26 Robot Unable to Differentiate an Alcove End from a L Intersection...............85
4.27 Misidentification of a Four Way as a Dual Alcove................................86
4.28 Misidentification of a Four Way as an Up T......................................86
xii


TABLES
Table
3.1 Rule to Feature Mapping...............................................................49
4.1 Percentage of Correct Feature Identifications.........................................82
4.2 Raw and Averaged Data Test Feature Identification.....................................83
xiii


1. Introduction
1.1 Background
Recall the last time you were asked for directions to a particular office or location in
a building you work in, say where the nearest copier is located. It is likely that the way you
answered went something like this:
Go to the T up ahead and turn right. Go to the end of that corridor where it Ts and turn
left. Go through a corridor intersection and past an alcove on the right. The next room on the
left is the copier room. If you come to another T youve gone too far.
You could also provide this information graphically in the form of a simple map. The
map wouldnt necessarily be to scale but would indicate the features highlighted in the verbal
description, as below:
Figure 1.1: Map to Nearest Copier
1


Both of these methods for providing directions emphasize the features that a person
would see as they proceeded towards the copier. The distance to the location and the time to
get there are secondary or irrelevant in most indoor situations.
Now, the copier in this case seems pretty far away but you would probably feel fairly
certain that the person asking for directions will be able to successfully find the copier
without too much effort. What if it was a robot that was asking for directions? Would a
robot be able to understand concepts like corridor, alcove, and T? Would it be able to
recognize these features when it came upon them?
To perform useful tasks a mobile robot needs a model of the near world [19] that
represents the worlds configuration and the robots location within this environment. Using
a model of its surroundings a robot can avoid obstacles, identify changes in the
environment, and navigate its way to the nearest copying machine. A map is a symbolic
construction and is meant to describe discrete entities, objects or places in the environment
[7]. The model, or map, that a robot maintains must provide the information needed to do its
work properly.
There are two main ways to express the model of the real world for a robot: grid-
based and topological. Grid-based maps are grids and capture, as accuracy allows, the true
layout of an environment. The verbal directions and the simple map presented above are
topological in nature. Dudek [7] states that Most humans naturally conceptualize
navigation information in both symbolic or topological terms as well as quantitative metric
terms, depending on the context, task, and scale.
2


Topological representations emphasize qualitative and relational information (Go
past two corridor intersections and an alcove on the right.) instead of exact measurements.
Janet, et al., [11] look at this as a more intuitive way to represent an environment than
approaches that provide specific distance information.
Dudek [7] does make the point that in many cases a topological map that is created
and used by a robot does not need to match up with the topological map/description that a
human would use to describe an area. A single room to a person could appear as two or more
rooms to a robot.
While this difference in perceiving and describing the environment may not be
critical for many types of robots, think back to the robot looking for the nearest copier.
Unless the robot has a map of the building that contains the features that a person sees, it will
be difficult, if not impossible, for it to find the copier. This does not preclude the robot from
having additional features or information, but it must be able to understand that a room or a
hallway that a person sees is a single entity.
One of the most popular methods for developing a map of a robots surroundings is
to collect sonar data via ultrasonic sensors. This sonar data can then be used to construct
grid-based representations or topological models, as described above, where the data has
been manipulated to identify/construct simple geometric shapes that compose the
environment [5] [15] [17] [26],
Grid-based maps present the environment as areas that are occupied or unoccupied
with a granularity that is defined by the size of the cells that make up the grid. The
topological approaches emphasize the relationships between landmarks or sets of primitives:
3


planes, comers, edges [5] or walls, comers, edges, and cylinders [17] and then attempt to
connect them together in a representation of the robots surroundings.
This research presents a method which will allow a robot to identify large-
scale indoor features such as corridors, alcoves, and T intersections. This approach has the
advantage of using features which have semantic value to humans as the building blocks
(primitives) of the environmental representation as compared to grid-based and small-scale
topological approaches. This will allow a high-level interface to robots which is more in line
with the way humans perceive and interact with the environment while being based on
constructs that robots can successfully identify directly from sensor data.
1.2 Problem Statement
Current research in developing environmental models for mobile robots use grid-
based approaches, topological maps of small-scale features, or a combination of both.
None of these approaches identifies features on the scale of corridors, intersections, etc.,
directly. This thesis develops an approach to identify these large-scale indoor features
directly from observations taken by a mobile robot.
1.3 Overview
The next chapter presents related work in the areas of grid-based maps, topological
representations, and feature identification. Chapter 3 describes the methodology that was
used for this work. Chapter 4 gives the results of the feature identification experiments.
Chapter 5 draws conclusions based on the results of this research and suggests possible areas
for future work.
4


2. Related Work
2.1 Overview
Robots have two primary ways of expressing knowledge about their surroundings:
grid-based representations and topological representations. These maps are used by robots
for obstacle avoidance, navigation and localization; that is, for determining where the robot
is, within an environment [18] [19]. Not surprisingly, much of the work reviewed in this
chapter deals with these topics.
The research presented in this thesis diverges from the majority of this work in one
important aspect. The focus is to develop an approach which will allow the identification of
large-scale features in an indoor environment. Most of the work surveyed deals with the
identification of primitive or small-scale features such as comers and planes, if it addresses
feature recognition at all. Large-scale features could be used to create a representation of the
robots surroundings for navigation and localization. They would also have the benefit of
having a semantic meaning to accompany the representation; that is, a corridor feature not
only looks like a corridor but it is identified as such. A map with these type of features
could be used to help the robot solve the find the nearest copier problem presented in
Chapter 1.
Maps and descriptions using large-scale features are used by humans to provide
meaningful directions all the time. The use of higher-level abstractions/concepts provides a .
simpler and more compact way of providing information. A person will better understand
5


and better use the directions go straight down this corridor to the first alcove on the left
than the directions go thirty six tiles straight ahead, stop, then turn to the left. Both sets of
directions are accurate and provide the means for a person to get to the copier. From that
standpoint the directions are equivalent. Now put yourself in the position of the person
wanting to find the copier. Do you want to count the number of tiles you have walked over
from where you received the directions? What would happen if the distance given was too
short or too long? Blindly following the directions would mean that you would go past the
copier or stop before you reached your destination. Are the sets of directions still equivalent?
It is also possible that the feature-based directions might be incorrect. In this case you are no
worse off than you were with directions that specified an incorrect distance to travel.
In contrast, it might be easier for a robot to use distance traveled than to identify
environmental features to determine if the robot has reached its goal. The robot could be
provided with an a priori map of the environment that specified distances. It could be
commanded to explore the environment and build a metric-based map itself. In either case
the ability of the robot to find the copier is dependent on its localization capability which is
based on the ability to determine distance traveled accurately. Depending on this accuracy is
not necessarily reasonable since localization and navigation are the subjects of many current
research efforts.
Use of a feature-based map will eliminate some, if not all, of these problems. The
use of features will also aid in interacting with humans. A person would be able to provide
directions to and receive directions from a robot in a much more natural way if the
information is topological in nature. Using features which have semantic value to humans
6


and robots as the building blocks for maps will have significant advantages over
representations that may have more precise distance information but are more restrictive.
2.2 Grid-Based Representations
Grid-based approaches use one or more two-dimensional arrays of cells as the basis
for a model of the world. In their simplest form, cells that appear occupied are marked as
such by assigning them a value of 1. Empty cells have a value of 0. Cells that are located in
unexplored territory could be marked as unknown. Figure 2.1 is an example of a simple grid.
- - - X X - - -
- X X X X X X
- X
X X
- X X X X X X
- X X - - -
- X X - - -
- X X - - -
Figure 2.1: A Simple Grid-Based Representation
The grid map above shows what the meeting of two corridors, a L intersection, might
look like. Cells that are occupied are marked with an X. Unknown cells are designated by a
dash in this example. Unoccupied cells are shown as empty.
More sophisticated approaches have probability values associated with each cell.
The approaches commonly used to determine and update the probability values of the cells
include Bayesian statistics, Dempster-Shafer methods, or variations of these two.
For Bayesian reasoning approaches [8] [16] [17] [26] the values are the probability
of the cell being occupied and the probability of the cell being unoccupied. For Dempster-
7


Shafer methods [18] [23] the values are the support for the cell being occupied and the
support for the cell being empty. Howard and Kitchen [10] add a third value relating to the
support for the cell being occupied or empty.
For both probability updating schemes, it is common for each cell in the grid to have
its probabilities initialized to a specific value [10] [17]. For Bayesian approaches a value of
0.5 for the occupied and unoccupied probabilities is commonly used. The value of 0.5
represents the fact that it is equally likely that a cell is occupied as it is unoccupied before
any readings have been taken. For Dempster-Shafer a mass distribution of:
m(R(j>) = 0
m(-iR<|>) = 0
m(R<|> v -iR<|>) = 1 (2.1)
could be used. This indicates no support for the cell being occupied, no support for the cell
being empty, and support for the cell being occupied or empty.
The Bayesian and Dempster-Shafer updating schemes act on data that indicates
whether a cell may be empty or occupied. This data is presented to these algorithms via a
sensor model. The research documented in [8] [17] provides the basic sensor model that is
used, with some modifications, by all grid-based approaches. This sensor model has the
following properties:
1) If a cell is closer than the range indicated by the sonar measurement then the
likelihood of the cell being empty increases.
2) If a cell is farther away than the range indicated by the measurement then the
occupied/empty probabilities dont change. Essentially there is nothing that can
be determined about the cell.
8


3) If a cell is at the same distance as the range reading, the cell may be the cause of
the return and the probability of occupancy is increased. The amount the
probability of occupancy increases is usually inversely proportional to the range
of the reading. This spreads the probability that one particular cell in an arc of
cells is causing the return. This essentially gives more weight to short range
readings than to long range readings.
Thus a grid map could have areas that are probably empty, probably occupied, and
unknown. Figure 2.2 shows an example of this sonar model.
The Histogramic In-Motion Mapping (HIMM) approach [2] describes a
simplification of the above model. HIMM only uses a single probability value known as the
Certainty Value with a range of 0 to 15. More importantly, only the cells along the acoustic
axis of the sensor are updated by a measurement versus the entire beam-width of the sensor.
The one cell that has its Certainty Value incremented is the cell at the measured range of the
reading. The empty cells between the sensor and the cell at the measured range have their
Certainty Values decremented. When a Certainty Value is incremented, its value is increased
by three but when the value is reduced the decrement is one. These values for incrementing
and decrementing the Certainty Values were arrived at based on experimentation.
9


An interesting problem that arises with the use of sonar sensors in mapping indoor
environments is that most surfaces in an indoor environment are very good acoustic mirrors
[3]. If a surface is at an angle to the sensor then the echo return could be partially or
completely reflected away from the sensor. This could make the surface appear farther away
or even invisible to a ultrasonic sensor [3] [10]. The sound pulse could also bounce off
multiple surfaces before being received by the sonar sensor. This would also yield a reading
that would indicate a surface is farther away than it is in actuality [3] [10] [16].
The approaches outlined in [2] [8] [17] took a simple approach to handling the
specular qualities of indoor environments by rejecting range readings above a certain
maximum value. This limit was meant to eliminate the problems caused by specular
reflection based on the assumption that range readings caused by specular reflection occur at
the maximum range of a'sonar sensor.
Howard and Kitchen [10] use a modified occupancy grid called a response grid to
build a model of an indoor environment. A response grid is a two-dimensional array of cells
like an occupancy/certainty grid. The modification attempts to provide a more realistic
handling of specular reflection to build a more accurate occupancy grid.
The basic premise of the response grid is that a cell can appear to be occupied when
viewed from one direction but will appear empty (that is, not generate a response) from
another. A smooth surface only returns an echo to a sensor when the angle of incidence
between the surface and the sonar beam is near zero. At larger angles of incidence the
surface will return a weak response or none at all. Thus the same feature at the same location
would appear differently based on the location of the sonar sensor. In other grid-based
10


approaches this would lead to a contradiction since they assume that an occupied cell would
appear occupied from all directions.
Each cell in the grid can be empty or contain one or more surfaces that will reflect
ultrasonic pulses. Cell occupancy is determined by assuming that a cell that has an echo
return from it, in one or more directions, must have a surface in it and is therefore occupied.
This method leaves open the possibility that a cell might have surfaces in it that do not
reflect in any direction. Howard and Kitchen state that the conditions that could cause this
are rare in indoor environments.
Whether a cell is occupied or not is indicated by the state variable Occ that can be
set to one of two values:
Occ(x,y) = [occupied, unoccupied] (2.2)
The response of a cell for a direction <|> is maintained by the state variable Res that
can be set to one of two values:
Res(x,y, Thus a cell that has one or more responses associated with it will be marked as
occupied with some amount of probability based upon the update methodology used.
Lim and Cho [16] also address the problem of specular reflection and how it can
affect the accuracy of a grid-based map. This paper introduced the concept of specular
reflection probability and used it to modify the Bayesian updating function for the grid. The
specular reflection probability is composed of two components; one is the Range Confidence
Factor (RCF) and the other is the orientation probability.
11


As noted above, specular reflection can cause misleading range information which
indicates an obstacle is farther away or that it is not there. As with the approaches in [2] [8]
[17] this will lead to interpreting range readings toward the maximum range of the sensor as
specular reflection. In contrast, instead of using a limit that throws away the data, [16]
applies specular reflection probability to reduce the confidence of the reading. The Range
Confidence Factor is used to reduce the confidence in the range of long range readings. This
will reduce the amount that a cells probability of occupancy will be incremented if that cell
is at a long range from the sensor.
The orientation probability indicates that the surface within a cell is oriented with a
certain probability. This probability is determined by collecting data at different locations for
the cell. In this sense it is somewhat like summing up all the Res state variables from [10] to
determine the orientation of the surface. The orientation probability is used to affect the
confidence of a range reading. Remember that the incidence angle of the sensor beam is also
a major parameter for specular reflection. If a cell appears to return a response but the
orientation probability indicates that the surface orientation is such that the angle of
incidence is high then the probability of occupancy should not be incremented as much as if
the incidence angle was low.
Standard sonar sensors have very poor angular resolution because of their wide
beam widths [2] [6] [8] [10] [16] [17] [22], This makes it is necessary to combine range
readings for a cell from a number of different positions to determine the probability of
whether a cell is occupied or unoccupied.
12


As an illustration of how this works assume that one reading indicates that there is an
object along an arc at a particular range. A second reading that indicates empty space
intersects the first arc. The area of intersection could be considered have a increased
probability of being empty or that the surface orientation of the cell is such that it provided a
better return from one position than another. This information will cause the probabilities of
occupancy and emptiness to be updated for the cells in the two sensor sweeps. As more data
is accumulated for a cell the probabilities will approach the real state of the cell.
Grid-based approaches suffer from space and time complexity [11] [26], especially
as the size of the environment represented grows. Moravec [17] mentions that the grid
representation was somewhat reluctantly adopted at Carnegie Mellons Mobile Robot
Laboratory. This reluctance may have been related to the amount of memory required to use
a grid-based map.
[12] and [19] address the space and computational complexities of grid-based
approaches by using tree structures to reduce the amount of data needed to represent an
environment. These tree structures are called Quadtrees and Octrees based on the maximum
number of children, four and eight, respectively, that a node in the tree may possess.
Quadtrees are commonly used to represent two-dimensional areas while Octrees are normally
applied to three-dimensional spaces [12],
The root node of the tree represents the entire grid map and the subsequent
generations of child nodes recursively partition the map into smaller and smaller areas.
Nodes can represent empty space, occupied space, or partially occupied space. Empty and
occupied nodes have no children while partially occupied nodes have the maximum number
13


of children (4 or 8) for the type of tree. In this way a single node can be substituted for a
large number of grid elements and reduce the memory required for the representation [12].
To summarize, grid-based approaches are a popular way to represent the
environment that a robot is traversing. This is in spite of the specular reflection and angular
resolution problems associated with the sonar sensors that are commonly used to provide
input to these maps. Ultrasonic sensors are attractive for use because of simplicity, low cost,
and distance measurements that are provided directly [8]. These distance measurements can
be directly placed into a grid-based map or modified to take into account uncertainties due to
specular reflection and angular resolution. Grid-based approaches suffer from space and time
complexity as the environment represented grows larger. Tree structures have been used to
reduce the memory required by grid maps.
2.3 Topological Representations
A topological map provides a high-level description of an environment that is
dependent on the structure and features detectable in that environment [19]. A topological
map could be a simple list of features [19] but more commonly the underlying
implementation is a graph [4] [7] [26]. The nodes in the graph represent interesting locations
or features found in the environment. These interesting locations, such as a room or a
corridor intersection, act as recognizable landmarks. The arcs of the graph can represent the
path between distinct places, like a hallway or a doorway, or the transitions between features.
Figure 2.3 shows a simple topological map with arcs representing hallways and numbers
indicating interesting areas, such as offices, intersections, etc., that were identified in the
exploration of an area.
14


7
1 --------- 2 ------------- 6
4 3 8 ---------- 9 --------- 12
Figure 2.3: A Simple Topological Map
Topological models usually provide a more compact representation of the
environment than grid-based approaches [7] [26]. They are also somewhat more intuitive
than grid-based approaches in the sense that they recognize distinct or recognizable areas in
the way a person might [7] [11]. Topological maps express the environment in terms of
landmarks, such as those mentioned to allow a robot to find the nearest copier machine from
Chapter 1.
Topological maps can be constructed directly by accumulating nodes and arcs as a
robot navigates through an environment or by translating another representation into a
topological map. Other representations that have been translated into topological maps
include grid-based maps [8] [26] and clusters of points that were assembled by a neural net
[11].
Elfes [8] approach uses a hierarchy of maps. The grid-based maps are the first level,
called the sensor level. The second level is the geometric level, created by identifying groups
15


of cells with high probabilities of occupancy and labeling them as unique entities, such as
desks and chairs. The third level is the symbolic level. The maps at this level are topological
in nature and contain information about larger areas than the maps on the lower two levels.
Nodes may represent interesting areas where additional information is provided or they could
represent corridors.
Thrun and Bucken [26] also build a topological map of the environment based on a
grid-based representation. To accomplish this the free space of the grid map is partitioned
into a number of regions separated by critical lines. Critical lines correspond to narrow
passages such as doorways. The partitioned map is then converted into a graph. The regions
are mapped to nodes and the critical lines, that is, the paths between the regions, become
arcs.
Pure topological approaches often have difficulty telling two different locations that
look alike apart, especially if they have been reached by different routes. This is because
topological approaches primarily use the robots position relative to landmarks to determine
where they are in the environment. The methods described in [8] and [26] use grid-based and
topological maps in combination to distinguish different locations that look alike
topologically. Accessing the position data available from a grid map makes differentiating
topologically similar locations easier.
Janet, et al., [11] use the combination of a neural network and hyper-ellipsoid
clustering to create a topological map. Hyper-Ellipsoid Clustering (HEC) groups sets of
points obtained from sonar data into elliptical areas. The elliptical areas filter out outlying
data points. By using a hill-climbing algorithm the data presented by the HEC Kohonen
16


method can be used for location recognition. The approach presented does identify large-
scale features like corridors as areas of open space but the primary focus is on identifying
and utilizing collections of line segments as landmarks.
Chong and Kleeman [5] use a grid map and a topological map in concert. The grid
map is used for obstacle avoidance while the feature-based map is used for localization.
Features are classified as planes, comers, edges, or unknown. Unknown features are not
added to the topological map. One interesting note about the grid-based map is that the cells
have occupancy and distance information associated with them instead of probabilities of
occupancy and emptiness.
Bulata and Devy [4] use a hierarchy of models to build a topological representation
of an environment, similar to [8] and [26], but do not use grid-based, maps. Another
difference is that the robot in this research uses a laser range finder instead of sonar sensors
to acquire information about its environment. The basic building block in this approach is a
landmark. Landmarks are defined as a set of line segments and include doorways, with and
without doors, portions of corridors, and geometric features found in rooms and corridors.
Only useful [4] landmarks in the data are extracted and used to construct the geometric
map.
The geometrical model contains information about landmarks. The symbolic model
groups landmarks into areas. An area corresponds to a complete entity such as a room or a
corridor. The topological model is a map composed of areas which define the entire known
environment of the robot.
17


Dudek [7] uses an approach that is very similar to that presented in [26], Grid maps
of local areas are merged together into a topological representation. The topological map is
composed of metric regions that have position and distance data collected for them, non-
metric regions that serve as parts of a topological link between metric regions, and unknown
regions that have not been visited by the robot. An office or other interesting location
would be an example of a metric region. A hallway could be a non-metric area.
Line segments are used to model collections of observations of the environment.
Each segment can be thought of as representing a section of a wall or other obstacle. Line
segments that are close together and parallel or near parallel are merged together.
Large-scale features could be generated from the grid maps but are not because this
would require domain specific assumptions about the environment. Dudek [7] cites the
example of an office building which would require rules and constraints such as typical
offices having rectilinear orientations and hallways and doors having standard widths.
It is interesting to note that the research presented in this thesis uses rules very much
like those mentioned in [7] for identifying large-scale features. However, this work doesnt
depend on the types of restrictive assumptions that Dudek feels are necessary for performing
feature identification. Also in contrast to Dudek, there was no concept of applying this
methodology outside of an office building environment.
Kunz, Willeke, and Nourbakhsh [14] present a method that constructs a topological
map mainly based on the movements of the robot, not on direct usage of sensor data. This
paper assumes that the environment the robot is in is rectilinear and that hallways have a
particular width for a specific building.
18


One assumption that was made is that sequential hallway intersections are at least six
feet apart. This is supposed to help differentiate between changes in one hallway and a new
hallway. Thus a staggered intersection is not allowed or would not be recognized. Figure
2.4 shows this situation.
Less than 6 feet
Figure 2.4: Staggered Hallway
The map that the robot produces is a graph that represents the topology of the office
building the robot is in. Nodes represent intersections and hallway transitions. Nodes contain
location information about location and whether adjacent nodes had been visited. The arcs of
the graph have distance information associated with them.
The approach in [14] does identify large-scale features. These features fall into three
categories: intersections, hallways, and open areas. An open area is defined as a path through
a physical open area and is differentiated from a hallway based on the expected width of a
hallway. This work has more in common with this thesis that any other paper surveyed. It
19


describes identifying large-scale features and using these features to understand and
represent the environment.
Topological maps provide a high-level representation of an environment and are
usually more compact than grid-based maps modeling the same environment. These models
are often used for localization but not for navigation since they do not explicitly represent
free space [19].
Topological-based approaches have the concept of identifying features but usually
on a smaller scale than in this research. One approach [14] does identify hallways, open
areas, and intersections but only as artifacts of constructing a topological map. Various
methodologies for identifying features are presented in the next section.
2.4 Feature Identification
Of the papers that discussed grid-based approaches only Moravec [17] described the
possibility of identifying objects directly from the grid representation. Tasks such as tracking
corridors and identifying doors and desks are mentioned but apparently left for future work.
Some topological approaches [4] [11] [14] dealt implicitly or explicitly with assembling
and/or identifying large-scale indoor features such as corridors or rooms. Most approaches,
however, deal with the identification of small-scale features. Methodologies for identifying
features are presented in this section.
Barshan and Kuc [1] present a method for distinguishing a planar feature, such as a
section of wall, from a comer. They describe, an intelligent sensor that uses multiple
ultrasonic transducers to detect differences in amplitudes and travel times of the pulses
emitted by the transducers.
20


The approach in [1] is based on the concept of a virtual receiver. If there are two
sonar sensors pointing at each other, one acting as a transmitter and the other acting as a
receiver, then it is possible to determine the distance between them using the amplitude of
the signal at the receiver and the angle of incidence between the two sensors. Figure 2.5
shows the geometry of a transmitter and a receiver.
Now instead of a transmitter/receiver pair, imagine a single sensor and a feature, a
plane or a comer, that it is facing. Since indoor features are good reflectors of sound they act
as mirrors. Thus, it is possible to place a virtual receiver on the other side of the feature
feature acts as if it was received by the virtual receiver. Planes and comers are differentiated
by the sign of the angle of incidence of the received signal. Figure 2.6 shows this
arrangement for planes and comers.
Transmitter
Receiver
Figure 2.5: Sonar Transmitter and Receiver
and calculate the distance to this phantom sensor because the reflected signal from the
21


Figure 2.6: Angle of Incidence for Planes and Comers
Politis and Probert [24] extend the work of [1] by using a Continuous Transmission
Frequency Modulated (CTFM) sonar. This system uses a frequency-based approach to
determine the type of feature. This method allows for the identification of planes, comers,
and edges.
22


The return signal seen by the receiver is mixed with the signal being emitted by the
transmitter. Filtering is performed to produce a signal with only one frequency. This
frequency is directly proportional to the range of the object that reflected the signal. Planes
and comers are differentiated by the sign of the angle of incidence of the signal. Edges only
return a fraction of the signal transmitted since most of the energy is reflected away from the
sensors.
Using this approach experiments were run to map the boundaries of a room. This
was successfully accomplished but no attempt was made to classify the room as an object or
feature itself.
Kleeman and Kuc [13] also extend the work presented in [1]. Similar to [24] this
approach is able to distinguish between planes, comers, and edges. The concept of an
unknown reflector type is also added. This paper identifies edges to include highly curved
surfaces along with convex comers.
This method does not use amplitude measurements to determine range as in [1]. This
is because the method in [1] will not provide accurate characterization of edge features. By
using two transmitters and two receivers the difference in angles of the signal bearings will
indicate the type of feature. A plane will have a positive difference, a comer will have a
negative difference, and an edge will have a value of zero. Time of flight information is used
in distinguishing edges from planes and comers. If a feature has a low confidence level
associated with it, it is classified as unknown.
Ohya, Nagashima, and Yuta [22] present work that is very similar to [1] and [13]. In
this case the primary purpose is to identify walls. This work highlights the fact that it is
23


possible to find long walls but it is difficult to find small walls, or indentations in walls, that
can only be seen from a very small area within a room or corridor.
Horst [9] presents an algorithm to convert a certainty grid representation into object
boundary curves. The object boundary curves are represented as piece-wise linear segments.
These boundary curves could then be used to detect higher-level features. It should be noted,
however, that the higher-level features in the context of this paper are comers, curves, and
lines.
The methodology developed by Chong and Kleeman [5] identifies partial planes and
comers and then uses a Julier-Uhlmann Kalman Filter (JUKF) to merge these elements into
a map of the environment. Newly identified planes are only merged with the partial plane
that is adjacent to them to prevent doorways from being closed off erroneously.
A partial plane is-described by its state parameters, the coordinates of its
approximate endpoints, and endpoint status. Endpoint status indicates whether an end
terminates with another plane to form a comer. When a wall is first detected it appears as a
partial plane with only one endpoint. A comer is characterized by its coordinates only. The
technique used in this paper [5] is unable to determine if a comer is concave or convex.
To eliminate false targets, the positions from where the robot took observations are
maintained. When the map is sufficiently complete filtering is performed by checking the
line of sight from the observation point to the false target. If a partial plane blocks the line of
sight and the false image is far enough away from the plane, the false target can be removed.
Localization is performed and then the feature fusion is done using the estimated
robot position. Removal of redundant features is also performed. That is, if two partial planes
24


are adjacent and co-linear, they will be merged into one feature. In this way features can be
expanded.
Lacroix and Dudek [15] associate the arcs of sonar scans with a set of real world
primitive features. This approach has the robot rotate in place for a number of revolutions to
collect sonar data. This is in contrast to approaches in [1] [5] [13] [22] [24] that identify a
small-scale feature by taking data from a single position or multiple positions and apply a
squared error or Kalman Filter method to the data.
The set of data taken after several rotations of the robot is used to produce a sonar
scan. The arcs that are a part of one of these scans are called Regions of Constant Depth
(RCDs) because they indicate an object is located at a constant radius along the arc. RCDs
are matched against a set of primitive features. The primitive features include Wall, Comer,
Edge, Cylinder, Cluttered Area, and Multi-Bounce RCD. A Cluttered Area is an object such
as a chair, shelves, etc., that generates RCDs but is not identifiable as a Wall, Comer, etc.
Multi-bounce RCDs are caused by multiple reflection echo due to the specular nature of the
environment.
Features are differentiated based on the angular width of the Region of Constant
Depth and a priori Bayesian probability density functions. An RCD corresponds to one of
the primitives in the above set. A hypothesis is created that represents a correspondence
between one RCD and one primitive. It is possible that a single RCD could potentially be a
number of different features, so a hypothesis would be created for each of these possibilities.
Each hypothesis would have an associated probability of existence.
25


As the robot moves through the environment scans are taken to produce RCDs from
different positions. RCDs developed at different positions are matched to find the Regions of
Constant Depth that correspond to the same primitive feature. Matching can also be used to
differentiate Wall RCDs from Comer and Edge RCDs since RCD orientation remains the
same for Walls but changes for other features.
Features are linked together by applying two rules to the current set of identified
features. One rule states that each Wall is ended by an edge, a comer, or a cluttered area. The
second rule is that each Edge or Comer is supported by two walls that are normal or parallel.
Walls, Comers, and Edges are complete when their supporting primitives are identified.
Work has also been done in the area of feature identification for Autonomous
Underwater Vehicles (AUVs) [25]. The methodology in this paper makes use of a Kalman
Filter to project feature hypotheses into the future. Hypotheses are associated with the type
of feature that may be being detected. This implies that there could be multiple hypotheses
for one detected feature. Hypotheses are pruned by additional measurements until only one
hypotheses is left.
As an example, a measurement might indicate that a feature is a plane or a curve.
The algorithm assumes the feature is a plane but subsequent predictions are generated both
for the feature being a plane and for it being a curve. Once a hypotheses has been satisfied
the incorrect branch can be pruned. Hypothesis trees can also be pruned when a set number
of hypothesis branches is reached or a time limit is reached.
While the authors of [25] state that distinctive features can be identified and
mapped there is no specific mention of the type of features to be detected. This is somewhat
26


surprising, especially in light of the fact that the paper represents its approach as a means of
encoding a priori knowledge of the environment. Based on the example of trying to identify
a plane versus a curve it would be reasonable that the granularity being explored is
equivalent to land-based studies that identify comers, walls, etc.
In summary, there has been a great deal of work done in the area of feature
identification and in the closely related topic of map representation for a mobile robot. The
motivation for this research was to improve robot navigation, localization, obstacle
avoidance, or a combination of these. This thesis differs from the majority of this work based
on the goal of identifying large-scale features such as corridors and intersections instead of
comers and partial sections of walls. One paper [14] did identify large-scale indoor features
explicitly to construct a topological map of an office building. While the number and type of
features identified was much simpler in [14] than in this research, it provides confirmation
that the identification of complete features is a reasonable approach to describing an indoor
office environment.
27


3. Approach
This chapter covers the tools that were used in the performance of this work.
Information regarding ultrasonic sensors, the robot platform, large-scale features in an
indoor environment, and an overview of the C++ software program is presented.
3.1 Overview
This research utilizes a mobile robot with a suite of ultrasonic sensors to detect the
features of an indoor environment. In defining this research a number of decisions were made
regarding the implementation. These decisions are listed below.
1) Make use of an off-the-shelf robot with simple sensors versus a specially made
robot and/or sensor suite. This would demonstrate that non-specialized robots
can perform productive work.
2) Use a simple algorithm for the identification of environmental features.
Specifically, the sonar data obtained by the robot would be used directly in
identifying features with a minimum of filtering and manipulation.
3) Identify complete or large-scale features in the environment as opposed to
components of these features such as walls and comers.
To perform its task, the robot is instructed to move a specified distance down a
corridor. Along the way the robot collects sonar data and processes it. When a feature is
detected the robot informs the user of this event.
28


The following sections present information about the ultrasonic sensors used, the
robot, and the software written to control the sonar data collection and feature identification
tasks.
3.2 Ultrasonic Sensors
3.2.1 Theory
Ultrasonic or sonar (SOund Navigation And Ranging) sensors are commonly used on
mobile robots that are meant to operate in an indoor environment [6], The information
provided to a user by the sensor is a single number representing the distance measurement
from the sonar transducer to the closest obstacle to it.
The ultrasonic sensors used in this research are time-of-flight sensors, i.e., these
sensors measure the distance to an object by emitting an energy signal, in this case sound
energy, listening for the echo, and dividing the time between the original signal and the
return echo by two [21].
R C(Techo Tsigna^/2 (3.1)
where R is the range or radial distance from the sensor to the closest object and c is the speed
of sound. The value of c is:
c = 331.4(T/273)1/2 m/sec (3.2)
where T is the temperature in degrees Kelvin.
Most sonar transmitters, like Radio Frequency (RF) transmitters, do not emit their
energy in an infinitely narrow beam or uniformly in all directions, but rather in a set of
29


shaped beams, or lobes. The transducers are designed such that the majority of the energy is
contained in the main lobe. Figure 3.1 (from [21]) illustrates this point.
Figure 3.1: Sonar Transducer Lobes
As the sonar pulse moves farther away from the transmitter the area covered by the
main lobe increases. Thus, the return that a sonar sensor receives is no more and no less than
an indication that there is something at a radial distance R along an arc that is bounded by the
beam width of the sonar pulse at distance R. This uncertainty causes great difficulty in
determining the exact location of an object [6] [8] [10] [16] [22], It should be noted that this
uncertainty in the actual location of an object will decrease as the sensor gets closer to the
object. Figure 3.2 shows the cross section of a sonar beam.
30


Figure 3.2: Cross Section of a Sonar Beam
Sonar sensors are sensitive to changes in temperature and humidity since these affect
the speed of sound in air [6] [8] [20]. As temperature and humidity increase the amount of
attenuation an ultrasonic signal will experience increases also. For a frequency of 50 kHz,
attenuation can range from 0.6 to 1.8 dB/meter for temperature ranges of 17 to 28 C and
relative humidity ranges of 15 to 70 percent [20], This should be less of a problem in an
indoor environment where these factors can be controlled by air conditioning. Indoor
environments should provide range readings that will be consistent over time.
The surface characteristics of objects in the environment and their orientation to the
main beam of the sonar will also affect the range readings of an ultrasonic sensor. Most
interior surfaces act as mirrors for sound waves and if the surface is at an angle to the sonar
beam, the return echo will be reflected away from the sensor. This will cause the object to
appear to be farther away or to not be detected at all [3] [6] [10]. Brown [3] describes the
problem as follows:
Using an ultrasonic sensor to look at arbitrary objects in a room is rather like
standing in a room completely filled with mirrored objects and having only a penlight glued
to your forehead as a source of light: specularity abounds and many surfaces are not visible.
31


The reflectivity or absorption characteristics of surfaces also can change the signal
intensity of the echo received by the transducer. The differences in signal intensity can
influence the rise time of the return echo in the sensor and cause more reflective objects to
appear closer[6].
3.2.2 Polaroid 600 Ultrasonic Sensor
The Polaroid 600 ultrasonic sensor uses its transducer as both a transmitter and as a
receiver. At the start of a ranging cycle a train of 16 transmit pulses at 49.4 kHz is
transmitted by the transducer. To eliminate false readings caused by the transducer ringing
the receiver circuitry is disabled for a brief period. Following the blanking period, the
transducer acts as a receiver [20] [21].
The Polaroid 600 sensor can measure distances from 6 inches to 35 feet (420 inches)
with an accuracy of +/- 1 percent over the range. The system used on the Scout robot restricts
the range from 17 inches to 255 inches. The beam width of the sensor is 25 [20] [21],
The sonar configuration of the Nomadic Technologies Scout robot has a ring of 16
Polaroid sensors spaced at 22.5 around the circumference. Figure 3.3 is a picture of the
sonar ring. Figure 3.4 shows the arrangement of the sonar sensors in the sonar ring.
32


Figure 3.3: Sonar Ring of the Scout Robot
13
12
11
Figure 3.4: Arrangement of the Sonar Sensors
33


3.3 Robot
A Nomadic Technologies Scout model was used in this research. An Application
Programmers Interface (API), written in the C programming language, is provided with the
robot and provides the means with which to control the robots movements and to collect
data from the sonar ring. Figure 3.5 is a picture of the robot.
The robot can be controlled by user supplied software that runs in the Linux
operating system environment. This software can run on a laptop computer that is attached to
the Scout robot directly or on a workstation that communicates with the Scout via Radio-
Ethernet. This research used the workstation/Radio-Ethemet configuration for controlling the
robot. Figure 3.6 provides a diagram of this configuration.
34


Figure 3.5: Nomadic Technologies Scout Robot
35


Linux Workstation
Figure 3.6: System Configuration
3.4 Software
The movement and data collection of the robot and the feature identification
algorithm are implemented in a C++ software program. This program was developed using
the GNU g++ compiler and the Nomadic Technologies API. The program runs in the Linux
OS environment.
The C++ program begins by initializing the robot in preparation for movement and
the collection and processing of sonar data. The robot is commanded to traverse a corridor
and collect sonar data at approximately fixed distance intervals (0.5 inches). The raw sonar
data sets are collected into groups of specified size (one or six) and are averaged together.
The averaged sonar data is compared to a set of feature patterns which represent the various
36


indoor environmental features. The averaged sonar data is matched against rules, i.e., what
the sonar data should look like, that uniquely identify one feature from another. As features
are detected position data and the sonar data used for identification are associated with the
feature. The detected features are logged and a report of the data collected is generated when
the robot reaches the distance it was commanded to travel. For a flow chart of the program,
see Figure 3.7. Refer to Appendix A for the program itself.
The features mentioned above are complete features found in an interior
environment such as corridors, alcoves, etc. This Feature Set encompasses knowledge of the
environment that the robot will be operating in. If the robot detects a feature that does not
satisfy any of the available rules then the feature is identified as unknown. While there is no
a priori map that the robot can refer to, there is a priori knowledge about the type of
environment it will be operating in [25]. Of course, it would be possible to add new features
to the Feature Set to handle alternative environments. The Feature Set is presented in the
following section.
37


Figure 3.7: Flow of the C++ Program
38


3.4.1 Feature Set
This work is based on the identification of large-scale features in an indoor
environment. As opposed to being represented as occupied and unoccupied cells in a grid-
based map or as a collection of planes, comers, etc., the features identified represent
complete entities or components of the environment. Figure 3.8 is the set of features that
were expected to be seen in the environment in which the robot was operating.
The features in this set are geometrically simple, angular, and rectilinear, as can be
seen in Figure 3.8. A rectilinear environment implies that the angles where features meet are
90 or 180. The feature identification approach of this thesis was only tested in a rectilinear
environment. This is because the test environment, the North Classroom building of the
Auraria Campus, is composed of these shapes. Brief descriptions of the members of the
feature set are below.
Corridor A feature that appears long and narrow, i.e., the distances in front and
back of the robot are significantly greater than those to the sides of the robot. For this
work an aspect ratio of 3 (distance front and back > 3 x distance to the sides) was used
(Figure 3.8a). This definition of a corridor eliminates the assumption of a specific corridor
width. Figure 3.9 presents a graph of the predicted sonar data for this feature. The graph
shows the expected range reading for each of the sonar sensors in the robots sensor ring
starting at sonar 0 and wrapping around the ring back to sonar 0.
39


n'r
j L
n r
a) Corridor b) Four Way Intersection c) Up T Intersection
~i r
d) Across T Intersection
e) L Intersection
L j L
r h r
g) Dual Alcove h) Corridor End
i) Alcove End
j) Dual Alcove End
Figure 3.8: Indoor Feature Set
40


Figure 3.9: Predicted Sonar Data for a Corridor
Four Way An intersection of two corridors where both corridors continue on for some
distance. Around the center of this feature distances to the front, back, and sides of the
robot are long (Figure 3.8b). Figure 3.10 shows the predicted sonar data for this feature.
Sonar Number
Figure 3.10: Predicted Sonar Data for a Four Way Intersection
T Intersection An intersection of two corridors where one of the corridors ends. For this
research two features represent this concept: Up T and Across T. An Up T is detected by
41


the robot when it is moving up the lower part of the T (Figure 3.8c). An Across T is the
situation where the robot is moving across the top of the T (Figure 3.8d). Predicted sonar
data for going up a T intersection and across a T intersection are shown in Figures 3.11 and
3.12, respectively.
Sonar Number
Figure 3.11: Predicted Sonar Data for an Up T Intersection
Sonar Number
Figure 3.12: Predicted Sonar Data for an Across T Intersection
42


L Intersection An intersection of two corridors where both corridors end. The robot
would detect a long distance to the rear and to one side (Figure 3.8e). Predicted sonar data
for this feature is shown in Figure 3.13. This graph assumes that the robot is entering the L
such that one corridor is behind the robot and the other is to the right of the robot.
Sonar Number
Figure 3.13: Predicted Sonar Data for a L Intersection
Alcove A feature where one side of a corridor is wider than the normal width of the
corridor for some distance (Figure 3.8f). Figure 3.14 presents the predicted sonar data for
this feature.
Sonar Number
Figure 3.14: Predicted Sonar Data for an Alcove
43


Dual Alcove Similar to an alcove except that both sides of the corridor are wider than
normal (Figure 3.8g). Predicted sonar data for this type of feature is shown in Figure 3.15.
Sonar Number
Figure 3.15: Predicted Sonar Data for a Dual Alcove
Corridor End A feature that represents the end of a corridor. It differs from a corridor in
the fact that one end is closed (Figure 3.8h). Figure 3.16 presents predicted sonar data for a
Corridor End.
Sonar Number
Figure 3.16: Predicted Sonar Data for a Corridor End
44


Alcove End A corridor end with one side wider than is normal for the corridor (Figure
3.8i). Figure 3.17 represents the predicted sonar data set for this feature.
Sonar Number
Figure 3.17: Predicted Sonar Data for an Alcove End
Dual Alcove End A corridor end where both sides are wider than normal for the corridor
(Figure 3.8j). A graph of predicted sonar data for a Dual Alcove End is shown in Figure 3.18.
Sonar Number
Figure 3.18: Predicted Sonar Data for a Dual Alcove End
45


As mentioned in the ultrasonic sensor section above, one source of uncertainty in
sonar readings is caused by the beam spreading as it gets farther away from the sensor. The
approach used in this work to detect features actually makes use of this fact. Patterns can be
detected by using sonar readings from different sensors that are taken at the same time and
location. The mechanism for matching sonar data to a feature pattern is by applying a set of
rules that the feature pattern contains to the collected sonar data. The rules of a feature
pattern are used to differentiate it from other feature patterns.
When sonar data is processed it is matched against the rule sets of each feature
pattern. The feature pattern with the highest matching percentage identifies the feature that
the sonar data described. The matching percentage for a feature is determined by dividing the
number of rules satisfied by the total number of rules the feature contains. Thus, if the sonar
data satisfies all the rules for a particular feature it will have a matching percentage of 100.
Matching Percentage = # of rules matched/# of rules (3.3)
If there is more than one feature pattern with the highest matching percentage a
simple tie-breaking algorithm is used. If one of the best matches is a corridor, it will be
identified as the feature. If one of the best matches is a four way intersection it will be
selected unless one of the other candidate feature patterns is a corridor. Otherwise, the first
feature detected with the highest matching percentage is identified as the feature.
3.4.2 Rules
When sonar data is being compared to the various features to determine which
feature the data matches, the range readings are actually being applied to a set of rules that
46


each feature pattern contains. It is how well the sonar observations conform to one of these
rule sets that determines what feature the robot identifies.
Brief descriptions of the rules are presented below. Table 3.1 identifies which rules
are used by which feature patterns.
BackLongRuIe This rule is used to check whether the sonar data indicates there is a
distance greater than or less than the threshold for long distances to the rear of the robot. If
the value is greater than the threshold the rule is true.
CorrRule This rule is used to check whether sonar readings indicate that the aspect ratio
of the forward and backward pointing readings to the left and right facing readings is above
or below a set value. If the aspect ratio is greater than the threshold the rule is true.
FrontLongRule If the reading for the sonar pointing directly forward is greater than
the specified long threshold then there is open area for a long distance in front of the robot.
In this case the rule returns true.
FrontShortRule This rule is used to check for obstacles near the front of the robot. If the
reading for the sonar facing directly forward is less than the specified short threshold then
the rule is true.
SidelnterRuIe The rule is true if there is an object at a distance between the short and
long thresholds to one side of the robot.
47


SideLongRule This rule returns true if either the sonar facing directly to the left or
directly to the right of the robot indicates a long open area.
SideShortRule This rule is true if the range reading for the sonar sensor facing directly
left or the sonar sensor facing directly right is less than a specified threshold.
TwoSidelnterRule This rule returns true if there are obstacles to both sides of the
robot at distances that are between the short and long threshold values.
TwoSideLongRule This rule returns true if the sonar sensors that directly point left and
right indicate that there are long open areas to the sides of the robot.
TwoSideShortRule This rule is true if the readings for both of the side-facing sensors is
less than a specified threshold.
48


Rule Feature
BackLongRule Corridor Four Way Intersection Up T Intersection Across T Intersection L Intersection Alcove Dual Alcove Corridor End Alcove End Dual Alcove End
CorrRule Corridor
FrontLongRule Corridor Four Way Intersection Across T Intersection Alcove Dual Alcove
FrontShortRule Up T Intersection L Intersection Corridor End Alcove End Dual Alcove End
SidelnterRule Alcove Alcove End
SideLongRule L Intersection Across T Intersection
SideShortRule L Intersection Alcove Alcove End
T woSidelnterRule Dual Alcove Dual Alcove End
TwoSideLongRule Four Way Intersection Up T Intersection
TwoSideShortRule Corridor Corridor End
Table 3.1: Rule to Feature Mapping
49


The match function of a rule performs the test to determine whether the sonar data
satisfies the rule or not. Figure 3.19 shows the match function from FrontLongRule. The
complete code for all the rules may be found in Appendix A.
bool FrontLongRule::match(const vector ktheData) const
{
return (getFront(theData) > itsThreshold) ? true : false;
}
Figure 3.19: match Function from FrontLongRule
50


4. Results
4.1 Overview
This chapter covers experiments conducted using the robot and software described in
Chapter 3. This system was tested in several runs at different locations within a building. The
system was able to properly identify the features it traversed. The results of identifying
individual features are presented first. A specific experiment to identify multiple features in a
single run is then discussed. A summary of the results is then presented.
4.2 Results of Individual Feature Identification
A series of experiments was run to ascertain whether the approach described in
Chapter 3 successfully identifies individual features. A typical experiment involved
configuring the distance for the robot to travel and the number of sonar readings to average
together for feature determination. Experiments were conducted using either single readings
or sets of six sonar readings averaged together for feature identification. All these values are
contained in the robot.cfg file. An example of the file is contained in Appendix B.
Once the software variable values had been set, the robot was placed in a feature,
usually a corridor, aligned to traverse the feature or set of features in as straight a line as
possible, and turned on. The software controlling the robot was then started and the
experiment proceeded. The robot would identify the initial feature it was in while moving but
as subsequent features were identified the robot would stop to give a visual cue that this
51


event had occurred. When the robot reached the prescribed distance to travel it stopped and
reported the features it had detected.
Sonar, feature identification, and debugging data were collected to files to allow
post-experiment analysis. The data collected for an experiment to identify a Corridor are
presented in Appendix B.
The features to be identified were presented in Chapter 3 as part of the feature set.
The results of identifying these individual features are presented in the following sections.
4.2.1 Corridor
A Corridor is composed of two walls and is long and narrow in shape. Figure 4.1 is a
scatter plot of the sonar data collected for a Corridor.
Robot view Show Refresh panels
Uindou tourtfc: LL<-000(K314.-00001803). U?(OOO)15.*OOOC1810)
Actual pcsJtlor: hot available :n real robot aods.
Encoder pcsitior: X=*CWM214 Y=-000CC00C S=0000 T=0O
Ccepass value: COCO
Previous comne: watt, l, 1. 2)
Units: coordinates = o.l inches: angles = 0.1 deyecs
Figure 4.1: Sonar Plot for a Corridor
52


The solid circle in Figure 4.1 represents the position of the robot at the end of the
run. The shapes and range values of predicted and actual sonar data for a Corridor are
plotted in Figure 4.2.
Predicted
Actual
(a) Predicted and Actual Sonar Shapes
Sonar Number
Predicted
Actual
(b) Predicted and Actual Sonar Ranges
Figure 4.2: Predicted and Actual Sonar Data for a Corridor
The important elements of the Corridor feature are large distance ranges to the front
and back of the robot, as reflected by the readings from sonar 0, the sonar which points
directly ahead of the robot, and sonar 8 which points directly behind the robot. Side readings,
from sonar sensors 4 and 12, would be much smaller because of the Corridors walls.
53


While the actual data matches the shape of the predicted data very well it is
interesting to note that the magnitude of the range readings to the front and back are smaller
than would be expected. This is discussed in Section 4.4.
During test runs Corridors were always successfully identified. One run did
demonstrate that if the robot was significantly offset from the mid-line of a hallway the
feature would be identified as an Alcove. This is because the rule set for the Corridor feature
looks for two walls at near range while the alcove feature rules expect one near wall and one
wall at a longer distance away.
Corridors and Alcoves were sometimes identified with equal certainty because the
Corridor Rule in the Corridors rule set was not true. As described in Chapter 3, this rule
looks at the aspect ration of the feature to see if the length is a set threshold longer than the
width. When the front, back, or both sonar sensors reported shorter than expected values,
this rule could be violated. Occasionally, a Corridor would be incorrectly identified as a
Corridor End due to short front range readings. These readings were transient and probably
caused by a strong reflection off of a comer or a highly acoustically reflective object.
4.2.2 Four Way Intersection
Four Way intersections occur when two orthogonal corridors cross each other and
both continue for some distance. Figure 4.3 is a scatter plot of sonar data for a Four Way
intersection.
54


Robot View Show Refresh Paneb
liinfcpy toutfsi L(H>XW4284.-C00C1454). lR(*OW2£S.000C145)
Actual position: fix available in real rubot node.
FnrwW* prwit.im* X=*0000lfc>(' Ys*OfifK000 SsfrttO "aftM
Ctwpass value: 0300
Previous comartd: w!l. 1, 1, 2)
Units: coordinates = 0.1 indies; angles = 0.1 degrees
Figure 4.3: Sonar Plot for a Four Way Intersection
The corridor that the robot was traversing and the comers where the two corridors
meet are easily identifiable. The cross corridor is not so well defined in the sonar plot. This
is not critical since the robot identified the feature as a Four Way intersection based on
having long ranges of open space to the front, back, and sides.
The first experiments to identify a Four Way intersection were not very successful.
The Four Way features were misidentified as Up T or Dual Alcove features. This was
primarily caused by setting the long threshold for the rules to 120 inches and the short
threshold to 60 inches. As noted above, long range readings were not as long as they were
expected to be. The long and short threshold values were lowered to 78 inches and 54 inches,
respectively, based on the data collected in various experiments.
The rule set for the Four Way pattern was also modified. The Four Way comer rule
(FWComerRule) was removed from the rule set. Analysis of sonar data showed that the
reasoning behind the rule was somewhat naive. In looking at a Four Way intersection it could
55


be expected that the comers would return short ranges while the hallways would return long
range readings. In actuality the comer areas return longer range readings that the open
corridors. This was most likely caused by specular effects. Figure 4.4 compares the shapes
and the range values of predicted and actual sonar data for a Four Way intersection.
Predicted
Actual
(a) Predicted and Actual Sonar Shapes
Sonar Number
Predicted
Actual
(b) Predicted and Actual Sonar Ranges
Figure 4.4: Predicted and Actual Sonar Data for a Four Way Intersection
With the changes to the threshold values and the Four Way rule set, these features
were always identified once the robot was into the feature. However, misidentifications do
56


occur frequently on entering and exiting a Four Way intersection. This is mainly caused by
one of the side sonar sensors seeing the cross corridor before the other. The pattern
matched in this circumstance was that of an Across T instead of a Four Way intersection.
Once the other side sensor received long range readings the feature was correctly identified
as a Four Way intersection. Averaging sonar readings together usually eliminated one
incorrect identification but did not eliminate them entirely. An interesting side note was that
the right side sensor (12) consistently detected a new feature first. This does not appear to be
caused by a misalignment of the left or right side sensors. It is possible that the main lobe of
sensor 12 is slightly wider than normal.
The misidentification of a Four Way as an Across T occurred because the front
sensor, back sensor, and a side sensor reported long readings while the other side sensor did
not see a long distance. This illustrates how other misidentifications can occur if one or more
sensor readings for a Four Way intersection do not report long. Instead of a Four Way the
sonar readings could match an Up T, an Across T, an Alcove, or a Dual Alcove.
57


4.2.3 Up T Intersection
Figure 4.5 presents the sonar scatter plot for an Up T intersection feature.
Robot View Show Refresh fanels



iL i<
FT
Hirdow bounce: U.(-<00W2-M,-O01649>, ffi^OOMjiS.^OOWieSo)
RcUal position: Net available in real robot no&.
Encoder position: X-O0C0145? Y-COOOOW S^COOO T-OOX
Cotuass value: (COO
rVeviouj cowad: nj(l, 1, 1, 2)
Units; coordinates 0.1 inches; angles : 0.1 degrees
Figure 4.5: Sonar Plot for an Up T Intersection
The scatter plot shows that the ultrasonic sensors detected the walls of the corridor
that the robot was originally traversing and the wall of the cross corridor thafit was
approaching. The cross corridor is indicated by the open spaces to the right and left of the
robot. Graphs of the shapes and range values for predicted and actual sonar data are
presented in Figure 4.6.
58


2
1
0
15
Predicted
Actual
(a) Predicted and Actual Sonar Shapes
Sonar Number
Predicted
Actual
(b) Predicted and Actual Sonar Ranges
Figure 4.6: Predicted and Actual Sonar Data for an Up T Intersection
The shape of the actual data matches closely with that of the predicted data. The
robot senses long ranges to the sides and rear with an obstacle or obstacles to the front. Once
again, a major difference between expectations and real data was the magnitude of the long
range readings.
As the robot approached an Up T it initially identified the feature as a Corridor. As it
moved closer to the T itself there was a period where the wall blocking its path was below
59


the long threshold but above the short threshold for the rules set. Misidentifications of the
feature occurred during this region.
Runs using one sonar reading for identification indicated that the robot had entered a
corridor end when the front range readings were between the long and short threshold values.
As with the Four Way features sonar 12 (right side) began detecting long ranges a few inches
before the left side sonar. This lead to the identification of the Up T as an L until the left side
sonar began reporting long ranges. If the cross corridor was wide enough then a Four Way
intersection was identified until the range from the robot to the wall in front of it dropped
below the short threshold. At this point the feature was correctly identified as an Up T and
did not change from this identification.
Experiments that averaged six sonar readings together for pattern matching produced
fewer misidentifications. Readings that had the right side sonar reporting long ranges before
the left side sonar were averaged with prior readings that would have matched a Corridor
feature. The result was that the entry into the Up T was identified as an Alcove. The
identification then switched to a Four Way intersection until the range to the cross corridor
wall dropped below the short threshold. The feature was then correctly identified as an Up T
intersection.
4.2.4 Across T Intersection
Across T intersections are related to Up T features by the fact that they are the same
feature but the robot approaches them from different directions. A sonar data plot for an
Across T is presented in Figure 4.7.
60


Figure 4.7: Sonar Plot for an Across T Intersection
The scatter plot very clearly shows the corridor that the robot was traversing. The
hash marks around the open area representing the other corridor are the comers where the
two corridors meet. The two bumps in the corridor on the left of the plot are half columns
which projected into the hallway. The intersecting hallway looks very much like the cross
corridor in the Four Way sonar plot. Comparisons of predicted and actual sonar data are
presented in Figure 4.8.
61


0
Predicted
Actual
(a) Predicted and Actual Sonar Shapes
Sonar Number
Predicted
Actual
(b) Predicted and Actual Sonar Ranges
Figure 4:8: Predicted and Actual Sonar Data for an Across T Intersection
The actual sonar data indicates long ranges to the front and back of the robot. One
side also has long range readings while the other side indicates an obstacle at short range.
The double hump of sonar sensors 2 through 4 may indicate specular reflection off the comer
to the front and left of the robot. The actual and predicted shapes match up very well.
There were no feature misidentifications when the robot transitioned into the Across
T from the Corridor and out of the Across T back into a Corridor in mns using one or six
62


sonar readings for feature matching. However, in the runs which used averaged data single
sonar readings indicating an Alcove or L feature were collected when the T was entered.
These data points were filtered out by the averaging algorithm. As indicated above, these
readings were caused by sonar returns that should have been long but were reported as short.
In these cases an Across T could be misidentified as an Alcove or an L intersection.
4.2.5 L Intersection
A sonar plot for an L intersection would show that the ultrasonic sensors had
detected the corridor that the robot was traversing, the wall of the intersecting corridor in
front of it, and open space to one side where the other corridor was located. Figure 4.9 is a
sonar plot of this type of feature.
Rnlmt Vbtw Show Rnfimh Panot*
Figure 4.9: Sonar Plot for a L Intersection
The half-circle in the corridor is a column that was not flush with the wall. The hash
marks across from the column indicate a doorway with the door closed.
63


For an L intersection it would be expected that the front sonar and one side sonar
would indicate short ranges while the back sonar and the other side sonar would report long
ranges. Graphs comparing actual sonar data to predicted sonar data for an L intersection are
shown in Figure 4.10.
Predicted
Actual
(a) Predicted and Actual Sonar Shapes
Sonar Number
Predicted
Actual
(b) Predicted and Actual Sonar Ranges
Figure 4.10: Predicted and Actual Sonar Data for an L Intersection
The shapes of the actual and predicted data match very well. The difference in
magnitude of the long ranges is not surprising given that this difference was seen before
64


when identifying other features. Another contributor could be the narrowness of the two
corridors forming the L where the tests were performed.
Experiments using raw sonar data, that is single instances of sonar data for feature
pattern matching, had no misidentifications transitioning from the Corridor into the L.
However, it should be noted that sometimes only 50% (2 out of 4) of the L intersection rules
were being matched. This was in the area where the wall in front of the robot was between
the long and short range thresholds and the back range reading dropped below the short
threshold.
Runs averaging six sonar readings together for feature identification displayed much
greater problems with correctly identifying the L intersection. The data shows that the
corridor was correctly identified and at the transition point to the L an L feature was
identified. However, this identification was quickly switched to an Alcove and then to an
Alcove End. While the L had rule matching percentages that equaled the Alcove and the
Alcove End, the algorithm preferred the other features when there was a tie.
At first it appeared that the averaging was causing this misidentification by having a
bad reading or readings affect the average values of the data used for pattern matching. The
real reason was that the range measurements for one of the side sonar sensors, number 4,
reported a value that was equal to the short threshold. It turned out that this value would
cause rules looking for short ranges and rules looking for a range between the short and long
thresholds to be satisfied. If this value only indicated a short range then the L feature would
have been correctly identified. The rules, SidelnterRule and SideShortRule, were modified
65


and the tests were rerun to prove this hypothesis. With these modifications the L intersection
was correctly identified.
4.2.6 Alcove
An Alcove looks something like an Across T except that instead of a long cross
corridor there would be a pushing out of the corridor. The sonar data plot for such a
feature is presented in Figure 4.11.
Robot View Show Refresh Panels
Uiradow bands: U.<-OOOU,-OOOolfci9>, UK*COOCWtt5,*OOCcieiO>
fictwl pcsJUor; Na callable :n real robot nodj.
Encoder position X=*d0011449 Y=-OOOOOOOC SsOOOO rsOODO
Ccspass value; (000
Previous ccmarc: wad. 1, 1. 2)
Units: coordinates = 0.1 inches: angles = 0.1 degrees
Figure 4.11: Sonar Plot for an Alcove
The plot shows the Corridor with the Alcove being the trapezoidal section pushed
out to one side. The expected shape of the sonar data for this type of feature would be to
have long ranges to the front and rear, a short range to one side, and an intermediate range,
one between the short and long thresholds, to the other side. Figure 4.12 compares predicted
and actual sonar data for this feature.
66


1
0
Predicted
Actual
(a) Predicted and Actual Sonar Shapes
Sonar Number
-----Predicted
-----Actual
(b) Predicted and Actual Sonar Ranges
Figure 4.12: Predicted and Actual Sonar Data for an Alcove
Tests using one data reading and six data readings for feature identification correctly
identified the Alcove feature. There were no incorrect feature identifications at the
transitions to and from the Alcove. It should be noted that if an Alcove were shallow enough
it would not be identified as a separate feature but would be considered part of the Corridor.
Deep Alcoves would be classified as Across T intersections.
67


4.2.7 Dual Alcove
A Dual Alcove could be considered halfway between a Corridor and a Four Way
intersection. As Figure 4.13 shows, a Dual Alcove looks like a Four Way intersection but the
ends of the cross corridor are detectable by the robots sonar sensors.
Figure 4.13: Sonar Plot for a Dual Alcove
The expected shape of the sonar data for a Dual Alcove would be to have long
ranges to the front and rear, and intermediate ranges to each side. Figure 4.14 compares
predicted versus actual sonar data.
Predicted
Actual
(a) Predicted and Actual Sonar Shapes
68


250 T
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0
Sonar Number
Predicted
Actual
(b) Predicted and Actual Sonar Ranges
Figure 4.14: Predicted and Actual Sonar Data for a Dual Alcove
The shapes of the predicted and actual data are very consistent. The valleys at
sonar numbers 2, 5, 11, and 14 would appear to be caused by returns off the walls of the
alcoves on either side of the corridor.
In all runs the right side sonar sensor, number 12, detected the start and end of the
dual alcove first. Thus, the identification of features went Corridor, Alcove, Dual Alcove,
Alcove, Corridor. It is possible to have a staggered Dual Alcove, that is, where an Alcove
starts (or ends) on one side of a Corridor before an Alcove on the other side of the Corridor,
but for most of the feature it is a Dual Alcove. Unless the stagger between the starts of the
Alcoves is significant, it would be very difficult to tell the difference between a real
staggered Dual Alcove and one that was created by one side sonar sensor detecting a feature
prior to the other side sonar sensor.
69


4.2.8 Corridor End
Arriving at the end of a Corridor the sonar sensors of the robot would produce an
image like that of Figure 4.15.
Robot '/lew Show Refresh Panels
Uiridu* Uwds. LU-00C04374,-4)00164)/ UR<-O0CO4375,
ffctual position: Not awailabl; in real robot rode.
Encoder position; X=-C0C814 OMOOoOO $=C0 7=0000
Coopass value: 00(0
frevixs command: wsU, 1,1, 2)
Uiits: coordinates = C.l inches: angles = 0.1 eegrees
Figure 4.15: Sonar Plot for a Corridor End
The sides of the Corridor and the end wall are clearly seen. The bulges on both sides at the
start of the Corridor are doorways.
The sonar range readings for a Corridor End would be expected to have a long range
to the rear of the robot and short distances to the front and sides. Figure 4.16 compares
predicted sonar data to actual sonar data collected in a Corridor End.
70


2
1
0
15
3
4
5
6
14
13
12
11
10
Predicted
Actual
(a) Predicted and Actual Sonar Shapes
Sonar Number
Predicted
Actual
(b) Predicted and Actual Sonar Ranges
Figure 4.16: Predicted and Actual Sonar Data for a Corridor End
While the shapes of the predicted and actual data are similar it is apparent that the
range readings to the back of the robot are much less than would be expected. The
explanation for this probably relates to the narrowness of the hallway in which the tests were
run. The comers of the doorways at the start of the corridor also provided much better
surfaces for returns versus flat walls that would have reflected most of the sound energy
away from the sensors.
71


In tests, identification of the feature fluctuated between Corridor and Corridor End
until the range to the wall in front of the robot fell below the short threshold. The changes in
feature identification were driven by the range readings obtained by the rear pointing sonar
sensor. When the readings showed a long range then a Corridor matched that data better.
When short ranges to the back of the robot were reported then Corridor End provided a better
match. Once the range to the front wall fell below the short threshold the Corridor End
feature was a better match than Corridor regardless of the range the rear-facing sensor was
reporting.
4.2.9 Alcove End
The Alcove End feature is a combination of the Corridor End and Alcove features.
This feature terminates a hallway but one side of the feature is wider than the normal
corridor width. Figure 4.17 is a scatter plot of sonar data for a feature of this type.
Figure 4.17: Sonar Plot for an Alcove End
72


As with the Corridor End, the sonar range readings for an Alcove End would be
expected to have a long range to the rear of the robot and a short distance to the front. One
side would have short range readings while the other would indicate intermediate ranges.
Figure 4.18 compares expected sonar data to actual data for an Alcove End.
2
3
4
5
6
0
1 15
14
13
12
11
10
7 9
8
Predicted
Actual
(a) Predicted and Actual Sonar Shapes
Sonar Number
Predicted
Actual
(b) Predicted and Actual Sonar Ranges
Figure 4.18: Predicted and Actual Sonar Data for an Alcove End
Similar to the actual data collected for the Corridor End, the range data to the rear of
the robot for the Alcove End feature is not very long. As with the Corridor End this is most
likely due to the narrowness of the hallway being used for the test.
73


In testing, the feature identification fluctuated between Corridor and Corridor End
until the range to the wall in front of the robot was less than the short threshold. The feature
was then identified as a Corridor End until the Alcove could be observed by a side facing
sonar. When this happened the feature identification was switched to Alcove End.
This misidentification is very similar to what happened in identifying an Up T
intersection. Until the robot was actually in the feature, in this case an Alcove End, the data
it was collecting matched another feature perfectly. Once it was in the feature a correct
identification was possible.
4.2.10 Dual Alcove End
A Dual Alcove End is very similar to an Up T feature. The major difference is that
the ends of the cross corridor are detectable by the robot sonar sensors in a Dual Alcove End.
A sonar scatter plot for this feature is presented if Figure 4.19.
Figure 4.19: Sonar Plot for a Dual Alcove End
74


The sonar range readings for a Dual Alcove End would have a long range to the rear
of the robot and a short distance to the front. Both sides would indicate intermediate ranges.
Figure 4.20 compares predicted sonar data to actual data collected for a Dual Alcove End.
2
3
4
5
6
0
1
7
15
14
13
12
11
10
9
8
Predicted
Actual
(a) Predicted and Actual Sonar Shapes
Sonar Number
Predicted
Actual
(b) Predicted and Actual Sonar Ranges
Figure 4.20: Predicted and Actual Sonar Data for a Dual Alcove End
As with the Corridor End and Alcove End, the shapes of the predicted and actual
data for a Dual Alcove End are similar but the magnitudes are off. Once again this is
probably due to the close confines of the area used for testing.
75


The experiments in identifying this feature followed the pattern of the Alcove End
testing. The feature identification fluctuated between Corridor and Corridor End until the
range to the wall in front of the robot was less than the short threshold. The feature was then
identified as a Corridor End until an Alcove could be observed by the right side facing sonar.
When this happened the feature identification was switched to Alcove End. Once the Alcove
on the left side was seen by the left side sonar sensor the feature was correctly identified as a
Dual Alcove End.
4.3 Results of Multiple Feature Identification
A set of experiments was run to verify that the robot could successfully identify a
series of features as it traversed an indoor environment. The tests were set up similarly to the
description in Section 4.2. The distance to be traversed for these experiments was set at 480
inches (40 feet). Tests were run with one of two values (one or six) for the number of sonar
data readings to average together for feature identification. Using one data reading provided
identification using raw data. Sets of six readings produced filtered or averaged data. The
short range threshold was set to 54 inches and the long range threshold was set to 78 inches.
The series of features that the robot maneuvered through was as follows:
Alcove
Corridor
Double Alcove
Corridor
Four Way Intersection
Corridor
76


One feature that was not part of the region to be traversed but that may have
impacted the test was an alcove end that terminated the corridor beyond the end of the test
area. This alcove end had glass walls on each side and a metal door facing the test region.
This area was acoustically very specular, a fact that became obvious when entering it and
having sounds echo back very strongly. To determine if this area affected the experiments
one test was run with a sound absorbing surface placed in front of it very near to the end of
the forty foot test distance. This.environment is depicted in Figure 4.21. The location where
the sound dampening material was placed is indicated by the dashed line.
Figure 4.22 is a photograph of a portion of the area the robot traversed. The metal
door of the alcove end can be seen in the picture. Figure 4.23 is a sonar plot of this
environment.
Start
End
Figure 4.21: Map of Multiple Feature Environment
77


Figure 4.22: A Portion of the Multiple Feature Environment
78


Figure 4-23: Sonar Plot for Multiple Feature Environment
In all tests the initial Alcove feature was correctly identified with the sonar data
matching the Alcove rule set 100%. The transition from the Alcove to the Corridor occurs at
approximately 44 inches into the run. The robot identified this feature change correctly.
This first Corridor feature was never misidentified though there were occasions
where the Corridor rule set was only matched 50% by the sonar data. This was caused in
locations where the range readings to the back of the robot dropped to 70 90 inches.
Averaging six sonar data readings together for feature identification eliminated this effect.
Entry into the Dual Alcove feature was detected by the right side sonar sensor first in
most tests. This caused the feature to be initially identified as an Alcove when using raw data
for feature identification. This identification changed when the left side Alcove came into
view of the left side sonar sensor. Tests using averaged data identified the Dual Alcove with
no incorrect identification of an alcove.
79


Once both side ultrasonic sensors could detect the Alcoves to either side of the robot
the rules for the Dual Alcove were matched 100%. The trash can at the start of the right hand
side Alcove had no effect other than to cause the right side ranges to report 20 inches shorter
than the left side until the robot completely passed the trash can. The trash can was observed
in the sonar readings for approximately 17-20 inches.
The transition from Dual Alcove to Corridor was detected by the right side sonar
sensor first. This caused an identification of an Alcove in all runs except one that used
averaged data. The Dual Alcove in this case was symmetric so the detection of Alcoves on
entering and leaving the feature were incorrect and not an indication that the Alcoves were
offset.
Immediately after exiting the Dual Alcove all the runs have a location or small
distance where the range'readings to the front of the robot drop. This caused all the raw data
tests and all but one of the averaged data runs to identity a Corridor End feature. This
location was from three to six inches in length. The averaged data experiments did not
always filter this data out due to the fact that the distance over which the data was filtered
was approximately three inches. This misidentification was probably caused by a sonar ping
being received by the forward pointing sensor that had been generated by a previously fired
transducer. The front facing sonar probably mistook this multi-bounce return as the return to
the ping it generated. There-are some comers in the corridor which could have causes the
multi-bounce effect.
After this small area the algorithm correctly identified the Corridor and maintained
this identification until the robot reached the Four Way intersection. Entering into the Four
80


Way intersection all runs except one averaged data test identified an Across T feature. This
was because the front, back, and right side sonar sensors were reporting long distances while
the left side sensor was seeing a short range. The one averaged data test reported an Alcove
instead of an Across T. This misidentification was caused by the fact that half the data
readings matched a Corridor and the other half matched an Across T. Averaging these
readings together yielded ranges that matched an Alcove feature.
Once the left sensor began reporting long ranges the intersection was properly
identified. Approximately three feet into the Four Way intersection front range readings
began to drop to levels that caused the algorithm to identify the feature as either a Four Way
intersection or as an Up T intersection. The feature matching algorithm will select a Four
Way over other features other than a Corridor, so the intersection was still correctly
determined to be a Four Way intersection. The front range readings continued to go up and
down through the rest of the intersection. Using averaged data reduced the impact of these
range fluctuations on feature identification.
One note of interest is that by the time the robot was entering the Four Way
intersection it was obvious that it was pulling to the right. The robot drifted to the right by
four to six inches by the end of a run in all tests. This had never been seen in previous tests
but did not appear to affect the identification of features.
The last feature in the test series was a Corridor. The runs using raw data identified a
transition from a Four Way intersection into a Corridor End instead of a Corridor. The data
shows that the front range readings were fluctuating above and below the short range
81


threshold. The correct identification of a Corridor was made when the front range value
would rise but the majority of readings indicated a Corridor End.
Test runs using averaged data identified an Alcove or Dual Alcove when moving
from the Four Way intersection into the Corridor. Averaging effects account for this as they
did when the robot entered the Four Way and identified the feature as an Alcove. The
averaged data runs that did not have sound deadening material across the Corridor identified
the feature as a Corridor End as the raw data tests had done. The test with the material in the
hallway correctly identified the feature as a Corridor and then identified a Corridor End
when the range to the material dropped below the short range threshold.
Except for the Alcove section and the first Corridor section all the features were
misidentified upon entry or exit in one or more of the runs. The averaged data runs did better
at correctly identifying features and maintaining that identification than the raw data tests.
This performance difference is even greater if single or transient feature identifications are
discarded from the runs. Table 4.1 compares the number of correct feature identifications to
the total number of feature identifications performed for runs using raw and averaged data.
Table 4.2 lists the features identified in the experiments with transient features discarded.
Data Type Number of Identifications Number of Correct Identifications Percent Correct
Raw 388 339 87
Averaged 63 59 94
Table 4.1: Percentage of Correct Feature Identifications
82


Actual Feature Raw Data Tests Averaged Data Tests
Alcove Alcove Alcove
Corridor Corridor Corridor
Dual Alcove Alcove Dual Alcove Alcove Dual Alcove
Corridor Corridor Corridor End Corridor Corridor
Four Way Across T Four Way Four Way
Corridor Corridor Corridor End Corridor Corridor End
Table 4.2: Raw and Averaged Data Test Feature Identification
4.4 Summary of Results
At the beginning of testing the value for the long threshold was set to 120 inches and
the value for the short threshold was 60 inches. Review of data showed that while the short
threshold was reasonable the long threshold was not. The long threshold was reduced to 78
inches (6 6) and the short threshold was slightly reduced to 54 inches (4 6).
The rule sets for the Four Way intersection and the Up T intersection were modified
based on empirical data. The logic of the SideShortRule and SideLongRule were modified
based on data obtained during tests run to identify L intersections. These changes increased
the likelihood of correctly identifying a feature.
Misidentification of features was caused by two sources: the physical layout of an
area such that the sonar sensors on the robot could not see the correct feature and sonar
range readings which did not represent the distance to an obstacle correctly.
83


Examples of the first case were found in identifying Up T intersections and Alcove
and Dual Alcove Ends. At this point it is important to recall that the rules used to identify
features dealt primarily with four specific sensors. These sensors pointed straight forward
(sonar 0), straight to the left (sonar 4), straight back (sonar 8), and straight right (sonar 12).
Thus, the misidentifications in these cases were caused because the end of the Corridor was
detected but the openings that represented a cross corridor or Alcove areas were not. Figure
4.24 illustrates this point. .
Figure 4.24: Robot Detecting a Corridor End Instead of an Up T
Even if the feature identification method used data from all the sonar sensors on the
robot incorrect identifications of this sort could still occur. As the robot approaches a feature
how could it tell an Up T intersection from a Dual Alcove End or an L intersection from an
Alcove End? Figures 4.25 and 4.26 depict these situations.
84


Figure 4.25: Robot Unable to Differentiate an Up T from a Dual Alcove
Figure 4.26: Robot Unable to Differentiate an Alcove End from a L Intersection
Misidentification of features also results from incorrect or misleading range
readings. A corollary cause is expecting certain range readings but not seeing them.
Essentially sonar sensors can only report the ranges they see and the rules for each of the
features can only operate on the data presented by the sensors.
As was noted above, the original range thresholds were set such that objects at
greater than 120 inches would be at a long range and that features closer than 60 inches
85


would be considered to be located at short range. In initial tests a Four Way intersection was
often identified as a Dual Alcove or an Up T. This was due to shorter than expected range
readings to the front or sides. Changing these thresholds greatly reduced the occurrence of
this problem. Figures 4.27 and 4.28 illustrate these situations.
Figure 4.27: Misidentification of a Four Way as a Dual Alcove
Figure 4.28: Misidentification of a Four Way as an Up T
Incorrect feature identifications still occur due to incorrect range readings as
evidenced by the phantom Corridor Ends seen in the multiple feature identification
86


Full Text
experiments. The sonar readings definitely indicated obstacles at ranges that in actuality
were open spaces. This effect was most likely caused by having greater than normal
reflective surfaces and/or multi-bounce effects. Most incorrect identifications seem to be
confined to the areas where two features meet. Thus moving from a Corridor into a Four
Way intersection can cause the transient identification of an Across T or Alcove feature.
These occurrences were reduced by the use of averaged data to compare to the various
features rule sets.
In summary, all features in the feature set were correctly identified by the
methodology presented in this research. There were problems with misidentifying features at
transitions between features but these were transitory and the use of averaged sonar data
reduced their occurrence. Some misidentifications that occurred wer.e due to incorrect range
readings. It is important to note that the identification of a current feature did not depend on
the identification of a previous or future feature. That is, there was not, and would not be, a
string of incorrectly identified features created because one in a series was improperly
identified. Identification of a feature was, and is, dependent on the instance, or instances, of
sonar data collected and the rule set for the feature that matched this data the best.
87


5. Conclusions
5.1 Evaluation
The purpose of this thesis was to develop a simple approach for the identification of
large-scale features in an indoor environment using ultrasonic sensors. This goal has been
met with some success.
All the features in the feature set were correctly identified and distinguished from
each other. Identification of features was achieved not only during tests to detect and identify
one type of feature but also in tests that had the robot traverse areas of a building that had
multiple features in them. The correct identification of a feature was not dependent on
correctly identifying features before or after the current one.
Misidentification of features was minimized by relatively minor changes to the logic
and threshold settings of the program. Incorrect identifications were primarily restricted to
areas where two features met and were transitory in nature. As noted above, all features were
correctly identified but this required that the robot was fully into the feature. More work
needs to be done in this area to reduce misidentifications.
This approach made use of an off-the-shelf robot with simple sensors. The robot
and its sensors were sufficient to correctly identify the features of an indoor environment.
This satisfied the overall philosophy of minimizing the use of specialized, non-standard, and
potentially expensive equipment (e.g., stereo vision systems, laser range finders, radar, etc.).
88


Another area where complexity was minimized was in the software. A set of simple
rules were combined in various ways to allow identification of the different features. The
sonar data collected by the robot was matched against these rules with little or no filtering.
The only filtering performed involved averaging six data sets together and using this
averaged data set to identify features. This averaging did have the effect of reducing some
misidentifications. This approach provided the means to identify large-scale features such as
corridors and L intersections.
5.2 Future Work
As in many areas, obtaining answers to questions leads to the generation of more
questions. The following areas could be explored as extensions of this study.
One area for future work identified above is to reduce, and hopefully eliminate,
feature misidentification. One approach would disallow the identification of a new feature if
the currently identified feature and a possible new feature have equivalent rule matching
percentages. Another approach would be to provide a sliding set of sonar data for feature
identification instead of the current method of using a fixed number of readings to apply to
the rule sets. This larger set of data could be used together or segmented for feature
identification. Both methods would allow a feature transition to be verified or proven false
by waiting until additional data could be collected.
A different way of identifying features could be explored. The concept of comparing
what sonar data for a particular type of feature should look like to actual data could be
researched via the use of neural nets. A neural net or nets could be trained to recognize the
various features and used in place of the current set of rules.
89


Another area to explore would be to modify the feature identification algorithm to be
adaptive. One way would be to make the algorithm rotationally invariant. This would mean
that the algorithm could correctly identify the current feature regardless of the orientation of
the robot. This could be accomplished by normalizing the sonar data or by performing some
form of pattern recognition on the data.
Creating a more adaptive algorithm could also be accomplished by modifying the
rules such that they would be adaptive to new surroundings, i.e., the rules can correctly
identify features in different buildings that have different proportions. As an example, the
hallways in one building may be eight feet wide while in another they are twelve feet wide.
These features are both corridors but the thresholds that would work in the first building
would cause features to be misidentified in the second. Having the rules adjust their
thresholds as changes in the environment are detected would be an approach to test. Another
means to explore would be to develop rules that are geometrical or shape-based in nature.
These rules would be similar to the current CorrRule that makes use of the detected length
and width of the feature the robot is traversing.
To better use the ability to identify features the softwares control of the robots
navigation and maneuvering capabilities will need to be expanded. This would allow the
robot to successfully navigate and identify features of an entire floor of a building. Once this
capability was added the robot could build a map of its environment based on the features it
identifies. This map could be used to identify changes in the environment, such as a door that
was closed but is now open, and possibly identify areas where movement has been detected.
90


A very interesting capability to provide would be the capacity for the robot to accept
directions to a location an then successfully navigate to that spot. This could be demonstrated
in two modes: with and without a map. In both cases the robot would be provided with
directions to the desired location, such as where the nearest copier is located. In the case
where the robot does not currently have a map the robot could demonstrate its ability to
identify features and arrive at the location indicated by the directions. Using a map, a person
could indicate the location to go. to on the map itself. The robot would use current sensor
readings and the stored map information to localize itself and navigate to the goal.
53 Summary
The ability for a robot to perform work is predicated on it being able to have a map
of its surroundings and to determine its location in that environment. How to develop a map
for a mobile robot has been the focus of much work and has lead to two main methods: grid-
based and feature-based. This thesis, while following many other studies in the use of
ultrasonic sensors, differs from previous work by using this data to identify the large-scale
features of the environment such as corridors, intersections, etc. The approach presented here
is computationally simple, uses off-the-shelf hardware, and uses the data obtained via the
sonar sensors with a minimum of filtering and manipulation. While there are issues with
correctly handling the transition from one feature to another and with incorrect range
readings this approach does successfully identify the features found in an indoor
environment in a new way. Finally, future work for improving this method and for adding
new capabilities were described which highlights the amount of additional research that
could be performed in this area.
91


Appendix A: Computer Program
The C++ software program to perform large-scale feature identification is presented
in this appendix. The classes are presented in alphabetical order with the header (.h) file first,
followed by the implementation (.cc) file.
92


#ifndef AUTO_PTR_H
#defme AUTO PTR H
llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
// Name: auto_ptr.h
// Description: Class which manages memory for an object created on the
// heap. Implementation if from the Appendix of Scott
// Meyer's More Effective C++. Meyers credits a 3/30/96
// posting to comp.std.c++ by Greg Colvin for this
// implementation.
//Created: 10/15/98
//Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
////////////////////////
// Forward Decls
////////////////////////
/////////////////////
// Namespaces
/////////////////////
template
class auto__ptr
{
////////////////////////////
// Public Functions
////////////////////////////
public:
// Constructor
explicit auto_ptr(T* p=0) : owner(p),
px(p)
{}
// Copy constructor
auto__ptr(const auto_ptr& ap) : owner(ap.owner),
px(ap.release())
{}
93


// Destructor
~auto_ptr() {if(owner) delete px;}
// op*
T& operator*() const {return *px;}
// op->
T* operator->() const {return px;}
// Get pointer to managed object
T* get() const {return px;}
// Give up ownership of managed object
T* release() const{owner=0; return px;} ;
// Manage a new object
// This function was removed from latest version of auto_ptr
// because it is redundant with op=
void reset(T *p) {owner=p; px=p;}
// op=
auto_ptr& operator=(const auto_ptr& ap)
{
if((void*)&ap != (void*)this)
{
if(owner)
{
delete px;
}
owner = ap.owner;
px = ap.release();
}
return *this;
}
////////////////////////////////
// Protected Functions
llllllllllllllllllllllllllllllll
protected:
94


////////////////////////////
// Private Functions
////////////////////////////
private:
///////////////////////////////
// Protected Members
///////////////////////////////
protected:
////////////////////////////
// Private Members
////////////////////////////
private:
mutable bool owner;
T*px;
};
#endif AUTO PTR H


#ifndef BACKLONGRULE_H
#defme BACKLONGRULE H
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name:
// Description:
//
// Created:
//Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
BackLongRule.h
Rule that indicates there is a "long" distance in back
of the robot.
12/1/98
////////////////
// Includes
////////////////
#include "Rulelmpl.h" // Base class
////////////////////////
// Forward Decls
////////////////////////
/////////////////////
// Namespaces
/////////////////////
using namespace std;
class BackLongRule : public Rulelmpl
{
////////////////////////////
// Public Functions
////////////////////////////
public:
// Constructor
BackLongRule(long theThreshold);
// Destructor
~BackLongRule();
// Determine if data matches
virtual bool match(const vector & theData) const;
96


////////////////////////////////
// Protected Functions
////////////////////////////////
protected:
////////////////////////////
// Private Functions
////////////////////////////
private:
///////////////////////////////
// Protected Members
///////////////////////////////
protected:
////////////////////////////
// Private Members
////////////////////////////
private:
long itsTbreshold;
#endif
llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
// Name: BackLongRule.cc
// Description: Implementation of rule to determine if there is a "long"
// distance in back of the robot.
// Created: 12/1/98
// Last Mod.:
Illlllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
////////////////
// Includes
////////////////
//include "BackLongRule.h"
//////////////
// Statics
//////////////
97


////////////////////////////
// Public Functions
////////////////////////////
BackLongRule: :BackLongRule(long theThreshold)
{
itsThreshold = theThreshold;
}
BackLongRule: :~BackLongRule()
{
}
bool BackLongRule::match(const vector &theData) const
{
return (getBack(theData) > itsThreshold) ? true : false;
}
////////////////////////////////
// Protected Functions
////////////////////////////////
////////////////////////////
// Private Functions
////////////////////////////
98


#ifndefCONFIG_H
#defme CONFIG H
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name: Config.h
// Description: Class for providing configuration info to robot (via
// a flat file).
// Created: 12/27/98
// Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
#include
////////////////////////
// Forward Decls
////////////////////////
class ifstream;
/////////////////////
// Namespaces
/////////////////////
using namespace std;
class Config
{
////////////////////////////
// Public Functions
////////////////////////////
public:
// Constructor
Config(ifstream &in);
// Destructor
virtual ~Config();
// Get a string from the input stream
virtual string getStringO;
99


// Get a float from the input stream
virtual float getFloat();
// Get an integer from the input stream
virtual int getlntQ;
// Get a long from the input stream
virtual long getLong();
///////////////////////////////
// Protected Functions
///////////////////////////////
protected:
////////////////////////////
// Private Functions
////////////////////////////
private:
//////////////////////////////
// Protected Members
//////////////////////////////
protected:
///////////////////////////
// Private Members
///////////////////////////
private:
ifstream&- itslnput;
};
#endif
100


Illlllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
// Name: Config.ee
// Description: Implementation for obtaining robot config data
// Created: 12/27/98
// Last Mod.:
Illlllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
mmhmum
II Includes
////////////////
#include "Config.h"
#include
#include
#include "ConfigError.h"
//////////////
// Statics
//////////////
////////////////////////////
// Public Functions
////////////////////////////
Config: :Config(ifstream &in) : itslnput(in)
{
}
Config: :~Config()
{
}
string Config::getString()
{
bool haveLine = false;
char data[200];
// Get string from file
while(!haveLine && itslnput.getline(data,200))
{
// Check to see if line is commented out
if(data[0] != #')
{
101


haveLine = true;
}
} // while
if(!haveLine)
{
throw ConfigError("End of File");
}
// Create string with data read in
return string(data);
}
float Config::getFloat()
{
return static_cast(atof(getString() ,c_str()));
}
int Config::getInt()
{
return atoi(getString().c_str());
}
long Config::getLong()
{
return atol(getString().c_str());
}
////////////////////////////////
// Protected Functions
////////////////////////////////
////////////////////////////
// Private Functions
////////////////////////////
102


#ifhdef CONFIGERROR_H
#defme CONFIGERROR_H
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name: ConfigError.h
// Description: Derived exception class which indicates a problem
// associated with reading configuration data
// Created: 12/27/98
//Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
#include
#include
////////////////////////
// Forward Decls
////////////////////////
/////////////////////
// Namespaces
/////////////////////
using namespace std;
class ConfigError : public exception
{
////////////////////////////
// Public Functions
////////////////////////////
public:
// Constructor
ConfigError(const string &verbage);
// Destructor
virtual ~ConfigError();
// Description of the exception
virtual string& what() throw();
103


///////////////////////////////
// Protected Functions
///////////////////////////////
protected:
////////////////////////////
// Private Functions
////////////////////////////
private:
llllllllllllllllllllllllllllll
// Protected Members
llllllllllllllllllllllllllllll
protected:
///////////////////////////
// Private Members
///////////////////////////
private:
string itsMessage;
};
#endif
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
II Name: ConfigError.ee
// Description: Implementation for the ConfigError exception.
// Created: 12/27/98
// Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
#include" ConfigError.h"
//////////////
// Statics
//////////////
104


////////////////////////////
// Public Functions
////////////////////////////
ConfigError: :ConfigError(const string &verbage) : itsMessage(verbage)
{
}
ConfigError: :~ConfigError()
{
}
string& ConfigError: :what() throw()
{
return itsMessage;
}
////////////////////////////////
// Protected Functions
////////////////////////////////
////////////////////////////
// Private Functions
////////////////////////////
105


#ifndef CORRRULE_H
#define CORRRULE H
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name:
// Description:
//
// Created:
//Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
CorrRule.h
Rule to check if an area is longer by a set ratio (the
aspect ratio) than it is wide.
11/28/98
////////////////
// Includes
////////////////
#include "Rulelmpl.h" // Base class
////////////////////////
// Forward Decls
////////////////////////
/////////////////////
// Namespaces
/////////////////////
using namespace std;
class CorrRule : public Rulelmpl
{
////////////////////////////
// Public Functions
////////////////////////////
public:
// Constructor
CorrRule(long theAspectRatio);
// Destructor
~CorrRule();
// Determine if data matches
virtual bool match(const vector & theData) const;
106


///////////////////////////////
// Protected Functions
///////////////////////////////
protected:
////////////////////////////
// Private Functions
////////////////////////////
private:
//////////////////////////////
// Protected Members
//////////////////////////////
protected:
///////////////////////////
// Private Members
///////////////////////////
private:
long itsAspectRatio;
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name: CorrRule.cc
// Description: Implementation of a rule to see if a feature is longer
// by a ratio than it is wide.
// Created: 11/28/98
// Last Mod.:
Illlllllllllilllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
////////////////
// Includes
////////////////
#include
#include "CorrRule.h"
//////////////
// Statics
//////////////
// Data being matched
107


////////////////////////////
// Public Functions
////////////////////////////
CorrRule:: CorrRule(long theAspectRatio)
{
itsAspectRatio = theAspectRatio;
}
CorrRule: :~CorrRule()
{
}
bool CorrRule: :match(const vector &theData) const
{
// Get front & back & add
long length = getFront(theData) + getBack(theData);
//Get sides and add
long width = getLeft(theData) + getRight(theData);
// Compare length to width mult by aspect ratio & return
return ((width*itsAspectRatio) < length) ? true : false;
}
////////////////////////////////
// Protected Functions
////////////////////////////////
////////////////////////////
// Private Functions
////////////////////////////
108


#ifndef DATAFELTER_H
#define DATAFILTER H
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name: DataFilter.h
// Description: DataFilter will be an abstract base class for filters
// that can be used by Sonarlmage to filter raw data.
// Currently is implemented as an initial test.
//Created: 11/1/98
//Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
#include
////////////////////////
// Forward Decls
////////////////////////
/////////////////////
// Namespaces
/////////////////////
using namespace std;
class DataFilter
{
////////////////////////////
// Public Functions
////////////////////////////
public:
// Constructors
DataFilter();
// Destructor
~DataFilter();
long filter(const vector &theRawData);
109


///////////////////////////////
// Protected Functions
///////////////////////////////
protected:
////////////////////////////
// Private Functions
////////////////////////////
private:
//////////////////////////////
// Protected Members
//////////////////////////////
protected:
///////////////////////////
// Private Members
///////////////////////////
private:
};
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name: DataFilter.cc
// Description: Implementation for the DataFilter class.
// Created: 11/1/98
// Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
#include "DataFilter.h"
#include // For accumulate
//////////////
// Statics
//////////////
110


////////////////////////////
// Public Functions
////////////////////////////
DataFilter: :DataFilter()
{
}
DataFilter: :~DataFilter()
{
}
long DataFilter: :filter(const vector &theRawData)
{
return (accumulate(theRawData.begiri(),theRawData.end(),0)/theRawData.size());
}
////////////////////////////////
// Protected Functions
////////////////////////////////
////////////////////////////
// Private Functions
////////////////////////////
111


#ifndef ENVFEATURE_H
#defme ENVFEATURE H
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name: EnvFeature.h
// Description: Base class (eventually) for environmental features that
// the robot will detect and add to a map of the
// environment.
//Created: 11/15/98
// Last Mod.: 12/29/98
// Added list of Sonarlmages
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
#include // For type
#include // Container for Sonarlmages
////////////////////////
// Forward Decls
////////////////////////
class ostream;
class Sonarlmage;
/////////////////////
// Namespaces
/////////////////////
using namespace std;
class EnvFeature
{
////////////////////////////
// Public Functions
////////////////////////////
public:
// Constructors
EnvFeature();
EnvFeature(const string &theType);
112


EnvFeature(const EnvFeature &orig);
// Destructor
~EnvFeature();
// Add Sonarlmage to feature
void add(const Sonarlmage* image);
// Get Sonarlmages
const list& getlmages() const;
// Accessor for feature type
const string& getType() const;
// Set feature type
void setType(const string& type);
// Summary of feature type, start, end
char* summaryO const;
// Convert feature to string
char* toString() const;
// op=
EnvFeature& operator=(const EnvFeature &orig);
// op=
bool operator=(const EnvFeature &other);
// op
friend ostream& operator(ostream &os, const EnvFeature &feature);
///////////////////////////////
// Protected Functions
///////////////////////////////
protected:
////////////////////////////
// Private Functions
////////////////////////////
private:
113


//////////////////////////////
// Protected Members
//////////////////////////////
protected:
///////////////////////////
// Private Members
///////////////////////////
private:
// Type of feature
string itsType;
// Sonarlmage container
list itslmages;
};
inline const list& EnvFeature::getImages() const
{
return itslmages;
}
inline const string& EnvFeature::getType() const
{
return itsType;
}
inline void EnvFeature::setType(const string &type)
{
itsType = type;
}
#endif
114


Illlllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
// Name: EnvFeature.cc
// Description: Implementation file for EnvFeature class.
11/15/98
12/29/98
Added add, setType, cctor, op=, op
1/5/99
Added summary & toString
// Created:
// Last Mod.:
//
//
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
#include "EnvFeature.h"
#include
#include
#include "Sonarlmage.h"
//////////////
// Statics
//////////////
////////////////////////////
// Public Functions
////////////////////////////
EnvFeature: :EnvFeature()
{
}
EnvFeature::EnvFeature(const string &theType) : itsType(theType)
{
}
EnvFeature::EnvFeature(const EnvFeature &orig): itsType(orig.itsType),
itslmages(orig.itslmages)
/
i
}
EnvFeature: :~EnvFeatureO
{
}
115


void EnvFeature::add(const Sonarlmage* image)
{
itslmages.push_back(image);
}
char* EnvFeature::summary() const
{
ostrstream oss;
oss "Feature Type: itsType endl;
if(!itslmages.empty0)
{
const Sonarlmage* start = itshnages.front();
const Sonarlmage* end = itslmages.back();
oss "Start: start->getImage().getXPosit();
oss End: end->getlmage().getXPosit();
oss endl;
}
oss '\0';
return oss.strO;
}
char* EnvFeature::toString() const
{
ostrstream oss;
oss "Feature Type: itsType endl;
if(!itslmages.empty())
{
const Sonarlmage* start = itshnages.front();
const Sonarlmage* end = itslmages.back();
oss "Start: start->getImage().getXPosit();
oss End:" end->getImage().getXPosit();
oss endl;
}
oss "Sonarlmages:" endl;
116


list::const_iterator iter;
for(iter = itslmages.begin();iter != itslmages.end(); ++iter)
{
oss **iter endl;
}
oss <\0';
return oss.str();
}
EnvFeature& EnvFeature::operator=(const EnvFeature& orig)
/
i
if(this != &orig)
{
itsType = orig.itsType;
itslmages = orig.itslmages;
}
return *this;
}
bool EnvFeature::operator=(const EnvFeature& other)
{
return (itsType = other.itsType) ? true : false;
}
ostream& operator(ostream &os, const EnvFeature &feature)
{
os "Feature Type: feature.getType() endl;
if(!feature.getlmages():empty())
{
const Sonarlmage* start = feature.getIinages().ffont();
const Sonarlmage* end = feature.getlmages().back();
os "Start: start->getImage().getXPosit();
os End: end->getImage().getXPosit();
os endl;
}
os "Sonarlmages:" endl;
117


list silist = feature.getlmages();
list::const_iterator iter;
for(iter = silist.begin();iter != silist.end(); ++iter)
{
os **iter endl;
}
return os;
}
////////////////////////////////
// Protected Functions
////////////////////////////////
////////////////////////////
// Private Functions
////////////////////////////
118


#ifndef FEATUREPATTERN_H
#defme FEATUREPATTERN H
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name:
// Description:
//
//
//
//
//
// Created:
// Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
FeaturePattem.h
Header file for FeaturePattem class. This class
is an Abstract Base Class for derived FeaturePattems.
A FeaturePattem is how an indoor environmental
feature "looks" to the robots sonars. It is used to
identify the type of EnvFeature to add to the robot's
map.
10/20/98
////////////////
// Includes
////////////////
#include
////////////////////////
// Forward Decls
////////////////////////
class EnvFeature;
class Rule;
template
class vector;
class FeaturePattem
{
////////////////////////////
// Public Functions
////////////////////////////
public:
// Constructors
FeaturePattem();
FeaturePattem(const EnvFeature &theFeature,
const list &theRules);
//Destructor
119


virtual
'FeaturePattemQ;
// Get Feature that Pattern matches
virtual const EnvFeature& getFeature() const = 0;
// Get the number of rules used by the pattern
virtual long getNumOfRules() const = 0;
// Get percent matching of pattern to data
virtual float getPercentMatch() const = 0;
// Determine if data matches this Pattern
virtual bool match(const vector &theData) = 0;
///////////////////////////////
// Protected Functions
///////////////////////////////
protected:
////////////////////////////
// Private Functions
////////////////////////////
private:
// Copy ctor prevent copies from being made
FeaturePattem(const FeaturePattem &orig);
// Operator = prevent assignments
FeaturePattem& operator=(const FeaturePattem &orig);
//////////////////////////////
// Protected Members
//////////////////////////////
protected:
///////////////////////////
// Private Members
///////////////////////////
private:
};
#endif
120


Illlllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
// Name: FeaturePattem.ee
// Description: Implementation file for FeaturePattem Abstract class.
// Created: 10/20/98
// Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
#include "FeaturePattem.h"
//////////////
// Statics
//////////////
////////////////////////////
// Public Functions
////////////////////////////
FeaturePattem: :FeaturePattem()
{
}
FeaturePattem: :FeaturePattem(const EnvFeature &theFeature,
const list &theRules)
{
}
FeaturePattem: :~FeaturePattem()
{
}
////////////////////////////////
// Protected Functions
////////////////////////////////
////////////////////////////
// Private Functions
////////////////////////////
121


#ifhdef FEATUREPATTERMMPL_H
#defme FEATUREPATTERMMPL H
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name: FeaturePattemlmpl.h
// Description: Header file for FeaturePattemlmpl class. This class
// is an implementation class for FeaturePattem.
// It provides methods and variables for use by derived
// classes.
//Created: 11/8/98
// Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
#include "FeaturePattem.h" // Base class
#include // Container for Rules
#include
#include "EnvFeature.h"
////////////////////////
// Forward Decls
////////////////////////
class Rule;
class FeaturePattemlmpl: public FeaturePattem
{
////////////////////////////
// Public Functions
////////////////////////////
public:
// Constructors
FeaturePattemImpl();
FeaturePattemImpl(EnvFeature *theFeature,
list *theRules );
FeaturePattemImpl(const FeaturePattemlmpl &orig);
//Destmctor
122


-FeaturePattemlmplO;
// Get Feature that Pattern matches
virtual const EnvFeature& getFeature() const;
// Get number of rules used by pattern
virtual long getNumOfRules() const;
// Get percent matching of pattern to data
virtual float getPercentMatch() const;
// Determine if data matches this Pattern
virtual bool match(const vector &theData);
// Operator=
FeaturePattemImpl& operator=(const FeaturePattemlmpl &orig);
///////////////////////////////
// Protected Functions
///////////////////////////////
protected:
const list& getRules() const;
void setPercentMatch(float theMatch);
////////////////////////////
// Private Functions
////////////////////////////
private:
//////////////////////////////
// Protected Members
//////////////////////////////
protected:
///////////////////////////
// Private Members
///////////////////////////
private:
float itsPercentMatch;
auto_ptr itsFeature;
123


auto_ptr > itsRules;

#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name:. FeaturePattemImpl.ee
// Description: Implementation for FeaturePattemlmpl class.
//Created: 11/8/98
//Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
#include
#include
#include "FeaturePattemlmpl.h"
#include "Rule.h"
#include
//////////////
// Statics
//////////////
////////////////////////////
// Public Functions
////////////////////////////
FeaturePattemlmpl::FeaturePattemImpl() : itsFeature(new EnvFeature()),
itsRules(new list)
{
itsPercentMatch = 0;
}
FeaturePattemlmpl::FeaturePattemImpl(EnvFeature *theFeature,
list *theRules)
{
itsFeature.reset(theFeature);
itsRules.reset(theRules);
itsPercentMatch = 0;
124


}
FeaturePattemImpl::FeaturePattemImpl(const FeaturePattemlmpl &orig)
{
itsFeature = orig.itsFeature;
itsRules = orig.itsRules;
itsPercentMatch = orig.itsPercentMatch; .
}
FeaturePattemlmpl: :~FeaturePattemImpl()
{
cout "FPI dtor" endl;
}
const EnvFeature& FeaturePattemImpl::getFeature() const
{
return *itsFeature;
}
long FeaturePattemlmpl ::getNumOfRules() const
{
return (*itsRules).size();
}
float FeaturePattemImpl::getPercentMatch() const
{
return itsPercentMatch;
}
bool FeaturePattemlmpl ::match(const vector &theData)
{
list: :const_iterator iter;
long matches = 0;
// Check to see if data matches any rules
for(iter = (*itsRules).begin(); iter != (*itsRules).end(); -H-iter)
{
Rule *rule = *iter;
if(rule->match(theData))
{
-H-matches;
}
125


}
// Calculate the percentage of rules matched and return true/false
itsPercentMatch = ((float)matches/(*itsRules).size()) 100;
return (matches > 0) ? true : false;
}
FeaturePattemImpl& FeaturePattemImpl::operator=(const FeaturePattemlmpl &orig)
{
if(this != &orig)
{
itsPercentMatch = orig.itsPercentMatch;
itsFeature = orig.itsFeature;
itsRules = orig.itsRules;
}
return *this;
}
////////////////////////////////
// Protected Functions
////////////////////////////////
const list& FeaturePattemlmpl::getRules() const
{
return *itsRules;
}
void FeaturePattemImpl::setPercentMatch(float theMatch)
{
itsPercentMatch = theMatch;
}
////////////////////////////
// Private Functions
////////////////////////////
126


#ifndef FILELOG_H
#define FILELOG_H
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name: FileLog.h
// Description: Derived log class which writes information to a flat file.
//Created: 12/14/98
// Last Mod:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
#include "Log.h"
#include
#include
////////////////////////
// Forward Decls
////////////////////////
class ostream;
class Sonarlmage;
/////////////////////
// Namespaces
/////////////////////
using namespace std;
class FileLog : public Log
{
////////////////////////////
// Public Functions
////////////////////////////
public:
// Constructors
FileLog(const char *filename);
FileLog(const string &filename);
// Destructor
127


~FileLog();
///////////////////////////////
// Protected Functions
///////////////////////////////
protected:
////////////////////////////
// Private Functions
////////////////////////////
private:
// Write information to file
void log(const string &aString);
//////////////////////////////
// Protected Members
//////////////////////////////
protected:
///////////////////////////
// Private Members
///////////////////////////
private:
ofstream logfile;
};
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name: FileLog.cc
// Description: Implementation of a Log which writes data to a flat file.
// Created: 12/14/98
// Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
#include "FileLog.h"
#include // Access to time functions
#include
128


//////////////
// Statics
//////////////
////////////////////////////
// Public Functions
////////////////////////////
FileLog::FileLog(const char ^filename)
{
logfile.open(filename);
if(!logfile)
{
cerr "Unable to open log file filename endl;
}
else
{
logfile "Start log: Timestamp::timestampO endl;
logfile endl;
}
}
FileLog::FileLog(const string& filename)
{
logfile.open(filename.c_str());
if(!logfile)
{
cerr "Unable to open log file filename endl;
}
else
{
logfile "Start log: Timestamp::timestamp() endl;
logfile endl;
}
}
FileLog: :~FileLog()
{
logfile endl;
logfile "End log: Timestamp::timestamp();
}
129


///////////////////////////////
// Protected Functions
///////////////////////////////
////////////////////////////
// Private Functions
////////////////////////////
void FileLog::log(const string &aStr)
{
logfile aStr endl;
}


#ifndef FRONTLONGRULE_H
#defme FRONTLONGRULE H
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name:
// Description:
//
// Created:
// Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
FrontLongRule.h
Rule that indicates there is a "long" distance in front
of the robot.
12/1/98
////////////////
// Includes
////////////////
#include "Rulelmpl.h" // Base class
////////////////////////
// Forward Decls
////////////////////////
class FrontLongRule : public Rulelmpl
{
////////////////////////////
// Public Functions
////////////////////////////
public:
// Constructor
FrontLongRule(long theThreshold);
// Destructor
~FrontLongRule();
// Determine if data matches
virtual bool match(const vector & theData) const;
///////////////////////////////
// Protected Functions
///////////////////////////////
protected:
131


////////////////////////////
// Private Functions
////////////////////////////
private:
//////////////////////////////
// Protected Members
//////////////////////////////
protected:
///////////////////////////
// Private Members
///////////////////////////
private:
long itsThreshold;
};
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name: FrontLongRule.ee
// Description: Implementation of rule to determine if there is a "long"
// distance in front of the robot.
// Created: 12/1/98
// Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
#include "FrontLongRule.h"
//////////////
// Statics
//////////////
////////////////////////////
// Public Functions
////////////////////////////
FrontLongRule: :FrontLongRule(long theThreshold)
132


{
itsThreshold = theThreshold;
}
FrontLongRule: :~FrontLongRule()
{
}
bool FrontLongRule: :match(const vector &theData) const
{
return (getFront(theData) > itsThreshold) ? true : false;
}
///////////////////////////////
// Protected Functions
///////////////////////////////
////////////////////////////
// Private Functions
////////////////////////////
133


#ifndef FRONTSHORTRULE_H
#define FRONTSHORTRULE H
llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
FrontShortRule.h
Rule that indicates there is a "short" distance in front
of the robot.
12/17/98
// Name:
// Description:
//
// Created:
// Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
#include "Rulelmpl.h" // Base class
////////////////////////
// Forward Decls
////////////////////////
class FrontShortRule : public Rulelmpl
{
////////////////////////////
// Public Functions
////////////////////////////
public:
// Constructor
FrontShortRule(long theThreshold);
// Destructor
~FrontShortRule();
// Determine if data matches
virtual bool match(const vector & theData) const;
///////////////////////////////
// Protected Functions
///////////////////////////////
protected:
134


////////////////////////////
// Private Functions
////////////////////////////
private:
//////////////////////////////
// Protected Members
//////////////////////////////
protected:
///////////////////////////
// Private Members
///////////////////////////
private:
long itsThreshold;
};
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////////
FrontShortRule.ee
Implementation of rule to determine if there is a "short"
distance in front of the robot.
12/17/98
// Name:
// Description:
//
// Created:
// Last Mod.:
Illlllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
////////////////
// Includes
////////////////
#include "FrontShortRule.h"
//////////////
// Statics
//////////////
////////////////////////////
// Public Functions
////////////////////////////
FrontShortRule: :FrontShortRule(long theThreshold)
135


{
itsThreshold = theThreshold;
}
FrontShortRule: :~FrontShortRule()
{
}
bool FrontShortRule: :match(const vector &theData) const
{
return (getFront(theData) <= itsThreshold) ? true : false;
}
///////////////////////////////
// Protected Functions
///////////////////////////////
////////////////////////////
// Private Functions
////////////////////////////
136


#ifndef LOG_H
#defme LOG_H
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name: Log.h
// Description: Base class for Log Hierarchy. Provides interface for
// derived log classes that are used by the robot.
// Created: 12/13/98
//Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
//////////////// '
#include
#include "Observer.h"
////////////////////////
// Forward Decls
////////////////////////
/////////////////////
// Namespaces
/////////////////////
using namespace std;
class Log : public Observer
{
////////////////////////////
// Public Functions
////////////////////////////
public:
Log();
virtual ~Log();
virtual void update(const string &aString);
137


///////////////////////////////
// Protected Functions
///////////////////////////////
protected:
virtual void log(const string &aString) = 0;
////////////////////////////
// Private Functions
////////////////////////////
private:
//////////////////////////////
// Protected Members
//////////////////////////////
protected:
///////////////////////////
// Private Members
///////////////////////////
private:
};
#endif
llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
// Name: Log.cc
// Description: Implementation for Log class.
// Created: 12/13/98
// Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
#include "Log.h"
//////////////
// Statics
//////////////
138


////////////////////////////
// Public Functions
////////////////////////////
Log::Log()
{
}
Log::~Log()
{
}
void Log::update(const string &aString)
{
log(aString);
}
///////////////////////////////
// Protected Functions
///////////////////////////////
////////////////////////////
// Private Functions
////////////////////////////


#ifndef LOGGERJH
#defme LOGGERH
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Name: Logger .h
// Description: Class which provides logging facilities for robot.
//Created: 12/10/98
// Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
#include
#include
////////////////////////
// Forward Decls
////////////////////////
/////////////////////
// Namespaces
/////////////////////
class Logger : public Subject
{
////////////////////////////
// Public Functions
////////////////////////////
public:
// Constructor
Logger();
// Destructor
-Logger/);
// Log message
void log(const string &message);
// Log message with timestamp
void logt(const string &message);
140


///////////////////////////////
// Protected Functions
///////////////////////////////
protected:
////////////////////////////
// Private Functions
////////////////////////////
private:
//Do not allow copying
Logger(const Logger &logger);
Logger &operator=(const Logger &logger);
//////////////////////////////
// Protected Members
//////////////////////////////
protected:
///////////////////////////
// Private Members
///////////////////////////
private:
};
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name: Logger.cc
// Description: Implementation for logging facility.
// Created: 12/10/98
// Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
#include
#include "Logger.h" //header file
141


//////////////
// Statics
//////////////
////////////////////////////
// Public Functions
////////////////////////////
Logger: :Logger()
{
}
Logger: :~Logger()
{
}
void Logger: :log(const string &message)
{
notify(message);
}
void Logger: :logt(const string &message)'
{
string tMsg(Timestamp: :timestamp());
tMsg += :
tMsg += message;
notify(tMsg);
}
///////////////////////////////
// Protected Functions
///////////////////////////////
////////////////////////////
// Private Functions
////////////////////////////


#ifodef MEMORY
#defme MEMORY
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name: memory
// Description: Substitute for Standard C++ Library memory file.
// #include's auto_ptr.h
//Created: 10/15/98
//Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
#include "auto^ptr.h"
#endif
143


#ifndef OBSERVER_H
#define OBSERVER H
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name:
// Description:
//
// Created:
// Last Mod.:
Observer.h
Class which monitors another class (the Subject). Based
on the Observer pattern in Design Patterns.
10/12/98
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
#include
////////////////////////
// Forward Decls
////////////////////////
class Subject;
/////////////////////
// Namespaces
/////////////////////
using namespace std;
class Observer
{
////////////////////////////
// Public Functions
////////////////////////////
public:
Observer();
virtual ~Observer();
virtual void update(const string &aString) = 0;
144


///////////////////////////////
// Protected Functions
///////////////////////////////
protected:
////////////////////////////
// Private Functions
////////////////////////////
private:
//////////////////////////////
// Protected Members
//////////////////////////////
protected:
///////////////////////////
// Private Members
///////////////////////////
private:
};
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name: Observer.cc
// Description: Implementation for Observer class.
// Created: 10/13/98
// Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
#include "Observer.h"
//////////////
// Statics
//////////////
////////////////////////////
// Public Functions
////////////////////////////
145


Observer:: Observer()
{
}
Observer: :~Observer()
{
}
///////////////////////////////
// Protected Functions
///////////////////////////////
////////////////////////////
// Private Functions
////////////////////////////


#ifndef ROBOT_H
#defme ROBOT H
////////////////////////////////////////////////////////////////////////////////////////////////////////////
It Name: Robot.h
// Description: This class provides the interface for the Robot class. This
// class was originally part of a class project for CSC 5804 Robotics
// at the University of Colorado, Denver, Spring 1998. This class has been
// modified as part of .my Master's thesis at the University of Colorado,
// Denver, Fall 1998 Spring 1999. This class is responsible for controlling
// the movement of the robot and the collection and processing of sonar data
// to identify indoor features.
//Created: 3/7/98
//Last Mod: 11/19/98
// Added logger and logs
// Modified explore to collect sonar data and identify
// features
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

// For holding EnvFeatures
// For auto_ptr
// For holding FeaturePattems and SonarData
"Nclient.h" //Header for robot interface library






////////////////////////
// Forward Decls
////////////////////////
/////////////////////
// Namespaces
/////////////////////
using namespace std;
147


class Robot
{
////////////////////////////
// Public Functions
////////////////////////////
public:
// Constructor
Robot(const char* filename);
// Destructor
~Robot();
// Determine direction to move to avoid an obstacle
int avoid();
// Check for obstacles
void checkForObstacles();
// Explore
void explore();
// Initialize
bool init();
// Check to see if there is an obstacle
bool obstacle() const {return myObstacle;}
// Log collected data
void report() const;
// Command which wraps/corrects robot's vm command
void scoutVm(short theTrans, short theRot);
// Shutdown
void shutdownO;
///////////////////////////////
// Protected Functions
///////////////////////////////
protected:
148


////////////////////////////
// Private Functions
////////////////////////////
private:
// Make sure we don't hit a wall
void checkRange(long range);
// Make sure we don't hit a wall version 2
void checkRange(long *state);
// Get variable parameters
void getConfIg();
// Get X position of Robot
long getXPosit(int sensorld);
// Get Y position of Robot
long getYPosit(int sensorld);
// Create Sonarlmages for self-test
void initlmages();
// Create FeaturePattems to be used
void initPattemsO;
// Initialize the sensor suite
bool initSensors();
// Convert measurements in tenths of inches to inches
float tenthsToInches(long tenths) const { return (tenths/10.0);}
//////////////////////////////
// Protected Members
//////////////////////////////
protected:
///////////////////////////
// Private Members
///////////////////////////
private:
unsigned int myTransSpeed; //Translational speed .1 in/sec
149


int myDistance; //Travel dist (in .1 inches)
int mySonarFireRate; //Firing rate for sonars
const int myTimeout = 0; //Robot has no timeout
const int myTumAngle = 450; // Angle to turn (in 0.1 deg)
int myCorrAspectRatio;
int myReadingsPerlmage;
int myF W ComerMatches;
int myReadingDistance; // 0.1 inches to take a reading at
const long myld = 1; //ED of Robot to server
long myMinRangeT oObs;
long myShortThreshold;
- long myLongThreshold;
bool myObstacle;
bool avoiding; //new
int myDirection;
int myRet;
long robotPosit;
int mySonarFiringOrder [ 16];
string - myObstacleSensed;
PosData myPosData;
DataFilter myDataFilter;
EnvFeature* myCurrentFeature;
150


auto_ptr
auto_ptr
autojptr
auto_ptr
auto_ptr

myConfig;
myScreenLogger;
myF eatureLogger;
mySonarLogger;
myDebugLogger;
vector myPattems;
list myFeatures;
vector mySonarlmages; // For self test
#endif ROBOT H
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name: Robot.cc
// Description: Implementation for Robot class. This class was
// originally part of a class project for CSC 5804 Robotics
// at the University of Colorado, Denver, Spring 1998. It
// has been modified as part of my Masters thesis at the
// University of Colorado, Denver, Fall 1998 Spring 1999.
// This class is responsible for controlling the movement
// of the robot and the collection and processing of sonar
// data to identify indoor features.
//Created: 3/7/98
//Last Mod: 3/26/98
// Added functionality to avoid obstacles in the path of
// the robot
// 3/31/98
// Added avoid, checkForObstacles, & modified explore
// 11/19/98
// Added use of logger and logs
// Modified explore to collect sonar data and added
// functionality to ID large-scale indoor features.
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
151


#include "Robot.h" //Header for Robot
#include
#include
#include
#include
#include
#include-
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//////////////
// Statics
//////////////
////////////////////////////
// Public Functions
////////////////////////////
Robot: :Robot(const char* filename): myObstacleSensed(""),
myCurrentFeature(O)
{
// Provide logging to screen
152


myScreenLogger.reset(new Logger);
auto_ptr sl(new ScreenLog);
myScreenLogger->attach(sl);
// Create logger and file for debug data
myDebugLogger.reset(new Logger);
string debugFile(filename);
debugFile += ".debug";
autojptr debugLog(new FileLog(debugFile));
myDebugLogger->attach(debugLog);
// Create logger and file for sonar data
mySonarLogger.reset(new Logger);
string sonarFile(filename);
sonarFile += ".sonar";
auto_ptr sonarLog(new FileLog(sonarFile));
mySonarLogger->attach(sonarLog);
// Create logger and file for features
myFeatureLogger.reset(new Logger);
string featureFile(filename);
featureFile += ".feature";
auto_ptr featureLog(new FileLog(featureFile));
myFeatureLogger->attach(featureLog);
// Read configuration parameters
getConfigO;
// Create feature patterns
initPattems();
// Initialize obstacle avoidance variables
avoiding = false;
myDirection = 0;
myObstacle = false;
myRet = 0;
robotPosit =0;
// For a "self-test" of the pattern matching code, call initlmages
#ifdef SELFTEST
inithnages()
#endif
myScreenLogger->log("Robot Created");
153


}
//Destructor
Robot: :~Robot()
{
// Clean up delete myCurrentFeature to prevent leak
delete myCurrentFeature;
// Log destruction of robot
myScreenLogger->log("Robot destructed");
}
int Robot: :avoid()
{
//Direction to return
int myDirection = -1;
int obslnt = atoi(myObstacleSensed.c_str());
//Determine which case is being dealt with
switch(obslnt)
{
case 10000: case 11000: case 1000: case 11100: case 1100: case 1010: case 1110
case 10100: case 10110: case 11001: case 11010: case 11110:
myDirection = 450;
myDebugLogger->logt("Tuming Right");
break;
case 1: case 11: case 10: case 111: case 101: case 110: case lOOl: case 10010:
case 10011: case 1101: case 1111:
myDirection = 3150;
myDebugLogger->logt("Tuming Left");
break;
case 100:
myDirection = 450;
myDebugLogger->logt("Obstacle directly ahead. Turning Right.");
break;
case 0: case 10001:
myDirection = 0;
break;
case 11111: case 10101: case 10111: case 11011: case 11101:
myObstacle = true;
154


break;
default:
myDebugLogger->logt("Unrecognized obstacle pattern");
break;
}
return myDirection;
}
void Robot::checkForObstacles()
{
myObstacleSensed =
for(int i=2;i>=0;i)
if(State[STATE_SONAR_2 i] < myMinRangeToObs)
myObstacleSensed += "1";
else
myObstacleSensed += "0";
for(int i=l;i>=0;i~)
if(State[STATE_SONAR_15 -i] < myMinRangeToObs)
myObstacleSensed += "1";
else
myObstacleSensed += "0";
//Explore
void Robot: :explore()
{
myDebugLogger->logt("Entering explore");
// Collect initial sensor reading
gs();
checkF orObstacles();
// Keep track of how far robot has moved
long distTravelled = 0;
// Keep track of data collected to produce Sonarlmage
int amountOfData = 0;
// Container for raw sonar data
155


vector dataT oFilterfinyReadingsPerlmage);
while((State[STATE_CONF_X] < myDistance) && (obstacle() = false))
{
// Collect sensor readings
gs();
long currX = State[STATE_CONF_X];
if((currX-distTravelled) >= myReadingDistance)
{
long currY = State[STATE_CONF_Y];
//get sonar data
vector rawData(16);
for(int i=0;i {
rawData[i] = State[17+i];
}
SonarData sonarData(tenthsTolnches(currX),
tenthsT olnches(currY),
rawData);
// Record all SonarData collected
mySonarLogger->logt("SonarData collected");
mySonarLogger->log(sonarData.toString());
dataToFilter[amountOfData] = SonarData;
amountOfData++;
// If enough data has been collected, filter and
// create Sonarlmage
if(amountOfData = myReadingsPerlmage)
{
Sonarlmage *image = new SonarImage(myDataFilter,dataToFilter);
// Record filtered data
mySonarLogger->logt("SonarImage created");
mySonarLogger->log(image->toString());
156


// Reset data counter
amountOfData = 0;
// Keep track of percent match per FPI & which FPI has highest
// match
float bestPercentMatch = 0.0;
FeaturePattemlmpl *bestMatch = 0;
// ***** Added 1/9/99 *****
vector mpvec;
size_t numSortFeatures = 3;
// ***** Added 1/9/99 *****
//pattern match
vector::iterator iter;
for(iter=myPattems.begin(); iter!=myPattems.end(); ++iter)
{
FeaturePattemlmpl *fpi = *iter;
// Check to see if FPI is the best match for data
if(fpi->match(image->getImage().getSonarPings()))
' {
// ***** Added 1/9/99 *****
mpvec.push_back(SonarImage::matchPair(fpi->getPercentMatch(),
fpi->getFeature().getType()));
// ***** Added 1/9/99 *****
if(fpi->getPercentMatch() > bestPercentMatch)
{
bestMatch = fpi;
// Set bestPercentMatch to that of FPI
bestPercentMatch = fpi->getPercentMatch();
}
else if(fpi->getPercentMatch() = bestPercentMatch)
{
// Prefer corr to 4W, 4W to Ts
if(bestMatch->getFeature().getType() != "corridor")
{
if(fpi->getFeature().getType() = "fourWay")
{
bestMatch = fjpi;
}
157


// Otherwise, stay with pattern that was found first
} // if feature != corridor
} // else if percent matches are same
} // if match
} // myPattems loop
iffbestMatch)
{
H ***** 1/9/99 *****
sort(mpvec.begin(),mpvec.end(),greater());
if(mpvec.size() > numSortFeatures)
{ .
mpvec.erase(mpvec.begin() + 3, mpvec.end());
}
image->setMatches(mpvec);
H ***** Added 1/9/99 *****
// If first feature, set to current and add Sonarlmage
if(!myCurrentFeature)
{
myCurrentFeature = new EnvFeature(bestMatch->getFeature());.
myCurrentFeature->add(image);
// Log feature
myScreenLogger->logt("Initial Feature Detected");
myScreenLogger->log(myCurrentFeature->getType());
myFeatureLogger->logt(myCurrentFeature->summary());
mySonarLogger->logt(myCurrentFeature->toString());
}
// If still in current feature, add Sonarlmage
else if(bestMatch->getFeature().getType() = myCurrentFeature->getType())
{
myCurrentFeature->add(image);
myFeatureLogger->logt("");
myFeatureLogger->log(myCurrentFeature->summary());
mySonarLogger->logt("");
mySonarLogger->log(myCurrentFeature->toString());
158


}
// If new feature, save old and set current to new feature
// Stop robot to indicate new feature detected
else
{
// Command robot to stop
st();
sleep(5);
EnvFeature* old = myCurrentFeature;
myFeatures.push_back(old);
myCurrentFeature = new EnvFeature(bestMatch->getFeature());
myCurrentFeature->add(image);
// Log feature
myScreenLogger->logt("New Feature Detected");
myScreenLogger->log(myCurrentFeature->getType());
myFeatureLogger->logt("");
myFeatureLogger->log(myCurrentFeature->summary());
mySonarLogger->logt(" ");
mySonarLogger->log(myCurrentFeature->toString());
}
} // if bestmatch
else
{
mySonarLogger->logt("SonarImage did not match a Pattern");
mySonarLogger->log(image->toString());
}
// Prevent leak
//delete bestMatch;
} // if amountOfData = myReadingsPerlmage
//increment distTravelled
distTravelled = cuitX;
} // if delta X >= myReadingDistance
159


checkForObstacles();
int dir = avoid();
switch(dir)
{
case-1:
break;
case 0:
if(! avoiding)
{
scoutVm(myTransSpeed,0);
avoiding = false;
}
else
{
myDebugLogger->logt("*** Should turn back to original dir ***")
//cout "Direction to turn is: -myDirection << endl;
avoiding = false;
st();
ws(l,l,l,2);
scoutVm(0,myRet);
scoutVm(myTransSpeed,0);
ws(l,l,l,2);
}
break;
case 450:
if(! avoiding)
{
myRet = 3150;
avoiding = true;
st();
ws(l,1,1,2);
scoutVm(0,450);
scoutVm(myTransSpeed,0);
ws(l,l,l,2);
}
break;
case 3150:
160


if(! avoiding)
{
myRet = -myTumAngle;
avoiding = true;
st();
ws(l,l,l,2);
scoutVm(0,3150);
scoutVm(myTransSpeed,0);
ws(l,1,1,2);
}
break;
default: . .
myDebugLogger->logt("Unrecognized return from avoid()");
break;
} // switch dir
} // while
//tell robot to stop
st();
ws(l,l,l,2);
// Add "last" current feature to feature list
if(myCurrentFeature)
{
myFeatures.push_back(myCurrentFeature);
}
}
//Initialize
bool Robot: :init()
{
myDebugLogger->logt("Initializing robot");
int status = 0;
//Connect to server
status = connect_robot(myId);
if(! status)
{
myDebugLogger->log("unable to connect to robot");
}
//Zero the Robot location
161


int statuszr = zr();
status += statuszr;
if(!statuszr)
{
myDebugLogger->log("unable to zero robot location");
}
//Set command timeout
int statustm = conf_tm(myTimeout);
status += statustm;
if(! statustm)
{
myDebugLogger->log("unable to set timeout");
}
//Set the motion parameters
int statussp = sp(myTransSpeed,0,0);
status += statussp;
if(! statussp)
{
myDebugLogger->log("unable to set motion params");
}
//Initialize the sensors ** Note: May not need to do this **
#ifdef SNSRINIT
bool sensorStatus = initSensorsO;
if(!sensorStatus)
{
myDebugLogger->log("unable to init sensors");
}
#endif
#ifdef SNSRINIT
return ((status + (int)sensorStatus) = 5) ? true : false;
#else
return (status 4) ? true : false;
#endif
// Log EnvFeatures detected
void Robot: :report() const
{
myScreenLogger->log("");
myScreenLogger->logt(" ");
162


myFeatureLogger->log("");
myFeatureLogger->logt("");
list: :const_iterator iter;
for(iter = myFeatures.begin();iter !- myFeatures.end();++iter)
{
myScreenLogger->log((*iter)->summaiy());
myFeatureLogger->log((*iter)->toString());
}
}
// Command robot to move
void Robot::scoutVm(short theTrans, short theRot)
{
int rot = (int)((float)theRot 377.0 / 3600.0);
vm(theTrans + rot, theTrans rot, 0);
}
//Shutdown
void Robot: :shutdown()
{
myScreenLogger->logt("Shutting Down Robot");
myDebugLogger->logt("Shutting Down Robot");
//Disconnect from server
disconnect_robot(myId);
}
////////////////////////////////
// Protected Functions
////////////////////////////////
/////////////////////////////
// Private Functions
/////////////////////////////
//Check ranges to avoid collisions
void Robot: :checkRange(long range)
{
cout "myObstacle = myObstacle endl;
163


if(range < myMinRangeToObs)
{
myObstacle = true;
}
myDebugLogger->logt(" ");
myDebugLogger->log("****** ************************ ************")
myDebugLogger->log(" !! IOBSTACLE DETECTED AHEAD!!! ");
//Check ranges to avoid collisions
void Robot: :checkRange(long *s)
{
long r = myMinRangeToObs;
if((s[17] < r) || (s[l8] < r) || (s[21] < r) || (s[29] < r) || (s[32] < r))
{
myObstacle = true;
}
myDebugLogger->logt("");
myDebugLogger->log(M******************************************")
myDebugLogger->log'(" !!IOBSTACLE DETECTED AHEAD!!! ");
void Robot: :getConfigO
{
myScreenLogger->log("Reading in configuration data");
myDebugLogger->logt("Reading in configuration data");
// Open config file for reading
ifstream ifs("robot.cfg");
// Create Config object
Config cfg(ifs);
// Get information from file
try
{
myTransSpeed = cfg.getlnt();
ostrstream mts;
mts "Trans Speed is:" myTransSpeed \0';
myDebugLogger->log(mts.str());
164


myDistance = cfg.getlnt();
ostrstream md;
md "Travel Distance is:" myDistance '\0';
myDebugLogger->log(md.str());
mySonarFireRate = cfg.getlnt();
ostrstream msfr;
msfr "Sonar Firing Rate is:" mySonarFireRate '\0';
myDebugLogger->log(msfr.str());
myCorrAspectRatio = cfg.getlnt();
ostrstream mcar;
mcar "Corridor Aspect Ratio is: myCorrAspectRatio \0';
myDebugLogger->log(mcar.str());
myReadingsPerlmage = cfg.getlnt();
ostrstream mrpi;
mrpi "Readings per Sonarlmage is: myReadingsPerlmage '\0';
myDebugLogger->log(mrpi.str());
myFWComerMatches = cfg.getlnt();
ostrstream mfcm;
mfcm "Comers to Match are:" myFWComerMatches '\0';
myDebugLogger->log(mfcm.str());
myMinRangeToObs = cfg.getLong();
ostrstream mmrto;
mmrto "Min Range to Obstacles is: myMinRangeToObs '\0';
myDebugLogger->log(mmrto.str());
myShortThreshold = cfg.getLong();
ostrstream mst;
mst "Short Threshold is:" myShortThreshold '\0';
myDebugLogger->log(mst.strO);
myLongThreshold = cfg.getLong();
ostrstream mlt;
mlt "Long Threshold is:" myLongThreshold ,\0';
myDebugLogger->log(mlt.strQ);
myReadingDistance = cfg.getlnt();
ostrstream mrd;
mrd "Reading Distance is: myReadingDistance ,\0;
165


myDebugLogger->log(mrd.str());
}
catch(ConfigError &ce)
{
myDebugLogger->log("Exception caught: EOF of config file, exiting");
myDebugLogger->log(ce.what());
exit(l);
}
catch(...)
{
myDebugLogger->log("Unexpected exception caught: exiting");
exit(l);
}
long Robot: :getXPosit(int sensorld)
{
//convert to inches
robotPosit = State[34]/10;
if(sensorId = 0)
{
if(State[STATE_SONAR_0] <= 120)
{
robotPosit += State[STATE_SONAR_0];
}
else
robotPosit += 99999;
}
cout "robotPosit = robotPosit endl;
return robotPosit;
}
long Robot::getYPosit(int sensorld)
{
//Get adjustment due to Robot drift
long adjustment = State[35]/10;
return (sensorld = 4) ? State[STATE_SONAR_4] adjustment:
State[STATE_SONAR_12] + adjustment;
}
166


void Robot: :initlmages()
{
myDebugLogger->logt("Initializing Sonarlmages for self test");
// Create Set of Sis
// Create arrays & vectors
long corrArray[16] = {226,154,200,44,43,44,209,120,202,106,170,36,32,33,201,150};
vector v 1 (&corrArray [0] ,&corrArray [ 16]);
long fwAiray[16] = {234,211,200,131,169,132,66,190,222,170,66,186,136,113,223,200};
vector v2(&fwArray[0],&fwArray[l 6]);
//long atArray[16] = {};
//vector v3 (&f\v Array [0] ,&fw Array [16]);
long utArray[16] = {39,40,70,73,198,191,65,99,207,153,65,126,133,184,72,40};
vector v4(&utArray[0],&utArray[l 6]);
long alcArray[16] = {206,124,180,44,43,44,209,120,202,102,53,76,75,76,180,120};
vector v5(&alcArray[0],&alcArray[16]);
long dalcArray[16] = {206,124,180,71,70,80,57,98,197,102,53,76,75,76,180,120};
vector v6(&dalcArray[0],&dalcArray[16]);
//long ceArray[16] = {};
//vector v7(&dalcArray[0],&dalcArray[16]);
//long aeArray[16] = {};
//vector v8(&dalcArray[0],&dalcArray[ 16]);
//long daeArray[16] = {};
//vector v9(&dalcArray[0],&dalcArray[16]);
long lArray [ 16] = {66,71,70,42,41,42,60,91,95,96,51,89,186,203,212,150};
vector vl0(&lArray[0],&lArray[16]);
// Create SonarDatas and lists for Sis
long x = 45;
long y = 90;
SonarData sdl(x,y,vl);
SonarData sd2(x,y,v2);
//SonarData sd3(x,y,v3);
167


SonarData sd4(x,y,v4);
SonarData sd5(x,y,v5);
SonarData sd6(x,y,v6);
//SonarData sd7(x,y,v7);
//SonarData sd8(x,y,v8);
//SonarData sd9(x,y,v9);
SonarData sdlO(x,y,vlO);
vector sdlist;
// Create Sis
sdlist.push_back(sd 1);
Sonarlmage *sil =new SonarImage(myDataFilter,sdlist);
sdlist.pop_back();
sdlist.push_back(sd 1);
Sonarlmage *sila = new SonarImage(myDataFilter,sdlist);
sdlist.pop_back();
sdlist.push_back(sd2);
Sonarlmage *si2 = new SonarImage(myDataFilter,sdlist);
sdlist.pop_back();
sdlist.push_back(sd4);
Sonarlmage *si4 = new SonarImage(myDataFilter,sdlist);
sdlist.pop_back();
sdlist.push_back(sd5);
Sonarlmage *si5 = new SonarImage(myDataFilter,sdlist);
sdlist.pop_back();
sdlist.push_back(sd6);
Sonarlmage *si6 = new SonarImage(myDataFilter,sdlist);
sdlist.pop_back();
sdlist.push_back(sd 10);
Sonarlmage *sil0 = new SonarImage(myDataFilter,sdlist);
sdlist.pop_back();
// Insert Sis into list to test matching functions
// Start with corridor then switch to other Sis
// 3 corr
myDebugLogger->log("Adding 3 corr to SI list");
mySonarImages.push_back(si 1);
168


mySonarImages.push_back(si 1 a);
mySonarImages.push_back(si 1);
// 2 fw
myDebugLogger->log("Adding 2 four way to SI list");
mySonarImages.push_back(si2);
mySonarImages.push_back(si2);
//1 corr
myDebugLogger->log(" Adding 1 corr to SI list");
mySonarImages.push_back(si 1);
//1UT
myDebugLogger->log(" Adding 1 UT to SI list");
mySonarImages.push_back(si4);
//1 corr
myDebugLogger->log("Adding 1 corr to SI list");
mySonarImages.push_back(si 1);
// alcove
myDebugLogger->log("Adding 1 alcove to SI list");
mySonarImages.push_back(si5);
// dual alcove
myDebugLogger->log("Adding 1 dual alcove to SI list");
mySonarImages.push_back(si6);
// L
myDebugLogger->log(" Adding 1 L to SI list");
mySonarImages.push_back(si 10);
// Print out Sonarlmages list
vector: iterator iter;
for(iter = mySonarImages.begin();iter != mySonarImages.end(); ++iter)
{
myDebugLogger->log((*iter)->toString());
}
}
void Robot: :initPattems()
{
myDebugLogger->logt("Initializing patterns");
// Create corridor pattern
EnvFeature *corridor = new.EnvFeature("corridor");
list *corrRules = new list;
corrRules->push_front(newFrontLongRule(myLongThreshold));
corrRules->push_back(newBackLongRule(myLongThreshold));
169


corrRules->push_back(new TwoSideShortRule(myShortThreshold));
corrRules->push_back(new CorrRule(myCorrAspectRatio));
myPattems.push_back(new FeaturePattemImpl(corridor,corrRules));
// Create four way pattern
EnvFeature *fourWay = new EnvFeature("four way");
list *fwRules = new list;
fwRules->push_back(newBackLongRule(myLongThreshold));
fwRules->push_back(newFrontLongRule(myLongThreshold));
fwRules->push_back(newTwoSideLongRule(myLongThreshold));
// fwRules->push_back(new FW ComerRule(myFW ComerMatches));
myPattems.push_back(new FeaturePattemImpl(fourWay,fwRules));
// Create across T pattern
EnvFeature *acrossT = new EnvFeature("across T");
list *acrossTRules = new list;
acrossTRules->push_back(new BackLongRule(myLongThreshold));
acrossTRules->push_back(newFrontLongRule(myLongThreshold));
acrossTRules->push_back(new SideLongRule(myShortThreshold,myLongThreshold));
myPattems.push_back(newFeaturePattemImpl(acrossT,acrossTRules));
// Create up T pattern
EnvFeature *upT = new EnvFeature("up T");
list *upTRules = new list;
upTRules->push_back(newBackLongRule(myLongThreshold));
/7upTRules->push_back(newFrontArcRule(niyLongThreshold));
upTRules->push_back(newTwoSideLongRule(myLongThreshold));
upTRules->push_back(newFrontShortRule(myShortThreshold));
myPattems.push_back(newFeaturePattemImpl(upT,upTRules));
// Create corridor alcove pattern
EnvFeature *alcove = new EnvFeature("alcove");
list *alcRules = new list;
alcRules->push_back(newFrontLongRule(myLongThreshold));
alcRules->push_back(newBackLongRule(myLongThreshold));
alcRules->push_back(new SideInterRule(niyShortThreshold,myLongThreshold));
170


alcRules->push_back(new SideShortRule(myShortThreshold));
myPattems.push_back(new FeaturePattemImpl(alcove,alcRules));
// Create corridor dual alcove pattern
EnvFeature *dualAlcove = new EnvFeature("dual alcove");
list *dAlcRules = new list;
dAlcRules->push_back(new FrontLongRule(myLongThreshold));
dAlcRules->push_back(new BackLongRule(myLongThreshold));
dAlcRules->push_back(new TwoSideInterRule(myShortThreshold,myLongThreshold));
myPattems.push_back(new FeaturePattemImpl(dualAlcove,dAlcRules));
// Create corridor end pattern
EnvFeature *corrEnd = new EnvFeature("corridor end");
list *corrEndRules = new list;
corrEndRules->push_front(new FrontShortRule(myShortThreshold));
corrEndRules->push_back(newBackLongRule(myLongThreshold));
corrEndRules->push_back(new TwoSideShortRule(myShortThresfrold));
myPattems.push_back(newFeaturePattemImpl(corrEnd,corrEndRules));
// Create alcove end pattern
EnvFeature *alcoveEnd = new EnvFeature("alcove end");
list *alcEndRules = new list;
alcEndRules->push_back(newFrontShortRule(myShortThreshold));
alcEndRules->push_back(new BackLongRule(myLongThreshold));
alcEndRules->push_back(new SideInterRule(myShortThreshold,myLongThreshold));
alcEndRules->push_back(new SideShortRule(myShortThreshold));
myPattems.push_back(new FeaturePattemImpl(alcoveEnd,alcEndRules));
// Create dual alcove end pattern
EnvFeature *dualAlcoveEnd = new EnvFeature("dual alcove end");
list *dAlcEndRules = new list;
dAlcEndRules->push_back(new FrontShortRule(myShortThreshold));
dAlcEndRules->push_back(newBackLongRule(myLongThreshold));
dAlcEndRules->push_back(new
TwoSideInterRule(myShortThreshold,myLongThreshold));
171


myPattems.push_back(new FeaturePattemImpl(dualAlcoveEnd,dAlcEndRules));
// Create L pattern
EnvFeature *L = new EnvFeature("L");
list *lRules = new list;
lRules->push_back(newFrontShortRule(myShortThreshold));
lRules->push_back(newBackLongRule(myLongThreshold));
lRules->push_back(new SideShortRule(myShortThreshold));
lRules->push_back(new SideLongRule(myShortThreshold,myLongThreshold));
myPattems.push_back(newFeaturePattemImpl(L,lRules));
}
//Initialize the sensor suite
bool Robot: :initSensors()
{
int status = 0;
//Attach position data to sonar data
status += posDataRequest(POS_SONAR);
//Configure sensors for firing
status += conf_sn(mySonarFireRate,mySonarFiringOrder);
return (status = 2) ? true: false;
}
172


Illlllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
I I Name:
// Description:
//
//
// Created:
// Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
Robot2Main.cc
Main for robot exploration program which identifies
large-scale indoor features such as corridors,
four way intersections, etc.
9/25/98
////////////////
// Includes
////////////////
#include "Robot.h"
llllIIIII III
II Main
////////////
int main(int /* argc */, char *argv[])
{
//Create robot
Robot robby(argv[l]);
#ifdef SELFTEST
robby.explore();
robby.report();
#else
if(robby.init())
{
robby.explore();
robby.report();
}
robby. shutdo wn();
#endif
return 0;
}
173


#ifndef RULE_H
#defme RULE H
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name:
// Description:
//
//
// Created:
//Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
Rule.h
Base class for Rule hierarchy. Rules are used by
FeaturePattemlmpl's to determine if a feature is matched
by a particular set of sonar data.
11/25/98
////////////////
// Includes
////////////////
////////////////////////
// Forward Decls
////////////////////////
template class vector;
class Rule
{
////////////////////////////
// Public Functions
////////////////////////////
public:
// Destructor
virtual ~Rule();
// Determine if data matches
virtual bool match(const vector & theData) const = 0;
///////////////////////////////
// Protected Functions
///////////////////////////////
protected:
////////////////////////////
// Private Functions
////////////////////////////
private:
174


//////////////////////////////
// Protected Members
//////////////////////////////
protected:
///////////////////////////
// Private Members
///////////////////////////
private:
};
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name: Rule.cc
// Description: Implementation for Rule class. Used to provide non-
// inline virtual destructor.
// Created: 11/25/98
//Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
#include "Rule.h"
//////////////
// Statics
//////////////
////////////////////////////
// Public Functions
////////////////////////////
Rule::~Rule()
{
}
///////////////////////////////
// Protected Functions
///////////////////////////////
175


////////////////////////////
// Private Functions
////////////////////////////


#ifndef RULEIMPL_H
#define RULEIMPL H
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name:
// Description:
//
// Created:
// Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
Rulelmpl.h
Provides implementations of functions for use by derived
classes. Rulelmpl is derived from Rule.
11/26/98
////////////////
// Includes
////////////////
#include
#include "Rule.h" // Base class
////////////////////////
// Forward Decls
////////////////////////
/////////////////////
// Namespaces
/////////////////////
using namespace std;
class Rulelmpl: public Rule
{
////////////////////////////
// Public Functions
////////////////////////////
public:
// Constructor
Rulelmpl();
// Destructor
virtual -RulelmplQ;
177


///////////////////////////////
// Protected Functions
///////////////////////////////
protected:
// Get data from SonarData
long getBack(const vector &theData) const;
long getBackArc(const vector &theData) const;
long getBackLeftArc(const vector &theData) const;
long getBackRightArc(const vector &theData) const;
long getFront(const vector &theData) const;
long getFrontArc(const vector &theData) const;
long getFrontLeftArc(const vector &theData) const;
long getFrontRightArc(const vector &theData) const;
long getLeft(const vector &theData) const;
long getLefitArc(const vector &theData) const;
long getRight(const vector &theData) const;
long getRightArc(const vector &theData) const;
////////////////////////////
// Private Functions
////////////////////////////
private:
//////////////////////////////
// Protected Members
//////////////////////////////
protected:
///////////////////////////
// Private Members
///////////////////////////
private:

#endif
178


IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
I I Name: Rulelmpl.cc
// Description: Provides implementations of functions for use by
// derived classes.
// Created: 11/26/98
// Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
#include "Rulelmpl.h"
//////////////
// Statics
//////////////
////////////////////////////
// Public Functions
////////////////////////////
Rulelmpl: :RuleImpl()
{
}
Rulelmpl: :~RuleImpl()
{
}
///////////////////////////////
// Protected Functions
///////////////////////////////
long Rulelmpl::getBack(const vector &theData) const
{
return theData[8];
}
long Rulelmpl::getBackArc(const vector &theData) const
{
return (theData[7] + theData[8] + theData[9]);
}
long Rulelmpl::getBackLeftArc(const vector &theData) const
179


{
return (theData[5] + theData[6] + theData[7]);
}
long RuleImpl::getBackRightArc(const vector &theData) const
{
return (theData[9] + theData[10] + theData[l 1]);
}
long RuleImpl::getFront(const vector &theData) const
{
return theData[0];
}
long RuleImpl::getFrontArc(const vector &theData) const
{
return (theData[15] + theData[0] + theData[l]);
}
long RuleImpl::getFrontLeftArc(const vector &theData) const
{
return (theData[l] + theData[2] + theData[3]);
}
long RuleImpl::getFrontRightArc(const vector &theData) const
{
return (theData[13] + theData[14] + theData[15]);
}
long RuleImpl::getLeft(const vector &theData) const
{
return theData[4];
}
long RuleImpl::getLeftArc(const vector &theData) const
{
return (theData[3] + theData[4] + theData[5]);
}
long RuleImpl::getRight(const vector &theData) const
{
return theData[12];
}
180


long RuleImpl::getRightArc(const vector &theData) const
{
return (theData[l 1] + theData[12] + theData[13]);
}
////////////////////////////
// Private Functions
////////////////////////////
181


#ifndef SCREENLOGH
#defme SCREENLOG_H
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name: ScreenLog.h
// Description: Derived log class which writes information to the screen.
// Created: 12/14/98
//Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
#include "Log.h"
//include
#include
////////////////////////
// Forward Decls
////////////////////////
/////////////////////
// Namespaces
/////////////////////
using namespace std;
class ScreenLog : public Log
{
//////////////////////////// .
// Public Functions
////////////////////////////
public:
// Constructor
ScreenLogO;
// Destructor
-ScreenLogO;
///////////////////////////////
// Protected Functions
///////////////////////////////
182


protected:
////////////////////////////
// Private Functions
////////////////////////////
private:
// Write information to the screen
void log(const string &aString) {cout aString endl;}
//////////////////////////////
// Protected Members
//////////////////////////////
protected:
///////////////////////////
// Private Members
///////////////////////////
private:
};
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name: ScreenLog.cc
// Description: Log class which writes data to screen.
// Created: 12/14/98
// Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
#include "ScreenLog.h"
//////////////
// Statics
//////////////
////////////////////////////
// Public Functions
////////////////////////////
183


ScreenLog: :ScreenLog()
{
}
ScreenLog: :~ScreenLog()
{
}
///////////////////////////////
// Protected Functions
///////////////////////////////
////////////////////////////
// Private Functions
////////////////////////////


#ifhdef SIDEINTERRULE_H
#defme SIDEINTERRULE_H
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name:
// Description:
//
//
// Created:
//Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
SidelnterRule.h
Rule that indicates there is a "intermediate" distance to
at least one side of the robot. Intermediate distance
is assumed to indicate an alcove.
12/15/98
////////////////
// Includes
////////////////
#include "Rulelmpl.h" // Base class
////////////////////////
// Forward Decls
////////////////////////
class SidelnterRule : public Rulelmpl
{
////////////////////////////
// Public Functions
////////////////////////////
public:
// Constructor
SideInterRule(long theShortThreshold,
long theLongThreshold);
// Destructor
~SideInterRule();
// Determine if data matches
virtual bool match(const vector & theData) const;
///////////////////////////////
// Protected Functions
///////////////////////////////
protected:
185


////////////////////////////
// Private Functions
////////////////////////////
private:
//////////////////////////////
// Protected Members
//////////////////////////////
protected:
///////////////////////////
// Private Members
///////////////////////////
private:
long itsShortThreshold;
long itsLongThreshold;
};
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name: SideInterRule.ee
// Description: Implementation of rule to determine if there is at least
// one intermediate distance to the side of the robot.
// Created: 12/15/98
// Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
#include "SidelnterRule.h"
//////////////
// Statics
//////////////
////////////////////////////
// Public Functions
////////////////////////////
186


SidelnterRule:: SideInterRule(long theShortThreshold,
long theLongThreshold)
{
itsShortThreshold = theShortThreshold;
itsLongThreshold = theLongThreshold;
}
SidelnterRule: :~SideInterRule()
{
}
bool SidelnterRule: :match(const vector &theData) const
{
bool left = ((getLefit(theData) <= itsLongThreshold) &&
(getLeft(theData) >= itsShortThreshold)) ? true : false;
bool right = ((getRight(theData) <= itsLongThreshold) &&
(getRight(theData) >= itsShortThreshold)) ? true : false;
return ((left = true) || (right = true)) ? true : false;
}
///////////////////////////////
// Protected Functions
///////////////////////////////
////////////////////////////
// Private Functions
////////////////////////////
187


#ifhdef SDDELONGRULEH
#defme SIDELONGRULE H
llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
// Name:
// Description:
//
// Created:
//Last Mod.:
Illlllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
SideLongRule.h
Rule that indicates there is a "long" distance to
at least one side of the robot.
12/4/98
////////////////
// Includes
////////////////
#include "Rulelmpl.h" // Base class
////////////////////////
// Forward Decls
////////////////////////
class SideLongRule : public Rulelmpl
{
////////////////////////////
// Public Functions
////////////////////////////
public:
// Constructor
SideLongRule(long theShortThreshold,
long theLongThreshold);
// Destructor
~SideLongRule();
// Determine if data matches
virtual bool match(const vector & theData) const;
///////////////////////////////
// Protected Functions
///////////////////////////////
protected:
188


////////////////////////////
// Private Functions
////////////////////////////
private:
//////////////////////////////
// Protected Members
//////////////////////////////
protected:
///////////////////////////
// Private Members
///////////////////////////
private:
long itsShortThreshold;
long itsLongThreshold;
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name:
// Description:
//
// Created:
// Last Mod.:
Illlllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
SideLongRule.ee
Implementation of rule to determine if there is at least
one long distance to the side of the robot.
12/4/98
////////////////
// Includes
////////////////
#include "SideLongRule.h
//////////////
// Statics
//////////////
////////////////////////////
// Public Functions
////////////////////////////
SideLongRule::SideLongRule(long theShortThreshold,
189


long theLongThreshold)
{
itsShortThreshold = theShortThreshold;
itsLongThreshold = theLongThreshold;
}
SideLongRule: :~SideLongRule()
{
}
bool SideLongRule: :match(const vector &theData) const
{
bool left = ((getLeft(theData) > itsLongThreshold) &&
(getRight(theData) < itsShortThreshold)) ? true : false;
bool right = ((getRight(theData) > itsLongThreshold) &&
(getLeft(theData) < itsShortThreshold)) ? true : false;
return ((left = true) || (right = true)) ? true : false;
}
///////////////////////////////
// Protected Functions
///////////////////////////////
////////////////////////////
// Private Functions
////////////////////////////
190


#ifhdef SIDESHORTRULEH
#define SIDESHORTRULE H
////////////////////////////////////////////////////////////////////////////////////////////////////////////
SideShortRule.h
Rule that indicates there is a "short" distance to
at least one side of the robot.
12/1/98
// Name:
// Description:
//
// Created:
//Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
#include "Rulelmpl.h" // Base class
////////////////////////
// Forward Decls
////////////////////////
class SideShortRule : public Rulelmpl
{
////////////////////////////
// Public Functions
////////////////////////////
public:
// Constructor
SideShortRule(long theThreshold);
// Destructor
~SideShortRule();
// Determine if data matches
virtual bool match(const vector & theData) const;
///////////////////////////////
// Protected Functions
///////////////////////////////
protected:
191


////////////////////////////
// Private Functions
////////////////////////////
private:
//////////////////////////////
// Protected Members
//////////////////////////////
protected:
///////////////////////////
// Private Members
///////////////////////////
private:
long itsThreshold;
};
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name:
// Description:
//
// Created:
// Last Mod.:
SideShortRule.ee
Implementation of rule to determine if there is at least
one short distance to the side of the robot.
12/4/98
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
#include "SideShortRule.h"
//////////////
// Statics
//////////////
////////////////////////////
// Public Functions
////////////////////////////
SideShortRule:: SideShortRule(long theThreshold)
{
192


itsThreshold = theThreshold;
}
SideShortRule: :~SideShortRule()
{
}
bool SideShortRule: :match(const vector &theData) const
{
return ((getLeft(theData) < itsThreshold) 11
(getRight(theData) < itsThreshold)) ? true : false;
}
/////////////////;/////////////
// Protected Functions
///////////////////////////////
////////////////////////////
// Private Functions
////////////////////////////
193


#ifndef SONARDATA_H
#defme SONARDATA H
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name:
// Description:
//
// Created:
// Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
SonarData.h
Class which represents the set of sonar data taken at
a particular position.
10/20/98
////////////////
// Includes
////////////////
#include
////////////////////////
// Forward Decls
////////////////////////
class ostream;
/////////////////////
// Namespaces
/////////////////////
using namespace std;
class SonarData
{
////////////////////////////
// Public Functions
////////////////////////////
public:
// Default ctor
SonarData();
//ctor which takes x posit, yposit, and vector of sonar data
SonarData(long xData, long yData, const vector &sonarPings);
//ctor which takes x posit, yposit, and vector of sonar data
194


SonarData(float xData, float yData, const vector &sonarPings);
//dtor
~SonarData();
//copy ctor
SonarData(const SonarData &data);
//op=
SonarData& operator=(const SonarData &data);
// Add a ping to itsSonarPings
void add(long theSonarPing) {mySonarPings.push_back(theSonarPing);}
const vector &getSonarPings() const {return mySonarPings;}
float getXPosit() const {return myXPosit;}
float getYPositQ const {return myYPosit;}
// Set timestamp of SonarData
void . setTime();
// Set X position
void setXPosit(long theXPosit);
void setXPosit(float theXPosit);
// Set Y position
void setYPosit(long theYPosit);
void setYPosit(float theYPosit);
char* toStringO const;
friend ostream & operator(ostream & os, const SonarData & data);
///////////////////////////////
// Protected Functions
///////////////////////////////
protected:
////////////////////////////
// Private Functions
////////////////////////////
private:
195


//////////////////////////////
// Protected Members
//////////////////////////////
protected:
///////////////////////////
// Private Members
///////////////////////////
private:
//timestamp for sonar readings
long mySeconds; .
long myMilliseconds;
//X position of robot when sonar readings were taken
float myXPosit;
//Y position of robot when sonar readings were taken
float myYPosit;
vector mySonarPings;
};
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name:
// Description:
//
// Created:
// Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
SonarData.cc
Implementation for a class which sonar data obtained
from the Scout robot.
10/20/98
////////////////
// Includes
////////////////
#include "SonarData.h"
#include
#include
#include
#include // For gettimeofday
196


//////////////
// Statics
//////////////
////////////////////////////
// Public Functions
////////////////////////////
SonarData:: SonarData()
{
// Set timestamp
setTime();
myXPosit = 0.0;
myYPosit = 0.0;
}
SonarData::SonarData(long xData, long yData, const vector & sonarPings)
mySonarPings(sonarPings)
{
//Set timestamp
setTimeQ;
// Convert data from long to float
setXPosit(xData);
setYPosit(yData);
}
SonarData::SonarData(float xData, float yData, const vector & sonarPings)
mySonarPings(sonarPings)
{
//Set timestamp
setTime();
myXPosit = xData;
myYPosit = yData;
}
//copy ctor
SonarData: :SonarData(const SonarData &data):
mySonarPings(data.mySonarPings)
{
mySeconds = data.mySeconds;
197


myMilliseconds = data.myMilliseconds;
myXPosit = data.myXPosit;
myYPosit = data.myYPosit;
}
SonarData: :~SonarDataO
{
}
//op=
SonarData & SonarData: :operator=(const SonarData &data)
{
if(&data != this)'
{
mySeconds = data.mySeconds;
myMilliseconds = data.myMilliseconds;
myXPosit = data.myXPosit;
myYPosit = data.myYPosit;
mySonarPings = data.mySonarPings;
}
return *this;
}
void SonarData::setTime()
{
//Get timestamp
struct timeval tempTime;
struct timezone tempZone;
gettimeofday(&tempTime,&tempZone);
mySeconds = tempTime.tv_sec;
myMilliseconds = tempTime.tv_usec;
}
void SonarData::setXPosit(long theXPosit)
{
myXPosit = theXPosit/10.0;
}
void SonarData: :setXPosit(float theXPosit)
{
myXPosit = theXPosit;
}
198


void SonarData::setYPosit(long theYPosit)
{
myYPosit = theYPosit/10.0;
}
void SonarData::setYPosit(float theYPosit)
{
myYPosit = theYPosit;
}
char* SonarData::toString() const
{
ostrstream oss;
oss "Time: mySeconds myMilliseconds endl;
oss "X: myXPosit Y:" myYPosit endl;
for(size_t i=0;i oss i " mySonarPings[i] ";
oss endl;
oss \0';
return oss.str();
}
ostream & operator(ostream & os,const SonarData & data)
{
os "Time: data.mySeconds data.myMilliseconds endl;
os "X: data.myXPosit Y: data.myYPosit endl;
for(size_t i=0;i os i ": data.mySonarPings[i] "
os endl;
return os;
}
///////////////////////////////
// Protected Functions
///////////////////////////////
////////////////////////////
// Private Functions
////////////////////////////
199


#ifhdef SONARIMAGE_H
#defme SONARIMAGE H
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name: Sonarlmage.h
// Description: A Sonarlmage is a filtered SonarData created from N
// SonarDatas. Can be compared to FeaturePattems to
// determine what feature the image represents.
//Created: 10/31/98
//Last Mod.: 12/22/98
// Added op
// 1/9/99
// Added matchPair vector and operations
// modified op & toString
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
#include
#include
#include
#include
#include "SonarData.h"
// For Feature type
// Container for raw sonar data
// For Feature type/percent match pairs
// Holds filtered sonar data
////////////////////////
// Forward Decls
////////////////////////
class DataFilter; // Filter for raw data
class ostream; // For op
///////////////////// .
// Namespaces
/////////////////////
using namespace std;
class Sonarlmage
{
////////////////////////////
// Public Functions
////////////////////////////
200


public:
// typedef for matchPair
typedef pair matchPair;
// Constructors
SonarImage(DataFilter &theFilter,
vector &theSonarData);
// Destructor
~SonarImage();
// Provide filtered data to a client
const SonarData& getlmage() const {return itsFilteredData;}
// Provide best matches to a client
const vector& getMatches() const {return itsMatches;}
// Add matchPairs to Sonarlmage
void setMatches(const vector& theMatches);
// Convert Sonarlmage (filtered data) to a string
char* toStringO const;
friend ostream& operator(ostream &os, const Sonarlmage &image);
///////////////////////////////
// Protected Functions
///////////////////////////////
protected:
////////////////////////////
// Private Functions
////////////////////////////
private:
SonarImage(const Sonarlmage &orig);
SonarImage& operator=(const Sonarlmage &orig);
void filter();
void setXPosit();
201


void setYPosit();
//////////////////////////////
// Protected Members
//////////////////////////////
protected:
///////////////////////////
// Private Members
///////////////////////////
private:
mutable SonarData itsFilteredData;
DataFilter& itsDataFilter;
vector& itsRawData;
vector itsMatches;

#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name: Sonarlmage.cc
// Description: Implementation for Sonarlmage class.
// Created: 10/31/98
// Last Mod.: 12/22/98
// Added op for displaying Sonarlmage
// 1/9/99
// Added matchPair operations, modified op and toString
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
#include
#include
#include
#include
#include
202


#include "Sonarlmage.h"
#include // For filtering of raw data
//////////////
// Statics
//////////////
////////////////////////////
// Public Functions
////////////////////////////
SonarImage::SonarImage(DataFilter &theFilter,
vector &theSonarData) :
itsDataFilter(theFilter),
itsRawData(theSonarData)
{
filter();
setXPosit();
setYPosit();
}
Sonarlmage: :~SonarImage()
{
}
void Sonarlmage::setMatches(const vector& theMatches)
{
itsMatches = theMatches;
}
char* Sonarlmage::toString() const
{
ostrstream oss;
oss itsFilteredData;
if(! itsMatches. empty ())
{
oss "Best Feature Matches:" endl;
vector: :const_iterator iter;
for(iter = itsMatches.begin(); iter != itsMatches.end(); ++iter)
{
203


oss (*iter).first "" (*iter).second endl;
}
}
oss \0';
return oss.str();
}
ostream& operator(ostream &os, const Sonarlmage &image)
{
os image.getlmage();
if(!image.getMatches().empty())
{
os "Best Feature Matches:" endl;
vector:: const_iterator iter;
for(iter = image.getMatches().begin(); iter != image.getMatches().end(); ++iter)
{
os (*iter).first "" (*iter).second endl;
}
}
return os;
}
///////////////////////////////
// Protected Functions
///////////////////////////////
////////////////////////////
// Private Functions
////////////////////////////
void Sonarlmage: :filter()
{
// Steps that Sonarlmage must perform before giving raw data to filter
// Need to decide whether "bad" data points will be thrown out before or after
// filtering
vectorrawData(itsRawData.size());
// Get vectors of data to give to filter and filter data
for(int i=0;i<16;++i)
{
204


for(size_t j=0;j {
rawData[j] = (itsRawData[j].getSonarPings())[i];
}
// Filter data
itsFilteredData.add(itsDataFilter.filter(rawData));
}
void SonarImage::setXPosit()
{
vector xPosits(itsRawData.size());
for(size_t i=0;i {
xPosits[i] = itsRawData[i].getXPosit();
}
itsFilteredData.setXPosit(static_cast(accumulate(xPosits.begin(),xPosits.end(),0.0)/x
Posits.size()));
}
void SonarImage::setYPosit()
{
vector yPosits(itsRawData.size());
for(size_t i=0;i {
yPosits[i] = itsRawData[i].getYPosit();
}
itsFilteredData.setYPosit(static_cast(accumulate(yPosits.begin(),yPosits.end(),0.0)
/yPosits.size()));
}
205


#ifhdef SUBJECT_H
#defme SUBJECT H
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name:
// Description:
//
//
// Created:
// Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
Subject.h
Class which is monitored by other classes and provides
updates to these Observers. Based on the Observer
pattern in Design Patterns.
10/12/98
////////////////
// Includes
////////////////
#include
#include -
#include
#include "Observer.h"
////////////////////////
// Forward Decls
////////////////////////
/////////////////////
// Namespaces
/////////////////////
using namespace std;
class Subject
{
////////////////////////////
// Public Functions
////////////////////////////
public:
// Destructor
virtual ~Subject() = 0;
// Add an Observer
virtual void attach(auto_ptr anObserver);
// Send notification to Observers
206


virtual void notify(const string &aString);
///////////////////////////////
// Protected Functions
///////////////////////////////
protected:
// Get Observers
const list >& getObs() const {return observers;}
////////////////////////////
// Private Functions
////////////////////////////
private:
//////////////////////////////
// Protected Members
//////////////////////////////
protected:
///////////////////////////
// Private Members
///////////////////////////
private:
list > observers;
};
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name: Subject.cc
// Description: Implementation for Subject class.
//Created: 10/15/98
// Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
#include
#include "Subject.h"
207


//////////////
// Statics
//////////////
////////////////////////////
// Public Functions
////////////////////////////
Subj ect: :~Subj ect()
{
}
void Subj ect: :attach(auto_ptr anObserver)
{
observers.push_back(anObserver);
}
void Subj ect: :notify(const string &aString)
{
list >: iterator iter;
for(iter = observers.beginQ; iter != observers.end(); ++iter)
{
(*iter)->update(aString);
}
}
///////////////////////////////
// Protected Functions
///////////////////////////////
////////////////////////////
// Private Functions
////////////////////////////
208


#ifndef TIMEST AMP_H
#define TIMESTAMP H
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name:
// Description:
//
// Created:
// Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
Timestamp.h
Representation of a timestamp used in logging
information for the robot
12/31/99
////////////////
// Includes
////////////////
#include // For access to time functions
////////////////////////
// Forward Decls
////////////////////////
/////////////////////
// Namespaces
/////////////////////
class Timestamp
{
////////////////////////////
// Public Functions
////////////////////////////
public:
// Get time of form Month Day HH:MM:SS Year
static const char* timestamp();
// Get millseconds
static long getUsec();
// Get seconds from epoch
static long getSec();
///////////////////////////////
// Protected Functions
///////////////////////////////
209


protected:
////////////////////////////
// Private Functions
////////////////////////////
private:
//////////////////////////////
// Protected Members
//////////////////////////////
protected:
///////////////////////////
// Private Members
///////////////////////////
private:
static struct timeval aTime;
static struct timezone aZone;
};
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Name: Timestamp.cc
// Description: Implementation to provide timestamps for log information
//Created: 12/31/98
//Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
#include "Timestamp.h"
#include
//////////////
// Statics
//////////////
struct timeval Timestamp::aTime;
struct timezone Timestamp::aZone;
210


////////////////////////////
// Public Functions
////////////////////////////
const char* Timestamp::timestamp()
{
gettimeofday(&aTime,&aZone);
time_t theSeconds = aTime.tv_sec;
string strtime(ctime(&theSeconds));
strtime.replace(strtime.find("\n" ,0),2,"");
return strtime.c_strO;
}
long Timestamp::getUsec()
{
gettimeofday(&aTime,&aZone);
return aTime.tvjusec;
}
long Timestamp::getSecO
{
gettimeofday(&aTime,&aZone);
return aTime.tv_sec;
}
///////////////////////////////
// Protected Functions
///////////////////////////////
////////////////////////////
// Private Functions
////////////////////////////
211


#ifndef TWOSIDEINTERRULE_H
#defme TWOSIDEINTERRULE H
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
11 Name:
// Description:
//
//
// Created:
// Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
TwoSidelnterRule.h
Rule that indicates there is a "intermediate" distance
on two sides of the robot. Intermediate distance
is assumed to indicate an alcove.
12/15/98
////////////////
// Includes
////////////////
#include "Rulelmpl.h" // Base class
////////////////////////
// Forward Decls
////////////////////////
class TwoSidelnterRule : public Rulelmpl
{
////////////////////////////
// Public Functions
////////////////////////////
public:
// Constructor
TwoSideInterRule(long theShortThreshold,
long theLongThreshold);
// Destructor
~TwoSideInterRule();
// Determine if data matches
virtual bool match(const vector & theData) const;
///////////////////////////////
// Protected Functions
///////////////////////////////
protected:
212


////////////////////////////
// Private Functions
////////////////////////////
private:
//////////////////////////////
// Protected Members
//////////////////////////////
protected:
///////////////////////////
// Private Members
///////////////////////////
private:
long itsShortThreshold;
long itsLongThreshold;
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name:
// Description:
//
// Created:
// Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
TwoSideInterRule.ee
Implementation of rule to determine if there are two
intermediate distances to the side of the robot.
12/15/98
////////////////
// Includes
////////////////
#include "TwoSidelnterRule.h"
//////////////
// Statics
//////////////
////////////////////////////
// Public Functions
////////////////////////////
213


T woSidelnterRule: :T woSideInterRule(long theShortThreshold,
long theLongThreshold)
{
itsShortThreshold = theShortThreshold;
itsLongThreshold = theLongThreshold;
}
TwoSideInterRule::~TwoSideInterRule()
{
}
bool TwoSideInterRule::match(const vector &theData) const
{
bool left = ((getLeft(theData) <= itsLongThreshold) &&
(getLeft(theData) >= itsShortThreshold)) ? true : false;
bool right = ((getRight(theData) <= itsLongThreshold) &&
(getRight(theData) >= itsShortThreshold)) ? true : false;
return ((left true) && (right = true)) ? true : false;
}
///////////////////////////////
// Protected Functions
///////////////////////////////
////////////////////////////
// Private Functions
////////////////////////////
214


#ifndef TWOSDDELONGRULEH
#defme TWOSIDELONGRULE H
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name:
// Description:
//
// Created:
//Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
TwoSideLongRule.h
Rule that indicates there is a "long" distance on
both sides of the robot.
12/1/98
////////////////
// Includes
////////////////
#include "Rulelmpl.h" // Base class
////////////////////////
// Forward Decls
////////////////////////
class TwoSideLongRule : public Rulelmpl
{
////////////////////////////
// Public Functions
////////////////////////////
public:
// Constructor
TwoSideLongRule(long theThreshold);
// Destructor
~TwoSideLongRule();
// Determine if data matches
virtual bool match(const vector & theData) const;
///////////////////////////////
// Protected Functions
///////////////////////////////
protected:
215


////////////////////////////
// Private Functions
////////////////////////////
private:
//////////////////////////////
// Protected Members
//////////////////////////////
protected:
///////////////////////////
// Private Members
///////////////////////////
private:
long itsThreshold;
};
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name:
// Description:
//
// Created:
//Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
TwoSideLongRule.ee
Implementation of rule to determine if there are two
long distances to the side of the robot.
12/4/98
////////////////
// Includes
////////////////
#include "TwoSideLongRule.h"
//////////////
// Statics
//////////////
////////////////////////////
// Public Functions
////////////////////////////
TwoSideLongRule: :TwoSideLongRule(long theThreshold)
216


{
itsThreshold = theThreshold;
}
T woSideLongRule: :~T woSideLongRule()
{
}
bool TwoSideLongRule::match(const vector &theData) const
{
return ((getLeft(theData) >= itsThreshold) &&
(getRight(theData) >= itsThreshold)) ? true : false;
}
///////////////////////////////
// Protected Functions
///////////////////////////////
////////////////////////////
// Private Functions
////////////////////////////
217


#ifhdef TW OSIDESHORTRULE_H
#defme TWOSIDESHORTRULE H
////////////////////////////////////////////////////////////////////////////////////////////////////////////
TwoSideShortRule.h
Rule that indicates there is a "short" distance on
both sides of the robot.
12/1/98
// Name:
// Description:
//
// Created:
//Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////
// Includes
////////////////
include "Rulelmpl.h" // Base class
////////////////////////
// Forward Decls
////////////////////////
class TwoSideShortRule : public Rulelmpl
{
////////////////////////////
// Public Functions
////////////////////////////
public:
// Constructor
TwoSideShortRule(long theThreshold);
// Destructor
~T woSideShortRule();
// Determine if data matches
virtual bool match(const vector & theData) const;
///////////////////////////////
// Protected Functions
///////////////////////////////
protected:
218


////////////////////////////
// Private Functions
////////////////////////////
private:
//////////////////////////////
// Protected Members
//////////////////////////////
protected:
///////////////////////////
// Private Members
///////////////////////////
private:
long itsThreshold;
};
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Name:
// Description:
//
// Created:
// Last Mod.:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
TwoSideShortRule.ee
Implementation of rule to determine if there are two
short distances to the side of the robot.
12/4/98
////////////////
// Includes
////////////////
#include "TwoSideShortRule.h"
//////////////
// Statics
//////////////
////////////////////////////
// Public Functions
////////////////////////////
TwoSideShortRule: :TwoSideShortRule(long theThreshold)
219


{
itsThreshold = theThreshold;
}
TwoSideShortRule::~TwoSideShortRule()
{
}
bool TwoSideShortRule::match(const vector &theData) const
{
return ((getLeft(theData) <= itsThreshold) &&
(getRight(theData) <= itsThreshold)) ? true : false;
}
///////////////////////////////
// Protected Functions
///////////////////////////////
////////////////////////////
// Private Functions
////////////////////////////
220


Appendix B: Program Output and Configuration File
The output from a typical execution of the computer program and the. configuration
file used by the program are presented in this appendix. The output is from a short traversal
of a corridor. Logs which contain information relating to feature identification, sonar data
collection, and debugging are presented in that order. The configuration file, robot.cfg, is
presented last.
221


Feature Identification Log
Start log: Sun Feb 7 12:30:37 1999
Sun Feb 7 12:30:42 1999: Feature Type: corridor
Start: 4.9 End: 4.9
Sun Feb 7 12:30:45 1999:
Feature Type: corridor
Start: 4.9 End: 12.4667
Sun Feb 7 12:30:48 1999:
Feature Type: corridor
Start: 4.9 End: 20.2167
Sun Feb 7 12:30:51 1999:
Feature Type: corridor
Start: 4.9 End: 27.55
Sun Feb 7 12:30:55 1999:
Feature Type: corridor
Start: 4.9 End: 38.45
Sun Feb 7 12:30:58 1999:
Feature Type: corridor
Start: 4.9 End: 46.0333
Sun Feb 7 12:31:01 1999:
Feature Type: corridor
Start: 4.9 End: 53.15
Sun Feb 7 12:31:03 1999:
Feature Type: corridor
Start: 4.9 End: 53.15
Sonarlmages:
Time: 918415842.62862
X: 4.9 Y: 0
0: 224 1: 122 2: 86 3: 51 4: 49 5: 74 6: 146 7: 145 8: 165 9: 97 10: 94 11: 50 12:49 13: 50
14: 204 15: 169
Best Feature Matches:
100 corridor
75 alcove
66.6667 four way
222


Time: 918415845.92774
X: 12.4667 Y: 0
0: 231 1: 110 2: 80 3: 51 4: 49 5: 52 6: 132 7: 137 8: 136 9: 99 10: 124 11: 50 12: 49 13: 50
14: 214 15: 177
Best Feature Matches:
100 corridor
75 alcove
66.6667 four way
Time: 918415848.122776
X: 20.2167 Y: 0
0:223 1: 110 2:74 3:514: 50 5:51 6: 165 7: 156 8: 146 9: 105 10: 142 11:51 12:49 13:50
14:215 15:178
Best Feature Matches:
100 corridor
75 alcove
66.6667 four way
Time: 918415851.172788
X: 27.55 Y: 0
0:223 1: 118 2: 69 3:51 4: 50 5:54 6: 197 7: 160 8: 148 9: 111 10: 143 11:50 12: 48 13:49
14: 207 15: 188
Best Feature Matches:
100 corridor
75 alcove
66.6667 four way
Time: 918415855.522787
X: 38.45 Y: 0
0:221 1: 132 2: 69 3:514: 50 5:51 6: 191 7: 159 8: 158 9: 121 10: 150 11:61 12:48 13:49
14: 198 15: 171
Best Feature Matches:
100 corridor
75 alcove
66.6667 four way
Time: 918415858.532783
X: 46.0333 Y: 0
0: 234 1: 125 2: 73 3: 51 4: 50 5: 57 6: 157 7: 162 8: 164 9: 126 10: 140 11: 49 12: 48 13: 49
14:214 15: 164
Best Feature Matches:
100 corridor
75 alcove
223


66.6667 four way
Time: 918415861.392786
X: 53.15 Y:0 *
0:227 1: 118 2:77 3:51 4: 50 5:52 6: 183 7: 152 8: 169 9: 127 10: 160 11:49 12:48 13:49
14: 184 15: 158
Best Feature Matches:
100 corridor
75 alcove
66.6667 four way
End log: Sun Feb 7 12:31:03 1999
224


Sonar Data Collection Log
Start log: Sun Feb 7 12:30:37 1999
Sun Feb 7 12:30:39 1999: SonarData collected
Time: 918415839.381796
X: 1.7 Y: 0
0: 238 1: 122 2: 89 3: 51 4: 49 5: 54 6: 93 7: 156 8: 126 9: 122 10: 90 11: 51 12: 49 13: 50
14: 202 15: 154
Sun Feb 7 12:30:39 1999: SonarData collected
Time: 918415839.791776
X: 2.7 Y: 0
0: 238 1: 122 2: 89 3: 51 4: 49 5: 54 6: 93 7: 174 8: 144 9: 89 10: 91 11: 50 12: 49 13: 50 14:
191 15: 153
Sun Feb 7 12:30:40 1999: SonarData collected
Time: 918415840.451777
X: 4.4 Y: 0
0:210 1: 124 2:87 3:514:49 5:53 6: 184 7: 147 8: 168 9: 93 10: 93.11:50 12: 49 13:50
14: 191 15: 153
Sun Feb 7 12:30:40 1999: SonarData collected
Time: 918415840.931784
X: 5.5 Y: 0
0: 222 1: 123 2: 86 3: 51 4: 49 5: 114 6: 159 7: 132 8: 168 9: 93 10: 93 11: 50 12: 49 13: 50
14: 228 15: 150
Sun Feb 7 12:30:41 1999: SonarData collected
Time: 918415841.401790
X: 6.7 Y: 0
0: 219 1: 121 2: 86 3: 51 4: 49 5: 114 6: 159 7: 132 8: 191 9: 95 10: 128 11: 50 12: 49 13: 50
14:217 15:203
Sun Feb 7 12:30:42 1999: SonarData collected
Time: 918415842.61782
X: 8.4 Y: 0
0: 219 1: 121 2: 84 3: 51 4:49 5: 56 6: 193 7: 131 8: 196 9: 95 10: 73 11: 50 12:49 13: 50
14: 198 15: 206
Sun Feb 7 12:30:42 1999: Sonarlmage created
Time: 918415842.62862
X: 4.9 Y: 0
225


0: 224 1: 122 2: 86 3: 51 4: 49 5: 74 6: 146 7: 145 8: 165 9: 97 10: 94 11: 50 12: 49 13: 50
14: 204 15: 169
Sun Feb 7 12:30:42 1999: Feature Type: corridor
Start: 4.9 End: 4.9
Sonarlmages:
Time: 918415842.62862
X: 4.9 Y: 0
0: 224 1: 122 2: 86 3: 51 4: 49 5: 74 6: 146 7: 145 8: 165 9: 97 10: 94 11: 50 12: 49 13: 50
14: 204 15: 169
Best Feature Matches:
100 corridor
75 alcove
66.6667 four way
Sun Feb 7 12:30:42 1999: SonarData collected
Time: 918415842.501787
X: 9.4 Y: 0
0: 255 1: 85 2: 83 3: 51 4: 50 5: 54 6: 203 7: 140 8: 135 9: 97 10: 73 11: 50 12: 49 13: 50 14:
198 15:206
Sun Feb 7 12:30:42 1999: SonarData collected
Time: 918415842.921776
X: 10.5 Y: 0
0:216 1: 118 2:81 3:51 4: 50 5:54 6: 203 7: 140 8: 135 9: 97 10: 133 11:50 12: 49 13:50
14:22115:176
Sun Feb 7 12:30:43 1999: SonarData collected
Time: 918415843.541888
X: 12 Y: 0
0: 216 1: 118 2: 81 3: 51 4: 49 5: 54 6: 95 7: 125 8: 134 9: 98 10: 134 11: 50 12: 49 13: 50
14: 220 15: 165
Sun Feb 7 12:30:44 1999: SonarData collected
Time: 918415844.1762
X: 13 Y: 0
0:255 1: 116 2: 80 3: 51 4:49 5:51 6: 95 7: 139 8: 138 9: 100 10: 134 11: 50 12: 49 13: 50
14: 220 15: 165
Sun Feb 7 12:30:44 1999: SonarData collected
Time: 918415844.671785
X: 14.1 Y: 0
226


0: 223 1: 115 2: 79 3: 51 4: 49 5: 51 6: 95 7: 139 8: 138 9: 100 10: 136 11: 50 12: 49 13: 50
14: 209 15: 207
Sun Feb 7 12:30:45 1999: SonarData collected
Time: 918415845.91783
X: 15.8 Y:0
0:224 1: 113 2: 79 3:51 4: 50 5:51 6: 101 7: 143 8: 137 9: 102 10: 137 11: 55 12:49 13:50
14: 220 15: 147
Sun Feb 7 12:30:45 1999: Sonarlmage created
Time: 918415845.92774
X: 12.4667 Y: 0
0: 231 1: 110 2: 80 3:514:49 5:52 6: 132 7: 137 8: 136 9: 99 10: 124 11:50 12: 49 13:50
14:214 15: 177
Sun Feb 7 12:30:45 1999:
Feature Type: corridor
Start: 4.9 End: 12.4667
Sonarlmages:
Time: 918415842.62862
X: 4.9 Y: 0
0:2241: 122 2: 86 3:514: 49 5:74 6: 146 7: 145 8: 165 9:97 10:94 11:50 12:49 13:50
14: 204 15: 169
Best Feature Matches:
100 corridor
75 alcove
66.6667 four way
Time: 918415845.92774
X: 12.4667 Y: 0
0: 231 1: 110 2: 80 3: 51 4: 49 5: 52 6: 132 7: 137 8: 136 9: 99 10: 124 11: 50 12: 49 13: 50
14:214 15:177
Best Feature Matches:
100 corridor
75 alcove
66.6667 four way
Sun Feb 7 12:30:45 1999: SonarData collected
Time: 918415845.541796
X: 16.9 Y: 0
0: 224 1: 113 2: 77 3: 51 4: 50 5: 51 6: 116 7: 187 8: 159 9: 103 10: 140 11: 53 12: 49 13: 50
14: 220 15: 147
227


Sun Feb 7 12:30:46 1999: SonarData collected
Time: 918415846.191783
X: 18.5 Y: 0
0: 225 1: 112 2: 76 3: 51 4: 50 5: 51 6: 202 7: 156 8: 142 9: 105 10: 140 11: 53 12: 49 13: 50
14:217 15:185
Sun Feb 7 12:30:46 1999: SonarData collected
Time: 918415846.641771
X: 19.5 Y: 0
0: 227 1: 110 2:74 3: 51 4: 50 5:51 6: 202 7: 156 8: 142 9: 105 10: 141 11: 52 12: 49 13:50
14:218 15: 186
Sun Feb 7 12:30:47 1999: SonarData collected
Time: 918415847.101799
X: 20.8 Y: 0
0: 227 1: 110 2: 74 3: 51 4: 50 5: 51 6: 188 7: 142 8: 144 9: 106 10: 142 11: 50 12: 49 13: 50
14:218 15: 186
Sun Feb 7 12:30:47 1999: SonarData collected
Time: 918415847.721782
X: 22.3 Y: 0
0:2141: 109 2: 73 3: 51 4: 50 5:51 6: 142 7: 148 8: 145 9: 108 10: 145 11:50 12:49 13:50
14:216 15:178
Sun Feb 7 12:30:48 1999: SonarData collected
Time: 918415848.121780
X: 23.3 Y: 0
0: 223 1: 108 2: 72 3: 51 4: 50 5: 51 6: 142 7: 148 8: 145 9: 108 10: 145 11: 50 12: 49 13: 50
14:20115:189
Sun Feb 7 12:30:48 1999: Sonarlmage created
Time: 918415848.122776
X: 20.2167 Y: 0
0: 223 1: 110 2: 74 3: 51 4: 50 5: 51 6: 165 7: 156 8: 146 9: 105 10: 142 11: 51 12: 49 13: 50
14:215 15: 178
Sun Feb 7 12:30:48 1999:
Feature Type: corridor
Start: 4.9 End: 20.2167
Sonarlmages:
Time: 918415842.62862
X: 4.9 Y: 0
0:2241: 122 2: 86 3:51 4: 49 5:74 6: 146 7: 145 8: 165 9: 97 10: 94 11: 50 12:49 13:50
14: 204 15: 169
228


Best Feature Matches:
100 corridor
75 alcove
66.6667 four way
Time: 918415845.92774
X: 12.4667 Y: 0
0: 231 1:. 110 2: 80 3: 51 4:49 5:52 6: 132 7: 137 8: 136 9: 99 10: 124 11: 50 12:49 13:50
14: 214 15: 177
Best Feature Matches:
100 corridor
75 alcove
66.6667 four way
Time: 918415848.122776
X: 20.2167 Y: 0
0: 223 1: 110 2: 74 3: 51 4: 50 5: 51 6: 165 7: 156 8: 146 9: 105 10: 142 11: 51 12: 49 13: 50
14:215 15:178
Best Feature Matches:
100 corridor
75 alcove
66.6667 four way
Sun Feb 7 12:30:48 1999: SonarData collected
Time: 918415848.531778
X: 24.3 Y: 0
0: 223 1: 108 2:72 3:51 4: 50 5:54 6: 185 7: 159 8: 146 9: 109 10: 146 11:50 12:49 13:50
14: 201 15: 189
Sun Feb 7 12:30:49 1999: SonarData collected
Time: 918415849.161774
X: 25.8 Y: 0
0: 226 1: 106 2:71 3:51 4: 50 5: 53 6: 194 7: 149 8: 148 9: 111 10: 146 11: 50 12: 49 13: 50
14: 206 15: 204
Sun Feb 7 12:30:49 1999: SonarData collected
Time: 918415849.581782
X: 26.8 Y: 0
0: 226 1: 113 2: 71 3: 51 4: 50 5: 53 6: 194 7: 149 8: 148 9: 111 10: 149 11: 50 12: 48 13: 50.
14:213 15: 186
Sun Feb 7 12:30:50 1999: SonarData collected
Time: 918415850.51788
229


X: 28 Y:0
0:226 1: 113 2:69 3:514: 505:57 6: 1877: 221 8: 149 9: 112 10: 150 11:50 12:48 13:50
14:213 15: 186
Sun Feb 7 12:30:50 1999: SonarData collected
Time: 918415850.751786
X: 29.6 Y: 0
0:210 1: 133 2: 68 3:514: 50 5:56 6:211 7: 141 8: 150 9: 114 10: 150 11:50 12: 48 13:49
14: 209 15: 182
Sun Feb 7 12:30:51 1999: SonarData collected
Time: 918415851.171789
X: 30.8 Y: 0
0: 229 1: 138 2: 67 3: 51 4: 50 5: 56 6: 211 7: 141 8: 150 9: 114 10: 117 11: 50 12: 48 13: 49
14: 204 15: 183
Sun Feb 7 12:30:51 1999: Sonarlmage created
Time: 918415851.172788
X: 27.55 Y: 0
0:223 1: 118 2: 69 3:51 4:50 5: 54 6: 197 7: 160 8: 148 9: 111 10: 143 11:50 12:48 13:49
14: 207 15: 188
Sun Feb 7 12:30:51 1999:
Feature Type: corridor
Start: 4.9 End: 27.55
Sonarlmages:
Time: 918415842.62862
X: 4.9 Y: 0
0: 224 1: 122 2: 86 3:514: 49 5: 74 6: 146 7: 145 8: 165 9: 97 10: 94 11:50 12:49 13:50
14:204 15: 169
Best Feature Matches:
100 corridor
75 alcove
66.6667 four way
Time: 918415845.92774
X: 12.4667 Y: 0
0:231 1: 110 2: 80 3: 51 4:49 5: 52 6: 132 7: 137 8: 136 9: 99 10: 124 11: 50 12:49 13: 50
14:214 15: 177
Best Feature Matches:
100 corridor
75 alcove
66.6667 four way
230


Time: 918415848.122776
X: 20.2167 Y: 0
0: 223 1: 110 2: 74 3: 51 4: 50 5: 51 6: 165 7: 156 8: 146 9: 105 10: 142 11: 51 12: 49 13: 50
14:215 15: 178
Best Feature Matches:
100 corridor
75 alcove
66.6667 four way
Time: 918415851.172788
X: 27.55 Y: 0
0: 223 1: 118 2:69 3:51 4: 50 5: 54 6: 197 7: 160 8': 148 9: 111 10: 143 11: 50 12:48 13:49
14:207 15:188
Best Feature Matches:
100 corridor
75 alcove
66.6667 four way
Sun Feb 7 12:30:53 1999: SonarData collected
Time: 918415853.231782
X: 35.3 Y: 0
0: 220 1: 135 2: 66 3: 51 4: 50 5: 52 6: 192 7: 154 8: 156 9: 119 10: 163 11: 50 12: 48 13: 49
14: 199 15: 179
Sun Feb 7 12:30:53 1999: SonarData collected
Time: 918415853.631797
X: 36.9 Y: 0
0: 223 1: 133 2: 64 3: 51 4: 50 5: 52 6: 185 7: 130 8: 156 9: 119 10: 163 11:50 12: 48 13:49
14: 201 15: 176
Sim Feb 7 12:30:54 1999: SonarData collected
Time: 918415854.41784
X: 37.8 Y: 0
0: 220 1: 133 2: 64 3: 51 4: 50 5: 52 6: 185 7: 130 8: 156 9: 120 10: 135 11: 53 12:48 13: 49
14: 189 15: 174
Sun Feb 7 12:30:54 1999: SonarData collected
Time: 918415854.661772
X: 38.8 Y: 0
0: 220 1: 131 2:74 3:514: 50 5:51 6:215 7: 154 8: 160 9: 122 10: 135 11:53 12: 48 13:49
14: 189 15: 174
Sun Feb 7 12:30:55 1999: SonarData collected
231


Time: 918415855.101782
X: 40.4 Y: 0
0:223 1: 130 2:74 3:51 4: 50 5:52 6: 185 7: 195 8: 160 9: 122 10: 133 11: 111 12:48 13:
49 14: 190 15: 154
Sun Feb 7 12:30:55 1999: SonarData collected
Time: 918415855.521793
X: 41.5 Y: 0
0:223 1: 130 2: 74 3:51 4: 50 5:52 6: 185 7: 195 8: 162 9: 124 10: 175 11:50 12: 48 13:50
14: 224 15: 171
Sun Feb 7 12:30:55 1999: Sonarlmage created
Time: 918415855.522787
X: 38.45 Y: 0
0: 221 1: 132 2: 69 3: 51 4: 50 5: 51 6: 191 7: 159 8: 158 9: 121 10: 150 11: 61 12: 48 13: 49
14: 198 15: 171
Sun Feb 7 12:30:55 1999:
Feature Type: corridor
Start: 4.9 End: 38.45
Sonarlmages:
Time: 918415842.62862
X: 4.9 Y: 0
0:224 1: 122 2: 86 3:51 4: 49 5:74 6: 146 7: 145 8: 165 9: 97 10: 94 11:50 12:49 13:50
14: 204 15: 169
Best Feature Matches:
100 corridor
75 alcove
66.6667 four way
Time: 918415845.92774
X: 12.4667 Y: 0
0: 231 1: 110 2: 80 3: 51 4: 49 5: 52 6: 132 7: 137 8: 136 9: 99 10: 124 11: 50 12: 49 13: 50
14: 214 15: 177
Best Feature Matches:
100 corridor
75 alcove
66.6667 four way
Time: 918415848.122776
X: 20.2167 Y: 0
0: 223 1: 110 2: 74 3: 51 4: 50 5: 51 6: 165 7: 156 8: 146 9: 105 10: 142 11: 51 12: 49 13: 50
14:215 15: 178
Best Feature Matches:
232


100 corridor
75 alcove
66.6667 four way
Time: 918415851.172788
X: 27.55 Y: 0
0:223 1: 118 2: 69 3:51 4: 50 5: 54 6: 197 7: 160 8: 148 9: 111 10: 143 11:50 12: 48 13:49
14: 207 15: 188
Best Feature Matches:
100 corridor
75 alcove
66.6667 four way
Time: 918415855.522787
X: 38.45 Y: 0
0:221 1: 132 2: 69 3:51 4: 50 5:51 6: 191 7: 159 8: 158 9: 121 10: 150 11:61 12:48 13:49
14: 198 15: 171
Best Feature Matches:
100 corridor
75 alcove
66.6667 four way
Sun Feb 7 12:30:56 1999: SonarData collected
Time: 918415856.171779
X: 43.1 Y: 0
0: 254 1: 128 2: 74 3: 51 4: 50 5: 54 6: 196 7: 162 8: 163 9: 125 10: 128 11: 49 12: 48 13: 50
14: 202 15: 171
Sun Feb 7 12:30:56 1999: SonarData collected
Time: 918415856.621772
X: 44.1 Y: 0
0:230 1: 126 2: 73 3:51 4: 50 5:59 6: 205 7: 162 8: 163 9: 125 10: 128 11:49 12:48 13:50
14: 202 15: 169
Sun Feb 7 12:30:57 1999: SonarData collected
Time: 918415857.61773
X: 45.3 Y: 0
0:230 1: 126 2:73 3:51 4: 50 5:59 6: 205 7: 190 8: 165 9: 126 10: 184 11:49 12:48 13:49
14:228 15:166
Sun Feb 7 12:30:57 1999: SonarData collected
Time: 918415857.691792
X: 46.9 Y: 0
233


0: 250 1: 124 2:72 3:51 4: 50 5:56 6: 193 7: 148 8: 166 9: 128 10: 165 11:49 12: 48 13:49
14: 228 15: 166
Sun Feb 7 12:30:58 1999: SonarData collected
Time: 918415858.121797
X: 47.9 Y: 0
0: 222 1: 123 2: 75 3: 51 4: 50 5: 58 6: 73 7: 156 8: 166 9: 128 10: 165 11: 49 12: 48 13: 49
14: 229 15: 165
Sun Feb 7 12:30:58 1999: SonarData collected
Time: 918415858.531793
X: 48.9 Y: 0
0:222 1: 123 2: 75 3:51 4:50 5:58 6: 73 7: 156 8: 164 9: 128 10:75 11:49 12: 48 13:49
14: 200 15: 151
Sun Feb 7 12:30:58 1999: Sonarlmage created
Time: 918415858.532783
X: 46.0333 Y: 0
0: 2341: 125 2: 73 3:51 4: 50 5:57 6: 157 7: 162 8: 164 9: 126 10: 140 11:49 12:48 13:49
14:21415:164
Sun Feb 7 12:30:58 1999:
Feature-Type: corridor
Start: 4.9 End: 46.0333
Sonarlmages:
Time: 918415842.62862
X: 4.9 Y: 0
0:2241: 122 2: 86 3:51 4: 49 5:74 6: 146 7: 145 8: 165 9:97 10:94 11:50 12: 49 13:50
14: 204 15: 169
Best Feature Matches:
100 corridor
75 alcove
66.6667 four way
Time: 918415845.92774
X: 12.4667 Y: 0
0: 231 1: 110 2: 80 3: 51 4: 49 5: 52 6: 132 7: 137 8: 136 9: 99 10: 124 11: 50 12: 49 13: 50
14:214 15:177
Best Feature Matches:
100 corridor
75 alcove
66.6667 four way
Time: 918415848.122776
234


X: 20.2167 Y: 0
0: 223 1: 110 2: 74 3: 51 4: 50 5: 51 6: 165 7: 156 8: 146 9: 105 10: 142 11: 51 12: 49 13: 50
14:215 15: 178
Best Feature Matches:
100 corridor
75 alcove
66.6667 four way
Time: 918415851.172788
X: 27.55 Y: 0
0:223 1: 118 2: 69 3:51 4: 50 5:54 6: 197 7: 160 8: 148 9: 111 10: 143 11:50 12:48 13:49
14:207 15: 188
Best Feature Matches:
100 corridor
75 alcove
66.6667 four way
Time: 918415855.522787
X: 38.45 Y: 0
0: 221 1: 132 2: 69 3: 51 4: 50 5: 51 6: 191 7: 159 8: 158 9: 121 10: 150 11: 61 12: 48 13: 49
14: 198 15: 171
Best Feature Matches:
100 corridor
75 alcove
66.6667 four way
Time: 918415858.532783
X: 46.0333 Y: 0
0: 2341: 125 2: 73 3:51 4: 50 5:57 6: 157 7: 162 8: 164 9: 126 10: 140 11:49 12: 48 13:49
14:214 15:164
Best Feature Matches:
100 corridor
75 alcove
66.6667 four way
Sun Feb 7 12:30:59 1999: SonarData collected
Time: 918415859.151772
X: 50.4 Y: 0
0: 246 1: 121 2: 76 3: 51 4: 50 5: 57 6: 187 7: 136 8: 170 9: 116 10.: 135 11: 49 12: 48 13: 49
14: 200 15: 151
Sun Feb 7 12:30:59 1999: SonarData collected
Time: 918415859.551775
235


X: 51.4 Y: 0
0: 211 1: 119 2: 83 3: 51 4: 50 5: 52 6: 189 7: 136 8: 170 9: 116 10: 135 11: 49 12: 48 13:49
14: 75 15: 161
Sun Feb 7 12:30:59 1999: SonarData collected
Time: 918415859.971787
X: 52.4 Y: 0
0: 211 1: -119 2: 83 3: 51 4: 50 5: 52 6: 189 7: 197 8: 172 9:,134 10: 217 11: 50 12: 48 13: 49
14: 220 15: 161
Sun Feb 7 12:31:00 1999: SonarData collected
Time: 918415860.581792
X: 53.9 Y: 0
0: 219 1: 118 2: 72 3:51 4: 50 5:52 6: 174 7: 148 8: 174 9: 129 10: 163 11:50 12:48 13:49
14: 220 15: 160
Sun Feb 7 12:31:00 1999: SonarData collected
Time: 918415860.991798
X: 54.9 Y: 0
0:240 1: 116 2:74 3:51 4: 50 5:52 6: 174 7: 148 8: 174 9: 129 10: 163 11:50 12: 48 13:49
14: 195 15: 158
Sun Feb 7 12:31:01 1999: SonarData collected
Time: 918415861.391785
X: 55.9 Y: 0
0: 240 1: 116 2:74 3:514: 50 5:52 6: 190 7: 151 8: 159 9: 138 10: 150 11:50 12:48 13:49
14: 195 15: 158
Sun Feb 7 12:31:01 1999: Sonarlmage created
Time: 918415861.392786
X: 53.15 Y:0
0: 227 1: 118 2:77 3:51 4: 50 5:52 6: 183 7: 152 8: 169 9: 127 10: 160 11:49 12: 48 13:49
14: 184 15: 158
Sun Feb 7 12:31:01 1999:
Feature Type: corridor
Start: 4.9 End: 53.15
Sonarlmages:
Time: 918415842.62862
X: 4.9 Y: 0
0: 224 1: 122 2: 86 3: 51 4: 49 5: 74 6: 146 7: 145 8: 165 9: 97 10: 94 11: 50 12: 49 13: 50
14: 204 15: 169
Best Feature Matches:
100 corridor
236


75 alcove
66.6667 four way
Time: 918415845.92774
X: 12.4667 Y: 0
0:231 1: 110 2: 80 3:51 4:495:52 6: 132 7: 137 8: 136 9: 99 10: 12411:50 12:49 13:50
14:214 15: 177
Best Feature Matches:
100 corridor
75 alcove
66.6667 four way
Time: 918415848.122776
X: 20.2167 Y: 0
0:223 1: 110 2: 74 3: 51 4: 50 5: 51 6: 165 7: 156 8: 146 9: 105 10: 142 11: 51 12: 49 13: 50
14:215 15:178
Best Feature Matches:
100 corridor
75 alcove
66.6667 four way
Time: 918415851.172788
X: 27.55 Y: 0
0:223 1: 118 2: 69 3:51 4: 50 5:54 6: 197 7: 160 8: 148 9: 111 10: 143 11: 50 12:48 13:49
14: 207 15: 188
Best Feature Matches:
100 corridor
75 alcove
66.6667 four way
Time: 918415855:522787
X: 38.45 Y: 0
0: 221 1: 132 2: 69 3: 51 4: 50 5: 51 6: 191 7: 159 8: 158 9: 121 10: 150 11: 61 12: 48 13: 49
14: 198 15: 171
Best Feature Matches:
100 corridor
75 alcove
66.6667 four way
Time: 918415858.532783
X: 46.0333 Y: 0
0: 234 1: 125 2: 73 3: 51 4: 50 5: 57 6: 157 7: 162 8: 164 9: 126 10: 140 11: 49 12: 48 13: 49
14:214 15: 164
Best Feature Matches:
237


100 corridor
75 alcove
66.6667 four way
Time: 918415861.392786
X: 53.15 Y:0
0:227 1: 118 2: 77 3:51 4: 50 5: 52 6: 183 7: 152 8: 169 9: 127 10: 160 11:49 12: 48 13:49
14: 184 15: 158
Best Feature Matches:
100 corridor
75 alcove
66.6667 four way
Sun Feb 7 12:31:02 1999: SonarData collected
Time: 918415862.11781
X: 57.4 Y: 0
0:223 1: 114 2: 73 3:51 4: 50 5:52 6: 179 7: 156 8: 178 9: 132 10: 150 11:50 12: 48 13:49
14: 223 15: 157
Sun Feb 7 12:31:02 1999: SonarData collected
Time: 918415862.421869
X: 58.5 Y: 0
0: 225 1: 112 2: 73 3: 51 4: 50 5: 52 6: 179 7: 156 8: 178 9: 132 L0: 214 11: 49 12: 48 13: 49
14:214 15:144
Sun Feb 7 12:31:02 1999: SonarData collected
Time: 918415862.821786
X: 59.4 Y: 0
0: 225 1: 112 2: 73 3: 51 4: 50 5: 52 6: 155 7: 128 8: 180 9: 135 10: 147 11: 49 12: 48 13: 49
14:214 15:144
End log: Sun Feb 7 12:31:03 1999
238


Debug Log
Start log: Sun Feb 7 12:30:37 1999
Sun Feb 7 12:30:37 1999: Reading in configuration data
Trans Speed is: 25
Travel Distance is: 600
Sonar Firing Rate is: 25
Corridor Aspect Ratio is: 3
Readings per Sonarlmage is: 6
Comers to Match are: 6
Min Range to Obstacles is: 18
Short Threshold is: 54
Long Threshold is: 78
Reading Distance is: 5
Sun Feb 7 12:30:37 1999: Initializing patterns
Sun Feb 7 12:30:37 1999: Initializing robot
Sun Feb 7 12:30:37 1999: Entering explore
Sun Feb 7 12:31:03 1999: Shutting Down Robot
End log: Sun Feb 7 12:31:03 1999
239


Configuration File robot.cfg
#translational speed for robot (0.1 inch/sec)
25
#distance for robot to travel (0..1 inches)
600
#sonar firing rate
25
#corridor aspect ratio (ratio of length to width of sensor readings)
3
#readings (SonarData) per Sonarlmage
6
#number of readings that have to be true for FWComerRule to be true
6
#minimum range (in inches) to an obstacle before robot tries to avoid
18
#short threshold (in inches) for rules
54
#long threshold (in inches) for rules
78
#distance between sonar readings in 0.1 inches
5
240


References
[1] Barshan, B., and Kuc, R., Differentiating Sonar Reflections from Comers and
Planes by Employing an Intelligent Sensor, IEEE Transactions on Pattern
Analysis and Machine Intelligence, 12(6):560-569, June, 1990.
[2] Borenstein, J., and Koren, Y., Histogramic In-motion Mapping for Mobile
Robot Obstacle Avoidance, IEEE Transactions on Robotics and Automation,
7(4):535-539, August, 1991.
[3] Brown, M. K., Feature Extraction Techniques for Recognizing Solid Objects
with an Ultrasonic Range Sensor, IEEE Journal of Robotics and Automation,
RA-l(4):191-205, December, 1985.
[4] Bulata, H., and Devy, M., Incremental Construction of a Landmark-based and
Topological Model of Indoor Environments by a Mobile Robot, Proceedings
. of the 1996 IEEE International Conference on Robotics and Automation, 1054-1060,
April, 1996.
[5] Chong, K. S., and Kleeman, L., Sonar Based Map Building for a Mobile
Robot, Proceedings of the 1997 IEEE International Conference on Robotics and
Automation, 1700-1705, April, 1997.
[6] Dixon, J., and Henlich, O., Mobile Robot Navigation Final Report, Surveys and
Presentations in Information Systems Engineering (SURPRISE) 97,
Imperial College, 1997.
[7] Dudek, G., Environment Representation Using Multiple Abstraction Levels,
Proceedings of the IEEE, 84(11):1684-1704, November, 1996.
[8] Elfes, A., Sonar-Based Real-World Mapping and Navigation, IEEE Journal
of Robotics and Automation, RA-3(3):249-265, June, 1987.
241


[9] Horst, J. A., Maintaining multi-level planar maps in intelligent systems,
Proceedings of the 1996 IEEE International Conference on Robotics and
Automation, 1061-1066, April, 1996.
[10] Howard, A., and Kitchen, L., Sonar Mapping for Mobile Robots,
Technical Report 96/34, Department of Computer Science, University
of Melbourne, November, 1996.
[11] Janet, J. A., Scoggins, S. M., White, M. W., Sutton, HI, J. C., Grant, E., and
Snyder, W. E., Using a Hyper-Ellipsoid Clustering Kohonen for Autonomous
Mobile Robot Map Building, Place Recognition and Motion Planning,
Proceedings of the 1997 IEEE International Conference on Neural Networks,
1699-1704, June, 1997.
[12] Jung, D., and Gupta, K., Octree-Based Hierarchical Distance Maps for Collision
Detection, Journal of Robotic Systems, 14(11):789-806, November, 1997.
[13] Kleeman, L., and Kuc, R., Mobile Robot Sonar for Target Localization and
Classification, International Journal of Robotics Research, 14(4):295-318,1995.
[14] Kunz, C., Willeke, T., and Nourbakhsh, I. R., Automatic Mapping of
Dynamic Office Environments, Proceedings of the 1997 IEEE International
Conference on Robotics and Automation, 1681-1687, April, 1997.
[15] Lacroix, S., and Dudek, G., On The Identification of Sonar Features.,
Proceedings of the IEEE/RSJ International Conference on Intelligent Robots
and Systems, 586-593, September, 1997.
[16] Lim, J. H., and Cho, D. W., Physically Based Sensor Modeling for a Sonar
Map in a Specular Environment, Proceedings of the 1992 IEEE International
Conference on Robotics and Automation, 1714-1719, May, 1992.
[17] Moravec, H.P., Sensor Fusion in Certainty Grids for Mobile Robots AI
Magazine, 9(2):61-74, Summer, 1988.
242


[18] Murphy, R. R., Gomes, K., and Hershberger, D., Ultrasonic Data Fusion as a
Function of Robot Velocity, 1996 SPIE Sensor Fusion and Distributed Robotic
Agents, 114-126, November, 1996.
[19] Nebot, E.M., and Pagac, D., Quadtree Representation and Ultrasonic
Information for Mapping an Autonomous Guided Vehicles Environment,
International Journal of Computers and their Applications, 2(3): 160-170,
December, 1995.
[20] Nomad 200 Hardware Manual, Nomadic Technologies, Mountain View, CA, 1997.
[21] Users Manual, Software Version 2.6., Nomadic Technologies, Mountain View,
CA, 1997.
[22] Ohya, A., Nagashima, Y., and Yuta, S., Exploring Unknown Environment
and Map Construction Using Ultrasonic Sensing of Normal Direction of
Walls, Proceedings of the 1994 IEEE International Conference
on Robotics and Automation, 485-492, May, 1994.
[23] Pagac, D., Nebot, E. M., and Durrant-White, H., An evidential approach to
probabilistic map-building, Proceedings of the 1996 IEEE International Conference
on Robotics and Automation, 745-750, April, 1996.
[24] Politis, Z., and Probert, P., Perception of an Indoor Robot Workspace by
Using CTFM Sonar Imaging, Proceedings of the 1998 IEEE International
Conference on Robotics and Automation, 2801 -2806, May, 1998.
[25] Smith, C. M., Leonard, J. J., Bennett, A. A., and Shaw, C., Feature-Based
Concurrent Mapping and Localization for AUVs, Proceedings of Oceans 97,
896-901, October, 1997.
[26] Thrun, S., and Bucken, A., Integrating Grid-Based and Topological Maps for
Mobile Robot Navigation, Proceedings of the Thirteenth AAAI National
Conference on Artificial Intelligence, 944-951, August, 1996.
243



PAGE 1

ENVIRONMENTAL DESIGN \ AURARIA LIBRARY 7-0-1 0-5-5 4-1-.42 -5---.1./v---FOR PRESERVATION OF OPEN SPACE IN tHE COLORADO FRONT RANGE URBANIZING CORRIDOR by ) A thesis presented in partial fulfillment of the requirements for the degree of Master of Planning and Community Development University of Colorado Denver, Colorado October 22, 1984

PAGE 2

City and Countryside If we can create the humane city, rather than the city of bondage to toil, then the choice of city or country-side wil,l be between two excellences, each indispensable, each different, b.oth complementary, both life-enhancing. Man in Nature. -Ian McHarg Colorado Front Range Open Space For the first time in Colorado, business interests, environmentalists, and state and local government. officials agreed that preservation of open space can and should, play an important role in preserving and enhancing the quality of life along Colorado's Front Range. The Colorado Front Range Project

PAGE 3

TABLE OF CONTENTS Page Foreword ...... _. ................. _. _. _. ... _. .. _. ... _. 1 AND METHODOLOGY ....................... CHAPTER II GROWTH SCENARIOS .................................... 8 Forecast for the Year 2010 8 New Housing Land Requirements 9 All Urban Activities Land Requirements 9 Three Scenarios 10 CHAPTER III THE CONTEXTUAL ENVIRONMENT; ISSUES AND TRENDS AFFECTING RETENTION OF OPEN SPACE ........... 14 Twenty Stumbling Blocks 14 Twenty Opportunities v 18 CHAPTER IV TECHNIQUES FOR PRESERVING OPEN SPACE Urban Techniques Rural Techniques ............................................ ............................................ CHAPTER V WHAT FRONT RANGE CITIES ARE DOING 25 25 33 38 Techniques for Preserving Open Space 41 Techniques for Containing Sprawl 46 Summary of City Techniques 53 CHAPTER VI WHAT FRONT RANGE COUNTIES ARE DOING Techniques for Preserving Large Scale Open Space Techniques for Preserving Small Scale Open Space Techniques for Housing Densities, Infill and Contiguous Development Summary of County Techniques 58 65 68./ 73

PAGE 4

CHAPTER VII CONCLUSIONS ........................................ Trends ...................................................... Recommendations Getting There ............................................. ............................................... APPENDIX 0 Survey Questionnaire Colorado Front Range Colorado Front Range ........................................ Cities ................................. Counties ................................ REFERENCES . ................................................ 76 76 / 79 82 86 86 89 90 91

PAGE 5

Foreword My roots are in the open Iowa farm country and the dense Southside of Chicago. The farm and the big city are both life-renewing to me. Moving to Colorado Springs in 1974, I found beauty and inspiration in the mountains, foothills, and plains of Colorado--driving city streets by car, taking a motorcycle out on the highways, hiking in the mountains, fishing the streams. Between 1974 and 1980 I watched Colorado Springs out in every direction. On the many trips I made to Denver along Interstate Highway 25, the natural countryside was gradually making room for urban development Over the last several years I have listened to Coloradans lament that soon there will be one city from Colorado Springs to Denver and Fort Collins. No one likes the idea, but seemingly nothing can be done to change what is happening. It is inevitable. I believe something can be done to preve_nt the Front Range from following the model of New York/New Jersey or Los Angeles urban areas. It is possible to plan for a balance between city and countryside. That is the motivation for this study. I would like to thank Herbert Smith, professor of Planning and Community Development, University of Colorado at Denver, for his helpful comments in the research and writing of this thesis, and for his encouragement along the way. Doug Wheeler Denver, Colorado, 1984

PAGE 6

CHAPTER I INTRODUCTION AND METHODOLOGY Population forecasts for the year 2010 (25 years away) anticipate 1.5 million more of us living along the Front Range from Ft. Collins to 1 Pueblo. If new growth occurs in the same densities and patterns as has to the present--nearly 750 square miles of land will become city and suburb to accommodate the new residents. 2 Included in this .. new urban build-up is today's farm land, ranch land, and open space between cities. Seven hundred fifty square miles of new urban development ca n be pictured as a continuous string of homes, shopping malls, roads, industrial sites, small parcels of vacant land, parks--one mile wide and stretching from Denver to El Paso, Texas, and 20 miles into Mexico. Or, alternately, a path of new development six miles in width from Colorado Springs to Ft. Collins. Driving the highways from Ft. Collins to Colorado Springs, there is very little land remaining that has not already been subdivided and 1 March -1984, Colorado Department of Local Affairs Population Estimates (by County) and Population Forecasts for 2010 (by County). 2urban land use area in 2010 is based on 1984 total Front Range urban land use area and 1984 total Front Range population. If current urban density continues, 750 square miles of open space would be required for the 25 year population growth.

PAGE 7

2 : ... .. .. ... ... [ B L o

PAGE 8

3 zoned for urban development. Over the next 25 years, the Front Range could lose most of today s open space between cities, the uncluttered mountain views along major highways, and the food producing farm and ranch lands--unless city and county jurisdictions, the State Legisla-ture, Front Range residents and business interests--begin to plan a future that plans for retention of open space. Once the natural envi-ronment is covered with urban development, it is gone--forever. This study uses a broad definition of open space: any land which brings together urban residents and their natural environment. Open space includes scenic unobstructed mountain views, truck farms growing vegetables for urban residents, hayfields, parks, natural rock formacattle and sheep ranches, wildlife habitats, green belts between cities, meandering bike paths along canals and rivers, freeways with scenic vistas. Open spaces in an urban area such as the Front Range come in small and large pieces--but all bring together city and country-side. This thesis has three purposes. The first purpose is to explore the issues and trends that make difficult the retention of Front Range open space, and issues and trends that are encouraging protection of open space. The second intention of this study is to provide a "shopping list" of potential strategies that are currently used by cities and counties. in the United States to accomplish a balance between urban development and preservation of open space and agricultural lands. Front Range cities and counties are then surveyed to find out what strategies are being used locally.

PAGE 9

4 The third purpose of this report is to present recommendations of techniques and strategies that could be adopted by cities and counties. A critical concern is: can local governments preserve open space without strong state legislated regional land use policies? The ten Front Range urbanizing counties included in this study are Adams, Arapahoe, Boulder, Denver, Douglas, El Paso, Jefferson, Larimer, Pueblo, and Weld Counties. Several assumptions are made in this thesis: Population and economic growth will continue in the region. The presence of high technology and energy industries, the location of the U.S. Space Command Center, regional military and government employment centers, and a general national perception of the Colorado Front Range as a desirable place to live and locate a business--have created a momentum for growth which is likely to continue over the next 25 years. -It would not be ethically desirable or politically feasible to limit growth in the region or "close the door" to new residents and industry. Population growth and preservation of open space need not be' incompatible. There are a wide range of possible scenarios in which the Front Range can receive 1.5 million new residents over the next 25 years and retain open space. -A comprehensive state initiative to plan for population growth and preservation of open space along the Front Range is unlikely in the near future. Cities and counties therefore will need to develop their local initiatives. State policies may eventually emerge as Front Range residents and local governments become concerned and active in implementing open space preservation strategies. Retaining open space in the Front Range urban corridor encounters multiple issues, each of which could merit a major study. Agricultural issues include land costs, production grain and livestock market prices, speculation in agricultural land on the urban fringe, and the availability of water for irrigation. Urban issues include housing pre-ferences of Front Range residents, city and suburban land values, urban

PAGE 10

5 infill housing policies, annexation policies, and infrastructure costs. Other governmental issues include the role of special service districts, the role of regional planning, state land use policy, and the role of Federal policies. Private sector issues include short-term versus long-term goals of developers, housing financing policies of lending institu tions, and the question of who will pay for open space--public or private sector. Economic, social, and political issues are closely interwoven. This complexity is a constraint. While recognizing the of these issues, this study seeks to narrow the scope and develop a "menu" of do-able techniques--some working directly to preserve open space, and some indirectly preserving open space by raising urban densities and encouraging new development to occur within existing communities. Secondary research for this study has included: The National Agricultural Lands Study--the primary resource for agricultural land preservation techniques. Agricultural Land Conversion in Colorado was a valuable resource for addressing regional issues. The San Francisco Bay Area study Room Enough: Housing and Open Space in the Bay Area--a comprehensive study of the relationship between protecting open space and strategies for infill and moderate density housing. Room Enough was an important influence on the philosophy and methodology of this thesis. The national report Costs of Sprawl--used in this study as a model for developing general cost and land requirement comparisons of alternative growth scenarios and housing

PAGE 11

6 densities. Computer population forecasts from the Colorado Department of Local Affairs provide population growth estimates used in this study. Workgroup reports from the Colorado Front Range Project (Open Space, Housing, Land Use)--provided extensive background data for regional issues and trends. This study aims to find out what strategies and techniques (many of which were recommended by the Front Range Project) are being tried and implemented by the counties and cities of the region. Primary research surveyed the ten and 27 selected cities in the Front Range region to find out what techniques and strategies are now being used to preserve open space. Primary research has included: A questionnaire mailed to planning directors of the 27 cities surveyed. A 74% response was attained. The assistance of Sam Mamet and the Colorado Municipal Leagu.e was especially valuable. Follow-up interviews were conducted with planning staffs of several cities which did not respond. A table of techniques currently used by cities of the region was then compiled. With each of the ten counties of the region, in-person interviews were conducted with either the county planning director or a planning staff person. A table of techniques used by counties was then compiled from these interviews. Interviews were carried out with a number of people who are working with land use and open space preservation issues in the region: Steve Ellis (Colorado Department of Local Affairs). ; Terr.y Minger (Governor's Office), Jim Rue bing (Colorado Department of Agriculture), and Marty Zeller (Colorado Open Lands).

PAGE 12

7 $econdary.research found that many studies have been done on agricultural land retention and issues relating to farming and ranching. Likewise, considerable research has been done on urban infill and urban sprawl. Surprisingly few studies are available that link together rural and urban needs, problems, and objectives. The result is somewhat myopic research that approaches agricultural land retention as if the need for inexpensive urban housing did not exist, and urban studies that fail to consider the impact of urban policies on agriculture and open space. The hypothesis of this study is that urban and rural issues cannot be separated when considering the goal of preserving agricultural lands and open space. There are alternatives and choices--for both rural and urban interest groups within the region. This study explores opportunities for Front Range residents and their local governments to plan for future open space, to achieve a balance between city and countryside, while creating a life-enhancing place for future generations to live.

PAGE 13

CHAPTER II GROWTH AND OPEN SPACE SCENARIOS Front Range Population Forecast for the Year 2010 The single most important challenge to Colorado Front Range: open space. is the region's rapid population growth. New residents require new homes New homes require land on which to build. The most readily avai;l.able land is the region's agricultural and open space lands. The Colorado Department of Local Affairs estimates a 1984 popula-tion of 2,438,398 for the Front Range counties of Adams, Arapahoe, Boulder, Denver, Douglas, El Paso, Jeffer.son, Larimer, Pueblo and Weld. A population of 4,057,054 is forecast for the ten county region in the year 2010-.:...a gain of more than 1.5 million residents over the next 25 years. At 2.6 persons per household (the Denve r Metropolitan Area average household size in 1980)1--576, 923 new housing units will needed new residents. These new housing units will be constructed on land. The portion of new housing that will be built within the present urbanized areas 1 Denver Regional Council of Governments, Regional Data 1980-82 County Population and Household Estimates.

PAGE 14

9 the portion that will be built on present agricultural lands and open space, will be decided in the planning choices which residents and their local city and county governments make. Land Required for New Housing (Square Miles) (Assuming 2.6 persons per household) With Low Density Development (2.5 D.U. Acre) With Moderate Density Development (7.0) D.U. Acre) With High Density Development (10 .0 D.U. Acre) Slow Growth 1,000,000 New Residents (square miles) 240 86 60 Moderate Growth 1,500,000 Hew Residents (square miles) .360 129 90 At moderate residential densities ( 7.0 D. U. per acre) })etween 8.6 and 1.29 square miles of land will be needed--for residential development only. When other land uses are considered--for the activities that will support 1 -1.5 million new residents--the regional impact of popu-lation growth becomes apparent. Land Required for All Urban Activities (Square Miles) At 3.58 persons per acre Arapahoe County Urban Pattern At 8.65 persons per acre Denver County Urban Pattern 1 Million Growth 436 180 1.5 Million Growth 655 271

PAGE 15

10 Arapahoe County and Denver County provide a contrast of population densities and urban form (population divided by acres of urban development). Arapahoe County represents a lower density suburban model of population concentration and land use--3 .58 persons per urban acre. Denver represents a higher density urban form--8 .65 persons per urban acre. Whether "spread out" as in Arapahoe County, or "compact" as in Denver--land uses in both counties provide for the wide spectrum of social and economic activities essential to the people living in an urban community: housing, factories, warehouses, offices, schools, hospitals, retail shops and stores, gas stations and garages, restaurants, entertainment and recreation. centers, vacant parcels of land, streets and highways, airports, and the hundreds of other activities that together make up the urban infrastructure. The land needed for housing and urban infrastructure to support 1.5 million new residents is the greatest obstacle to preserving Front Range open space. At Arapahoe County densities more than 650 square miles of open space and agricultural land will need to be converted to urban uses. Yet it would be theoretically possible to have the same population growth occur wi.thin existing urban areas and convert no agricultural or operi space land--through greatly increasing densities and efficiently using existing land and urban infrastructure. Three Scenarios Front Range open space and urban density in the year 2010 will be shaped by the sum of decisions made by cities, counties, the Colorado State Legislature, land developers, and the business community. The

PAGE 16

11 choice for or against open space will be made at all levels of the public and private sectors. -The state legislature in deciding wither to adopt enabling legislation for strong regional open space planning. -The private sector in location decisions for new urban develop-ment and in decisions to support or oppose retention of open space. -Routine city council and county commission decisions relating to zoning densities, open space acquisition, the form of urban growth, and support of regional agriculture. Three scenarios for Front Range population growth and retention of open space-are presented. The first scenario would require a strong and unambiguous public and vate sector decision to use every planning technique available that retains open space. The second scenario would result from a clear public and private sector decision not to plan for Front Range open space. The third scenario would occur with mixed decisions and ambiguous planning policies. Scenario Ill In this scenario, most new development would occur within existing urban communities, and large expanses of open space would be permanently retained. Each city and urban unincorporated area would increase in density and population. Townhomes and condominiums would be permitted on all developable land, except land dedicated for parks and open space. In Denver, this might mean a ten mile long "new town" of town homes and condominiums fronting on the Platte River, together with infill housing throughout the city. In Colorado Springs, increasing densities might mean single family-homes and townhomes in many large tracts of land "skipped over" in-that city's growth. In Aurora, population might double with the "filling in" of undeveloped land within that city's boundaries. A 20 square mile new community might rise on the plains of Arapahoe County--with 100

PAGE 17

..._, _. 12 square miles of surrounding land publicly dedicated for farming, ranching, and recreation. In unincorporated Jefferson County, very high density development might occur in nodes adjacent to Chatfield Lake and National Forest lands This scenario is likely with the following conditions: High level of public planning, including the creation of a Front Ra,nge umbrella land use commissio. n to delineate urban and rural development areas. -Cities and counties developing-' a .. mix of --techniques. and strategies to increase resid"en't'{ai. ,densl, t:i -es andjointly delineate urban and rural service>areas-with corresponding housing densities and of : _services. : --: : .::._'!' -Counties stringently limiting subdivision in rural areas. -Cities taking a conservative approach to annexation of undeveloped open lands. Strategies implemented for acquisition of critically located undeveloped lands. Scenario 112 In this scenario, new development would occur largely on land that _is currently open countryside. single family detached homes and attached townhomes would be built within new subdivisions where market conditions are most favorable: areas with highway accessibility, proximity to employment centers, low land costs, and where scenic ame!lities are greatest. A mix of housing types and densities, together with employment centers and commercial centers would occur in a diffused pattern, but generally following major highways of the region. This scenario would emphasize small parcels of open acreages for single family homes and semi-p_rivate landscaped common areas for townhomes. Open -countryside between urban communities and scenic viewsheds would be retained where market conditions and topography are unfavorable for development. Open space in close proximity to urban communities would be in the form of small park and recreation areas. Urban infrastructure costs would be maximized in thi.s scenario. With relatively low population densities, transportation options would be limited to automobile and highway transit. The greatest loss of agricultural land would occur with this scenario.

PAGE 18

13 This scenario is likely with the following conditions: -Low level of public support for retention of open space. Low level of public for development of the region. Low levels of infill housing activity' within cities and unincorporated urban areas and inability of urban areas to increase housing densities. -Cities and counties unable to delineate urban and rural development areas and reach agreement on annexation, subdivision, zoning, and infrastructure policies. -Cities. and counties unable to develop strategies for retention of critically located open space areas. Scenario 113 In this scenario, development patterns would be a mix of scenarios one and two. Some high density infill development would occur within the region's cities and counties and some mixed density housing would be built in diffused development on relatively inexpensive farm and ranch lands . Cities and counties that early adopted strategies for retaining open countryside between and around urban communities would provide a sharp contrast in urban form with cities and counties that adopted no open space retention policies. Farm and ranch lands and large expanses of open space would be retained in some areas within the Front Range corridor, while other areas would become continuous urban development. This scenario is likely with the following conditions: City and county initiatives (rather than state or regional) for protecting agricultural land and open space. Mixed support from the reiion's residents for the goal of retaining open space, and mixed public support for the goal of increasing development densities within the existing urban communities. Planning for open space occurring after development pressures are already strong.

PAGE 19

CHAPTER III THE CONTEXTUAL ENVIRONMENT: ISSUES AND TRENDS AFFECTING RETENTION OF OPEN SPACE Twenty constraints and twenty opportunities for preserving open space have been identified from the Colorado Front Range Project (Work-group Reports), Agricultural Land Conversion in Colorado, Room Enough: Housing and Open Space in the Bay Area, and the National Agricultural Lands Study. Twenty Stumbling Blocks: Issues and Trends Discouraging Open Space Preservation The following issues and trends are presented as critical factors making difficult the retentioh of open space in the Front Range urbanizing corridor. This listing ofconstraints is not intended as a hierarchical prioritization, but rather as a grouping of dynamic and continually changing and interacting social, economic, and political trends and issues. -Population growth of the region is a critical deterrent. 1 .5 million new residents will require land on which to live, shop, work, and travel. -There is a perception that open space and urban development are mutually exclusive goals--that preserving open space and making room for 1.5 million new residents are mutually exclusive.

PAGE 20

15 -High profits can be made by owners of agricultural land in the path of urban development. Regulation of land to preserve open space could reduce profits. -Nearby mountain lands and acreages of state and national forests and parks leads many to think that the preservation of agricultural lands and open space is not a high priority. -Existing zoning and subdivision regulations are often viewed as an end in themselves, serving the local needs of local residents, rather than a means to achieve a high quality of life in the larger community. A neighborhood, city, or county, may adopt zoning policies which serve local interests, but negatively affect the larger regional community over the long run. -There is a perception that agriculture is not important to the Front Range economy. Open land used for agricultural purposes is worth more when sold for urban development than it is in farming or ranching. 30-70 acres of dry grazing land are required per head of cattle (depending on rainfall). Irrigated crop land has a greater economic potential and therefore has a greater economic value. Agricultural land converted to urban development has the greatest economic potential and greatest value. -The population of the Front Range region tends to be highly mobile. The "Native," "Alien," and "Semi-Native" bumper stickers tell the story of where present residents have come from. Bumper stickers telling where residents are going to would also show the transience of the Front Range population. The revolving door quality of the Front Range population may have the effect of discouraging long range planning for open space and agricultural lands. A common attitude is: "We plan to move in a few years.

PAGE 21

16 Those who will live here in 25 years should plan for the kind of community they want to live in 25 years from now." -If agriculture is to continue in a locality, there must be sufficient farm and ranch acreage in the region to support a wide range of agricultural related businesses and services (Agricultural Critical Mass). In a similar way, new urban development acreage requires an urban critical mass. Urban development is a catalyst for more urban growth in a region (Urban Critical Mass). A decision to remove a few acres of agricultural land from production may have little impact on open: space. And a few acres of new urban development may have no appreciable impact on open space. It is the multiplier effect of the sum of these "little" decisions that alters the agricultural critical mass and the urban critical mass, and results in loss of agricultural lands and open space. -To make affordable housing available to the largest possible cross-section of the region's population, the housing industry has tended to concentrate new development where the land costs are least--open agricultural land in urban fringe locations. The Colorado Front Range region has a history of political conflict between advocates of state land use planning and advocates of local .land use planning. This conflict has led to the dismantling of the state planning department. No regional planning authority exists that has the statutory authority to implement a regional land use program that would encourage contiguous and infill development and preserve large tracts of open space. Planning and zoning policies for open space and infill/contiguous development must occur at the local level (each county 'and city)., which frequently results in fragmented planning and loss of a regional context for what is done locally. Currently there are over 550 local

PAGE 22

17 government entities along the Front Range, each with its own agenda and priorities. -There is an over supply of single family detached zoning districts, and a shortage of higher .density residential zoning in new suburban areas. -People (including some government officials) feel that higher density land uses result in lower quality of life, and low density is better. -A reasonably high level of service is provided by existing Front Range interstate highways and multi-lane state highways. These highways make it. possible for current open space areas to develop at urban densities. -There is a perception that local governments can do little to provide urban buffering and preserve open space adjacent to urban areas. -There is a perception that fee simple acquisition is the only way to protect open space, and all funding for open space must come from the public sector. -A lack of communication exists between housing-related groups regarding existing programs and strategies for infill housing. Inflexibility of existing regulations, fees, laws, and ordinances discourages infill development. At all planning levels--from each individual neighborhood to the ten county region as a whole--there are trade-offs between density and open space. Up to this point the connection between density and open space has not been appreciated by residents and elected officials. Few counties and cities have planning mechanisms in place which can handle the trade-offs between density and open space. -Adopting and implementing regulations and strategies to preserve open space is a time consuming and difficult change process. Citizen groups are most supportive of the status quo.

PAGE 23

18 Twenty Opportunities: Issues and Trends Encouraging Open Space Preservation A population gain of 1.5 million new Front Range residents will create pressures for converting open space and agricultural land to urban uses. Yet paradox.li.cally, the very magnitude of this population growth may be the catalyst for shaping public opinion and developing local government policies that will protect existing farm and ranch lands, preserve wildlife habitats and natural areas, and enhance the vitality and beauty of the region. Population growth is both obstacle and opportunity. It is possible for the region to both grow in population and maintain large open space areas. Digging ten holes at raridom in a tennis court would seriously interfere with the game, but digging all ten holes beneath the net would have almost no disruptive effect. a :9: I ' similar manner, the location and distribufion of open space areas and new urban development, will be the critical factor in shaping the quality of life for Front Range residents over the next 25 years The following twenty issues and trends express the contextual environment for developing policies that would preserve open space. The listing of opportunities is intended as a grouping of continually changing regional social, economic, and political trends and issues. -Taxpayers are becoming increasingly aware of the costs of sprawl. Even with strategies in which "development pays its own way"--there are hidden costs which are left to local governments to pay. A 1983 report that calculated infrastructure capital costs for single family low density residential development on typical open land on the urban fringe, found infrastructure costs to average $31,600 per

PAGE 24

19 housing unit. Assuming 576,923 new housing units will be needed to house new Front Range residents over the next 25 years--over 18 billion dollars (1983 dollars) will be needed to pay for new highways, streets, sewer and water systems, schools, libraries, parks, police and fire protection, and other infrastructure capital costs. Taxpayers and local governments are becoming increasingly aware that .these capital costs can be reduced through higher density dev:elopment and infill development that more efficiently uses the urban infrastructure (Costs of Sprawl, adjusted to 1983 .Hbusehold sizes and 1983 dollars). -Between 1959 and 1978 400,000 Front Range acres of farm land formerly used for producing hay, corn, sugar beets, potatoes, fruits, and vegetables, was converted to urban uses. An additional 900,000 acres of ranch lands were converted to non-agricultural uses. A total of 2,031 square miles of land has gone out of agricultural use. The result is an increasing importation of food and reduced capability of the Front Range to produce fresh milk and vegetables. Regional food self-sufficiency will become more important as pressures on agricultural land increase elsewhere (as is occurring in California) and energy costs increase. Consumer awareness of the source of the regional food supply encourages policies to protect the Front Range "milk shed" (including hay fields) and fruit and vegetable farms. Tax dollars spent on agricultural greenbelts between or around cities are partially returned in lowered food costs and a higher quality locally produced food supply (Agricultural Land Conversion in Colorado, 1980). -A growing national concern for protecting agricultural lands encourages protection of Front Range agricultural lands. The National Agricultural Lands Study found that 3

PAGE 25

20 million acres of agricultural land are converted to nonagricultural uses each year. 13% of all U.S. farmland lies within the 242 SMSAs in the country--farmland that is particularly development. vulnerable to conversion to urban -During the last two years a number of Front Range business interests have created and financially supported Colorado Open Lands, a non-profit public purpose partnership established to promote and actively pursue the preservation of critical Colorado open space areas. In the short time Colorado Open Lands has existed, projects have included the Evans Ranch in Clear Creek County, a greenbelt buffer between Loveland and Ft. Collins, and consulting work with counties and cities in the region. Other non-profit national organizations, such as the San Francisco based Trust for Public Land, have also been engaged in purchasing critical parcels for open space. -Low density Front Range urban development generates higher levels of air pollution than high-density development housing the same number of people (20-30% higher). Air pollution increases with number of automobiles and length and number of trips. Surveys consistently show air pollution to be the number one concern of Front Range residents. Public policies encouraging moderate or high density housing both within e _xis ting urban areas and in developipg areas on the urban fringe--are consistent with the regional concern for improving air quality (Agricultural Land Conversion in Colorado, 1980). -Shifting Front Range demographic, lifestyle, and economic trends of the 1980's favor moderate density development. A "smaller and smarter" trend translates into smaller household sizes (1984 average household size of 2.6 in the Denver Metropolitan Area), smaller (but creative) housing units built on smaller lots, to match with the

PAGE 26

21 lower real income levels of the 1980's. Soaring housing costs and cost of money have resulted in only 29% of households in the U.S. earning enough to quality for a conventional mortgage. Together, these trends suggest opportunities for moderate or high density infill and urban fringe development that over the long term can work to preserve open space in the Front Range region (Planning, January 1984). Over the past ten years Front Range voters have supported funding for acquisition of open space lands: Jefferson County has instituted a for open space programs; the city of Boulder has established a sales tax for open space lands acquisition; statewide voters have given approval for a lottery and an income-tax check-off for conservation purposes. -An attractive quality of life is the reason most frequently given by businesses and new residents for moving to the Colorado Front Range from other regions of the country. Creation of a megalopolis stretching from Ft. Collins to Pueblo is perceived to be destructive to the region's quality of life and to the region's economy. New high tech industries establishing in the Front Range for the vitality and beauty of the natural environment could become a catalyst for open space. -Agriculture is big business in Colorado, contributing well over $2.5 billion a year to the state's the revenue brought in by mining and three times that generated by tourism. Colorado is the second largest agricultural producer among the eleven western states, topped only by California, and ranks fifteenth among all the states in total agricultural sales. In a recent year, Weld County ranked third in agricultural sales among all counties in the nation. Agricultural economic interests are particularly important in the northern one-half of the

PAGE 27

22 Front Range region (Agricultural Land Conversion in Colorado, 1980). Front Range cities and counties are beginning to develop policies to take advantage of opportunities for infill housing that exist within cities and unincorporated urban areas of counties. A national survey estimates 20% of most cities' land is developable and vacant. The percentage is likely even greater in Colorado where urban population densities are below the national average. In Denver there is 1,200 acres of undeveloped vacant land zoned R-2 or less in over 3,000 parcels (excluding undeveloped Northeast and Southwest annexation areas of the city). More than 14,000 units of infill housing could be constructed on this land if it is developed at maximum density under present zoning categories (Denver Post, April 29, 1984). The Colorado Front Range Project housing workgroup identified a wide range of financing .alternatives that could act as a catalyst for urban infill housing projects. If even a small number of these financing programs are developed, there is potential for increasing Front Range infill housing starts. The Colorado Front Range Project identified the preservation of open space as a top priority. This is significant--in that business interests, developers, and state and local government officials agreed that protecting open space lands should play an important role in sustaining a desirable quality of life in the region. There is evidence that a broad base of interest groups is beginning to work for preservation of open space within the region. The administrative branch of Colorado state government has consistently advocated for policies that would manage Front Range growth and protect open space. The Governor's

PAGE 28

23 Office, the Department of Agriculture, and the Department of Local Affairs are particularly active in efforts to protect agriculture and open space. -Within the legislative branch of Colorado state government, there is a potential for creating a coalition of rural and urban legislators that could enact needed enabling legislation for techniques that would protect agricultural lands and open space. -Throughout the Front Range region there are large tracts of land owned by the federal government (military bases, Bureau of Land Management, Army Corps of Engineers, Forest Service) and state and local governments (highway surplus lands, parks). These public lands are a unique asset and of fer a number of largely unexplored possibilities for balancing urban growth and protecting natural open space. 1) High density development tends to be attracted to certain types of open space (such as Cheesman Park in Denver and Cherry Creek Reservoir in Aurora). New density development could be encouraged on land adjacent to large tracts of existing public open space (National Forest, reservoirs, county and city open space lands). 2) Publicly owned lands in areas where open space preservation is not a critical need could be traded for privately owned land in locations where open space is a critical need. -A number of "urban buffering" projects needed along the Front Range have already been proposed by counties and cities. At the center of the Front Range region, Denver Regional Transportation District proposals to build a light rail system would encourage higher density new housing in Denver and suburban communities.

PAGE 29

24 -The techniques exist which could protect large and small parcels of Front Range open space without tying up large public expenditures. -In some locations within the region there are large tracts of land with geological conditions which make development nearly impossible. In these urbanizing areas geological constraints guarantee future open space.

PAGE 30

CHAPTER IV TECHNIQUES FOR PRESERVING OPEN SPACE Techniques for Cities and Urban Counties_ to Use in Preserving Open Space Protecting open space and encouraging infill/incremental new development within existing urbanized areas--are closely related urban dynamics. Looking at the overall picture of a growing urban area, techniques which encourage one also encourage the other. Cities and urban counties have a wide range of policy options. The following techniques are some approaches currently used by local govern-ments in the United States to preserve open space and encourage infill and incremental development. Most of the techniques could potentially be adopted by Front Range citiesand counties. Techniques wh_ich encourage infill and incremental new development tend to be most frequently used by cities. Techniques which preserve conservation lands, scenic views, greenbelts between communities, ancJ farming and ranch lands, tend to be most frequently used by counties. Because local conditions vary greatly from one area to another, there is much overlap between the role that cities and counties may play in preserving open space. There are few exclusively "city techniques" and few exclusively "county techniques." ADVOCACY--Publicsupport from elected public offfcials and agencies for the policy of preserving open space. Advocacy by public officials and agencies is a prerequisite for

PAGE 31

26 effective implementation of techniques for preserving open space and encouraging infill/ incremental new development. Advocacy includes facilitating a public planning forum involving all interest groups within a community. Public Cost: Variable with the strategies and techniques a city or county adopts. ANNEXATION POLICY--A technique in which a city bases boundary change decisions on the impact an annexation would have on preservation of open space. Critical factors to be considered by annexation policies include: Will the annexation promote incremental development (rather than leapfrog development)? Will a decision not to annex mean development will take place anyway, without provisions for open space? Will a decision not to annex encourage preservation of open space by excluding urban services? When water rights are required with annexation, this tends to encourage development of prime agricultural lands. Public Cost: Cost savings from efficiently utilizing city infrastructure. BUILDING HEIGHT LIHITATION--A technique fo-r protecting scenic views that is effective when linked to a specific viewshed. A 60 story building could be compatible with the landscape of one location, while a three story building may be incompatible with the landscape of another location. Public Cost: No cost. CAPITAL IMPROVEMENTS PLANNING--A technique in which a city or county projects five years or more into the future and delineates annual needed improvements through a budgetary prbcess. The timing of construction of new streets, improvements to existing streets, extension of sewer and water lines, and purchase and development of parks, are

PAGE 32

27 included within the Capital Improvements Plan. This technique is effective in encouraging incremental planned growth, and is indirectly effective in preserving open space away from the urban service area. Over the long term, Capital Improvements Planning cannot be used to protect open space within a city by denying urban services. The technique can be useful in projecting open space needs and timing purchase of lands for open space or parks. Public Cost: Cost savings from efficiently utilizing city and county financial resources. COHPRKHKNSIVE PLAN--An official document, normally adopted by a city or county planning board and elected body, which serves as a policy guide for decisions regarding future physical, social, and economic development. The inclusion of an element for infill urban development and an open space element, can be useful for accomplishing these objectives--if the plan is referred to when policy decisions are being made, and if the plan is periodically reviewed and updated to reflect changing local conditions. Public Cost: Variable with the strategies and techniques a city or county adopts. CONSERVATION EASEMENTS--A city or county may acquire the development rights for land that has a public conservation interest. Wildlife habitats, valuable ecosystems, and significant farming and grazing lands are identified in the Comprehensive Plan. The city or county may acquire development rights for the land by purchase (negotiation or eminent domain), donation, or developer dedication during the subdivision review process. Public Cost: Variable.

PAGE 33

28 DEVELOPMENT STANDARDS FLEXIBILITY--A city or county may create flexibility in zoning regulations and building code staQdards in order to encourage infill new development and rehabilitation of existing structures. Greater flexibility can result in higher new housing densities in targeted neighborhoods, and ;increased feasibility of housing structures, manufactured housing, and development of small lots and difficult sites. Public Cost: Cost savings from efficiently utilizing infra-structure. ':, DEVELOPMENT RELATED FEES--A city or county may encourage new infill housing by reducing (or waiving) front end costs in targeted neighborhoods by such methods as reduced fees for sewer and water hookups, building permits, zoning change requests. This technique targets areas and types of projects which would increase efficient use of existing infrastructure and require no new capital costs for local government. Public Cost: Short term loss of some revenue from ment fee waiver or reduction, compensated by increased tax base. Must be carefully targeted for specific areas and types of projects. FINANCING PROGRAMS FOR INFILL DEVELOPMENT--A city or county may assemble financing programs to encourage infill ho.using and rehabilitation projects. Examples of programs include: 1) federal funding through Community Development Block Grants and Urban Development Action Grants, 2) city or county funding through general obligation bonds and property tax abatement, and 3) private sector funding through lending institution mortgage pools and equity syndication strategies involving developers and non-profit organizationso New infill development financed through city or county assembled

PAGE 34

29 programs will be small in relationship to total new construction throughout a region. The effectiveness of infill financing strategies is in acting as a catalyst for new development with.in an existing urban service area. Public Cost: Low to high. Varies with the mix of public and private funding sources. FRONTAGE ROADS--A county or city may adopt a policy in which service roadways along major highways, freeways, or parkways, are constructed at a distance from the highway. Service roadways are located in relationship to contours of the landscape rather than as ribbons closely paralleling the highway. New development is thus encouraged away from the highway and open space along major highways is preserved. When linked with open space zoning provisions, this technique can be somewhat effective in protecting some open land between communities. Public Cost: Low. LAND BANKING--The acquisition of land for permanent city or county ownership or for later resale in a manner that directs the pattern and rate or urban growth. Land may be purchased through either eminent domain or voluntary purchase. This technique may be used by a redevelopment agency in assembling sufficiently large parcels of land for new inf;ill development, or may be used within a Capital Improvements Plan for purchase of future park lands and open space. Public Cost: Can achieve long term cost savings by purchas-' ing land for public uses before development pressures raise land costs. LIMITED ACCESS ROADWAYS--A city or county may adopt policies which petition the state to build roadways between cities

PAGE 35

30 with few or no points for access from abutting parcels. of land. This technique discourages conversion of existing open space and agricultural lands between urban areas. Because state roadways are paid for by people who live throughout the state, this technique assumes highways are constructed primarily to serve statewide interests, rather than local interests. Public Cost: No cost. PURCHASE OF DEVELOPMENT RIGHTS--This technique operates on the presumption that the ownership of property consists of a "bundle of rights" that are unique and separable from each other. A city or county purchases the development rights and the landowner continues to use the land for agricultural purposes. Purchase of development rights may be used to protect a conservation interest (conservation easement), a scenic view (scenic easement), or to provide a greenbelt around a city or between cities. Public Cost: Usually high. May be reduced if a landowner sells development rights below market value in exchange for tax benefits. PLANNED UNIT DEVELOPMENT AND SUBDIVISION OPEN SPACE KENTS--Scenic views and natural open space can be protected through PUD and subdivision open space requirements. This technique can preserve relatively large amounts of space within large scale new subdivisions. Development is clustered in such a manner that a viewshed or a wildlife habitat remains in a natural state. When there is strong development pressure or when other open space techniques are not acceptable, this technique can become a "middle road" strategy for protecting strategic open space. Public Cost: None.

PAGE 36

31 SCENIC EASEMENTS--A county or city may acquire the development rights for land in order to protect a scenic viewshed. Development rights are acquired by purchase, donation (with tax benefit to owner), or developer dedication during the subdivision review process. Public Cost: Variable. TRANSFER OF DEVELOPMENT RIGHTS--A complex technique which generally involves: -Designation of an open space zone and development zone. -Prescription of the number of development rights for each housing unit to be developed within the develop-ment zone. -Owners of preserved open space receive certificates of development rights in an amount that represents. the percentage of assessed value of all undeveloped land in the open space zone. -An owner of developable land who desires to develop land more intensely than that allowed by right, buys additional. development rights on the open market. Owners of preserved open space may sell development rights to owners of developable land, or to real estate brokers or speculators. Owners of preserved land thus are compensated without any capital costs to government. This technique has been successfully used for preservation of historic structures. It is a new strategy for preservation of open space. Public Cost: Low (Administrative Costs). URBAN AND RURAL SERVICE AREAS--A technique which designates agricultural service areas and urban service areas. Public services and capital expenditures (roadway traffic lanes, water and sewer services, police and fire protection) are provided only at a level required for the district. This

PAGE 37

32 technique is most effective when implemented on a regional scale by an umbrella governmental jurisdiction. In the Minneapolis-St. Paul Metropolitan Area this technique is expected to save $2 billion in public investments over a period of 15 years. The designation of service areas may also be used by a city and county on a sub-regional scale. Public Cost: Cost savings from efficiently utilizing infrastructure. ZONING---Local governments may adopt a wide range of combinations of zoning technr'4ues which both encourage incremental and infill new development, and discourage conversion of open space and agricultural lands. include: Bonus Floor Area Ratios (FAR) for infill development. Bonus Floor Area Ratios when open space is preserved. -Preservation of viewsheds and conservation areas within large Planned Unit Developments. -Increased housing densities permitted in all residential zones. -Permitting second units within existing housing. -Mixed use zoning to encourage housing along commercial streets. Mixed use zoning allowing housing within existing warehouse and industrial structures. -Agricultural districts in which subdivision is not permitted. Before adopting zoning techniques, a local government needs a carefully thought out Comprehensive Plan which includes an open space preservation element and infill housing element. Combinations of zoning techniques can then be adopted which "match up" with conditions of the local community. Public Cost:. No costs over and above normal administrative costs.

PAGE 38

33 Techniques for Urbanizing Counties to Use in Preserving Farm and Ranch Lands In urban areas where development pressure is strong, cities and counties share together a wide range of possible techniques which can be used to protect open space. Because most agricultural land lies outside of incorporated municipalities, counties have a number of additional potential techniques for preserving open space that is currently used for farm and ranching purposes. ADVOCACY--Public support from county elected officials and county agencies for protection of agricultural interests in a county. Advocacy begins with recognition of the importance of agriculture in a region. As advocacy moves on to facilitate a public planning forum in which various interest groups in the county participate, the issues rapidly become complex. Advocacy includes facilitating the adoption of policies which address the core of the problem: farmers and ranchers can realize more profit from the sale of land for urban development than they can earn by farming or ranching operations on the same land. Public Cost: Variable with the strategies and techniques a county adopts. AGRICULTURAL DISTRICTS--Voluntary aggregations of farms which band together to obtain legislatively granted benefits such as lower property tax rates (assessed only at farm value); immunity from nuisance legislation; limitation of public use of eminent domain for construction of power lines, road improvements, water and sewer lines. This technique can be moderately effective in preserving open space in urban counties--if stringent regulations are attached which provide for tax penalties when agricultural lands are converted to urban uses.

PAGE 39

34 Public Cost: Low. Costs are primarily in loss of potential tax revenue from rural land, but may be balanced by an increased urban tax base. COMPREBEHSIVK PLAN--A document adopted by elected county officials (normally a county planning board and county commissioners) that serves as a policy guide for future physical, social, and economic development within the county. The inclusion of agriculture and open space elements, delineation of urban and rural service areas, and provisions for county and inter-governmental .agreements, can be useful for accomplishing the of preserving open space. An adopted plan that is comprehensive in scope, gives legal support when implementing specific open space preservation techniques. The effectiveness of a Comprehensive Plan varies with the degree to which the plan is actually referred to as policy decisions made and the timing of periodic revisions of the plan to reflect changing local conditions. Public Cost: Variable with the strategies and techniques a county implements. DEVELOPMENT RIGHTS--A county may acquire the development rights for parcels of land in order to protect a conservation interest, scenic view, historic site, or to provide for a greenbelt between communities. The development rights might be acquired for a several acre site or for several thousand acres, depending on the scope of the public interest. Techniques for acquisition of development rights include: -Donation of development rights. A farmer or rancher rec.ei ves income tax benefits when development rights are donated to a non-profit conservation trust. The agricul-

PAGE 40

35 tural use of the land continues and the county receives permanent protection of open space. -Purchase of development rights (less than fee interest) for a parcel of land through negotiation or eminent domain. -Purchase of land (fee simple interest) and either resale or lease of the land with restrictions which assure uses compatible with the protection of open space. Purchase may be through negotiation or eminent domain. A successful county program for acquiring development rights requires a comprehensive identification of lands for which future open space protection is in the public interest, aggressive promotional efforts which match technique and individual land owner, and funding sources such as a county sales tax or state conservation trust funds. Public Cost: Low (for donation of development rights) to high (for large scale purchase of development rights). FARMLAND CONSERVANCY--A local quasi-governmental authority is empowered by state enabling legislation to intervene in any sale of land previously designated as important farmland. The larid may then be purchased at market value by the local authority, and the land resold with restrictions which assure continued farming of the land. Public Cost: Moderate to High. PROPERTY TAX ASSESSMENT--An indirect subsidy may be provided to the owners of property that is used for ranching or farming purposes. Land is taxed on the basis of its usevalue as ranch or farmland, rather than at its fair market value. Two types of differential property tax assessment laws have been adopted by states: 1) Preferential laws assess land on the basis of its use-value, and there are no penalties if the land is later sold for urban development.

PAGE 41

36 Farmers and developers alike welcome the lower taxes, but this technique does not deter selling and may encourage land speculation. 2) Deferred taxation laws also tax land on the basis of its use-value as ranch or farm land, but if the land is converted or sold for other uses the owner is required to pay all or some portion of the taxes which were excused. The more stringent the restrictions, the less participation in deferred tax programs. Public Cost: Low. Loss of rural tax revenues, but may be offset by increased urban tax revenues in some counties i ZONING--A county may demarcate areas for agricultural use. This technique is highly feasible and its effectiveness increases with distance from urban communities. In rapidly urbanizing counties, the effectiveness of zoning is diminished because zone categories can be changed as development pressures increase. A county may strengthen the effectiveness of zoning by requiring that all zoning changes be compatible with an adopted county Comprehensive Plan. Agricultural zoning used by some to encourage incremental urban growth. Agricultural. zones on the edge of an urban area are planned as short-term zoning designations, waiting for urban and urban development to reach an area. Leapfrog urban development is discouraged through this use of agricultural zoning. The minimum lot . size permitted in an agricultural zone is the critical factor influencing the effectiveness of agricultural zoning. When lot sizes of 5 or 10 acres are permitted, low density suburban development is encouraged and true open space between cities is lost. Public Cost: No costs over and above normal administrative costs.

PAGE 42

37 Techniques exist that could be used by Front Range cities and counties to protect open space Many of these techniques have proven track records in other regions of the U.S. and could be carried out in the Front Range region at little public expense. Others require more public expenditure and higher levels of taxpayer support. The art of protecting open space in the region begi-ps with public concern. and awareness. Techniques can then be selected and tailored to match with needs of each city or county.

PAGE 43

CHAPTER V WHAT FRONT RANGE CITIES ARE DOING-ctJRRENT POLICIES AND TECHNIQUES THAT MAKE ROOM FOR POPULATION GROWTH AND RETAIN OPEN SPACE With the valuable assistance of Sam Mamett and the Colorado Municipal League, a survey questionnaire was mailed to the planning directors of twenty-seven citiesin the Front Range region. The questionnaire was designed to inventory and evaluate the effectiveness of techniques currently being used to both make room for population growth and retain open space. Part one of the questionnaire looks at open space. Strategies li.sted range from purchase of large scale greenbelts, to small sca1.e building set backs and height limitations. Each planner was asked to indicate which of the strategies are currently used by the city, and then to evaluate the effectiveness of those techniques. Part two is an inventory of techniques that facilitate infill development, raise housing densities, and encourage contiguous development. Again, a range of possible techniques was listed, with the planner indicating which are currently being used, and the effectiveness of each. Part three asks for an estimate of new housing densities, and asks the opEm ended question--"what would it take to significantly increase infill housing in your city?"

PAGE 44

39 Because of the diversity among cities in locati9n, topography, population, and socio-economic characteristics--not all strategies are relevant to every city. Denver techniques and. Castle Rock techniques may be very different. For this reason, an effort is made to include in the questionnaire a range of potential approaches. The survey seeks to gather as much data as possible within parameters of a two page mailed questionnaire. This limited somewhat the number of techniques surveyed, and ruled out even brief narrative explanations for each of the techniques. Planners responding to the survey used their own interpretation of what implementing each technique might mean. The survey is also open-ended in assigning numerical to the effectiveness of the techniques. Each planner was asked to rate on a scale of 1-5 the effectiveness of each of the techniques currently used by the city--one being least effective and 5 highly effective. Consideration was given to developing standardized criteria for evaluating the local effectiveness of strategies. This might provide valuable research, but would also be time consuming and costly, and had the drawback of asking 27 planners to work through a lengthy manual criteria and fill in local statistics. Jn addition, a good planner knows almost intuitively what the local trends are and what is working and not working. The purpose of the survey was to look at trends, find out what cities are using what techniques, and gain an overall understanding for what approaches are likely to be effective in the Front Range. The questionnaire developed meets these objectives.

PAGE 45

40 Techniques Front Range Cities Are Using 5-Q) "C VI Q) m C'l "C r-Q)_ +J "C t: Q) c... 0 r-+-' "C +-' "C t: VI r-5-0 r-(/) 0 .->, > +J 0 t: Q) t: 0. t: 0::: rtl rtl Q) +J 4-5-3: 0 Q) Q) 0 0 .-rtl 0 +J r-"C 5-"C E Q) 'Q) u r-"C >, 3: E ...--.-t: E +J rtl 0 m 0 0 > .-Q) 3: rtl Q) C'l Q) ..0 5-+J rtl > 5-::;:) r-o _.-t: C'l Q) t: '+-t: > > Q) 0 VI Q) s... ::;:) 0 5-s... 0 Q) t: +J 55-rtl rtl 0 VI 0 ::;:) Q) c:r c:r co co co u 0 w LJ... <..!:l <..!:l _.I _.I _.I _.I _.I 0.. I-3: 3: gr Preservation X X and Purchases X X X X X X X X X X X :ondemnation for 1pen Space X X X X X i ty-County Agree. X X X X X X X X X X nnexation Policy X X X X X X X X X X X X rans. Rights X X X X X ur. Dev. Rights X onservation Esmt. X X ceni c Easements X 1eve 1 oper Open-.pace Set-Asides X X X X X X X X X X X X UD Open Space X X X X X X X X X X X X X X X X uilding Setbacks X X X X X X X X X X X X X ldg. Ht. Limits X X X X X X X X X X X X X lad-High Density oning X X X X X X X X X X lixed Use oning (Housing) X X X X X X X X econd Units X X IP for Infill X X X X X X X X X X nfill Fee Inc. X X X ev. Stds. Flex. X X X X nfill City Fin. X X X nfill Fed. Fin. X X X X X X X X ity Govt. Advocacy X X X X X X X X X X X X rend: Higher ens ity Sma 11 er ou X X X X X X X X X X X X X X X X X X ot Available: Golden, Green Mountain Falls, Littleton, Manitou Springs, Monument, Northglenn, Parker.

PAGE 46

41 Techniques for Preserving Open Space--Including Farm and Ranch Land, and Other Natural Open Space The survey asked what strategies are currently used by the city to encourage preservation of open space--such as agricultural lands and open space separating cities and scenic views along highways. City-County Agreements Delineating Urban and Rural Development Areas Eight cities reported city-county"agreements delineating urban and rural development areas. Two additional cities were considering such agreements. This approach generally takes the form of a city adopting a policy of providing water and sewer services only for areas within the city's boundaries. This may also be extended out to specified future annexation areas. City zoning techniques encourage new development to occur at specified urban densities. At the same time, a county adopts agricultural zoning and subdivi-sion policies which allow for rural residential subdivision only at very low densities--35 or more acres may be required for a single residential unit. This technique requires a city willing to adopt a plan for future annexation and future provision of services, and a county willing to adopt and. hold to very low density agricultural zoning and subdivision regulations. A county agrees to say to a new development proposal: "This is zoned for agriculture--35 acres is the minimum lot size." At the same time, the city follows the agreed upon annexation policy in determining whether a parcel of land will be and 4e.veloped at urban densities.

PAGE 47

42 With the exception of Pueblo, all of the cities reporting a form of such agreements are located in the northern one-half of the Front Range region. This approach for retaining agricultural lands and open space seems to be least workable in cities and counties which have large concentrations of existing urban development in unincorporated areas, such as in parts of Arapahoe, Jefferson, and El Paso Counties. Among the cities using this technique, the median effectiveness rating was 3.5e Eleven cities have adopted annexation policies delineating urban growth areas for future annexation. To be effective in retaining open space and encouraging infill development, the counties must play a tandem role. Several cities reported a frustration of adopting what they feel to be sound growth policies, and a county then changes zoning to allow development in adjacent unincorporated areas. The median of the effectiveness ratings given by the eleven cities that have annexation policies was 4.0. Transfer of Development Rights Three cities reported programs for retention of open space through use of transfer ofdevelopment rights (TDR). Denver's program is targeted to retain the scale of historic structures and districts in the city--which can be thought of as a unique and specialized form of urban open space. The nature of a recently adopted Englewood TDR program was not specified in the survey returned. Because of Englewood's location in the Denver Metropolitan Area, it is assumed the new program targets small scale urban open spaces. Finally, the city of Louisville reported

PAGE 48

43 use of a TDR approach for retaining open space, giving it an rating of 3.0. An ambitious TDR program is presently under consideration by Ft. Collins, Loveland, and Larimer County. The proposal would retain a large agricultural greenbelt between the cities, with development rights going to designated receiving areas located in the two cities and in the county. This program, developed with the consultation of Colorado Open Lands, has potential for creating a "win-win" approach to retention of agricultural land and open space. Other cities are watching closely to see if this could become a model for other areas in the Front Range. Acquisition of Development Rights for Agricultural Lands, Viewsheds, Wildlife Habitats, Conservation Lands None of the cities reported city purchase of development rights for open space. The questionnaire did not ask directly about donation of development rights. It would be useful to find out if the cities are prepared to receive the donation of development rights--a technique that can occasionally provide tax relief to a land owner. None of the cities reported strategies to create scenic easements (a form of acquisition of development rights). Only Louisville reported use of techniques to acquire conservation easements. Fee Simple Interest in Land for Open Space--Including Purchase of Land, Landbanking, and Parks Acquisition Twelve cities reported of land for open space and parks. Boulder's purchase of large scale agricultural lands to create a greenbelt around that city stands out as the most ambitious open space

PAGE 49

44 acquisition program in the region. Other cities reported smaller scale acquisition of lands for future parks and open space. Five cities said they would be willing to use eminent domain powers to purchase open space. Among cities using various strategies to purchase fee simple interest in land for future open space, the median effectiveness rating reported was 4.0, indicating this is felt to be an effective technique. Developer Set Asides for Parks, Recreation, and Open Space Lands Fourteen cities reported requirements for .developers to set aside land for public open space and parks. This technique may take several forms: 1) A percentage of land area on the site is dedicated to the city and set aside for park de-velopment or to protect environmentally critical parcels of land on site; or 2) A payment in lieu of land is paid by the developer and the city then uses the money for purchase of public open space off site. The formula for fixing the amount to be paid by the developer may be based on either land area or dwelling units within a subdivision or Planned Unit Development. When there are provisions requiring a city to use these funds only for the purchase of open space (rather than park maintenance or development) this approach is strengthened as a tool for protecting open space. Among cities. using this technique, the median effectiveness rating was 4.0, indicating that this is perceived to be a moderately effective strategy. A related approach is PUD private open space requirements. Fifteen cities reported PUD open space requirements, and .rated the effectiveness

PAGE 50

45 of this technique at 4.0. All PUD ordinances require provision of open space. When 40% or more of a PUD is required to be landscaped and when a city carefully negotiates the specific location of this open space--the effectiveness of this tool increases. The proposed greenbelt between Ft. Collins and Loveland uses PUD and subdivision open space requirements to enlarge and enhance the actual open area between those cities. Another application of this technique is in protecting scenic vistas along highways by retaining open space in relationship to viewsheds and locating development in a manner which does not detract. from the viewshed. Building Height Limitations and Building Setbacks To protect scenic views, twelve cities reported use of building height limitations and fourteen cities use building setbacks. Uniform height limitations and setbacks throughout a city do nothing to retain scenic views. Targeting is the critical factor. Denver's Mountain View Ordinance is a good example of effective targeting. The concept is one that recognizes that a 100 story building may have no negative impact on the viewshed of one site, while at another site a two story structure might entirely destroy the scenic vista. Similarly, at one site in a city no setback might be appropriate, while at another site a 1,000 foot setback might be needed to protect a viewshed. Building height limitations were given an effectiveness rating of 3.0 in protecting scenic views. Building setbacks were rated 2.5.

PAGE 51

46 Agricultural Preservation Only two cities--Louisville and Boulder--have agricultural preservation programs. This may indicate that agricultural open space per se is not a priority among Front Range cities. It may mean cities can play only a minor role in preserving agricultural lands. Or perhaps the association just is not made between city policies and retention of agricultural land outside the city. Techniques for Containing Sprawl--Housing Densities, Infill Housing, and Contiguous Development Strategies The survey asked a series of questions about approaches used by the city to raise housing densities, promote infill housing, and encourage contiguous development--"backdoor" strategies for retaining Front Range open space and agricultural lands. All cities responding to the survey (with the exception of Louisville and Greenwood Village) reported a trend toward higher housing densities and smaller housing units. Each city was asked to estimate the average density of housing constructed within the last two years, and planned/approved new residential development. Densities were requested in units per gross acres to gain an,understanding of the overall impact of new Front Range housing. The intention was to look at new housing on a regional and neighborhood scale--to find out the gross density of new residential development, which includes not only lots and housing, but also the amount of .land devoted to new streets, schools, and neighborhood parks. Gross

PAGE 52

47 densities were requested, rather than net densities--which exclude land devoted to public uses. Gross density is always a lower number (usually by 25-30%) than the net density for the same area. Average Gross Density of New Housing Reported by Front Range Cities Less than 2.5 Units/Gross Acres: Greenwood Jillage 2.5 5.0 Units/Gross Acres: Colorado Springs, Broomfield, Louisville, Loveland, Pueblo, Westminster, Wheat. Ridge 5.1-7.5 Units/Gross Acres: Arvada, Brighton, Ft. Collins, Greeley, Lafayette, Longmont 7.610.0 Units/Gross Acres: Boulder, Englewood, Thornton More than 10.0 Units/Gross Acres: Aurora, Denver, Lakewood These figures suggest new housing densities are still quite low in Front Range cities, even though all but two cities reported a trend of rising densities in recent years. 1 -8 units per gross acre is the typical density for single family detached homes; 7 -11 units per gross acre for duplexes; 12 -25 units per gross acre for townhomes; 24 52 units per gross acre for walk-up apartments; 50 105 units per gross acre for elevator apartments. The average densities for new housing reported by the cities suggests single family. detached homes continue to be popular, but housing types of a higher density are raising the average densities somewhat in of the cities. This trend toward higher densities could be attributed solely to economic and demographic factors--such as high interest rates, land prices, smaller household configurations, and less household income

PAGE 53

48 available for housing. The inf1uence of city policies should not be overlooked. some cities (Lakewood and Aurora are examples) reported trends to "puil in the reins" on moderate-high density development--even though market trends are favorable for higher densities. Other cities reported incentives that seek to encourage higher densities. Along with demographic and economi.c trends, the policies b7ing adopted by Front Range cities are acting to influence, and either encourage,j>, r discourage higher housing densities. Zoning Techniques Theoretically, as average residential densities in the region rise, agricultural land and open space retained between cities should rise proportionately. Zoning is the mechanism for controlling urban density. Average housing density could be raised by 25% by increasing permitted densit;ies "across the board" in all zone districts in a city. Or, average density could be increased by "up zoning" in targeted areas. On the edge of a city on present agricultural lands--zoning m:l,ght also be adopted which permit a high density development--in return for very large scale retention of lands. Ten cities reported use of some type of moderate or hi'gh density zoning strategy to encourage infill and contiguous development. The median effectiveness rating for zoning density techniques was 3.0, indicating _this i$ perceiyed as only moderately effective in guiding. urban growth. Comments included:

PAGE 54

49 Our city has a real 'hang up' about approving densities higher than those already approved. (Aurora) -Also leads to high land prices and speculation, which are counter-productive to residential infill development. (Denver) -Virtually all infill for several years has been medium to high density multi-family, leading to a feeling that the trend should be reversed. (Lakewood) -There is a strong community sentiment for keeping Louisville at a small scale. -Height regulations limit density. (Wheat Ridge) Eleven cities reported they are not using any approach that would increase zoning residential dens! ties. Probably many of these cities have some existing medium or even high density housing--but this can be interpreted as a general community and political sentiment that "low density is good, high density is undesirable." The comments from Denver are important--"upzoning" in some cities may be a disincentive to infill housing andhigher densities. Two questions relating to this phenomenon are: If very large areas of high density zoning were created--for example all of Douglas County, half of the city of Denver, half of Colorado Springs--would the market shift in such a way that the value of high density zoned land decreases and speculation be eliminated? High density zoning seems to "work" when in close proximity to a park, open space, or a body of water--such as Sloan's Lake and Cheesman Park in Denver and Cherry Creek Reservoir in Aurora. Could this not become a sort of principle for targeting high density zoning?

PAGE 55

so Mixed Use Zoning to Encourage Housing. Redevelopment Along Commercial Streets In almost every city in the Front Range there are major streets with large amounts of vacant and undeveloped lands. Sometimes these are streets that once served as the main connection between small cities: Highway 85 south out of Greeley; Santa Fe Boulevard from Denver south into Arapahoe County; Colfax Avenue in Aurora, Denver, and Lakewood; Highway 2-6-85 in Commerce City. Generally, these "strips" have been reserved for commercial uses. But because they have not been able to compete with shopping malls, or because there are not enough nearby residents to support locally-oriented businesses, they have tended to attract auto-oriented enter-prises--used car lots, drive-in theaters, fast food restaurants. Usually there are parcels of vacant land scattered among the commercial developments. These commercial corridors are a major potential housing land resource. Such development could occur with little impact on existing residential areas and little displacement of existing businesses. The higher density could allow for more affordable housing development. The Writer Corporation's planned townhome development along Santa Fe Boulevard in Littleton is an excellent example of use of this strategy for infill housing. Nine cities reported use of mixed use zoning to encourage housing development along commercial streets. Several cities had just adopted zoning ordinances for this purpose. A median effectiveness rating of

PAGE 56

51 3 .0 was assigned to this technique by the cities currently using this strategy. Capital Improvements Planning to Encourage Infill and Contiguous Development The level of water and sewer services provided and the construction of new streets and bridges may be used to encourage infill housing projects within a city, and contiguous growth on the edge of a city. Nine cities reported a Capital Improvements Plan that serves these objectives. The median effectiveness rating assigned by the cities to this technique was 3.5. Development Standards Flexibility to Encourage Infill Housing Small lots and difficult to develop sites may present obstacles for developing housing on "skipped over" parcels of land. Rigid standards may exclude manufactured housing and make illogical the moving of well-built older homes to infill sites. To overcome these obstacles, a city may adopt provisions for flexibility in zoning setbacks and open space requirements, and building codes to make feasible the location of new housing on small infill sites. Four cities reported use of some form of flexibility in development standards to use vacant land more efficiently for housing. The median effectiveness rating reported for this technique was 2.5, indicating that as presently practiced, this technique may have only limited importance as an incentive.

PAGE 57

52 Development Fee Incentives By reducing in targeted areas the city fees for water and sewer hook-ups, and zoning and building code fees--a city can improve the economic viability of infill projects. These development fees in some cities can add up to 10% or more of total construction costs for a single family detached or townhome. Three cities reported some form of development fee incentives to encourage infill housing starts. Brighton and Greeley have both sewer and water fee incentives orwaivers in targeted areas. They give this technique a highly positive of 4.5 as a tool for encouraging infill housing. The third city reporting use of a fee incentive approach was Englewood. The specific fee incentive was not reported. Second Units on Existing Homesites One way to make better use of existing developed residential land is to allow and encourage the development of second units that currently contain one single family home. New housing can be created by partitioning a house, adding one or two rooms, by finishing a basement, or by constructing a small separate building on the same lot. Such units make housing affordable to owner and renter, make efficient use of energy,. increase tax revenues for cities, and efficiently use city infrastructure. Concerns about possible changes in the appearance of a neighborhood can be avoided by simply applying the same design standards that anyone adding a room to a single family home must meet, and requiring that the second unit be smaller than the original house.

PAGE 58

53 Only Pueblo reported using this technique, though Denver and other cities likely also allow for this type of infill housing in certain limited situations. Pueblo rated the effectiveness of this technique at 4.0. Financing for Infill Housing City, county, state, and federal governments can provide low interest financing for new infill housing. When.carefully targeted by a city to specific areas, this technique may tip the scales to make financially feasible the various approaches to infill housing. Financing programs can act as a catalyst for infill development. Three cities reported the use of local financing programs for infill housing (presumably bond money), giving a median effectiveness rating of 3.0 to this technique. Eight cities reported use of federal monies (including CDBG and UDAG grants), and gave a median effectiveness rating of 3.0 for this strategy. Summary of City Techniques Front Range cities are engaged in efforts to retain agricultural and oped space lands, and encourage infill and contiguous development. The only question is--is it enough? Thirteen cities said they advocate these goals. They are choosing to use a variety of techniques and are coming up with mixed results. Many strategies are still in the experimental stage--waiting to be fully tested.

PAGE 59

54 The hottest issue is density, which on a regional scale is at the heart of retaining natural open space and agricultural lands. The trade-offs between higher density and natural open space are not easy ones for Front Range cities. Some cities may be close to finding the creative approaches that are needed if the region is to both grow and retain natural open space.

PAGE 60

CHAPTER VI WHAT FRORT RANGE COUNTIES ARE DOING--cuRRENT POLICIES AND TECHNIQUES THAT MAKE ROOM FOR POPULATION GROVIH AND RETAIN OPEN SPACE Each county in the Front Range region was visited (with the exception of the City and County of for a survey interview with the county planning staff and a "windshield survey" of existing agricultural lands and natural open space. A Denver response was obtained from the survey of cities, and therefore was not included in the county study. The questions included in the interviews with county planning staffs were similar to questions asked in the survey mailed to Front Ra.nge cities--with some additional emphasis on strategies for retaining farming and grazing lands. The interview method allowed for brief descriptive explanations of techniques, and provided valuable commentary from planners. For each technique, the county planner was asked whether it had been used. If so, the planner was asked to rate its effectiveness on a scale of 1-5. Many planners also told the story of how a particular technique evolved and the successes and failures with each. The inventory of county strategies consisted of three parts. Part one was a series of questions concerning methods to retain farming and grazing lands. Part two consisted of questions relating to protection of wildlife habitats, scenic areas, and small scale open space. Because some counties have large unincorporated urban areas, part thtee looked

PAGE 61

56 at strategies to encourage infill development and raise residential densities. At the end of the survey, each planner was asked, "Do you believe agriculture will be a part of the county's economy in 25 years?" and "What would it take to retain open space in the county--such as greenbelts between cities, important wildlife habitats, and unobstructed views along highways?"

PAGE 62

57 Techniques Front Range Counties Are Using c QJ 0 0 s... Vl 0 Vl s... QJ ttl U'l s... QJ 0 U'l ttl -c r-ttl QJ E rE 0. 01 0.. '+.-..0 -c ttl ttl :;::! :;::! '+-s... QJ r--c s... 0 0 rQJ ttl :;::! QJ c:x: c:x: CJ:l 0 LLJ ......, .....J 0.. 3: Comp. Plan Agr. Lands Element X X X X X Agr. Zoning Minimum 2.5 1. 6-35 2-35 5'2.3 .580lot Size (Acres) -35 160 35 10 -10 40 160 -Agr. Important in Year 2010 X X X X X X X Urb-Rur Dev Areas (City-County) X X X X X X TOR for Agr. land X County Tax to Purch. Open Sp. X Comp. Plan Open Space Element X X X X X X X X X Purch. of Land for Open Space X X X X X X Purch. Dev. Rights for Op. Sp. X Conservation Easements X X X X X Scenic Easements X X X Subdiv. Review Open Sp. Ded. X X X X X X X X X PUD Open Space Dedication X X X X X X X X x. Building Setbacks X X X X X Building Height limits X X X X X X Zoning for Mod.-High Density Urban Development Area X X X X X X X Development Standards Flex. X X X X Infill Fee Incentives Financing Programs for Infill X X X CIP for Contiguous Dev. X X X X X X Trend: Higher Density Sma 11 e r D U. X X X X X X X X

PAGE 63

58 Techniques for Preserving Large Scale Open Space--Including Fara and Ranch Lands, and Other Natural Open Space Counties are the local governmental bodies that influence agricul-tural use in the Front Range region. As a rule of thumb, agricultural land north of the Denver Metropolitan Area is characterized by produc-tive soils and a well developed irrigation system that supports row crops, vegetable truck farming, dairy farming, and livestock production. Pueblo County to the south has similar prime agricultural lands. Other counties to the south of Denver contain less productive soils, uneven terrain, and little irrigated farmland. Agriculture largely consists of dryland wheat farming and cattle grazing. Both the more intense form of agriculture in the northern one-half of the region, and the less intense form of the southern one-half, provide benefits to urban. residents. They range from the tangible benefit of fresh milk, produce, and eggs, to the more intangible benefit of :green open space around and between-cities, uncluttered mountain views, habitats for wildlife, and air quality renewal. The nine counties surveyed in the Front Range region hold a critical role in the retention of these agricultural and open space lands. Agricultural Lands Preservation Element in County Comprehensive Plans Five counties--Adams, Boulder, Larimer, Pueblo, and Weld--reported having some type of agricultural lands preservation element within their Comprehensive Plan. Weld and Boulder Counties stand out as two counties

PAGE 64

59 with extensive agricultural preservation elements. El Paso County, at the other extreme, has a land use plan that refers to agricultural lands as "agricultural and other unused land." In Douglas County--with large areas of open ranch lands and strong urban development pressures--a controversial agricultural lands preservation element was pointedly eliminated by county commissioners several years ago. County Comprehensive Plans are meaningful only when they are referred to as policies are considered by county commissioners. Yet the elements included within a county Comprehensive Plan are an indicator of local priorities. Agricultural Zoning/Rural Residential Density Zoning can be an effective tool for retention of agricultural land and open space. The critical factors are: -permitted rural residential density (number of acres required for each residential unit) -county-city agreements delineating urban and rural development areas ease or difficulty in obtaining zoning changes All counties indicated the use of some type of agricultural zoning. El Paso County is now in the process of zoning the eastern one-half of the county. Counties reported the following acreage requirements per residential unit in agricultural zones:

PAGE 65

60 Acres per County-City County Dwelling Unit Effectiveness Agreements! Adams 2.5 -35 3 Yes Arapahoe 1.6160 5 No Boulder 17.5-35 5 Yes Douglas 2 -35 1 No El Paso 35 (Recently No Created) Jefferson 5 10 2 Yes Larimer 2.30 10 1 Yes Pueblo .5 40 2 Yes Weld 80 160 5 Yes Interviews with county planners found a variety of approaches to agricultural zoning. Weld and Boulder Counties seem to be especially effective in the use of zoning to protect agricultural lands. In counties with small acreage requirements for residential development, zoning techniques are ineffective in retaining farm and ranch lands. Districts/Farmland Conservancy Districts Urban service districts may be created to facilitate u rban develop-ment by providing services such as water, sewer, and fire protection. Agricultural Districts and Farmland Conservancy Districts have the opposite intention--they seek to discourage urban development and facilitate the continuation of agricultural production. Within an Agricultural District, land is taxed only at its agricul-tural value, zoning allows for residential development only on very

PAGE 66

61 large sites, and eminent domain powers are restricted so as to discourage urban services. Farmland Conservancy Districts have the added authority to intervene in any sale of land previously designated as important farm or ranch land when the buyer intends to convert agricultural land to urban development. A group of Larimer County farmers are interested in forming an Agricultural District in order to protect the existing irrigation system and discourage extension of Ft. Collins urban services into a prime agricultural area. State enabling legislation would be required to create such districts in Colorado. Purchase of Lands for Open Space County purchase of fee-simple interest in agricultural lands does occur in the Front Range. The counties reporting some type of open space acquisition program are using approaches that fit their local context. Some programs retain agricultural use of the land, other approaches emphasize recreational uses and .wildlife habitats.

PAGE 67

County Adams Boulder Douglas El Paso Jefferson Larimer Pueblo 62 Focus Flood Control, Recreation, Trails I Urban Greenbelt, Agriculture, Compliment City of Open Space I Parks and Recreation Parks and Recreation Preservation of Natural Environment, Recreation Parks and Recreation Parks and Recreation Effectiveness 4 5 5 5 5 4 The most ambitious and successful county open space program is in Jefferson County, funded by a .5% sales tax that can only be used for open space acquisition. At one time the Jefferson County program leased land back for agricultural uses. Administrative costs and the demand for public access have led to ending lease back arrangements. In Jefferson County, open space lands are acquired through gifts, bargain sales, negotiation, and condemnation. The City of Boulder has another successful open space program to create a greenbelt around the city, with land leased back for agricul-tural uses. The County of Boulder plays a complementary and secondary role in purchase of lands for open space in the county. Adams County is considering purchase of open space lands for flood control, recreation, and development of an extensive trail system along several county waterways. Other counties have less extensive programs for purchasing land for future parks and recreational uses. Money for open space is the

PAGE 68

63 constraint expressed by every county. Counties are looking to state lottery funds and developer _fees in lieu of on-site dedication of open space. Purchase of Development Rights Larimer County used purchase of development rights to a very limited extent when acquiring Horsetooth Mountain Park to the west of Ft. Collins. Most of the park was purchased fee simple int_erest. No other county reported use of this technique. The Space Command Center locating east of Colorado Springs is considering use of this technique to assure a large agricultural and open space buffer around that new complex. Transfer of Development Rights Larimer County has been holding public meetings to consider adoption of a Transfer of Development Rights program for the undeveloped agricultural areas between Loveland and Ft. Collins. Participation of the county and both of the cities would be necessary for the program to be implemented. Several other counties expressed interest in adopting some type of TDR program to retain open space and agricultural lands. Preferential Tax Assessment for Agricultural Lands In all Colorado counties, land is taxed on the basis of its use value as ranch or farm land, rather than on the basis of actual market value. Colorado does not require a retroactive penalty payment if the

PAGE 69

64 land is later converted to urban development. As a tool for retaining agricultural open space lands and limiting urban sprawl, preferential tax assessment is viewed as both a positive and negative influence. County planners saw the technique encouraging speculation in land on the edge or urban areas. At the same time, preferential tax assessment has allowed many farmers and ranchers to stay in business. In Pueblo County, this tax provision was reported to have kept a large amount of land in agriculture. Agriculture to the Year 2010 Six of the nine counties projected a continuing importance of agriculture over the next 25 years. Douglas, El Paso, and Jefferson Counties see agriculture greatly decreasing in importance. County planners cited a number of new techniques that are needed if farm and ranch lands are to be retained in the Front Range region: More county control over special service districts. Money for purchase of major tracts of agricultural land. A few strategic purchases could shape the development of the county. -To discourage the break-up of ranch and farm lands--state legislation allowing county subdivision regulation of parcels of land 35 acres and larger. (Current subdivision regulation applies to parcels of land less than 35 acres in size.) -State enabling legislation for TDR and formation of Agricultural Districts. -State legislation making it more difficult agricultural water rights to municipalities. require water rights before annexation can encourage conversion of agricultural lands. -Agricultural zoning with larger lot sizes. to transfer Cities that take place,

PAGE 70

65 Techniques for Preserving Small-Scale Open Space--Including Wildlife Habitats, Scenic Views, Parks and Recreation Areas In counties experiencing rapid growth, that have chosen not to plan for large scale natural open space, it. is still possible to retain important wildlife habitats and scenic areas, require open space buffering of new development, and provide a system of open space parks and recreation areas. The survey asked a series of questions about approaches used by the county to encourage retention of small-scale open space. Acquisition of Conservation Easements and Scenic Easements To retain an important wildlife habitat or to protect a scenic area, a county may acquire the development rights for land. The land continues in private ownership for grazing or recreational uses. Such conservation and scenic easements can be acquired through purchase (including eminent domain), by donation, or by requiring dedication in the subdivision review process. In acquiring conservation and scenic easements, none of the counties reported purchase of development rights for crit:f.cal areas. Rather, easements are acquired in the subdivision review process. The counties are beginning to take a careful look at important scenic and wildlife areas that would be impacted by new development, and requiring dedication of conservation or scenic easements for these lands. Four counties reported use of a conservation easement technique. Douglas County has retained a large scenic and wildlife area located

PAGE 71

66 within the Highlands Ranch development. Adams County is in the process of accepting a .parcel of land from a gravel company that will become part of a wildlife and. trail sy.stem. Larimer and Jefferson Gounties reporied donation of easements for wildlife habitat areas. Larimer and El Paso Counties reported use of a scenic easement technique. Within the subdivision review process (Senate Bill 35), the counties require dedication of easements for important scenic areas. This is becoming an important technique in these two counties. Pueblo County has one scenic easement that was purchased through the efforts of the Pueblo Beautiful Association. Building Height Limitations and Building Setbacks All counties regulate building heights and setbacks. These techniques do little to protect scenic views, unless they are fine-tuned to the needs of specific sites and areas. Boulder and Douglas Counties are good examples of effective targeting. Boulder County a 1,500 foot open space setback along Highway 36 and other major highways. Douglas County is developing subdivision and PUD regulations which would guide location and height of structures in such a way that roof lines on hilltops would not obstruct scenic views. Subdivision and Planned Unit Development Open Space Requirements All counties reported having PUD and Subdivision open space requirements regulating coverage of the site and requiring dedication of park lands. Particularly on large sites, these requirements have a

PAGE 72

67 potential for protecting important viewsheds and natural wildlife areas. -Boulder County uses a rural PUD approach that allows two dwelling units on a 35 acre site. The county requires submission of a plan for what will be done with the open space portion of the site. Often the land remains in farming. -Douglas County has recently dropped a 30% open space requirement for new communities. Apparently the requirements were felt to be too limiting. -El Paso County uses a sliding scale based on gross density and square footage per dwelling unit, to determine the amount of land dedicated to the county for parks and open space. For higher density development, 25% of the site is dedicated for parks and public open space. The County Park Board only accepts regional scale parks (400 acres or more). Consequently, most developers must pay the $600 per dwelling unit fee in lieu of dedication of park land on the site. -Pueblo County uses a formula based on bedrooms per dwelling unit, to determine dedication of park lands within subdivisions. -Larimer County requires 30% of each PUD be open space. With the exception of Weld County,all Front Range counties are making good use of Senate Bill 35, granting counties the authority to require publicly dedicated open space and park lands within the subdivi-sion review process. Weld County, with 80 160 acre minimum lot sizes, reported no new subdivisions and no need for these provisions. For areas of Weld County already subdivided but not developed, Senate Bill 35 provides no benefit. Open Space Preservation Element in County Comprehensive Plans All nine counties reported having an open space preservation element. in their Comprehensive Plan. Adams, Boulder, El Paso, and

PAGE 73

68 Jefferson Counties have particularly strong elements to designate sign!-ficant areas for protection. Techniques for Containing Sprawl--Housing Densities, Infill Housing, and Contiguous Development Strategies Because many Front Range counties have large unincorporated areas that over the years have developed at urban densities, the survey asked a series of questions about attitudes toward increasing residential densities and adoption of policies that encourage infill housing and contiguous development. The proliferation of special districts to serve urban development within the Front Range region has created large areas of unincorporated urban development that are virtually indistinguishable from neighboring_ suburban municipalities. Some unincorporated urban development is found in all counties, but Adams, Arapahoe, Douglas, El Paso, and Jefferson Counties have the greatest concentration of urban special service districts, and the greatest susceptibility to sprawl and "leap-frog" development. The special service districts are often similar to municipalities in providing water, sewer, and fire protection services. Street maintenance, parks, and police services may be provided by either the county or district. Planning and regulation of development remain county responsibilities. In these areas, "backdoor" strategies for retaining Front Range agricultural lands and open space--by increasing residential densities and encouraging infill and contiguous development--rely on county

PAGE 74

69 initiative. The average gross density of new housing in unincorporated county areas is below that of Front Range cities, but the difference is. not great. Average Gross Density of New Housing in Unincorporated Areas of Front Range Counties Less than 2.5 Units/Gross Acres: Boulder, El Paso, Larimer, Pueblo, Weld 2.5 5.0 Units/Gross Acres: Arapahoe, Douglas 5.1 -7.5 Units/Gross Adams (Jefferson County densities not available.) Five counties reported a definite increase in residential densities for housing constructed within the last two years and for approved projects still in the development process. Boulder and Weld Counties--with strong agricultural zoning and county-city development agreements--reported little change in residential densities over the last several years. Pueblo County reported no changes in density of new housing--likely explained by poor economic conditions in the county and relatively little new housing constructed over the past several years. Jefferson County, with large unincorporated urban areas, reported rising residential densities. The Jefferson County planner in the survey does not see this as a long term trend--rather an indication of interest rates and affordability of housing. Zoning Techniques Rezoning to allow high density townhomes and condominiums in unin-corporated county areas received mixed reviews among Front Range

PAGE 75

70 counties. Like Front Range cities, the counties encounter strong oppo-sition to this .. infill. techni,que from nearby single-family homeowners. Boulder and Weld Counties discourage any rezoning to permit higher densities, to maintain the integrity of agricultural zoning and county-city development agreements. In Boulder County, this technique would be considered only in areas subdivided before of the current Com-prehensive Plan and current zoning regulations. Other Front Range counties reported some use of zoning that increase residential densities and encourage infill development. In Adams County, this has been achieved in PUD provisions. In the southern part of unincorporated Jefferson County and in Larimer, Arapahoe, and Pueblo Counties--this technique is used utility services are already in place and when local opposition of homeowners can be mitigated in some manner. Capital Improvements Planning to Encourage Infill and Contiguous Development In Jefferson County, the delay in construction of Colorado Highway C4 70 slowed development of that area and provided needed time for the county to purchase open space lands and plan for the future development of the area. In a similar manner, the of construction of county roads and bridges can be used to en6ourage infill and contiguous development. But because counties have no authority to provide critical water and sewer services, Capital Improvements Planning is a weak tool for guiding county growth.

PAGE 76

71 Most of the Front Range Counties reported some type of Capital Planning or management by objective program. Candid comments included: "Capital improvements follow development" and "we do catch-up road improvements." The critical missing link for guiding growth is the inability of counties to provide water and sewer services. El Paso County is actively seeking state legislation that would allow counties to form a water and sewer authority._ Development Standards Flexibility to Encourage Infill Housing Just as in Front Range cities, a degree of flexibility in zoning and building codes and fee incentives could be used as a technique to encourage development of "skipped over" parcels of land. For example, difficult to develop sites might receive special zoning consideration, or building codes might be changed to allow for manufactured homes. Many counties reported efforts to streamline the develo_pment review process (resulting in cost savings to developers) and create more flexibility in density and open space zoning requirements--policies that apply throughout the county. However, none of the counties had programs tailored specifically to the needs of infill projects. "Windshield" surveys in most of the counties showed significant areas of vacant land interspersed with urban development. In the interviews, none of the counties seemed to perceive infill to be a priority. Rather, the undeveloped land is seen as a sort of temporary "bonus" urban open space. The hodge-podge of overlapping special service district and county jurisdictions makes it difficult to do coherent -and comprehensive planning for either open space or infill development.

PAGE 77

72 Financing Programs for New Infill Housing County bond money and federally funded housing programs could be targeted to encourage infill development in unincorporated cQunty areas. Although all counties have small existing housing programs, there is no effort to target these programs to infill areas within their jurisdiction. Mixed Use Zoning to Encourage Housing Redevelopment Along Commercial Roads In each of the Front Range counties, there are highways that once served as links between cities. These highways often are lined with small businesses that rely on the trade of passing motorists, with many parcels of scattered vacant land. Highway 85 as it winds through Weld, Adams, Denver, Arapahoe, Douglas, El Paso, and Pueblo Counties, is an example of a highway with miles of low density strip commercial activity. As highway 85 passes through unincorporated urban areas, there is a major potential for redevelopment with higher density housing. Such redevelopment with townhomes and condominiums could occur with little impact on existing businesses. Only Adams and Pueblo County .reported current zoning flexibility that would permit redevelopment of this type. None of the counties is actively pursuing a redevelopment plan for this purpose. County-City Agreements Delineating Urban and Rural Development Areas To encourage contiguous and incremental urban development rather than "leap frog" development, Adams, Boulder, Larimer, Pueblo, and Weld

PAGE 78

73 Counties have formal agreements delineating urban and rural development/service are.as. Generally these agreements define future city annexation areas, city sewer and water service areas, and the residen-tial densities allowed within county zoning. Boulder and Weld Counties use this technique most effectively. The counties allow only very low density residential development (35 acre lots in Boulder County, 160 acre lots in Weld County) in the rural development/ service area. When development is proposed outside city boundaries, the developer must seek annexation to the city. Exceptions to the policy are found only in areas that were subdivided before current zoning and county-city agreements were adopted. Adams, Weld, and Pueblo Counties require reciprocal county and . review of any development (or water-sewer extension) .proposal within specified area. Several other counties reported informal county-city agreements. El Paso County, with large areas of suburban unincorporated development, is proposing to create urban and rural planning areas within the county. The urban area of the county would have its own planning commission. In counties with large unincorporated urban areas, this approach might accomplish the objective of encouraging contiguous and planned incremental development. Sa-mary of County Techniques In the absence of state or regional land use planning, Front Range counties are creating local strategies for retaining agricultural and

PAGE 79

74 open space lands. Each is taking a different track: Jefferson County is acquiring scenic, historical, and natural open space lands. Boulder County is emphasizing county-city agreements and low density zoning to retain agricultural open space areas between and around urban communities. Weld County is emphasizing retention of the county's large scale farm lands and is effectively using zoning and county-city development agreements. Adams County is emphasizing acquisition of open space lands for wildlife habitats and an extensive trail system, and is utilizing county-city development': agreements to guide urban growth. Larimer County is currently using many techniques and is considering the Transfer of Development Rights approach for retaining agricultural open space between Ft. Collins and Loveland. El Paso and Douglas County are emphasizing retention of important scenic and conservation areas through acquisition of easements and park lands in the subdivision review process. Pueblo and Arapahoe Counties are using a variety of techniques, but do not have an. approach that is particularly emphasized. A number of Front Range Counties are pro:-growth and place no emphasis in county policy on retaining agricultural lands or large scale open space between cities. These counties do, however, emphasize quality development and retention of small scale scenic and wildlife areas that will enhance the quality of the new urban environment. In contrast to Front Range cities, residential densities do not seem to be an important issue to Front Range counties. The connection between urban density and retention of natural open space is not accepted as an important planning issue at this time.

PAGE 80

75 The interviews with county planners showed a great variety of attitudes, techniques, and strategies among Front Range counties. They form a patchwork of approaches for making room for population_growth and retaining natural open space.

PAGE 81

.CHAPTER VII CONCLUSIONS Trends This study has explored the issues and trends affecting the retention of open space in the Colorado Front Range region over the next 25 years. If current urban density patterns continue, up to 750 square miles of today's natural open space will become city and suburb to make room for the region's population growth. The planning choices that will be made by the county, city, and state governments, will shape the region's retention of agricultural lands, scenic areas, and wildlife habitats. The Future of Agricultural Lands Counties and cities in the northern one-half of the Front Range generally have adopted growth management policies and are using a wide range of techniques to preserve large scale open space. The motives are to assure continuation of farming in the region, to protect natural scenic and wildlife areas, and to retain identifiable urban communities separated by open countryside. This study was surprised to find that nearly every technique used anywhere in the United States is either being used or considered by one or more of the cities and counties in the northern Front Range region. If current policies and planning

PAGE 82

77 techniques continue and are strengthened, this region should be in reasonably good shape in the year 2010. Counties and cities in the southern one-half of the Front Range are generally pro-growth and have not adopted growth management policies or techniques that encourage retention of agricultural lands. This was particularly found in Arapahoe, Douglas, and El Paso Counties. Pueblo County has more similarity to the northern counties in growth management philosophy. The southern cities and counties are using none of the potential techniques that could be used to retain large scale open space for ranching, farming, scenic areas, or conservation lands. Urban development at this time is limited primarily by land topography and location of roads and highways. If current policies and trends continue over the next 25 years, this region should be heavily urbanized, with ranching and large scale open space found only where the highways have not been built and where steep slopes make urban development impossible. The Future of Scenic, Recreation, and Wildlife Areas Cities and counties throughout the region place a priority on retention of scenic views and public park and recreation areas-generally small scale open space that enhances the quality of the urban environment. In the subdivision and Planned Unit Development review processes, cities and counties are requiring dedication of land for parks and schools. Counties and cities with a strong open space element within their Comprehensive Plan and a willingness to require dedi.cation of identified critical scenic and wildlife areas--should fare reasonably

PAGE 83

78 well over the next 25 years. On the other hand, local governments with weak Comprehensive Plan open space elements and those unwilling to require sizable dedications of scenic and conservation easements--will likely end up with bits and pieces of park and natural lands in places where the public will derive only minor benefits. The Future of Urban Infill and Residential Densities This study found few of the cities or counties wrestling with the connection between regional open space and housing densities in the existing urban areas. This is a major "blind spot." One would expect at least the larger cities of the region--those with more than 100,000 population--would have Comprehensive Plans and implementation strategies that encourage infill housing and would be favorable to increasing residerttial densities. This is not the case. Aurora, Colorado Springs, Denver, and Lakewood reported serious problems urban infill a{ld raising residential densities. The city and county of Boulder, in many ways pro-active in growth management and open space policies, is uncomfortable with measures that might significantly increase residential densities. Ironically, residential densities are increasing throughout the region. This trend is not the result of any planning policy to retain regional open space or manage city sprawl. Rather, smaller housing units and higher density new development has occurred in response to the economic and demographic factors that shape the housing market. The single family detached home of the 1950's and 1960's on a large suburban lot, is not likely to return to the Front Range. Current

PAGE 84

79 market factors will likely continue over the next 25 years, resulting in more efficient use of land. The question is--will the cities and counties take advantage of this trend and develop strategies that encourage population growth within the existing urban communities? Recommendations There is no easy "fix" that will retain Front Range open space over the next 25 years. This study has found the successful existing. programs to use combinations of land use guidance techniques and involve county, city, and private sector interests. The recommendations . to local governments are intended as a general framework to be adapted to local contexts. Planning for Agricultural Lands To retain large scale open space lands in agricultural usage, many of the techniques being used. by individual northern Front Range counties and cities can serve as a model for the region. -Develop an agricultural preservation element within the county Comprehensive Plan. City and county jointly define urban growth areas and agricultural areas. Zone all important agricultural lands for low density residential development--35 acre minimum lot sizes. -Create agricultural special districts to protect farming and ranching interests. Adopt city-county agreements requiring annexation before subdivision and rezoning can take place.

PAGE 85

80 Where strong pressures exist for subdivision of agricultural lands, create a TDR program to direct growth away from agricultural lands and to designated urban growth areas. Develop a funding source for purchase of large parcels of open space lands. Where a TDR program is not feasible to preserve greenbelt agricultural areas around urban commun ities, or where public access is desirable, purchase of critical open land is necessary. Carefully planned land purchases could provide future parks and land for longrange transportation needs (parkways or rail corridors). -Adopt stringent building setback requirements ( 1,500 2,000 feet) along major highway corridors. These highway corridors would then remain in agricultural uses. Planning for Parks, Scenic and Conservation Lands To retain smaller scale parcels of Front Range open space--park and recreational lands, scenic views, and wildlife areas--it is recommended that the cities and counties adopt the following strategy. Develop an open space preservation element within city and county. Comprehensive Plans. Identify specific scenic views and critical wildlife and natural areas for which protection is in the public interest. Where identified open space areas are large--the plan implementation techniques are the same as for retention of agricultural lands and greenbelts around cities (TOR, land purchases). Where identified open space areas are smaller scale--and. where urban development is planned in the Comprehensive Plan--require dedication of identified scenic and conservation easements in the subdivision and PUD processes. Where new development does not encroach on critical scenic or wildlife areas, developer payments in the place of land dedication can be used for purchase of park and conservation lands in other areas. Develop setback and building height regulations targeted to site specific viewsheds.

PAGE 86

81 Planning for Urban Infill and Increased Residential Densities To encourage infill development and increase residential densities in the urban communities of the Front Range, there is no clear pattern of techniques that are working. Recommendations to the cities (and counties with unincorporated urban areas) include: Conduct regional or local studies. of infill and residential density issues--including fiscal impacts, land speculation, and relationship between urban density and regional open space. -Develop an infill housing within the clty or county Comprehensive Plan. Implement techniques that look at density in juxtaposition to urban open space. High density residential development seems to work when located close to a lake, riverfront, park, scenic natural area, or farm land. There .is a need to plan high density development and open space as one planning process. Colorado. Springs neighborhood opposition to infill housing may be an expression of the need for more parks and urban open space in that city. Lakewood and Aurora citizen concern about high density residential development in their cities may not be so much opposition to density per se as dislike for mile after mile of high density townhomes and condominiums. Denver high density residential zoning that acts as a disincentive for new housing, may reflect a problem with the R-4 zoning district that allows for office use and results in land speculation. The lack of new high density residential development in Denver's R-4 zone may also reflect the absence of desirable open space in those areas of that city. -Redevelop the miles of strip commercial areas along highways of the Front Range. U.S. Highway 85 from Greeley to Pueblo presents interesting possibilities for creation of a new Front Range urban form. Along this highway, urban level infrastructure is already. in place in many areas, and potential park lands along the South Platte River and Plum Creek would seem to provide the needed juxtaposition with open space. -Allow construction of attached second housing units on existing lots in single family zone districts.

PAGE 87

82 -Cities and counties that decide to encourage some form of infill development and increase residential densities in planned areas, can then put together their local package of flexibility-incentive Getting There This study has found uneven levels of planning among Front Range cities and counties. If the region is to both make r .oom for population growth and retain natural open space, comprehensive planning and strong techniques for implementation are needed. The big question is--can local governments do it? Surveys and interviews with city and county of.ficials found a number .of obstacles: -Counties lack state enabling to gain control over the proliferation of urban service districts. Particularly in the southern one--half of the region, counties and service districts act as quasi-municipalities, with neither capable of carrying out long range planning. State enabling legislation is needed to clarify the legality of the TDR technique as applied to agricultural lands. State enabling legislation is also needed to allow the formation of agricultural protection districts. -Counties and cities throughout. the region find it difficult to connect their local needs and priorities with their regional context. Inasmuch as it is common for a Front Range resident in a week's time to live, work, shop, recreate, and travel within a dozen cities and three or four counties--it is difficult to justify purely local planning for open space. Local policies affecting agriculture, residential densities, open space, and population growth--impact in subtle ways residents of .cities and counties throughout the region. This study recommends that either a state authority; or state-enabled regional authority be created to protect natural open space. This state or regional authority would have responsibility for:

PAGE 88

83 -Identifying important farming and grazing lands, wildlife habitats, aquifer recharge areas, faults, wildlife areas, historic sites, and scenic views. -Inventorying unused publicly owned lands suitable for urban development and negotiating land trades that would protect open space adjacent to urban areas. (Such lands might include the Lowry Field Bombing Range, Rocky -Mountain Arsenal, Rocky Flats, and so_me identified National Forest and National Grassland areas.) -Acquiring the most critically located lands--either by purchase with state lottery funds to create a regional state park system,. or negotiation of land trades . -Aiding.counties, cities, and s'i:ate departments (including the Highway Department) in implementing open space and growth planning techniques. It is recommended that counties and cities be mandated by state legislation to include in their Comprehensive Plans a plan for the pro-tection of the identified important natural lands, and a plan for infill urban development. In order for urban levels of development to occur on important natural lands a developer and city or county would be to: (1) demonstrate that no other suitable land is available; and (2) show how the natural characteristics of the land will be protected. If a state or regional authority for open space planning is not created--cities and counties will need to continue and strengthen their local Elected city and county officials know the issues. Their profes-sional planners also know the issues, and the techniques that could be used. Public and private sector decision makers have participated in a remarkable study of Front Range issues and have made sound recommenda-tions. What really is missing is lively public discussion, and a strong citizen lobby for the measures needed.

PAGE 89

84 Whether open space planning becomes a regional responsibility or remains purely local, a lively public discussion and strong citizen's lobby for open space are needed. The discussion needs to examine the open space impact of a population growth exceeding one million new residents over the next 25 years. The discussion needs a positive approach that emphasizes quality of life and planning for both popula-tion growth and retention of open space. Governor Lamm's efforts at Front Range land use planning have (rightly or wrongly) been perceived as anti-growth. Residents seem to want both growth and prosperity, and open space. The discussion needs a positive public rallying point. It is interesting to listen as Senator Bill Armstrong extols the virtues of the "Sodbuster Bill"--a piece of legislation that probably does little to retain natural grasslands. Yet the senator has effectively created a rallying point around his "Sodbuster Bill" that raises images of protecting the natural Colorado environment. People respond. The public discussion needs tangible programs to consider. Some examples might be a linear park along Interstate Highway 25 from Castle Rock to the U.S. Air Force Academy, a large buffalo and antelope natural grasslands preserve defining the eastern boundary of the city of Aurora (wherever the limits are eventually drawn), and a land transfer program to exchange developable state or federally owned land for privately owned land on the edge of cities. The discussion needs a few gimmicks--such as a "save the Colorado Columbine" crusade, milk cartons on breakfast tables reminding residents they are drinking "Front Range Fresh" milk, and similar reminders on

PAGE 90

85 super market potato sacks (Colorado Front Range Potatoes) and restaurant menus (Front Range Prime Rib of nee f). Jacket patches, similar to those earrted for cross-country skiing, might become a fad for miles of Front Range trails hiked. The public discussion needs to examine the important link between urban density and regional agriculture and open space. The San Francisco Bay Area study Room Enough does .an excellent job of presenting the connection for that region. A similar study to look at density-open space trade-offs is needed for the Front Range. Citizen participation in open space preservation. has a potential for bringing together diverse interest groups to form a coalition of farmers, high tech industry (businesses that have located in Colorado for quality of environment reasons), conservation groups, and urban residents concerned for the future quality of life in the region. Early in the century, Denver's Mayor Speer planned for urban open space inthat city, creating an extensive systemof parks and parkways. The good mayor's foresight was not immediately apparent--it was the city's growth over the years that demonstrated the remarkably sound planning that had taken place decades earlier. The open ended question is--will the same thing happen with Colorado Front Range open space?

PAGE 91

APPENDIX

PAGE 92

86 PLEASE RETURN BY JUNE 8 TO SAM MAMET; COLORADO MUNICIPAL LEAGUE, 1500 Grant Street, Denver, CO 80203 UNICIPALITY -----------------------------HONE II ATE -----RATE'ON A SCALE OF 1-5 THE EFFECTIVENESS OF EACH TECHNIQUE THAT YOU .ARE CURRENTLY USING (1 being least effective, 5 highly effective) What strategies are currently used by your city to encourage preservation of strategic open space --such as open space separating cities and scenic views along major highways? City-County Agreements Delineating Urban and Rural Service Areas Transfer of Development Rights Purchase of Development Rights Condemnation for Open Space PUD Open Space Requirements Building Setbacks tb Protect Scenic Views Building Height Limitations to Protect Scenic Views Develqper Set-asides on New Development for Park, Recreation, and Open Space Land Banking -Including Public Purchase of Lands for Future Park. and Recreational Uses Limited Access Roadways Scenic Conservation Easements __ Agricultural Preservation Other Techniques: Effectiveness -------Effectiveness ----Effectiveness ------Effectiveness ------Effectiveness Effectiveness ------Effectiveness ------.Effect! veness ----Effectiveness ------Effectiveness -------Effectiveness ------Effectiveness ----Effectiveness ---------------------------------------------------------------

PAGE 93

87 . What strategies are currently used by your city to encourage cluster development (rather than leapfrog new development) and infill development (within an existing service area)? Residential Zoning for Moderate to High Densities Effectiveness ----Briefly describe: ____________________ Reduced Tap Fees Reduced Sewer Fees Waiver of Other Planning Related Fees. Relaxing of Standards/Requirements to Encourage Cluster or Infill Housing Mixed use Zoning to Encourage Housing Redevelopment Along Commercial Streets Second Units Housing Bonus Floor Area Ratios (FAR) or Other Density Incentives for lnfill Development Capital Improvements .Planning (streets, bridges, water, sewer) which encourage lnfill and Cluster Development City Government Advocacy Local Government Financing Programs for lnfill Housing Use of Federal Monies (such as CDBG and UDAG for_Infill Housing Annexation Effectiveness ------Effectiveness -------Effectiveness -------Effectiveness ------Effectiveness ----Effectiveness -----Effectiveness ------Effective-ness ----Effectiveness -------Effectiveness -----Effectiveness -----,Effectiveness ---Other Techniques: Estimate the average density of housing within the last 2 years, and planned/approved new residential development in your city. Less than 2.5 Dwelling Units per Gross Acre 2.5 5.0 Dwelling Units per Gross Acre 5.1 -7.5 Dwelling Units per Gross Acre 7.610.0 Dwelling Units per Gross Acre More than 10.0 Dwelling Units per Gross Acre

PAGE 94

88 Do you see a trend toward higher residential densities and smaller housing units in your city? Yes No ____ __ Do you see a trend toward higher residential densities and smaller housing units in your city? Yes No ----What would it take to significantly increase infill housing in your city?

PAGE 95

89 COLORADO FRONT RANGE CITIEs LARIMER Fort Longmont-: La layette 8 0 U L D E R LouiiViiiC WElD ;.MORGAN DAMS /Aurora "1 A p A H o E WASH .;fnglewaod "'Littleton .... ._ __ w--Parlt0r1 L eL PA80 I 1-------+---ONT p11eb\o CROY PUeiiiLO LOC

PAGE 96

90 COLORADO FRONT RANGE COUNTIES LA RIM C: R PARK I'Rf:MONT .. -... tf c:usrr:Rt't'. I..DCSAN WE 1.. 0 MORGAN ADAMS WASHINGTON ARAPAHOE ELiliERT LINCOLN EL PASO I f ; CROWLEY PUeBLO / OTERO I

PAGE 97

REFERENCES The City and County of Denver, Colorado. Official Housing Policy. Resolution No. 20. Denver: Author, l978. Colorado Department of Agriculture. Agricultural Land Conversion in Colorado, Volume I: Anlysis, and Volume II: Appendices. Denver: Author, 1980. Colorado Department of Local Affairs. County Population Projections to the Year 2010, by Age and Sex. March 1984. Colorado Division of Planning, Department of Local Affairs. Human Settlement Policies. Denver: Author, July 20, 1979. Colorado Office of the Governor. The Colorado Front Range Project Report to Front Range Conference II. Denver: Author, October 1981. Colorado Open Lands. Between Two Cities, Implementation Plan. Denver: Author, 1984. Denver Regional Council of Governments. Regional Data Series Population and Household Estimates 1980-1982. Denver: Author, July 1982. Ditmer, Joanne. "Denver High Density Zoning Blocks Close-In Housing. The Denver Post, April 25, 1984, pp. 1-D; 7-D. Douglas County, Colorado. Douglas County Master Plan. Castle Rock, Colorado: December 6, 1983. Ellis, Steve. Personal Interview with Colorado Department of Local Affairs Land Use Planner. April 1984. Freilich, Robert, and Wayne Senville. "Takings, TOR, and Environmental Preservation." Land Use Law, September 1983, pp. 4-8. Harris, Larry, and George Hepner. Open Space and Land Development. Kalamazoo, Michigan: Western Michigan University, 1983. Jacobs, Jane. "Cities and the Wealth of Nations." Atlantic Monthly, March 1984, pp. 41-66. Jefferson County, Colorado. 1983 Open Space Report. Golden, Colorado: Author, 1983. Keene, John, et al. Untaxing Open Space. Washington: Government Printing Office, 1976.

PAGE 98

92 Link, Tony. "Aurora Up Against Urban Sprawl." The Denver Post, July 22, 1984, pp. 1-E; 4-E. Lundstrom, Marjie. "Castle Rock: A Rural Town Suffering Pangs of Growth." The. Denver Post, March 4, 1984, pp. 1-A, 12-A, 13-A. Mamet, Sam. Personal Interview with Legislative Affairs Coordinator, Colorado Municipal League. March 1984. Minger, Terry. Personal Interview with Colorado Governor's Office Planning Consultant. April 1984. National Agricultural Lands Study. Executive Summary of NALS Final Report. Washington, D.C.: U.S. Government Printing Office, 1981. NALS Final Report. Washington, D.C.: U.S. Government Printing Office, 1981. Protecting Farm Land: A Guidebook for State and Local Governments. Washington, D.C.: U.S. Government Printing Office, 1981. Nyberg, Bartell. "Farmland Preservation Termed Vital to State." The Denver Post, February 15, 1984, p. 1-D. Parsons Brinckerhoff Consulting Firm. Existing Development and Future Growth Scenarios. Working Paper No. 2 I-25 Corridor Study DenverColorado Springs. Denver: Author, 1982. People for Open Space. Room Enough: Housing and Open Space in the Bay Area. San Francisco: Author, 1983. Real Estate Research Corporation. Costs of Sprawl. Washington: U.S. Government Printing Office, 1974. Roberts, Jeff. "Lakewood Wants to Limit High-Density Housing." The Denver Post, August 5, 1984, pp. 1-E, 4-E. Ruebhing, Jim. Personal Interview with Colorado Department of Agriculture Planner. Searles, Duane. "Clusters, Planned Unit Developments, Zero Lot Line Cost Effective, Harmonious." The Denver Post, July 22, 1984, p. 1-H. Smith, Herbert. The Citizens Guide to Planning. Chicago: Planners Press, 1979. Sternlieb, George, and James Hughes. "Less Space, Mor e Demand"" Planning, January 1984, pp. 4-20.

PAGE 99

93 Wilkinson, Bruce. "Public Land Trust at Work." The Denver Post, May 20, 1984, pp. 1-J; 24-J. Zeller, Marty. Personal Interview with Planning Consultant and Vice President of Colorado Open Lands. May 1984.