To build: % ./configure % make Then try `./xbraitenberg --help'. Other things to try: % ./xbraitenberg l v2a v2a v2a v2a % ./xbraitenberg l v2a v2b v3a v3b The arguments here add objects to the world -- vehicles and lights. `v2a', `v2b', `v3a', and `v3b' are four different kinds of Braitenberg vehicles, based on Braitenberg's Vehicles 2A, 2B, 3A, and 3B. `l' is a stationary light located at (0,0). There is also `timel', a "timed light" (see TimedLight below) located at (0,0); and the pair of lights `l2a' and `l2b', two stationary lights located at (-250,0) and (250,0). You can use command line arguments to control the logic between sensors and actuators. `--left-logic LOGIC' sets the left actuator's logic, and `--right-logic LOGIC' sets the right actuator's logic. The LOGIC arguments are C-like expressions. They are evaluated continuously to see how fast the actuators should fire: 0 means stay still, positive numbers mean fire forward, and negative numbers mean fire in reverse. The greater the absolute value, the faster the actuators will fire; values are pinned between -1 and 1. You can use the following constructs in the LOGIC expressions. Most of them are just like C operators, and the precedence follows C's precedence. left The left sensor's value. right The right sensor's value. E1 + E2 Addition. E1 - E2 Subtraction. E1 * E2 Multiplication. E1 / E2 Division. E1 ** E2 Exponentiation. E1 < E2 1 if E1 < E2; zero otherwise. E1 > E2 Other logical operators are similar. E1 <= E2 E1 >= E2 E1 == E2 E1 != E2 E1 && E2 1 if E1 != 0 and E2 != 0; zero otherwise. E1 || E2 1 if E1 != 0 or E2 != 0; zero otherwise. !E1 1 if E1 == 0; zero otherwise. E1 ? E2 : E3 If E1 != 0, then E2; otherwise E3. let VAR = E1 in E2 end Introduce a variable binding. VAR = E Set variable's value. Also +=, -=, *=, /=, **=. You can set `left', `right', or variables introduced with `let'. E1, E2 Evaluate E1 for side effects. Return E2. pin(E) Returns value of E pinned to be between 0 and 1. Same as (E < 0 ? 0 : (E < 1 ? E : 1)). flip(E) Same as 1 - pin(E). The default vehicles have the following logic. VEHICLE MIDDLE LOGIC v1 middle (v1 has 1 sensor & 1 actuator.) VEHICLE LEFT LOGIC RIGHT LOGIC v2a left right v2b right left v3a 0.3 * flip(left) 0.3 * flip(right) v3b 0.3 * flip(right) 0.3 * flip(left) v2ap same as v2a, but sensors detect restricted angles v2bp same as v2b, but sensors detect restricted angles v3ap same as v3a, but sensors detect restricted angles v3bp same as v3b, but sensors detect restricted angles You can change the world in other ways, but it requires changing the source code -- specifically, main.cc. You can change how many stationary lights there are, the kinds of headlights the vehicles have, how many sensors the vehicles have, how strong the various lights are, and the angles that the sensors can see, among other things. Here are some examples. TO CHANGE: the stationary lights LOOK IN: function make_default_vehicles(), around line 557 STATEMENTS: shelf->add("l", new FixedLight(Point(0, 0), 8, 1)); shelf->add("timel", new TimedLight(Point(0, 0), -M_PI, M_PI, 8, 1, 320)); shelf->add("l2a", new FixedLight(Point(-250, 0), 10, 1)); shelf->add("l2b", new FixedLight(Point(250, 0), 10, 1)); COMMENTS: Add new lines to add new possible lights to the world. Then you can select those lights on the command line by giving their names. Arguments to `new FixedLight' are: (1) new FixedLight(POSITION, STRENGTH, 1) (2) new FixedLight(POSITION, ANGLE1, ANGLE2, STRENGTH, 1) The second form makes the light shine only through a specified angle range. You can also make a timed light, which will shine for only a short period of time: (3) new TimedLight(POSITION, ANGLE1, ANGLE2, STRENGTH, 1, DURATION) Examples: // a bright light shelf->add("brightl", new FixedLight(Point(0, 0), 16, 1)); // a partial light in the upper-right corner shelf->add("cornerl", new FixedLight(Point(250, 250), -M_PI, -M_PI/2, 8, 1)); TO CHANGE: the kinds of lights the vehicles have LOOK IN: function main(), around line 600 STATEMENTS: //Light *headlight = new ThresholdLight(0, -M_PI, M_PI, 6, 1, .08); Light *headlight = new Light(0, -2*M_PI/5, 2*M_PI/5, 8, 1); //Light *headlight = new Light(0, -M_PI, M_PI, 8, 1); COMMENTS: This statement defines the kind of headlight vehicles will have. Arguments to `new Light' are: (1) new Light(0, ANGLE1, ANGLE2, STRENGTH, 1) ANGLE1 and ANGLE2 are the angles through which the light shines. The angle zero is the direction the vehicle is heading. STRENGTH is the strength of the headlight. You can also make a threshold light, which only turns on when there is some light in the vicinity. Its arguments are: (2) new ThresholdLight(0, ANGLE1, ANGLE2, STRENGTH, 1, THRESHOLD) where THRESHOLD is the amount of light that must be in the vicinity before the headlight turns on. These lights are attached to a Vehicle with the Vehicle::make_attachment() method. TO CHANGE: the sensors the vehicles have LOOK IN: function make_default_vehicles(), around line 518 STATEMENTS: Sensor *l_sensor = new Sensor(Point(10, -6), -M_PI, M_PI, 1, "left"); Sensor *r_sensor = new Sensor(Point(10, 6), -M_PI, M_PI, 1, "right"); //Sensor *l_sensor = new Sensor(Point(10, -6), -3*M_PI/4, M_PI/2, 1, "left"); //Sensor *r_sensor = new Sensor(Point(10, 6), -M_PI/2, 3*M_PI/4, 1, "right"); //Sensor *l_sensor = new Sensor(Point(10, -6), -M_PI/2, M_PI/2, 1, "left"); //Sensor *r_sensor = new Sensor(Point(10, 6), -M_PI/2, M_PI/2, 1, "right"); COMMENTS: The arguments to `new Sensor' are: (1) new Sensor(LOCATION, ANGLE1, ANGLE2, 1, NAME) LOCATION is the sensor's location, relative to the center of the vehicle. ANGLE1 and ANGLE2 specify the angles the sensor is sensitive to. Please send comments and patches to .