
TEACH VEHICLES1                                 Duncan Fewkes
                                                Jeremy Wyatt    Nov 2000

?? Mention the primer
    http://www.cs.bham.ac.uk/research/poplog/primer/
    Also on sale in library (suitable for people with
    previous programming experience.)

?? don't use string quotes for words, use word quotes.

?? don't use strings in programs when words will do, e.g. location.
    left, etc.


         CONTENTS - (Use <ENTER> g to access required sections)

 -- INTRODUCTION
 -- WHAT YOU SHOULD ALREADY KNOW
 -- VED: A RECAP
 -- XVED: A RECAP
 -- Pop-11: A RECAP
 -- Pop-11 and XVED
 -- The Pop-11 Braitenberg vehicle simulator
 -- What is a Braitenberg vehicle?
 -- Running Pop-11 commands
 -- Pop-11 Comments: ";;;"
 -- Command-terminators in Pop-11
 -- -- A SINGLE SEMI-COLON: ";"
 -- -- The PRINT ARROW: "=>"
 -- Pop-11 VARIABLES
 -- -- Declaring variables
 -- -- Assigning values to variables: "->"
 -- -- Extracting values from variables
 -- -- Re-assigning values to variables
 -- Pop-11 Data-types
 -- -- Words
 -- -- Numbers
 -- -- Booleans
 -- -- Lists
 -- The Pop-11 Braitenberg vehicle simulator
 -- VEHICLES
 -- -- Motors
 -- -- Sensors
 -- -- Sensor-motor links
 -- -- -- Representing the sensor-motor links
 -- -- Types of unit
 -- -- EXAMPLE VEHICLE CREATION.
 -- SOURCES
 -- BOXES
 -- Running the simulator - The control panel
 -- FIRST EXPERIMENT
 -- -- VEHICLE 1
 -- -- VEHICLE 2
 -- SECOND EXPERIMENT
 -- -- VEHICLE 3
 -- -- YOUR ATTEMPT
 -- -- VEHICLE 4
 -- -- YOUR ATTEMPT
 -- CONCLUSIONS

/* NOTES TO ME

NB - MUST DESCRIBE DIFFERENT POP-11 DATA TYPES - PUT in brait1
    i.e.
    There are 23 data types in Pop-11, but we only need to use 5 basic
types. 3 of which you will already have encountered in everyday life.
      = words
        numbers- NB - Ints and Floats.
        lists
        boolean = two special words - true or false


NOT DONE YET -

NB - user must do an 'Enter l1'

NOT DONE V. WELL - ask jeremy about these sections.

NB - note on ;;;  comment header.

NB - make the user try his own examples of lists, vars etc. ? more
hands-on

NB - intro to program ARGUMENTS is very bad!

NB - sections on variables and lists are badly incorporated into the
flow of the file.

NB - section on data-types not incorporated v. well


ALWAYS REMEMBER -

NB - many different ways of explaining/doing things, TELL THEM THAT THIS
IS OUR WAY OF DOING IT. Remind them that there  are always other ways of
doing these things/ defining these things.

NB - always tell them what is coming up and what they have done
previously. */


/*


-- INTRODUCTION -------------------------------------------------------

This is the first in a series of teach files that aim to introduce you
to the basics of programming and artificial intelligence (AI). You will
explore the principles and problems of AI by writing programs to control
robot creatures called vehicles in a simulated world.

In this first tutorial, which should take you several hours, you will
learn a number of basic skills that will be useful later on. You will

 (a) Become more familiar with the VED/XVED text editor.

 (b) Write simple programs in an AI programming language called Pop-11.

 (c) Learn about Braitenberg vehicles and the Pop-11 Braitenberg vehicle
     simulator.

 (d) Create your own vehicles in a simulated or virtual world.

 (e) Design and carry out experiments with these vehicles in the virtual
     world.

 (f) Think about the different methodologies for understanding
intelligence.


-- WHAT YOU SHOULD ALREADY KNOW ---------------------------------------

This teach file assumes that you already know the basics of XVED:

(a) How to move around a VED file (See TEACH QUICKVED),
    using either the mouse pointer or keyboard "move" keys,

(b) How to mark a range of text in the file (TEACH MARK)

(c) How to use LMR to load (compile) a marked range (TEACH LMR)

If you haven't read these three TEACH files go back and read them now.
Although this file does give a self-contained introduction to Pop-11 you
may want more detail, or to go more slowly through the material. To
learn about the basics of Pop-11 in a more leisurely way go back and
read TEACH VEDPOP and then TEACH VEDPROC, and then come back to this
file. If you become lost at any point don't hesitate to ask someone for
help!!

The following three sections recap on the roles of VED, XVED and Pop-11.
You can skip these sections if you like.

-- VED: A RECAP -------------------------------------------------------

VED is a program for creating and altering files. For example, all the
teach files were created with VED. Files are like documents in a filing
cabinet, except that they are stored on a magnetic disc attached to the
computer. In roughly the same way that a filing cabinet has separate
drawers, so the disc is divided into areas called directories. One of
these is your own personal directory, into which VED will put any files
that you create. In this way, your files will not be confused with
anyone else's. (VED knows which directory to use because you gave your
"login" name when you logged in.)

The disc is the computer's long term memory. The computer also has a
short term memory which is used when programs are running. You are now
reading a file which has been copied from the long term memory to the
short term memory in order for you to look at it. When you create files
using VED you work in the short term memory. From time to time you will
need to ensure that your file is copied from the short term to the long
term memory, so that you can access it if you come back again after
logging out.

Among the things you need to learn is how to start editing a file, how
to finish and save it on the disc, how to move around the file you are
editing, how to insert text, how to delete text, how to copy or move
bits from one part of the file to another. VED has commands for all of
these actions, and many more. Some of the commands are done by pressing
a special key. Some require you to press a sequence of keys. Some are
done by giving a command on the command line. The TEACH QUICKVED file
that you started with introduced examples of all these commands. If you
have trouble remembering them, you should go back to that file as
follows:

    Press: the <ENTER> key
    type:  teach quickved
    press: the <RETURN> key

When you have finished with that file you can QUIT it with the command
    Press: <ENTER>
    type:   q
    press: <RETURN>

to get back to this file.

Such commands are often abbreviated as

    <ENTER> q <RETURN>

or just

    <ENTER> q

Sometimes the teach files omit the angle brackets, as in:

    ENTER q


-- XVED: A RECAP ------------------------------------------------------

XVED has identical functions to VED, but it has a major advantage - it
uses a system of windows. This makes it much easier to keep track of
separate files and to work with several files at the same time. The
windows can be moved and manipulated by clicking the mouse buttons on
the title bar at the top of the window. Holding down the left mouse
button allows you to move it, the middle mouse button pushes it 'behind'
or in front of other windows and the right mouse button MINIMISES it to
an icon at the bottom right of your screen - a small grey box with the
window title written inside it (the window can then be restored by
clicking on this icon).

In the very top left hand corner of each window, there is an icon that
looks like a circle inside a square. Clicking a mouse button on this
will also minimise the window.

In the very top right hand corner of each window are two small icons.
Pressing and holding the left mouse button on the icon on the right
(which looks like 3 squares inside one another) allows you to resize the
window. Pressing and holding the left mouse button on the left icon
brings up a menu of window functions available.

More importantly, there are several pull-down menus just underneath
each window's title bar - click on the words "File", "Edit", "View" or
"Compile" with the left mouse button to open them. These menus contain
some of the most important and useful commands available in the VED text
editor - including file save and load, text edit functions, file viewing
functions and compiling options.

[[Are the students set up with the Ved menu, as invoked by
    ENTER menu
?? If so it may be worth mentioning it.]]

-- Pop-11: A RECAP ----------------------------------------------------

Pop-11 is a powerful language for writing AI programs and other
sorts of programs. It enables you to get the computer to do many
things, including numerical calculations, manipulating lists of words
and other things, creating plans, interpreting sentences, analysing
images, and solving problems. Pop-11 must be told what to do using
specific commands and syntax (grammar) that it understands.

When you have learnt the language you can give commands directly to the
Pop-11 compiler. However it is most convenient to ask the editor to do
this for you. The editor saves your commands so that you can repeat them
or modify them and then repeat. The rest of this file teaches you how to
do that.

-- Pop-11 and XVED ----------------------------------------------------

The XVED text editor is capable of passing the text file you create to
the POP11 compiler, which then analyses the text and tells the computer
what to do.

We describe the action above as loading or compiling your Pop-11
instructions. The words "load" and "compile" are used interchangeably,
for historical reasons, though strictly "compile" is more accurate, or
"compile_and_run".

Throughout the rest of this file, you will be compiling pieces of text
that tell POP11 to do specific things. The commands you will be using
have been created and defined as part of the POP11 Braitenberg vehicle
simulator.


-- The Pop-11 Braitenberg vehicle simulator ---------------------------

The Pop-11 Braitenberg simulator consists of lots of predefined
procedures. For now, think of it as an extension to Pop-11's abilities.
It allows the creation of virtual robots - or more specifically,
Braitenberg vehicles, which will be introduced and described in the next
section. These can then be inserted into a simple, virtual environment
for testing.

You will be making use of the simulator and then creating simple
control programs for Braitenberg vehicles.


-- What is a Braitenberg vehicle? -------------------------------------

Valentino Braitenberg has been described as a cybernetician and
neuroanatomist. His book, 'Vehicles: Experiments in Synthetic
Psychology' may sound forbidding, yet it is very clear and accessible.
He aims to provide insight into how sensors, nerve fibres and motor
mechanisms are sufficient to produce interesting behaviours.

He explains his ideas through a series of imaginary experiments. He
designs a series of `vehicles' that move around in response to smell,
vision and other aspects of their environment.

Each vehicle has a body and a method of propulsion. It is easiest to
imagine them as little carts or buggies, propelling themselves along
using motors and wheels.

The very first vehicle Braitenberg introduces has only one motor and one
sensor. This sensor is connected to the motor in such a way that the
more there is of the stimulus that the sensor detects (be it
temperature, smell, light etc.) the faster the motor turns.

Put the cursor on the line below and press <ESC> then D to compile it.

    uses brait

That will get the editor to compile the "brait" library procedures.
One of those procedures is called picture1. You can ask the editor to
run that procedure in the same way as you compiled the "uses brait"
command:

    picture1();

This gives a picture of a simple Braitenberg vehicle with one heat
sensor, one motor-driven wheel, and a link between the sensor and the
motor.

It may be helpful to think of the sensor as having a certain
"excitation" or voltage according to the concentration/level of the
stimulus it detects. The connecting wire simply  carries this voltage to
the motor, which then turns and propels the vehicle.

Thus, the vehicle can move only in the direction it is pointing in. If
the sensor is a heat sensor, the vehicle will speed up in warm areas of
the environment (i.e. near a heat source), and slow down in cold areas.

Why will it speed up in a warm area?

You can cause a simulated vehicle of the sort shown in picture1 to be
run past a few simulated heat sources. The vehicle will move in a
straight line, varying its speed according to how close it is to the

Put the cursor on the line below and press <ESC> then D to compile it.

    example1();

The red circles you can see are sources of heat - they give out heat
such that anything that approaches one of them gets warmer and gets
cooler on moving away. If there are several heat sources, then a sensor
will be affected by all of them, and the effects will combine, but the
nearest ones will affect the sensor most strongly.

As you can see, the vehicle can only move in a straight line. The dots
are being printed at the location of the vehicle every set period of
time, thus showing its path and speed (the further apart the dots are,
the faster the vehicle was travelling).

To remove the window, put the cursor on the line below and press <ESC>
then D.

    rc_kill_window_object(brait_world);

or hold down the left mouse button on the small box in the top
right-hand corner of the window, select 'Close' and then release the
button. (WARNING: If you are using a DEC Alpha Workstation, the second
method may cause your Pop-11/Ved session to be terminated, owing to a
problem of compatibility with the Suns.)

Unlike this first example, the remaining vehicles you will be working
with all have two motors, one the left and one on the right, each
driving a wheel. There may be several sensors connected to the motors.

However, before we get started you will need to know a little bit about
Pop-11.


-- Running Pop-11 commands --------------------------------------------

In the section above, you have compiled several lines of text, the
results of which have shown you a very small sample of the possibilities
when using Pop-11.

When you compile a line of text, the XVED editor passes the text to the
Pop-11 compiler, which then analyses the text and carries out the
appropriate actions.

The lines that you compiled above called predefined procedures, which
give a list of actions for Pop-11 to carry out. For example, the Pop-11
instruction:
    picture1();
told Pop-11 to create a new window and then draw lines and text in it,
to create the picture that you saw.

For now we can think of procedures as lists of actions for the computer
to carry out, though later more complex sorts of procedures will be
used.

The commands available in VED to hand Pop-11 instructions to the
compiler are of different sorts. They can be concerned with the whole
file, with a procedure definition, with the marked range or with only a
single line of Pop-11. For each case you can give a command using either
one of the Buttons on the Compile menu, or by giving an <ENTER> command,
or by using a keyboard sequence, as follows.


    Compiling...menu button         <ENTER> command      Keyboard
    (and explanation)
    ===========================================================

    CompileRange                    <ENTER> lmr           CTRL-d
    Load (compile) a marked range

    CompileFile                     <ENTER> l1          -------
    Load (compile) the whole file

    CompileLine                     <ENTER> ltl           <ESC> d
    Load (compile) this line

For example, mark and compile the next three lines:

    repeat 10 times
        oneof([cat dog mouse elephant]) =>
    endrepeat;

That should print out in a Ved file called "output.p" a randomly chosen
word from the list of words, ten times.


-- Pop-11 Comments: ";;;"

NOTE - Whenever you see THREE semi-colons together, i.e. ;;;, this is a
Pop-11 COMMENT. It tells the Pop-11 compiler to ignore anything that
follows it on the same line, allowing you to put comments in your
programs that Pop-11 will ignore.

e.g.

;;; Pop-11 will ignore this text if this line is compiled.
;;; Pop-11 will also ignore any commands that follow the semi-colons.
;;; Also, if you are writing a comment and it gets very long and passes
onto the next line, you will need three semi-colons at the beginning of
EACH LINE to tell Pop-11 that they are still comments. Otherwise, trying
to compile them will result in errors.

In some of the teach files you will also see

    /* comments that look like this */

Though you will not need to use them for now.


-- Command-terminators in Pop-11 --------------------------------------

One important point to notice is that every Pop-11 command is always
followed by a TERMINATOR. These tell the Pop-11 compiler where each
command ends and a new one will begin (in the same way that a full-stop
"." indicates the end of a sentence). This is vitally important when
compiling a range of text containing several commands. Without
terminators, the Pop-11 compiler cannot function.

-- -- A SINGLE SEMI-COLON: ";"

A SINGLE semi-colon ";" (not to be confused with the colon ":") is the
most common terminator in Pop-11. Most of the commands you compile in
this file will end with a semi-colon ";".

Where there are complex commands, made of several simple commands, the
terminator may occur between the individual commands, as a "separator".
E.g. If you use ESC and d on the following line it will obey the three
commands.

    pr("Hello"); pr(space); pr(popusername);

This will cause the word "Hello" (without quotation marks) then a space,
then your login name to be printed in your "output.p" file.


-- -- The PRINT ARROW: "=>"

There are other Pop-11 command terminators, the print arrow "=>", for
instance, and the "pretty print" arrow introduced later "==>"

The print arrow not only terminates the command, but also takes any
output of the command and prints it in a separate XVED window called
"output.p". This window is exactly the same as all other XVED windows
(you can edit the text, compile commands and perform all other XVED
functions in it), only whenever a print command is given to Pop-11, the
text is printed in this window.

e.g. try compiling the following lines. It should bring up a window
titled "output.p"  (if you did not already have such a file open) and
print the various items in it.

    12 =>
    12 + 5 =>
    12 * 5 =>
    'hello there' =>
    [ a list containing five words] =>

;;; A single list expression can be extended over several lines.
;;; Mark and compile these two lines:
    [ [a list of lists] [a list of lists] [a list of lists]
      [a list of lists] [a list of lists] ] =>


-- Pop-11 VARIABLES ---------------------------------------------------

In everyday life, we use NAMES to pick out and IDENTIFY certain things.
A person will use the same name for their whole life, even though they
change in all manner of ways. Names are used to identify cities, even
though they are constantly changing.

You could think of variables in the same way - as a pointer to a
specific part of the computer's memory. Any piece of information may be
stored in that part of the memory - it could be a word, number, list,
procedure, or any other piece of Pop-11 data. The information can then
be accessed by the pointer, the variable. This makes recalling the
information, manipulating it and storing it again very easy.

Later you will learn that there are different types of variables, that
you can use in different ways. For now, we will use simple, GLOBAL
variables, so-called because they are accessible to all parts of Pop-11.

-- -- Declaring variables

Compile this line,

    vars test1;

This DECLARES the word "test1" as a variable name. This is important as
it tells Pop-11 that whenever it sees the word "test1", that this piece
of text refers to a variable.

[[Omit this:
It also becomes even more important when
you use the different types of variable, as the way in which they are
declared sets the variable type.]]

As a shortcut, Pop-11 allows multiple variables to be declared in one
command, e.g.

    vars test2, test3, test4, test5;

This declares four global variables.

Notice that the variable names are separated by commas and the whole
command is terminated with a semi-colon - ";".


-- -- Assigning values to variables: "->"

The assignment arrow "->" assigns the data item to its left to the value
of the variable to its right, e.g.,

    27 -> test1;

This assigns the number '27' to the variable "test1".

-- -- Extracting values from variables

Compile the line below to tell Pop-11 to print the current value of
"test1" in the output.p window,

    test1 =>

In general, whenever a variable name is used, Pop-11 will examine that
variable and use the value that has been assigned to it.
Try these examples of variable manipulation,

    test1 + 20 =>
    test1 + test1 =>
    test1 - (test1 * test1) =>

-- -- Re-assigning values to variables

The assignment arrow is also used to update or re-assign values to
variables. Try altering then compiling the text below to assign
different numbers to the variable 'test1', then printing them out with
the second command.

    98 -> test1;
    test1 =>

(You can get both commands obeyed at once if you mark both lines
and then do CTRL D, to compile the whole marked range.)

Commands can also access a variable and change its value all in one go,
e.g.

    test1 + 1 -> test1;
    test1 =>

    test1 * test1 -> test1;
    test1 =>


-- Pop-11 Data-types --------------------------------------------------

In computing terms, information is often referred to as "data". As in
real life, there are different types of information and ways of
presenting it. These are known as "data-types". Some of them are
"built in" to the language, and others can be added in programs provided
as library packages or user programs.

In Pop-11, there are about 30 different types of data, but we will only
need to know about the following:

    WORDS,
        e.g. "cat", "the_house", "x", "->", "list1", "vehicle99"

    NUMBERS (two types)
        integers (whole numbers),
            e.g. 0, 1, 10023, -1, -99
        floating point (decimal numbers)
            e.g. 1.0, 3.7256, -1.0, -99.0, 3.1415926

    BOOLEANS
        only two of them: true and false

    LISTS (including the empty list), e.g.
        []
        [a list of words]
        [ list of words 99 33 -45 66.9 and numbers]
        [[a list] [of lists] and words]

Occasionally other data types will prove useful, e.g. strings, which,
unlike words, can include spaces and arbitrary combinations of
characters, e.g.
    'this is an example of a &^%%$%&^%&^%& string'

These data-types are explained in more detail in the following sections.

-- -- Words

Pop-11 WORDS, like words of English are composed of characters (upper or
lower case) except that in Pop-11 some words can include mixtures of
letters and numerals, e.g. "list5", "vehicle22", "cat34B" or can include
the underscore symbol, e.g. "the_cat", "current_vehicle", or can be made
up of sign characters, e.g. "+", "+++**++", "|+|+|"

Moreover, although some words in Pop-11 are meaningful to the Pop-11
compiler, e.g. the built in words, such as "+", "=", "define", "if",
"endif", and any words that are declared to be names of variables, there
are other words that can just be used as symbols which the compiler does
not understand. E.g. Here is a list of meaningful English words

    [the cat sat on the mat]

For Pop-11 those words do not mean anything, unless you somehow tell it
to use them as meaningful.

In Pop-11, you can use a combination of alphabetic and numeric
characters to form a word, as long as it begins with an alphabetic
character. An example of this is "test1" in the section above.

Many words are used as variable names (as described above). But some are
"syntax words" telling Pop-11 what sort of instruction you are giving,
e.g. "vars", "repeat", or where an instruction ends (e.g. the
terminators ";", "=>")

Occasionally when you attempt to declare a variable you will get an
error message because it clashes with either a system variable or a
Pop-11 syntax word.

-- -- Numbers

The values assigned to the variable "test1" in the examples above were
all NUMBERS, which you should all be familiar with.

There are several different types of numbers in Pop-11, but you will
only need to know about two of them - INTEGERS and FLOATING POINT
numbers (sometimes referred to as an "int" or a "float", or in the
Pop-11 system as a "decimal" number). This is important as Pop-11
procedures may treat different types of numbers in different
ways; for example, arithmetical procedures will give their results in a
format according to the type of number used in the input.

Compare these:

    3 + 4 =>
produces an integer
    ** 7

    3 + 4.0 =>
produces a decimal, because one of the numbers was a decimal:
    ** 7.0


-- -- Booleans

There is a special data-type reserved for the objects TRUE and
FALSE. This is done because they represent two very important and
useful concepts. For example, if your program performs a searching
operation, it may return the answer "true" if it succeeds, or "false" if
it does not.

More generally programs that use conditional instructions, use true and
false results to decide which action to perform. For instance in this
instruction with two conditions:

    if condition1 then action1
    elseif condition2 then action2
    else complain
    endif

the programmer has to ensure that the bits of program that come before
"then", i.e. the conditions, produce a result that is true or false.


The WORDS "true" and "false" are reserved as pointer to the objects TRUE
and FALSE, so you are not allowed to declare or use these as variables,
but you may assign the value of "true" or "false" to another variable.
E.g. if "result" is a variable you can write:

    true -> result;

NB: don't confuse this with assigning the word "true", as in
    "true" -> result;

It may help to think of the objects TRUE and FALSE as values or
constants. Note how Pop-11 prints out the values:

    true =>
    ** <true>

    false =>
    ** <false>

-- -- Lists

In everyday life we often make lists of things that we need to remember,
shopping lists for instance. A Pop-11 list is very similar - they are
often used as ways for programs to store and keep track of important
information. However, Pop-11 lists have a very rigid layout,

a) They must be contained within square brackets - [].

b) They are in a set order, from left to right, with item at the
far left (just after "[") being the first element in the list and the
item at the far right (just before "]") being the last.

c) There are no commas to separate items in the list. Spaces are used
instead. (This rule is changed in the more extended list syntax using
"%" which you may meet later.)

Unlike some languages, Pop-11 allows lists to contain any objects,
including other lists, mixed up in any way, e.g. this contains a
word, three numbers and two lists:

    [word 1 2 3 [the cat] [4 5 6] ]

Compile and run these examples, using ESC D on each line:

    ;;; declare three variables

    vars list1, list2, list3;

    ;;; assign a list of numbers to the variable list1
    [1 2 3 4 5 6] -> list1;

    ;;; print out the value of the variable
    list1 =>

    ;;; assign a list of words to list2, and print its value
    [bill ben flowerpot men] -> list2;

    list2 =>

    [7 5 90210 liquorice pants] -> list3;
    list3 =>


Pop-11 also allow you to use LISTS OF LISTS, i.e. a list where items in
the list are themselves lists.

e.g.

;;; This list has two items - item 1 is the list [4 3 2 1], item 2 is
;;; the list [32 43]

    [ [4 3 2 1]  [32 43] ] -> list1;
    list1 =>


;;; This list has three items - item 1 is the list [dude 43 4], item 2
;;; is the number 99 and item 3 is the list [53 pink blue].

    [ [dude 43 4] 99 [53 pink blue] ] -> list2;
    list2 =>

Pop-11 has a procedure called "length" that returns the number of items
in a list:

    length(list1) =>
    length(list2) =>

If you try to put a previously created list, e.g. list1, in a new list
you cannot simply do this:

    [list1 is a list]

for that will put the WORD "list1" in the list. To get the value of the
variable "list1", you can precede it with the "caret" or "hat" symbol
"^" (often above the 6 on the keyboard).

Compare what these two instructions print out (after ensuring that list1
has been given a value as shown above).

    [list1 is a list] =>

    [^list1 is a list] =>


    ;;; So we can make a list containing two lists, the value of "list1"
    ;;; and the value of "list2" thus

    ;;; first check the values of list1, and list2
    list1 =>
    list2 =>

    ;;; now create a list containing both of those lists:
    [ ^list1 ^list2 ] -> list3;
    list3 =>

You can make a list that contains an existing list twice, e.g.

    vars list4;

    [ ^list3 ^list3 ] -> list4;

    list4 =>

The above command prints out the list in a messy fashion. When you have
a list of lists which is too long to print on one line, it may be best
to use the "pretty print arrow", namely "==>" instead of the simple
print arrow "=>", e.g.

    list4 ==>



-- The Pop-11 Braitenberg vehicle simulator ---------------------------

In his book, Braitenberg's vehicles were designed to be real robots in
the outside world. However, a computer simulator allows quick and easy
experimentation in a simplified, virtual world.

Therefore, each vehicle never runs out of power and the sensors work
perfectly. The environment is extremely simple; it is two-dimensional.
Gravity and friction have been ignored and obstacles do not block light
or other stimuli. The various objects that can be put into the simulator
do, however, block the movement of vehicles.

There are three types of objects that can be put into the simulated
environment: vehicles, sources and boxes. I will describe each of these
below,


-- VEHICLES -----------------------------------------------------------


Each vehicle has a number of 'units'. These can be sensors, motors,
internal switches, internal energy units or a 'hand' for picking up
objects. For now, we will only look at motors, sensors, and internal
energy units. At first our vehicles will have only motors and sensors.


-- -- Motors

Every vehicle you will use will have two motors, one on the left and one
on the right of its body.

The motors units can have an 'activation level' between 0 and 100. At 0,
they are not turning and at 100 they are running at full speed. Any
value x between 0 and 100 and they will run at x% of their full speed.

Next we need some sensors, to detect the state of the environment, and
some way of linking the sensors to the motors.


-- -- Sensors

Each sensor has three characteristics:

    its "type", which indicates what sort of thing it detects,
        e.g. "proximity", "sound", "light", etc.

    its "location" which is one of the words "left" or "right"

    its "sensitivity" which is a decimal number between 0 and 1,
        e.g. 0.2, 0.6

The three features of a sensor are indicated by creating a list, e.g.
    [proximity left 0.6]

To specify two or more sensors we can produce a list of lists, e.g.

    [ [proximity left 0.6] [proximity right 0.6] ]

This will give the vehicle two proximity sensors, the first on the
front-left and the second on the front-right of the vehicle. To see
this, compile the line below,

    picture2();

XXXX move this somewhere else
The sensors always occupy the first n units of the vehicle, where n is
the number of sensors, in this case, 2. Thus the left sensor will be
'unit 1' and the right sensor will be 'unit 2'.

A sensor's excitation level depends on the level of the stimulus that it
detects. This can be between 0 (no stimulus) and 100 (maximum strength
of stimulus).


-- -- Sensor-motor links


These are the imaginary pieces of wire that carry the sensor's
excitation level (voltage) to the motors and make them turn.

The links between the sensor units and motor units can be more complex
than you may have thought. Each link has a WEIGHT. This affects the
level of voltage that the sensor gives out. For instance, if a sensor is
linked to a motor, but the link's WEIGHT is 0.5, then only HALF of the
sensor's voltage will be passed to the motor. Other examples can be seen
below,


Sensor Excitation       Link WEIGHT     Excitation/Voltage    Percentage
                                         passed to motor      passed on
=============================================================================

    100                    0.75               75                   75%
    100                    0.6                60                   60%
    100                    1                  100                  100%
    80                     0.1                8                    10%
    100                    0                  0                    0%


NOTE - if the number is ZERO, there will be no transfer of voltage
between the two units - hence there is no link between them.

Also, these WEIGHTS can be NEGATIVE NUMBERS. Thus, the link will
SUBTRACT from the target unit's excitation level.

Sensor Excitation       Link WEIGHT        Effect on Excitation/Voltage
                                                        of motor
=============================================================================

    100                     -0.75                       -75
    90                      -1                          -90
    80                      -0.1                        -8
    50                      +1                          +50


Thus, we can now have systems where one link passes a voltage to a motor
and another link subtracts from the motors voltage.


-- -- -- Representing the sensor-motor links

The links between sensors and motors have to be represented in a way
that the computer can understand and that can be manipulated in a
program. For this reason, they are represented by a MATRIX of numbers as
shown below.

A matrix is like a list of numbers, except that instead of just going
left-to-right, it also goes top-to-bottom. e.g.
             Columns

            [ 0 0 1 0 ]
 Rows       [ 0 0 0 1 ]
            [ 0 0 0 0 ]
            [ 0 0 0 0 ]

Counting DOWN the side gives you the ROW number, and counting ALONG the
top gives you the COLUMN number.

Each number in the matrix represents a link and the weight on that link.
The value of the number is the weight for the link and it's position in
the matrix show which two units it links. Remember, if the number is a
zero, then there will be no link between the two units. The ROW number
represents the SOURCE unit of the link (which unit it is FROM) and the
COLUMN number represents the TARGET unit of the link (which unit it goes
TO).

e.g.

                 TO
            1  2  3  4  5

      1   [ 0  0  0  0  1 ]   A link from unit 1 to 5 - weight=1
      2   [ 0  0 0.7 0  0 ]   A link from unit 2 to 3 - weight=0.7
FROM  3   [ 0  0  0  0  0 ]
      4   [ 0  0  0  0  0 ]
      5   [ 0 0.6 0  1  0 ]   Links from unit 5 to units 2 AND 4
                                - weight of the link to unit 2 = 0.6
                                - weight of the link to unit 4 = 1

In our vehicles, the first m units in the vehicle are the sensors, the
order depending on their order when creating the vehicle, and the last
two units are the motors (left the right).
    e.g.

                TO

        [ 0  0  0  1  0 ]   A link from sensor 1 to the left motor
        [ 0  0  0  1  1 ]   A link from sensor 2 to both motors
FROM    [ 0  0  0  0  0 ]
        [ 0  0  0  0  0 ]
        [ 0  0  0  0  0 ]


To see the links that this example would create, compile the line below,

    picture3();


-- -- Types of unit

Later on, you will learn that you can have several different types of
unit. They can pass on voltage in several different ways. For now, all
of the units you will use will be very simple, basic units that pass on
their input voltage according to the weights on the links.

However, you will be shown one unit that acts as an internal power
source. This unit accepts no input and gives out a constant, set level
of voltage. It can thus be linked to the wheels to make them turn at a
steady pace.

Each unit's type is specified in a LIST, with one entry per unit in the
vehicle. e.g.

[[basic_unit]          - a basic unit
 [basic_unit]          - a basic unit
 [internal_energy]     - an internal energy source
 [basic_unit]          - a basic unit
 [basic_unit]]         - a basic unit


You will notice that this is actually a LIST OF LISTS - this allows each
entry to hold further information that becomes necessary when different
types of unit are used. However,  in this file you will not need to
alter these lists.


-- -- EXAMPLE VEHICLE CREATION.

In order to create a vehicle, we run the procedure create_vehicle.
It takes several arguments (inputs) to specify the vehicle. The basic
format for invoking the procedure requires the following inputs:

o two integers to specify the length and the width of the vehicle

o two integers to specify the initial location of the vehicle (the x and
  y coordinates)

o an integer to specify the initial heading of the vehicle

o a list of lists of numbers indicating the connections between
  sensors and motors (the matrix of links)

o a list of lists indicating the types of units in the vehicle

o a list of lists, indicating the sensors, their types, their
  locations and their weights. (The larger the weight the larger
  the effect of the sensor on the units to which it is connected)

o a list of lists, possibly empty which can be ignored for now as it
  will be the empty list [] in our examples.

The procedure create_vehicle creates a vehicle instance, draws a
picture of it on the current window, and returns the Pop-11 data
structure (the instance) which represents the vehicle. This result can
be assigned to a variable in case it needs to be accessed by a program.

So the format for a Pop-11 command to create a vehicle and assign it to
the variable vehicle1 is as follows (NB: don't try to run these):

    ;;; declare the variable, then create a vehicle and assign it
    vars vehicle1;
    create_vehicle( <various inputs> ) -> vehicle1;


Because the various inputs to the vehicle are quite complex, the
second command will usually be extended over several lines.

Now you can declare the variable: compile this:

vars vehicle1;

Now mark and compile the range below, to create a vehicle and assign it
to the variable, starting from create_vehicle up to the
single semi-colon that terminates the command:

create_vehicle(
    200 ,120,                   ;;; Length and width of vehicle body
    300, 300,                   ;;; initial x and y coordinates
    90,                         ;;; initial heading

                                ;;; Matrix of links -
    [[0 0 1 0]                  ;;; Unit 1 (sensor1) to left motor
     [0 0 0 1]                  ;;; Unit 2 (sensor2) to right motor
     [0 0 0 0]                  ;;;
     [0 0 0 0]],                ;;;

    [[basic_unit]               ;;; Unit types - all are basic units
     [basic_unit]               ;;;
     [basic_unit]               ;;;
     [basic_unit]],             ;;;

                                ;;; Sensors specifications with weights
    [[proximity left 0.6]       ;;; sensor1: proximity detector on left
     [proximity right 0.6] ],   ;;; sensor2: proximity detector on right

    []) -> vehicle1;


Remember that all of the above is ONE COMMAND. It starts with
"create_vehicle( "  and ends with the semi-colon in  ")-> vehicle1;".
This is called split line compilation. The Pop-11 compiler will treat
everything as one command until it finds the separator at the end ";".

Where it finds three semicolons ";;;" it ignores them and everything
to the right of them. These are "end of line comments"

The command carried out was of the form:
    "create_vehicle( information ) -> vehicle1;".

The items of information included in brackets when running Pop-11
procedures are often called the ARGUMENTS for a procedure.

The object created when compiling the above is assigned to the variable
"vehicle1". Thus, we can use this variable to manipulate the vehicle,
e.g. try repeatedly compiling the following lines,

    randomise_position(vehicle1, 2000);
    randomise_position(vehicle1, 500);

The number restricts the distance of the vehicle from the bottom left
corner of the window. Think of the window as representing a
simulated 2-D field of size 1000 units by 1000 units.


-- SOURCES ------------------------------------------------------------

The sources are simple objects that exist as a point location and emit
stimuli. These stimuli have strengths between 0 (no stimulus present)
and 100 (maximum strength). The type, strength and method in which the
stimuli strength decays as you move away from the source can be
specified for each source object. The source objects also act as
obstacles.

-- BOXES --------------------------------------------------------------

The box objects are simply obstacles for vehicles, and can be used to
section off areas of the environment. They do not influence the way
stimuli are spread in the environment, i.e. they do not block light or
any other stimulus, so a sensor on one side of a wall will be able to
detect a source on the other side.


-- Running the simulator - The control panel --------------------------

The simulator may be controlled in two different ways - either by
compiling commands from XVED windows or through the control panel. For
now, we will use the control panel and the mouse.

Compile the line below to bring up the control panel,

    control_panel();

A window titled 'Control Panel' should appear in the top right-hand
corner of your screen. You should be able to see a total of eleven
buttons, separated into four different sections.

1) The first section contains four buttons. Two are used for starting
and stopping the simulator. Click on them with the left mouse button.

You can also click on the Slow Down and Speed Up buttons, to change the
speed of motion.

At the moment there is only one vehicle in the environment, and it won't
do much on its own, as its sensors are not stimulated, and therefore no
signals go to its motors! If you click on start you'll see it moving
nowhere!

2) The second section also contains two buttons. These are used for
adding new objects into the environment. Click the left mouse button on
the 'New Source' button. You will see a new source object (a blue
circle) appear near the bottom left- hand corner of the graphical
window. You can use the mouse to drag it to a new location. Put the
mouse cursor over the circle, then press and hold button 1 (left
button), and drag the circle somewhere close in front of the vehicle.
Release the mouse button to let go of the circle (stop dragging).

With the source object near the front of the vehicle, click on the start
button to make the vehicle start moving. You will see it move towards
the source, then turn away, then stop.

    After that try dragging the source object around whilst the
    simulator is running. See how the vehicle reacts! Try stopping the
    simulator, using the Stop button, then moving the source or the
    vehicle and then starting the simulator again.

Any source or vehicle object can be moved around like this, when the
simulator is running or even if it isn't.

The second button in the 'Add Objects' section adds a new Box object.
When you click on this button, the simulator pauses (if it was running)
and it waits for you to click in the graphical window. Pressing
the left mouse button specifies the location of a corner of the box,
which is then 'dragged out' as you move the mouse. Pressing the left
mouse button again will move the corner to the current cursor position,
and pressing the right mouse button (button 3) that will complete
construction of the box, and insert it into the environment, after which
you can no longer move it. If the simulator had been running when you
clicked on New Box, it will restart after you click using the right
mouse button.

    Try putting a large box around the vehicle, five or six times its
    length, to see what it does. It should repeatedly move towards one
    of the walls then turn as it approaches the wall. If it gets stuck,
    use the left mouse button to drag it to a new location in the box.

3) The third section of the control panel gives various options for
drawing the way the vehicle is moving. 'Blob Trace' puts a small blob at
the location of the vehicle at definite time intervals (showing speed of
the vehicle, much like a 'ticker tape'  you may have used in Physics
lessons back at school). 'Line Trace' draws a neat, continuous line and
'Path trace OFF' removes either of these facilities

4) The fourth and final section of the control panel allows you to
redraw the graphical window (if it has got messy with path traces), kill
the graphical window (although this WILL ALSO KILL any objects that are
currently in the window), create a new (empty) window or dismiss the
control panel itself.


In this next section, we will begin to perform some simple experiments,
to familiarise you with calling and using the Pop-11 Braitenberg
simulator. The experiments will also teach you a little about
Braitenberg vehicles and the difficulties in AI experimentation.


-- FIRST EXPERIMENT ---------------------------------------------------

In this experiment, you will be shown two vehicles and you should
attempt to determine how they will behave.


-- -- VEHICLE 1

This vehicle is equipped with two proximity sensors on the front left
and right corners of its body. The sensor on the left is linked to the
motor on the left and the sensor on the right is linked to the motor on
the right.

    showvehicle1();

The links have positive weights, so the more a sensor is stimulated (by
proximity to an object) the faster it will make the motor turn.

    Can you guess what this vehicle will do?

Mark the lines below and compile them to see how good your guess was.
Whilst the simulator is running, try moving the source object with
button 1 on the mouse. Try pausing the simulator with button 3, moving
the source and then unpausing.


  create_window(500,500);

  create_vehicle(
      200 , 120,
      500, 700, 10,

      [[0 0 1 0]                      ;;; sensor 1 -link to left motor
       [0 0 0 1]                      ;;; sensor 2 -link to right motor
       [0 0 0 0]
       [0 0 0 0]],

      [[basic_unit]                   ;;; Unit types - all are basic units
          [basic_unit]
          [basic_unit]
          [basic_unit]],

      [[proximity left 0.6]           ;;; sensor 1, front-left of vehicle
       [proximity right 0.6] ],       ;;; sensor 2, front-right of vehicle

      [] ) -> vehicle1;

    create_simple_source( 300, 400, sound ) -> source;

    control_panel();


When you ran the simulator, you should have noticed that the vehicle
turned and moved away from the source object and came to rest a certain
distance from it. When the source was moved closer, the vehicle again
turned and moved away from it.

It does this because, as a proximity sensor detects an obstacle, it
makes the motor on the SAME side as it SPEED UP. Thus, the motor on the
side that the obstacle is on will be turning faster than the other motor
and the vehicle will turn away from the obstacle.

The vehicle only moves when the source is within a certain distance
because the proximity sensors have a limited range.


-- -- VEHICLE 2

This vehicle is also equipped with two proximity sensors on the front
left and right corners. However, each is linked to the motor on the
opposite side of the vehicle. The links themselves are different - they
have negative weights, meaning that the higher the sensors excitation,
the more voltage they will subtract from the motors. This requires that
the vehicle's motors should turn of their own accord. To this end, it is
possible to link them to an internal energy source, which simply gives
the motors a constant voltage. This is then subtracted from by the
inhibitory links.

    showvehicle2();

    Can you guess what this vehicle will do?

Mark the lines below and compile them to see how good your guess was.
Whilst the simulator is running, try moving the source object with
button 1 on the mouse. Try pausing the simulator with button 3, moving
the source and then unpausing.


    create_window(500,500);

  create_vehicle(
    200 , 120,
    600, 600, 10,

    [[0 0 0 0 -0.1]                 ;;; sensor 1 -link to right motor
     [0 0 0 -0.1 0]                 ;;; sensor 2 -link to left motor
     [0 0 0 0.05 0.05]              ;;; internal energy source
     [0 0 0 0 0]
     [0 0 0 0 0]],

    [[basic_unit]                   ;;; Unit types
     [basic_unit]
     [internal_energy]              ;;; internal energy source
     [basic_unit]
     [basic_unit]],

    [[proximity left 0.6]         ;;; sensor 1
     [proximity right 0.6] ],     ;;; sensor 2

  [])->vehicle2;

    create_simple_source( 300, 400, sound) -> source;

    control_panel();


If you start the simulator, you should find that the vehicle
slowly moves in a straight line until it comes within a certain range of
the source. It then turns away and trundles off at the same speed. When
you move the source close to the vehicle, it comes to a halt. As you
move the source further away, the vehicle turns away from it and
trundles off again.

It drives around at the same speed because the internal energy is
constantly feeding the motors a certain voltage. The vehicle turns away
from the source because, as a proximity sensor detects an obstacle, it
makes the motor on the OPPOSITE side SLOW DOWN. Thus, the motor on the
side that the obstacle is on will be turning faster than the other motor
and the vehicle will turn away from the obstacle.

The vehicle comes to a halt when an obstacle is close because both
sensors are giving high inhibitory signals to the motors, negating all
of the voltage that the internal energy source is feeding them,
resulting in no activation of either motor.

By moving the source around you should be able to distinguish the
following main cases:

1. The source is far away: the vehicle drives in a straight line.

2. The source is close enough to one sensor to cause it to inhibit
   the motor on the opposite side, but not close enough to affect
   the other motor so much. The motor on the opposite side is
   slowed down, so the vehicle turns away from the source.

3. The source is symmetrically placed in front of or behind the vehicle,
   but not sufficiently close to completely suppress both motors. Both
   motors are slowed down. But what happens next depends on whether
   the source is behind or in front of the vehicle.

4. The source is very close. Then both motors are inhibited so much that
   they stop, no matter what the direction of the source is in relation
   to the vehicle.


-- SECOND EXPERIMENT --------------------------------------------------

In the first experiment you attempted to infer behaviour from a
mechanism, i.e. you were shown the structure of the vehicle and you
tried to guess how it would behave.

Now we will try it the other way around - run these experiments, observe
the behaviours of the vehicles and try to guess the mechanism.

HINT - all you will need to do is alter the matrix of links in the
'template' code given to try out your vehicles.


-- -- VEHICLE 3

Compile the lines below and run the simulator. Use the mouse to move the
source around and see what the vehicle does!

    create_window(500,500);
    create_vehicle3()->vehicle3;
    create_simple_source( 300, 400, sound) -> source;
    control_panel();

Now comes the hard bit. Try to guess what the links were inside the
vehicle. Alter the link matrix in the vehicle definition below, then
compile and run it to see if you were right! Don't worry about changing
anything else in the vehicle just yet.


-- -- YOUR ATTEMPT

    create_window(500,500);

  create_vehicle(
    200 , 120,
    600, 600, 45,

;;; MATRIX OF LINKS - replace a zero with a number to make a link

   [[0 0 0 0]                       ;;; Links from Sensor 1
    [0 0 0 0]                       ;;; Links from Sensor 2
    [0 0 0 0]
    [0 0 0 0]],

   [[basic_unit]                    ;;; Unit types
    [basic_unit]
    [basic_unit]
    [basic_unit]],

    [[proximity 'left' 0.6]         ;;; Sensor 1 -Front-left of vehicle
     [proximity 'right' 0.6] ],     ;;; Sensor 2 -Front-right of vehicle

  [])->vehicle3;


    create_simple_source( 300, 400, sound) -> source;
    control_panel();


Did it work? If not, try again - remember, each row in the matrix above
must have four numbers in it.

When you are ready to see the answer, compile the line below.

    answer_to_vehicle3();

-- -- VEHICLE 4

Let's try another one. Compile the lines below and examine what happens
when you slowly move the source around.


    create_window(500,500);
    create_vehicle4()->vehicle4;
    create_simple_source( 300, 400, sound) -> source;
    control_panel();


Now it's your turn. Fill in the matrix below, then compile and run your
vehicle. HINT - Look back at Vehicle 2.


-- -- YOUR ATTEMPT

    create_window(500,500);

  create_vehicle(
    200 , 120,
    600, 600, 45,

;;;MATRIX OF LINKS - replace a zero with a number to make a link

   [[0 0 0 0 0]                     ;;; Links: from Sensor 1
    [0 0 0 0 0]                     ;;; from Sensor 2
    [0 0 0 0 0]                     ;;; from unit 3-internal energy
    [0 0 0 0 0]
    [0 0 0 0 0]],

   [[basic_unit]                    ;;; Unit types
    [basic_unit]
    [internal_energy]               ;;; Internal energy source = Unit 3
    [basic_unit]
    [basic_unit]],

   [[proximity 'left' 0.5]          ;;; Sensor 1 -Front-left of vehicle
    [proximity 'right' 0.5] ],      ;;; Sensor 2 -Front-right of vehicle

  [])->vehicle4;


    create_simple_source( 300, 400, sound) -> source;
    control_panel();


Did it work? If not, try again - remember, each row in the matrix above
must have five numbers in it.

When you are ready to see the answer, compile the line below.

    answer_to_vehicle4();


-- CONCLUSIONS --------------------------------------------------------

    Braitenberg's law of uphill analysis and downhill invention.

    (Surprises (things the vehicles do that were not planned) and things
that should be easy but are in fact hard?)

    EMPHASISE IMPORTANCE OF MAKING OBSERVATIONS CAREFULLY.
    -small differences in behaviour may be due to drastically different
    mechanisms


*/

--- $poplocal/local/brait/teach/brait1
--- Copyright University of Birmingham 2000. All rights reserved. ------
