As mentioned in the introduction, the first test we'll be putting the simulator to is building Keanu-level intelligence. In particular, you should write a function
int computeRotationalVelocity()that maps the sonar values (the input) to a rotational velocity (the output), so that the robot (whose speed is fixed) survives as long as possible without hitting the walls or obstacles in various environments. The return value of computeRotationalVelocity is an integer, because that is the type expected by the velocity-setting call, vm. (A prototype function is provided in the test file, /cs/cs154/as/A/survivor.cc .
You may use the current rotational and translational velocities of the robot in your computeRotationalVelocity function -- they are accessible as State[39] and State[38], respectively.
In the write up, below, explain your approach and include the text of your code either in the HTML or as a link from it. Also, include the results of your algorithm run at a variety of different speeds on the above two worlds and at least one world of your own devising.
int
computeRotationalVelocity()
{
int oldrv = State[39];
double rv = 0.0;
/* Here we determine how imminent a collision is */
/* by finding the closest sonar reading among the front */
/* three sonars, 15, 0, and 1 */
int frontShortestI = getShortestSonarIndex(-2,2);
int frontShortest = State[frontShortestI];
/********************************************************/
/* */
/* The shortest sonar is compared to a threshhold that */
/* depends on the translational velocity of the robot */
/* In this case, it is read in from a file so that we */
/* could tune the parameter more easily. */
/* */
/* the value for trans. velocities 50 and 100 is 40 */
/* the value for trans. velocities 150 and 200 is 70 */
/* */
/********************************************************/
if (frontShortest < FORWARD_THRESH)
{
/* find side that pulls harder */
int leftSidePushI = getShortestSonarIndex(1,4);
int rightSidePushI = getShortestSonarIndex(-4,-1);
if (State[leftSidePushI] > State[rightSidePushI])
{
rv = (oldrv < -10) ? -MAX_SPEED : MAX_SPEED;
}
else
{
rv = (oldrv > 10) ? MAX_SPEED : -MAX_SPEED;
}
/********************************************************/
/* */
/* MAX_SPEED is another global parameter that depends */
/* on the trans. velocity. It indicates the angular */
/* speed commanded when the robot needs to turn. */
/* */
/* its value for trans. velocities 50 and 100 is 300 */
/* its value for trans. velocities 150 and 200 is 450 */
/* */
/********************************************************/
/********************************************************/
/* */
/* Note that the new rotational velocity depends on the */
/* old velocity. This is so that when heading into a */
/* corner, for example, the balanced readings on either */
/* side of the robot do not keep it headed in a */
/* line. */
/* */
/* You can see an example of this happening in world 2, */
/* at speed 150 and world 1, at speed 100, below. */
/* */
/********************************************************/
}
else
{
rv = 0;
}
return (int)rv;
}
I place the blame for the performance of the robot in the
last few examples squarely on the shoulders of the simulator.
Given my carefully constructed (and beautifully working) code
(see world 2, speed 50), there seems to be no explanation
for the other results. I suspect that another lab group
was connecting to my simulator (through port #7042) and so
the results of the lower runs actually indicate the performance
of their algorithm. Similarly, the results they present should
actually be credited to me.