Index: trunk/code/projects/colonet/client/RobotList.java
===================================================================
--- trunk/code/projects/colonet/client/RobotList.java	(revision 775)
+++ trunk/code/projects/colonet/client/RobotList.java	(revision 776)
@@ -15,7 +15,7 @@
   * For a given Point, finds the robot that conatins this Point
   * graphically. The coordinate system is based on the dimensions
   * of the image returned by the webcam loader, not the coordinates
-  * of the panel containing the image on in the applet. Returns null
+  * of the panel containing the image in the applet. Returns null
   * if no robot contains the Point, or if the Point is null. If
   * multiple robots overlap the point, one will be chosen arbitrarily.
   */
@@ -30,17 +30,5 @@
 		}
 		return null;
   }  
-  
-  /**
-  * Removes the destination coordinate for a specified robot. As
-  * a result, no destination vector is painted for the robot on 
-  * the webcam image. This method does not cause any command
-  * to be sent to the robot.
-  */
-  public void cancelMoveTo (int id) {
-    RobotIcon r = get(id);
-    if (r != null)
-      r.destx = r.desty = -1;
-  }
 
 }
Index: trunk/code/projects/colonet/client/Colonet.java
===================================================================
--- trunk/code/projects/colonet/client/Colonet.java	(revision 775)
+++ trunk/code/projects/colonet/client/Colonet.java	(revision 776)
@@ -492,7 +492,7 @@
 
 		RobotIcon r = robotIcons.get(botNum);
 		if (r != null) {
-		    r.battery = batteryIcon.convert(level);  // set contextual battery meter
+		    r.setBattery(batteryIcon.convert(level));  // set contextual battery meter
 		    batteryIcon.setLevel(level);             // set solo battery meter
 		}
 		super.repaint();
@@ -514,12 +514,11 @@
 			// Save previous robot information
 			RobotIcon oldIcon = robotIcons.get(id);
 			if (oldIcon != null) {
-			    newIcon.battery = oldIcon.battery;
-				newIcon.destx = oldIcon.destx;
-				newIcon.desty = oldIcon.desty;
+		    newIcon.setBattery(oldIcon.getBattery());
+				newIcon.setDestination(oldIcon.getDestination());
 			}
-			if (newIcon.id >= 0) {
-				newIcon.color = Color.GREEN;
+			if (newIcon.getID() >= 0) {
+				newIcon.setColor(Color.GREEN);
 			}
 			newList.put(id, newIcon);
 		}
@@ -534,7 +533,7 @@
     System.out.println("Got move update: " + line);
     String [] str = line.split(" ");
     int id = Integer.parseInt(str[1]);
-    robotIcons.cancelMoveTo(id);
+    robotIcons.get(id).clearDestination();
   }
 	
 	/**
@@ -620,10 +619,9 @@
 				
 				RobotIcon r = robotIcons.get(selectedBot);
 				if (r != null) {
-					r.destx = pt.x;
-					r.desty = pt.y;
+					r.setDestination(pt);
 					if (csi != null) {
-						csi.sendAbsoluteMove(r.id, r.destx, r.desty);
+						csi.sendAbsoluteMove(r.getID(), pt.x, pt.y);
 					}
 				}
 				return;
@@ -633,8 +631,14 @@
 			if ((e.getButton() == MouseEvent.BUTTON2 || e.getButton() == MouseEvent.BUTTON3)  
           && e.getID() == MouseEvent.MOUSE_PRESSED
           && station != null && station.contains(e.getX(), e.getY())) {
-        if (selectedBot >= 0)
+        if (selectedBot >= 0) {
+          RobotIcon r = robotIcons.get(selectedBot);
+          if (r != null) {
+            Point p = panelWebcam.convertPoint(station.getX(), station.getY());
+            r.setDestination(p);
+          }
           csi.sendRecharge(selectedBot);
+        }
 				return;
 			}
 
@@ -648,13 +652,11 @@
 				if (selectedBot < 0) {
 					return;
 				}
-
 				RobotIcon r = robotIcons.get(selectedBot);
 				if (r != null) {
-					r.destx = pt.x;
-					r.desty = pt.y;
+					r.setDestination(pt);
 					if (csi != null) {
-						csi.sendAbsoluteMove(r.id, r.destx, r.desty);
+						csi.sendAbsoluteMove(r.getID(), pt.x, pt.y);
 					}
 				}
 				return;
@@ -670,8 +672,8 @@
 				panelWebcam.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
 				for (Map.Entry<Integer,RobotIcon> entry : robotIcons.entrySet()) {
 					RobotIcon r = entry.getValue();
-					r.destx = pt.x;
-					r.desty = pt.y;
+					r.setDestination(pt);
+          //TODO: send absolute move commands
 				}
 				return;
 			}
@@ -711,7 +713,7 @@
 			// Otherwise, we are selecting a bot, or doing nothing
 			RobotIcon r = robotIcons.getBoundingIcon(pt);
       if (r != null)
-        selectedBot = r.id;
+        selectedBot = r.getID();
 		}
 	}
 
@@ -793,23 +795,23 @@
 			} else if (source == btnF) { // Robot Movement Controls
 				vectorController.setMaxForward();
 				vectorController.sendToServer();
-				robotIcons.cancelMoveTo(selectedBot);
+				robotIcons.get(selectedBot).clearDestination();
 			} else if (source == btnB) {
 				vectorController.setMaxReverse();
 				vectorController.sendToServer();
-				robotIcons.cancelMoveTo(selectedBot);
+				robotIcons.get(selectedBot).clearDestination();
 			} else if (source == btnL) {
 				vectorController.setMaxLeft();
 				vectorController.sendToServer();
-				robotIcons.cancelMoveTo(selectedBot);
+				robotIcons.get(selectedBot).clearDestination();
 			} else if (source == btnR) {
 				vectorController.setMaxRight();
 				vectorController.sendToServer();
-				robotIcons.cancelMoveTo(selectedBot);
+				robotIcons.get(selectedBot).clearDestination();
 			} else if (source == btnActivate) {
 				vectorController.setZero();
 				vectorController.sendToServer();
-				robotIcons.cancelMoveTo(selectedBot);
+				robotIcons.get(selectedBot).clearDestination();
       } else if (source == btnSetBounds) {
         boundary.set = true;
         panelWebcam.setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
@@ -842,10 +844,13 @@
 			  else
           csi.sendRecharge(2);
 			} else if (source == btnCommand_StopCharging) {
-			  if (selectedBot >= 0)
+			  if (selectedBot >= 0) {
+			    robotIcons.get(selectedBot).clearDestination();
 			    csi.sendRechargeStop(selectedBot);
-			  else
+			  } else {
+			    robotIcons.get(2).clearDestination();
           csi.sendRechargeStop(2);
+        }
 			} else if (source == btnAddTask) { // Queue Management
 				taskAddWindow.prompt();
 			} else if (source == btnRemoveTask) {
@@ -896,7 +901,7 @@
 						if (count % 30 == 0) {
 							for (Map.Entry<Integer,RobotIcon> entry : robotIcons.entrySet()) {
 								RobotIcon r = entry.getValue();
-									int id = r.id;
+									int id = r.getID();
 										if (id >= 0) {
 										csi.sendBatteryRequest(id);
 									}
@@ -999,23 +1004,23 @@
 				bufferedGraphics.setStroke(new BasicStroke(2));
 				for (Map.Entry<Integer,RobotIcon> entry : robotIcons.entrySet()) {
 					RobotIcon r = entry.getValue();
-					bufferedGraphics.setColor(r.color);
+					bufferedGraphics.setColor(r.getColor());
 					// Identifier circle
-					int px = (int) (x + r.x * scale);
-					int py = (int) (y + r.y * scale);
+					int px = (int) (x + r.getLocation().x * scale);
+					int py = (int) (y + r.getLocation().y * scale);
 					int radius = ColonetConstants.ROBOT_RADIUS;
 					bufferedGraphics.drawOval(px-radius, py-radius, 2*radius, 2*radius);
 					// ID, if applicable
-					if (r.id > 0) {
+					if (r.getID() > 0) {
 					    bufferedGraphics.setFont(new Font("arial", Font.PLAIN, 36));
-					    bufferedGraphics.drawString("" + r.id, px-10, py+10);
+					    bufferedGraphics.drawString("" + r.getID(), px-10, py+10);
 					}
 					// Battery
-					if (r.battery >= 0) {
-					    int pixels = r.battery * ColonetConstants.BATTERY_WIDTH / 100;
-						if (r.battery > 50)
+					if (r.getBattery() >= 0) {
+					    int pixels = r.getBattery() * ColonetConstants.BATTERY_WIDTH / 100;
+						if (r.getBattery() > 50)
 						    bufferedGraphics.setColor(Color.GREEN);
-						else if (r.battery > 25)
+						else if (r.getBattery() > 25)
 						    bufferedGraphics.setColor(Color.YELLOW);
 						else
 						    bufferedGraphics.setColor(Color.RED);
@@ -1024,8 +1029,8 @@
 						bufferedGraphics.drawRect(px+20, py+20, ColonetConstants.BATTERY_WIDTH, ColonetConstants.BATTERY_HEIGHT);
 					}
 					// If the robot has a destination, draw the vector
-					if (r.destx >= 0) {
-						bufferedGraphics.drawLine(px, py, (int)(x + r.destx * scale), (int)(y + r.desty * scale));
+					if (r.hasDestination()) {
+						bufferedGraphics.drawLine(px, py, (int)(x + r.getDestination().x * scale), (int)(y + r.getDestination().y * scale));
 					}
 				}
 			}
@@ -1033,8 +1038,8 @@
 			// Identify currently-selected robot
 			RobotIcon r = robotIcons.get(selectedBot);
 			if (r != null) {
-				int px = (int) (x + r.x * scale);
-				int py = (int) (y + r.y * scale);
+				int px = (int) (x + r.getLocation().x * scale);
+				int py = (int) (y + r.getLocation().y * scale);
 				int radius = ColonetConstants.ROBOT_RADIUS;
 				bufferedGraphics.setColor(Color.BLACK);
 				bufferedGraphics.drawOval(px-radius-6, py-radius-6, 2*radius+12, 2*radius+12);
@@ -1052,11 +1057,19 @@
 			if (img == null) {
 				return new Point(e.getX(), e.getY());
 			}
+			return convertPoint(e.getX(), e.getY());
+		}
+		
+		/**
+		* Convert a point on the webcam panel to a coordinate that is consistent with the
+		* original size of the image that the panel contains.
+		*/
+		public Point convertPoint (int panelx, int panely) {
 
 			// Calculate scaling
 			int border = ColonetConstants.WEBCAM_BORDER;
-			int clickx = e.getX();
-			int clicky = e.getY();
+			int clickx = panelx;
+			int clicky = panely;
 			int maxWidth = getWidth() - 2*border;
 			int maxHeight = getHeight() - 2*border;
 			double widthRatio = 1.0 * maxWidth / img.getWidth();
Index: trunk/code/projects/colonet/client/VectorController.java
===================================================================
--- trunk/code/projects/colonet/client/VectorController.java	(revision 775)
+++ trunk/code/projects/colonet/client/VectorController.java	(revision 776)
@@ -42,6 +42,7 @@
 
 	/**  Set the robot motion vector. The "vector" is defined as 
 	* (0,0)->(x,y) where (0,0) is in the center of the targeting ring.
+	* Does nothing if the specified point is outside the ring.
 	* @param x The x coordinate of the point.
 	* @param y The y coordinate of the point.
 	*/
Index: trunk/code/projects/colonet/client/Makefile
===================================================================
--- trunk/code/projects/colonet/client/Makefile	(revision 775)
+++ trunk/code/projects/colonet/client/Makefile	(revision 776)
@@ -49,6 +49,7 @@
 
 clean:
 	$(RM) -r $(DIR)
+	$(RM) *~
 
 run:
 	appletviewer http://128.2.99.176/colonet
Index: trunk/code/projects/colonet/client/RobotIcon.java
===================================================================
--- trunk/code/projects/colonet/client/RobotIcon.java	(revision 775)
+++ trunk/code/projects/colonet/client/RobotIcon.java	(revision 776)
@@ -1,13 +1,5 @@
 
-import javax.swing.*;
-import javax.swing.event.*;
-import javax.imageio.*;
 import java.awt.*;
-import java.awt.image.*;
-import java.awt.event.*;
-import java.net.*;
-import java.io.*;
-import java.util.*;
 
 /**
 *	 RobotIcon class
@@ -14,45 +6,165 @@
 *	 Provides a means for graphically representing and keeping track of webcam bots.
 */
 public class RobotIcon {
+	private int id;  // the XBee ID of the robot
+	private Color color;  // the color used for painting the robot on screen.
+	private Point location;  // the position of the robot in the coordinate system of the webcam image
+	private Point destination;  // the destination of the robot, if homing or charging
+	private int battery;  // the battery level, if available
 
-	public int x, y;
-	public int destx, desty;
-	public int id;
-	public Color color;
-	public int battery;
-
 	public RobotIcon (int id, int x, int y) {
-		this.color = Color.RED;
-		this.x = x;
-		this.y = y;
-		this.id = id;
-		this.destx = -1;
-		this.desty = -1;
-		this.battery = -1;
+		setID(id);
+		setColor(Color.RED);
+		setLocation(x, y);
+		clearDestination();
+		setBattery(-1);
 	}
+	
+	/**
+	*  Returns the ID of this RobotIcon.
+	*/
+	public int getID () {
+	  return id;
+	}
+	
+	/** 
+	*  Sets the ID of this RobotIcon.
+	*/
+	public void setID (int newid) {
+	  this.id = newid;
+	}
+	
+	/**
+	*  Returns the Color used for representing this RobotIcon on screen.
+	*/
+	public Color getColor () {
+	  return color;
+	}
+	
+	/** 
+	*  Sets the Color used for representing this RobotIcon on screen.
+	*/
+	public void setColor (Color newcolor) {
+	  this.color = newcolor;
+	}
+	
+	/**
+	*  Returns the battery level of this RobotIcon.
+	*  TODO: what numbering system is this?
+	*/ 
+	public int getBattery () {
+	  return battery;
+	}
+	
+	/**
+	*  Sets the battery level of this RobotIcon.
+	*  TODO: what numbering system is this?
+	*/
+	public void setBattery (int newbattery) {
+	  this.battery = newbattery;
+	}
+	
+	/**
+	*  Returns the location of this RobotIcon as a Point. The location is specified 
+	*  in the coordinate system of the original webcam image, NOT the coordinate
+	*  system of the scaled image as seen on screen.
+	*/
+	public Point getLocation () {
+	  return location;
+	}
 
 	/**
-	*	 Relocates this RobotIcon to a new coordinate point.
-	*
+	*	 Sets the location of this RobotIcon. The location should be specified in the
+	*  coordinate system of the original webcam image, NOT the coordinate system of
+	*  the scaled image as seen on screen.
 	*/
-	public void move (int newX, int newY) {
-		this.x = newX;
-		this.y = newY;
+	public void setLocation (int x, int y) {
+		location.setLocation(x, y);
 	}
+	
+  /**
+	*	 Sets the location of this RobotIcon. The location should be specified in the
+	*  coordinate system of the original webcam image, NOT the coordinate system of
+	*  the scaled image as seen on screen.
+	*/
+	public void setLocation (Point p) {
+    location.setLocation(p);
+	}
+	
+	/**
+	*  Returns the destination of this RobotIcon as a Point. The location is specified 
+	*  in the coordinate system of the original webcam image, NOT the coordinate
+	*  system of the scaled image as seen on screen. If the RobotIcon has no current
+	*  destination, then this method returns null.
+	*/
+	public Point getDestination () {
+	  if (!hasDestination())
+	    return null;
+	  return destination;
+	}
+	
+	/**
+	*  Determines whether this RobotIcon currently has a destination, e.g., for homing
+	*  to a specific point in the environment or finding a charging bay.
+	*/
+	public boolean hasDestination () {
+	  return (destination.x >= 0 && destination.y >= 0);
+	}
+	
+	/**
+	*	 Sets the destination of this RobotIcon for the purposes of homing to a specific
+	*  point in the environment of finding a charging bay. The destination point should
+	*  be specified in the coordinate system of the original webcam image, NOT the 
+	*  coordinate system of the scaled image as seen on screen.
+	*/
+	public void setDestination (int x, int y) {
+		destination.setLocation(x, y);
+	}
+	
+	/**
+	*	 Sets the destination of this RobotIcon for the purposes of homing to a specific
+	*  point in the environment of finding a charging bay. The destination point should
+	*  be specified in the coordinate system of the original webcam image, NOT the 
+	*  coordinate system of the scaled image as seen on screen.
+	*/
+	public void setDestination (Point p) {
+		destination.setLocation(p);
+	}
+	
+	/**
+	*  Clears the destination Point for this RobotIcon, indicating that the robot is
+	*  no longer homing.
+	*/
+	public void clearDestination () {
+	  setDestination(-1, -1);
+	}
 
 	/**
 	*	 Determines whether a given point is within the rectangle that circumscribes the
-	*	 robot's circlular icon. Used for clicking on robots in webcam view.
-	*
+	*	 robot's circlular icon. Used for click detection on robots in webcam view. The
+	*  parameter point should be specified in the coordinate system of the original
+	*  webcam image, NOT the coordinate system of the scaled image as seen on screen.
 	*/
 	public boolean contains (int px, int py) {
-	int radius = ColonetConstants.ROBOT_RADIUS;
-		Rectangle rect = new Rectangle(x-radius, y-radius, 2*radius, 2*radius);
-		return rect.contains(px, py);
+		return this.getBoundingRectangle().contains(px, py);
 	}
+	
+	/**
+	*  Returns the Rectangle object that circumscribes the RobotIcon identifier circle
+	*  that is painted on screen. The Rectangle is in the coordinate system of the 
+	*  original webcam image NOT the coordinate system of the scaled image as seen 
+	*  on screen.
+	*/
+	public Rectangle getBoundingRectangle () {
+	  int radius = ColonetConstants.ROBOT_RADIUS;
+	  return new Rectangle(location.x-radius, location.y-radius, 2*radius, 2*radius);
+	}
 
+  /**
+  *  Provides a text representation of this RobotIcon object
+  */
 	public String toString () {
-		String s = "RobotIcon at (" + x + "," + y + "), id " + id;
+		String s = "RobotIcon at (" + location.x + "," + location.y + "), id " + id;
 		return s;
 	}
 }
