CS 395 Behavior-Based Robotics Group Assignment 2: Sonar-based wandering

Out: Wednesday, October 16
Due: Monday, October 28, 2:00pm

Part 1: Freespace following

Your job is to implement and test a sonar-based freespace follower.  There are two ways to get readings from the sonars.  The simplest way is to simply ask for the latest range reading that's come in from each sonar.  These readings are stored in the signal sonar-readings, which is a vector of 16 integers, one per sonar.  Readings from individual sonars can be obtained using the vector-ref primitive:

`(vector-ref sonar-readings sonar-number)`

will return the last received distance reading on sonar-number.  In GRL, primitive procedures are automatically mapped over the elements of vectors, so that (log sonar-readings) gives you a vector of the logarithms of all the sonar readings, and (< sonar-readings 1500) gives you a vector of Booleans telling you which sonar readings are less than 1500.  You may also find the following useful:

(vector-max vector)
(vector-min vector)
Returns the largest/smallest value in vector.

(vector-arg-max vector)
(vector-arg-min vector)
Returns the index of the largest/smallest value in vector.

(vector-reduce operator start vector)
Returns the value: start operator e0 operator e1 operator e2 ... operator en, where e0 is the first element of the vector, e1 the second, etc, and en is the last.  Thus, ```(vector-reduce + 0 v)``` gives the sum of the elements of `v`.

(vector-region vector  start-index  length)
(vector-region-circular vector  start-index length)
Returns a new vector consisting of the length elements from vector starting at position start-index.  If the -circular form is used, then the region is allowed to wrap around the end of the vector, i.e. (vector-region sonar-readings 15 3), would return a vector consisting of elements 15, 0, and 1 from sonar-readings, in order.

The problem with using just range readings is that a given sonar is only read once a second or so, so the range readings are really telling you how far the closest obstacle was at some point in the past, in this case, up to 1 second ago.  A more sophisticated approach is to use the `egocentric-ping-positions` vector, gives you a vector (of type `xy-vector`) to the object most recently imaged by each of the sonars.  So if you say:

`(vector-ref egocentric-ping-positions 3)`

you get back a vector giving the estimated distance forward (x component of the vector) and to the left (y component), relative to the robot's current coordinates, of whatever was sonar 3 the time it was fired.

Design

You should encapsulate your freespace follower as a behavior (or as several behaviors).  You should try to optimize you system for the following properties, in decreasing order of importance:

1.   Safety
Ideally, your robot should never collide with any obstacles.  Because of the limitations of sonar sensors, perfection is probably not attainable.  However, you should try to make your system and safe as possible.
2.   Smoothness
Avoid sudden starts, stops, and turns, which can prematurely age the motors, gears, and batteries.
3.   Speed
You also want the robot to move as fast as possible, although you should not sacrifice safety to do so, nor should you generate jerky motor commands.

Part 2: Unwedging

It is very likely that your system will get caught in local minima.  To prevent this, you should either:

• Design a freespace follower with no local minima (this can be  difficult)
•  Implement an unwedging behavior that detects local minima and directs the robot away from the local minimum.  In this case, you would combine the two behaviors using the compound-behavior operator from class to make a single behavior that is fed to the motors.
• Implement the Balch avoid-recent behavior.  A simple way to do this would be to write a transducer that remembers some small number of recent positions and generates a vector away from them.  You would then need to combine the output of avoid-recent with the output of your wanderer using vector-summation.
• Think of something else cleaver to do.  If you choose this route, talk to Ian first.

You should also encapsulate your unwedger as a behavior.

Demoing

The assignment is due Friday October 25 at 2:00pm.  We will have pre-assigned demo slots for each group.  Each group will get four minutes to load your code and four minutes to demo.  You should also prepare a brief (1-3 minute) explanation of how your system works, which one of you should give during the demo.

You will load your code while the previous team is demoing.  If you are not ready to demo at the appointed time, your team will be skipped and your assignment will be counted as late.  You should therefore make sure you have your code loaded properly before we begin the demos and you should avoid making any last minute "improvements".

Grading

You will be graded based on the number of Bad Things that happen during your demo.  Bad Things are:

•  Collisions (-3 points)

•  Sudden jerks in the robot's behavior (-1 point)

•  Getting caught in a local minimum for more than five seconds (-1 point)

• Anything else that seems potentially dangerous to Ian and/or Aaron

In addition, we will allow the class to award 0-5 points each for subjective speed, subjective smoothness, and cool factor.  Finally, Ian and Aaron will assign 0-10 points based on overall quality of both the robot's behavior and of your code.  We will then curve all of this and announce the results in class the following Thursday.