Tuesday, September 20, 2011

Three Laws of Robotics

Whenever a person thinks of robots, they tend to think somewhere along the lines of C-3PO or R2-D2 - digitally charged beings programmed so superbly that they are nothing short of autonomous.  Now imagine, if you will, that R2-D2 had spent the majority of the Star Wars franchise sitting in place and twirling its dome-like noggin around in circles.  Han, Luke and Leia would have met an early death at the hands of Jabba the Hutt but R2-D2 would have performed exactly what I programmed my robots to do in Robocode.  Continuing down the line of not-so-obscure science fiction references, it is nearly blasphemous to talk about robots without talking about the Three Laws of Robotics as established by the late Isaac Asimov.  The laws state:

1. A robot may not injure a human being or, through inaction, allow a human being to come to harm.
2. A robot must obey any orders given to it by human beings, except where such orders would conflict with the First Law.
3. A robot must protect its own existence as long as such protection does not conflict with the First or Second Law.

Given my limited exposure to the joys of Robocode I was saddened to find that, while my robots all certainly cannot injure a human being and obey my poorly devised orders to the letter, they were all ill equipped to protect their own existence.  In my defense I, too, was given instructions on the functions that I was to write into my robots and, to their credit, all the robots I wrote performed valiantly on the field of battle with what they were given.

To get my feet wet, so to speak, I started off with a building a robot that did absolutely nothing.  This poor robot, when pitted against just about any other robot, was essentially defenseless.  I do make it a point to say just about any other robot because it drew every match it had against the sample SittingDuck robot which came packaged with Robocode to a dramatic stalemate.  However, as one might expect, making a robot that does absolutely nothing is not very interesting and soon, with the aide of a few built in movement methods, I was creating robots that could leisurely move across the playing field provided its opponents, too, were all pacifists who fired no bullets.  But even robots moving across the field back and forth quickly grew tiresome and it became all too obvious that more advanced techniques would be required to get them to perform more interesting movements.

Problems for me quickly arose when I attempted to create a robot that moved itself to the center of the playing field.  Firstly I realized that, due to the nature of how headings are organized from a range of 0 to 360, I had to warp my way of thinking and the trick to turning the robot efficiently would be to be very methodical and view destination headings as being relative to the robot's current headings.  To turn efficiently also meant that the choice to turn left or right was important and had to be based upon the robot's initial heading.  After tinkering around with the numbers a bit, I was finally able to get a robot to properly turn and move towards the center vertically and then horizontally.

Alas, I was not satisfied.  When walking to the middle of an open field, I would never first walk vertically along the field, turn 90 degrees, and proceed horizontally towards the middle.  Barring any obstacles, I would almost certainly walk diagonally across and I could think of no reason why my robot should not be allowed the same choice.  Thus, through trigonometry, I was able to devise an algorithm for which my robots were able to locate the center of the field, decide to turn left or right to be efficient and move straight to the center in a straight line.

Having mastered exhibited this skill a single time now, I forged ahead in my quest to learn Robocode and attempted to get my robots to not only acknowledge the existence of other enemies but to react to their existence as well.  Surprisingly, following another robot proved not to be as absurdly difficult as one might have imagined since Robocode actually offers several helpful methods for tracking enemies.  Since it is possible to keep a robot's radar facing in the same heading as the robot itself, following other robots was just a matter of turning my robot according to where the enemy is.  However, when it came time to finally work with the guns, a lot of unforeseen trouble headed my way.

Initially, working with guns seemed fairly straightforward: turn the gun in a direction which automatically activates the robot's radar and every time an enemy is scanned, fire away.  But when trying to track an enemy, I found that my previous algorithm for following an enemy did not translate very well.  This was due to the fact that, upon scanning an enemy, the bearings returned to my robot was relative to my robot's current heading, and not my robot's gun's current heading.  Thus working with bearings, which ranges from -180 to 180 and having to translate its relation from the robot's heading to its gun's heading turned out to be a spatial nightmare for me.  Ultimately, the solution I found was to translate the bearings into the same 0 to 360 range that headings worked in and after struggling with the problem for hours, I was able to get my robot to track another robot fairly well.  Albeit, at times, the tracking would still lose its target and the robot would be forced to spin its gun to relocate the enemy.

Although I was able to complete 13 simple robot implementations and develop a minor grudge against Robocode and mathematics in general, I realized that some of the instructions specified picking an enemy and although they did not necessarily always say to stick with the chosen enemy, the implication was there and had somehow gone over my head.  Thus, it is difficult to say that all 13 of my robots are living up to their specifications, but at least they are not injuring human beings.

No comments:

Post a Comment