/* TEACH VEHICLES1 Duncan Fewkes Jeremy Wyatt Nov 2000 CONTENTS - (Use 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 NOT DONE V. WELL - ask jeremy about these sections. - description of functions of xved sidebar menu (ENTER menu) - note on ;;; comment header. - make the user try his own examples of lists, vars etc. ? more hands-on - intro to program ARGUMENTS is very bad! - sections on variables and lists are badly incorporated into the flow of the file. - section on data-types not incorporated v. well */ -- 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 key type: teach quickved press: the key When you have finished with that file you can QUIT it with the command Press: type: q press: to get back to this file. Such commands are often abbreviated as q or just 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. There will also be a small sidebar menu present on your screen (if not, this can be invoked by pressing then typing 'menu' and pressing ). This provides buttons to perform various actions and call up various HELP and TEACH files. -- 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 data, 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 XVED 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 this. -- 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 then D to compile it. uses brait This 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, warmer areas will cause the sensor to have a higher excitation, in turn causing the motor to turn faster and the vehicle to speed up. You can see this using the Pop-11 Braitenberg simulator. Compiling the line below will run a procedure that creates a simple virtual environment, places a few virtual heat sources at various locations within the environment and then creates a vehicle as described in picture1 above. Put the cursor on the line below and press then D to compile it. example1(); The red circles you can see are the heat sources - they give out heat such that anything that approaches one of them gets warmer and then 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 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 on 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 command, or by using a keyboard sequence, as follows. Compiling...menu button command Keyboard (and explanation) =========================================================== CompileRange lmr CTRL-d Load (compile) a marked range CompileFile l1 ------- Load (compile) the whole file CompileLine ltl 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. -- 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 Comments: ";;;" 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. -- 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. 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. or lmr, 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. "+", "+++**++", "|+|+|" 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 command-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. 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. -- -- 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 => ** 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. Each of these will be described 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. Each of these units have a unit number, from 1 to the number of units present. The sensors always occupy the first n units of the vehicle, where n is the number of sensors. The motors will always occupy the last two units of the vehicle. For example, if there was a vehicle with 3 sensors, they would be unit 1, unit 2 and unit 3 with the motors being unit 4 and unit 5. For now, however, we will only look at motors, sensors, and internal energy units. -- -- 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(); 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, indicating any stimuli that the vehicle is emitting. This 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( ) -> 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. 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 contains an internal energy unit. This unit gives a constant output level of 100, allowing the motors that are linked to it to turn of their own accord. The vehicle is also equipped with two proximity sensors on the front left and right corners and each is linked to the motor on the opposite side of the vehicle. However, 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' activations. Thus, the internal energy unit is feeding a constant voltage to the motors which is subtracted from by the sensors. The higher a sensor's activation, the more voltage it subtracts from the motor it is linked to. 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 -------------------------------------------------------- These experiments have hopefully shown you that it is very hard to examine an entities behaviour and correctly predict the internal mechanism that produced the behaviour. However, it is relatively easy to invent new mechanisms to perform a desired behaviour. Braitenberg called this "the law of uphill analysis and downhill invention" - in that it is harder to analyse a system than it is to invent one. Observations must be made very carefully as small differences in behaviour may be due to drastically different mechanisms. Also, analysing the behaviours of systems often leads us to believe that they are more complex than they actually are. However, whilst designing systems and mechanisms to perform certain tasks, we are often surprised by things that the mechanisms do that were not planned, and by behaviours that seemed simple but are in fact very complex and hard to implement. --- $poplocal/local/brait/teach/brait1 --- Copyright University of Birmingham 2000. All rights reserved. ------ */