Index: AiboPup/Makefile
diff -c AiboPup/Makefile:1.14 AiboPup/Makefile:1.15
*** AiboPup/Makefile:1.14	Fri Jun 13 01:35:41 2003
--- AiboPup/Makefile	Mon Jul  7 14:08:12 2003
***************
*** 5,12 ****
  TinyFTPD_COMP=TinyFTPD
  SoundPlay_COMP=SoundPlay Shared/Config.o Shared/ProcessID.o Events/EventRouter.o Events/EventTranslator.o Events/EventBase.o Shared/LoadSave.o Shared/get_time.o
  TARGETS=all clean
! PREFIX=/usr/local/OPEN_R_SDK
! LD=$(PREFIX)/bin/mipsel-linux-ld
  
  # list of components for all processes
  # NOT SORTED, process directories need to be made first (generated stub header files)
--- 5,12 ----
  TinyFTPD_COMP=TinyFTPD
  SoundPlay_COMP=SoundPlay Shared/Config.o Shared/ProcessID.o Events/EventRouter.o Events/EventTranslator.o Events/EventBase.o Shared/LoadSave.o Shared/get_time.o
  TARGETS=all clean
! OPENRSDK_ROOT?=/usr/local/OPEN_R_SDK
! LD=$(OPENRSDK_ROOT)/bin/mipsel-linux-ld
  
  # list of components for all processes
  # NOT SORTED, process directories need to be made first (generated stub header files)
Index: AiboPup/Behaviors/Controller.cc
diff -c AiboPup/Behaviors/Controller.cc:1.18 AiboPup/Behaviors/Controller.cc:1.20
*** AiboPup/Behaviors/Controller.cc:1.18	Thu Jun 12 14:06:07 2003
--- AiboPup/Behaviors/Controller.cc	Sun Jul  6 21:00:07 2003
***************
*** 9,14 ****
--- 9,15 ----
  #include "Events/TextMsgEvent.h"
  #include "Shared/ERS210Info.h"
  #include "Shared/ERS220Info.h"
+ #include <sstream>
  
  Controller * Controller::theOneController=NULL;
  
***************
*** 155,160 ****
--- 156,181 ----
  	return *this;
  }
  
+ void Controller::loadGUI(const std::string& type, const std::string& name, unsigned int port, const std::vector<std::string>& args) {
+ 	std::stringstream ss;
+ 	ss << "load\n" << type << '\n' << name << '\n' << port << '\n';
+ 	for(unsigned int i=0; i<args.size(); i++) {
+ 		ss << '"';
+ 		for(unsigned int j=0; j<args[i].size(); j++) {
+ 			if(args[i][j]=='\\' || args[i][j]=='"' || args[i][j]=='\n')
+ 				ss << '\\';
+ 			ss << args[i][j];
+ 		}
+ 		ss << "\" ";
+ 	}
+ 	ss << '\n';
+ 	theOneController->gui_comm->write((const byte*)ss.str().c_str(),ss.str().size());
+ }
+ 
+ void Controller::closeGUI(const std::string& name) {
+ 	theOneController->gui_comm->printf("close\n%s\n",name.c_str());
+ }
+ 
  int Controller::gui_comm_callback(char *buf, int bytes) {
  	std::string s(buf,bytes);
  	//	cout << "Controller Received: " << s << endl;
***************
*** 347,354 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.2 $
   * $State: Exp $
!  * $Date: 2003/07/09 02:34:49 $
   */
--- 368,375 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.2 $
   * $State: Exp $
!  * $Date: 2003/07/09 02:34:49 $
   */
Index: AiboPup/Behaviors/Controller.h
diff -c AiboPup/Behaviors/Controller.h:1.14 AiboPup/Behaviors/Controller.h:1.16
*** AiboPup/Behaviors/Controller.h:1.14	Thu Jun 12 23:23:05 2003
--- AiboPup/Behaviors/Controller.h	Tue Jul  8 14:01:21 2003
***************
*** 42,61 ****
   *    <i>text:item-title<sub>numitems</sub></i>\n
   *    <i>text:item-description<sub>numitems</sub></i>' - refreshes the current menu\n
   *  - '<tt>status </tt><i>text</i>' - sets the status bar to <i>text</i> (until the next refresh)
   *
!  *  The upstream is the responsibility of the Controls, but the
!  *  protocol is listed here to keep it together.  When a control's
   *  state changes, it's that control's responsiblity to refresh the UI
   *  (LEDs, console, and GUI as appropriate).  Thus, future extensions
   *  to the upstream protocol are between the control which will use it
   *  and the GUI.  Future extensions to the downstream protocol would
   *  involve changing Controller and the GUI.
   *
!  *  One additional upstream command for the 1.4 release is planned:
!  *  - '<tt>load </tt><i>text:objectname</i> <i>int:port</i> [<i>arg1</i> [<i>arg2</i> [...]]]' - which will tell the GUI to load the java class named <i>objectname</i>, and have it connect to <i>port</i>, passing it the argument list.
!  *
!  *  This should allow pop-up windows with custom displays.  Also,
!  *  the Controller may connect to serr in the future to pop-up an alert
   *  anytime output to serr occurs.
   *
   *  Note that all state is maintained on the robot - even if the GUI
--- 42,73 ----
   *    <i>text:item-title<sub>numitems</sub></i>\n
   *    <i>text:item-description<sub>numitems</sub></i>' - refreshes the current menu\n
   *  - '<tt>status </tt><i>text</i>' - sets the status bar to <i>text</i> (until the next refresh)
+  *  - '<tt>load</tt>\n
+  *    <i>text:classname</i>\n
+  *    <i>text:instancename</i>
+  *    <i>int:port</i>\n
+  *    [<i>arg1</i> [<i>arg2</i> [...]]]' - tells the GUI to load the java class named <i>classname</i>, and have it connect to <i>port</i>, passing it the argument list.
+  *    <i>classname</i> should contain a constructor of the form <tt>Classname(String </tt><i>host</i>, <tt>int </tt><i>port</i>, <tt>String </tt><i>args</i><tt>[])</tt>
+  *    the argument list is parsed as if it were on the console - unescaped or unquoted spaces will separate args into elements in the array
+  *  - '<tt>close</tt>\n
+  *    <i>text:instancename</i>' - calls <tt>close()</tt> on an object previously created by a <tt>load</tt> message.
+  *    The Java object is expected to contain a function <tt>void close()</tt>.
+  *  
+  *  bool types are expected to be numerical values, 0 for false,
+  *  non-zero for true.
   *
!  *  <tt>load</tt> and <tt>close</tt> are intended to allow pop-up
!  *  windows for custom displays.
!  *
!  *  The upstream is the responsibility of the individual Controls, but
!  *  the protocol is listed here to keep it together.  When a control's
   *  state changes, it's that control's responsiblity to refresh the UI
   *  (LEDs, console, and GUI as appropriate).  Thus, future extensions
   *  to the upstream protocol are between the control which will use it
   *  and the GUI.  Future extensions to the downstream protocol would
   *  involve changing Controller and the GUI.
   *
!  *  The Controller may connect to serr in the future to pop-up an alert
   *  anytime output to serr occurs.
   *
   *  Note that all state is maintained on the robot - even if the GUI
***************
*** 103,108 ****
--- 115,126 ----
  	
  	virtual std::string getName() const { return "Controller"; }
  	static std::string getClassDescription() { return "Provides interface for activating/deactivating controls (and through them, behaviors)"; }
+ 	
+ 
+ 
+ 	static void loadGUI(const std::string& type, const std::string& name, unsigned int port) {loadGUI(type,name,port,std::vector<std::string>());} //!< attempts to open a Java object on the desktop
+ 	static void loadGUI(const std::string& type, const std::string& name, unsigned int port, const std::vector<std::string>& args); //!< attempts to open a Java object on the desktop
+ 	static void closeGUI(const std::string& name); //!< calls close() on a Java object loaded with loadGUI() (on the desktop)
  
  	static int gui_comm_callback(char *buf, int bytes); //!< called by wireless when there's new data from the GUI
  	static int console_callback(char *buf, int bytes);  //!< called by wireless when someone has entered new data on the tekkotsu console (NOT cin)
***************
*** 179,188 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.2 $
   * $State: Exp $
!  * $Date: 2003/07/09 02:34:49 $
   */
  
  #endif
--- 197,206 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.2 $
   * $State: Exp $
!  * $Date: 2003/07/09 02:34:49 $
   */
  
  #endif
Index: AiboPup/Behaviors/Controls/HelpControl.cc
diff -c AiboPup/Behaviors/Controls/HelpControl.cc:1.1 AiboPup/Behaviors/Controls/HelpControl.cc:1.3
*** AiboPup/Behaviors/Controls/HelpControl.cc:1.1	Fri Jun 13 02:05:40 2003
--- AiboPup/Behaviors/Controls/HelpControl.cc	Tue Jul  8 20:10:57 2003
***************
*** 30,43 ****
  		return;
  	const std::vector<ControlBase*>& slots=r->getSlots();
  	const std::string pre="  "+prefix;
! 	int len=slots.size()==0?0:(int)(log(slots.size()-1)/log(10));
  	for(unsigned int i=0; i<slots.size(); i++) {
  		if(slots[i]==NULL)
  			continue;
  		char * fmt;
  		std::string nm=slots[i]->getName();
  		std::string desc=slots[i]->getDescription();
! 		unsigned int len=term_width-(prefix.size()+nm.size()+2);
  		if((int)len<0)
  			len=0;
  		if(len>desc.size())
--- 30,45 ----
  		return;
  	const std::vector<ControlBase*>& slots=r->getSlots();
  	const std::string pre="  "+prefix;
! 	unsigned int numlen=1;
! 	if(slots.size()>1)
! 		numlen=(int)(log(slots.size()-1)/log(10))+1;
  	for(unsigned int i=0; i<slots.size(); i++) {
  		if(slots[i]==NULL)
  			continue;
  		char * fmt;
  		std::string nm=slots[i]->getName();
  		std::string desc=slots[i]->getDescription();
! 		unsigned int len=term_width-(prefix.size()+nm.size()+4+numlen);
  		if((int)len<0)
  			len=0;
  		if(len>desc.size())
***************
*** 45,54 ****
  		else
  			while(len>0 && !isspace(desc[len-1])) len--;
  		if(config->main.use_VT100)
! 			fmt="\33[1m%s%*d%s\33[0m: %s\n";
  		else
! 			fmt="%s%*d.%s: %s\n";
! 		sout->printf(fmt,prefix.c_str(),len,i,nm.c_str(),desc.substr(0,len).c_str());
  		while(len<desc.size() && isspace(desc[len])) len++;
  		desc=desc.substr(len);
  		while(desc.size()>0) {
--- 47,56 ----
  		else
  			while(len>0 && !isspace(desc[len-1])) len--;
  		if(config->main.use_VT100)
! 			fmt="\33[1m%s%*d. %s\33[0m: %s\n";
  		else
! 			fmt="%s%*d. %s: %s\n";
! 		sout->printf(fmt,prefix.c_str(),numlen,i,nm.c_str(),desc.substr(0,len).c_str());
  		while(len<desc.size() && isspace(desc[len])) len++;
  		desc=desc.substr(len);
  		while(desc.size()>0) {
***************
*** 77,85 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.2 $
   * $State: Exp $
!  * $Date: 2003/07/09 02:34:49 $
   */
  
--- 79,87 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.2 $
   * $State: Exp $
!  * $Date: 2003/07/09 02:34:49 $
   */
  
Index: AiboPup/Behaviors/Controls/ToggleHeadLightControl.h
diff -c AiboPup/Behaviors/Controls/ToggleHeadLightControl.h:1.1 AiboPup/Behaviors/Controls/ToggleHeadLightControl.h:removed
*** AiboPup/Behaviors/Controls/ToggleHeadLightControl.h:1.1	Fri Jun 13 01:50:16 2003
--- AiboPup/Behaviors/Controls/ToggleHeadLightControl.h	Tue Jul  8 22:31:39 2003
***************
*** 1,39 ****
- //-*-c++-*-
- #ifndef INCLUDED_ToggleHeadLightControl_h_
- #define INCLUDED_ToggleHeadLightControl_h_
- 
- #include "NullControl.h"
- #include "Shared/SharedObject.h"
- #include "Motion/PostureMC.h"
- #include "Shared/ERS220Info.h"
- 
- //! opens or closes the head light on an ERS-220
- class ToggleHeadLightControl : public NullControl {
- public:
- 	//! constructor
- 	ToggleHeadLightControl() : NullControl("ToggleHeadLightControl","Opens or closes the head light on an ERS-220") {}
- 
- 	//! opens/closes the head light
- 	virtual ControlBase * activate(MotionCommand::MC_ID disp_id, Socket * gui) {
- 		if(state->robotDesign & WorldState::ERS220Mask) {
- 			unsigned int light=ERS220Info::RetractableHeadLEDOffset;
- 			SharedObject<PostureMC> pose;
- 			pose->setOutputCmd(light,!state->outputs[light]);
- 			motman->addMotion(pose,true);
- 		}
- 		return NullControl::activate(disp_id,gui);
- 	}
- };
- 
- /*! @file
-  * @brief Defines ToggleHeadLightControl, which will open or close the head light on an ERS-220
-  * @author ejt (Creator)
-  *
-  * $Author: ejt $
-  * $Name: HEAD $
-  * $Revision: 1.2 $
-  * $State: Exp $
-  * $Date: 2003/07/09 02:34:49 $
-  */
- 
- #endif
--- 0 ----
Index: AiboPup/Behaviors/Demos/Aibo3DControllerBehavior.h
diff -c AiboPup/Behaviors/Demos/Aibo3DControllerBehavior.h:1.3 AiboPup/Behaviors/Demos/Aibo3DControllerBehavior.h:1.5
*** AiboPup/Behaviors/Demos/Aibo3DControllerBehavior.h:1.3	Thu Jun 12 14:06:10 2003
--- AiboPup/Behaviors/Demos/Aibo3DControllerBehavior.h	Sun Jul  6 21:00:07 2003
***************
*** 74,82 ****
--- 74,90 ----
  		// Turn on wireless
  		wireless->setReceiver(cmdsock->sock, aibo3dcontrollercmd_callback);
  		wireless->listen(cmdsock->sock, config->main.aibo3d_port);
+ 		// open gui
+ 		std::vector<std::string> tmp;
+ 		tmp.push_back("Aibo3D Load Instructions");
+ 		tmp.push_back("To load Aibo3D, you will need to install java3d\nand then run Tekkotsu/tools/aibo3d/");
+ 		tmp.back()+=getGUIType();
+ 		Controller::loadGUI("ControllerMsg","LoadAibo3d",getPort(),tmp);
+ 		//Controller::loadGUI(getGUIType(),getGUIType(),getPort());
  	}
  
  	virtual void DoStop() {
+ 		Controller::closeGUI(getGUIType());
  		// Close socket; turn wireless off
  		wireless->close(cmdsock);
  		// Disable remote control
***************
*** 85,96 ****
  		BehaviorBase::DoStop();
  	}
  
! 	virtual void processEvent(const EventBase &) {
!     // who needs events
! 	}
  
! 	virtual std::string getName() const { return "Aibo3DController"; } //!< returns name of behavior
! 	static std::string getClassDescription() { return "Listens to aibo3d control commands coming in from the command port."; }
  };
  
  
--- 93,107 ----
  		BehaviorBase::DoStop();
  	}
  
! 	virtual std::string getGUIType() const { return "Aibo3DPick"; }
! 	virtual unsigned int getPort() const { return config->main.aibo3d_port; }
  
! 	virtual std::string getName() const { return "Aibo3D Controller"; } //!< returns name of behavior
! 	static std::string getClassDescription() { 
! 		char tmp[20];
! 		sprintf(tmp,"%d",config->main.aibo3d_port);
! 		return std::string("Listens to aibo3d control commands coming in from port ")+tmp;
! 	}
  };
  
  
***************
*** 99,103 ****
--- 110,125 ----
      return aibo3dControllerBehavior->registerData(buf, bytes);
    return 0;
  }
+ 
+ /*! @file
+  * @brief Defines Aibo3DControllerBehavior, which listens to commands from the Aibo3D gui and shows current state
+  * @author alokl (Creator)
+  *
+  * $Author: ejt $
+  * $Name: HEAD $
+  * $Revision: 1.2 $
+  * $State: Exp $
+  * $Date: 2003/07/09 02:34:49 $
+  */
  
  #endif 
Index: AiboPup/Behaviors/Demos/Aibo3DMonitorBehavior.h
diff -c /dev/null AiboPup/Behaviors/Demos/Aibo3DMonitorBehavior.h:1.2
*** /dev/null	Tue Jul  8 22:31:39 2003
--- AiboPup/Behaviors/Demos/Aibo3DMonitorBehavior.h	Sun Jul  6 21:00:07 2003
***************
*** 0 ****
--- 1,32 ----
+ //-*-c++-*-
+ #ifndef INCLUDED_Aibo3DMonitorBehavior_h_
+ #define INCLUDED_Aibo3DMonitorBehavior_h_
+ 
+ //! Sends current pose to Aibo3D GUI, ignores incoming commands
+ class Aibo3DMonitorBehavior : public Aibo3DControllerBehavior {
+ public:
+ 	Aibo3DMonitorBehavior() : Aibo3DControllerBehavior() {}
+ 
+ 	virtual std::string getGUIType() const { return "Aibo3D"; }
+ 	virtual unsigned int getPort() const { return config->main.aibo3d_port; }
+ 
+ 	virtual std::string getName() const { return "Aibo3D Monitor"; } //!< returns name of behavior
+ 	static std::string getClassDescription() {
+ 		char tmp[20];
+ 		sprintf(tmp,"%d",config->main.aibo3d_port);
+ 		return std::string("Sends current pose on port ")+tmp;
+ 	}	
+ };
+ 
+ /*! @file
+  * @brief Defines Aibo3DMonitorBehavior, which sends current pose to Aibo3D GUI, ignores incoming commands
+  * @author ejt (Creator)
+  *
+  * $Author: ejt $
+  * $Name: HEAD $
+  * $Revision: 1.2 $
+  * $State: Exp $
+  * $Date: 2003/07/09 02:34:49 $
+  */
+ 
+ #endif
Index: AiboPup/Behaviors/Demos/EStopControllerBehavior.cc
diff -c /dev/null AiboPup/Behaviors/Demos/EStopControllerBehavior.cc:1.2
*** /dev/null	Tue Jul  8 22:31:39 2003
--- AiboPup/Behaviors/Demos/EStopControllerBehavior.cc	Tue Jul  8 20:10:57 2003
***************
*** 0 ****
--- 1,75 ----
+ #include "EStopControllerBehavior.h"
+ #include "Motion/EmergencyStopMC.h"
+ #include "Motion/MMAccessor.h"
+ 
+ EStopControllerBehavior* EStopControllerBehavior::theOne = NULL;
+ 
+ void EStopControllerBehavior::DoStart() {
+ 	// Behavior startup
+ 	BehaviorBase::DoStart();
+ 	// We listen to the estop
+ 	erouter->addListener(this, EventBase::estopEGID);
+ 	// Turn on wireless
+ 	wireless->setReceiver(cmdsock->sock, callback);
+ 	wireless->listen(cmdsock->sock, config->main.estopControl_port);
+ }
+ 
+ void EStopControllerBehavior::DoStop() {
+ 	// Turn off timers
+ 	erouter->forgetListener(this);
+ 	// Close socket; turn wireless off
+ 	wireless->close(cmdsock);
+ 	// Total behavior stop
+ 	BehaviorBase::DoStop();
+ }
+ 
+ void EStopControllerBehavior::runCommand(std::string s) {
+ 	if(s==std::string("start")) {
+ 		MMAccessor<EmergencyStopMC> estop(estop_id);
+ 		estop->setStopped(false);
+ 	} else if(s==std::string("stop")) {
+ 		MMAccessor<EmergencyStopMC> estop(estop_id);
+ 		estop->setStopped(true);
+ 	} else if(s==std::string("refresh")) {
+ 		MMAccessor<EmergencyStopMC> estop(estop_id);
+ 		if(estop.checkin(estop->getStopped()))
+ 			cmdsock->printf("on\n");
+ 		else
+ 			cmdsock->printf("off\n");
+ 	} else {
+ 		serr->printf("EStopControllerBehavior::runCommand() - bad message: '%s'",s.c_str());
+ 	}
+ }
+ 
+ void EStopControllerBehavior::processEvent(const EventBase & e) {
+ 	if(e.getTypeID()==EventBase::activateETID) {
+ 		cmdsock->printf("on\n");
+ 	} else if(e.getTypeID()==EventBase::deactivateETID) {
+ 		cmdsock->printf("off\n");
+ 	}
+ }
+ 
+ // The command packet reassembly mechanism
+ int EStopControllerBehavior::callback(char *buf, int bytes) {
+ 	static std::string cmd;
+ 	for(int i=0; i<bytes; i++) {
+ 		if(buf[i]=='\n') {
+ 			EStopControllerBehavior::theOne->runCommand(cmd);
+ 			cmd.clear();
+ 		} else
+ 			cmd+=buf[i];
+ 	}
+   return 0;
+ }
+ 
+ /*! @file
+  * @brief Implements EStopControllerBehavior, listens to commands coming in from the command port for remotely controlling toggling the estop
+  * @author tss (Creator)
+  * 
+  * $Author: ejt $
+  * $Name: HEAD $
+  * $Revision: 1.2 $
+  * $State: Exp $
+  * $Date: 2003/07/09 02:34:49 $
+  */
+ 
Index: AiboPup/Behaviors/Demos/EStopControllerBehavior.h
diff -c /dev/null AiboPup/Behaviors/Demos/EStopControllerBehavior.h:1.1
*** /dev/null	Tue Jul  8 22:31:39 2003
--- AiboPup/Behaviors/Demos/EStopControllerBehavior.h	Mon Jul  7 03:08:27 2003
***************
*** 0 ****
--- 1,74 ----
+ //-*-c++-*-
+ #ifndef INCLUDED_EStopControllerBehavior_h_
+ #define INCLUDED_EStopControllerBehavior_h_
+ 
+ #include <iostream>
+ #include "Wireless/Wireless.h"
+ #include "Behaviors/BehaviorBase.h"
+ #include "Motion/MotionManager.h"
+ #include "Events/EventRouter.h"
+ #include "Events/EventBase.h"
+ #include "Shared/Config.h"
+ 
+ //! Listens to control commands coming in from the command port for remotely controlling the head
+ class EStopControllerBehavior : public BehaviorBase {
+ 
+ public:	
+ 	//! Points to the one EStopControllerBehavior object that the input
+ 	//! command stream is talking to. A kludge. Dunno how you're gonna
+ 	//! make sure you're not using this uninitialized.
+ 	static EStopControllerBehavior * theOne;
+ 	static int callback(char *buf, int bytes); //!< called by wireless when there's new data
+ 
+ public:
+ 	//! constructor
+ 	EStopControllerBehavior(MotionManager::MC_ID estop)
+ 		: BehaviorBase(),
+ 			cmdsock(wireless->socket(SocketNS::SOCK_STREAM, 256, 256)),
+ 			estop_id(estop)
+ 	{
+ 		theOne=this;
+ 	}
+ 	//! destructor
+ 	virtual ~EStopControllerBehavior() { }
+ 
+ 	virtual void DoStart();
+ 
+ 	virtual void DoStop();
+ 
+ 	virtual void processEvent(const EventBase &);
+ 
+ 	virtual std::string getName() const { return "EStop Remote Control"; }
+ 	static std::string getClassDescription() {
+ 		char tmp[20];
+ 		sprintf(tmp,"%d",config->main.estopControl_port);
+ 		return std::string("Listens to estop commands coming in from port ")+tmp;
+ 	}
+ 
+ 	virtual void runCommand(std::string s);
+ 
+ protected:
+ 	//! The input command stream socket
+ 	Socket *cmdsock;
+ 
+ 	//! The estop to control
+ 	MotionManager::MC_ID estop_id;
+ 
+ private:
+ 	EStopControllerBehavior(const EStopControllerBehavior&); //!< don't call
+ 	EStopControllerBehavior operator=(const EStopControllerBehavior&); //!< don't call
+ 
+ };
+ 
+ /*! @file
+  * @brief Describes EStopControllerBehavior, listens to control commands coming in from the command port for remotely toggling the estop
+  * @author tss (Creator)
+  * 
+  * $Author: ejt $
+  * $Name: HEAD $
+  * $Revision: 1.2 $
+  * $State: Exp $
+  * $Date: 2003/07/09 02:34:49 $
+  */
+ 
+ #endif 
Index: AiboPup/Behaviors/Demos/HeadPointControllerBehavior.cc
diff -c /dev/null AiboPup/Behaviors/Demos/HeadPointControllerBehavior.cc:1.1
*** /dev/null	Tue Jul  8 22:31:39 2003
--- AiboPup/Behaviors/Demos/HeadPointControllerBehavior.cc	Sun Jul  6 21:00:08 2003
***************
*** 0 ****
--- 1,125 ----
+ #include "HeadPointControllerBehavior.h"
+ #include "Behaviors/Controller.h"
+ #include "Motion/MMAccessor.h"
+ 
+ HeadPointControllerBehavior* HeadPointControllerBehavior::theOne = NULL;
+ 
+ void HeadPointControllerBehavior::runCommand(unsigned char *command) {
+ 	// First, turn off the stop-if-no-heartbeat timer
+ 	erouter->removeTimer(this);
+ 
+ 	// Extract the command parameter
+ 	float param;
+ 	unsigned char *paramp = (unsigned char *) &param;
+ 
+ 	paramp[0] = command[1];
+ 	paramp[1] = command[2];
+ 	paramp[2] = command[3];
+ 	paramp[3] = command[4];
+ 
+ 	// Find out what type of command this is
+ 	switch(command[0]) {
+ 	case CMD_tilt:
+ 		t = param*outputRanges[HeadOffset+TiltOffset][MaxRange];
+ 		break;
+ 	case CMD_pan:
+ 		p = param*outputRanges[HeadOffset+PanOffset][MaxRange];
+ 		break;
+ 	case CMD_roll:
+ 		r = param*outputRanges[HeadOffset+RollOffset][MaxRange];
+ 		break;
+ 	default:
+ 		cout << "MECHA: unknown command " << command[0] << endl;
+ 	}
+ 
+ 	// If the command was a new motion command, apply the
+ 	// new motion parameters:
+ 	switch(command[0]) {
+ 	case CMD_tilt:
+ 	case CMD_pan:
+ 	case CMD_roll:
+ 		{
+ 			MMAccessor<HeadPointerMC> head(head_id);
+ 			head->setJoints(t,p,r);
+ 		}
+ 	}
+ 
+ 	// Reset the stop-if-no-heartbeat timer -- if we don't
+ 	// hear from the mothership in three seconds, stop immediately.
+ 	erouter->addTimer(this, 0, 3000, false);
+ }
+ 
+ void HeadPointControllerBehavior::DoStart() {
+ 	// Behavior startup
+ 	BehaviorBase::DoStart();
+ 	// We listen to timers
+ 	erouter->addListener(this, EventBase::timerEGID);
+ 	// Enable head control
+ 	head_id = motman->addMotion(SharedObject<HeadPointerMC>());
+ 	// Turn on wireless
+ 	wireless->setReceiver(cmdsock->sock, mechacmd_callback);
+ 	wireless->listen(cmdsock->sock, config->main.headControl_port);
+ 	// Open the WalkGUI on the desktop
+ 	Controller::loadGUI("HeadPointGUI","HeadPointGUI",config->main.headControl_port);
+ }
+ 
+ void HeadPointControllerBehavior::DoStop() {
+ 	// Close the GUI
+ 	Controller::closeGUI("HeadPointGUI");
+ 	// Turn off timers
+ 	erouter->forgetListener(this);
+ 	// Close socket; turn wireless off
+ 	wireless->close(cmdsock);
+ 	// Disable head pointer
+ 	motman->removeMotion(head_id);
+ 	// Total behavior stop
+ 	BehaviorBase::DoStop();
+ }
+ 
+ // The command packet reassembly mechanism
+ int HeadPointControllerBehavior::mechacmd_callback(char *buf, int bytes) {
+   static char cb_buf[5];
+   static int cb_buf_filled;
+ 
+   // If there's an incomplete command in the command buffer, fill
+   // up as much of the command buffer as we can and then execute it
+   // if possible
+   if(cb_buf_filled) {
+     while((cb_buf_filled < 5) && bytes) {
+       cb_buf[cb_buf_filled++] = *buf++;	// copy incoming buffer byte
+       --bytes;				// decrement remaining byte ct.
+     }
+     // did we fill it? if so, execute! and mark buffer empty.
+     if(cb_buf_filled == 5) {
+       if(HeadPointControllerBehavior::theOne) HeadPointControllerBehavior::theOne->runCommand((unsigned char*) cb_buf);
+       cb_buf_filled = 0;
+     }
+   }
+ 
+   // now execute all complete bytes in the incoming buffer
+   while(bytes >= 5) {
+     if(HeadPointControllerBehavior::theOne) HeadPointControllerBehavior::theOne->runCommand((unsigned char *) buf);
+     bytes -= 5;
+     buf += 5;
+   }
+ 
+   // finally, store all remaining bytes in the command buffer
+   while(bytes) {
+     cb_buf[cb_buf_filled++] = *buf++;
+     --bytes;
+   }
+ 
+   return 0;
+ }
+ 
+ /*! @file
+  * @brief Implements HeadPointControllerBehavior, listens to control commands coming in from the command port for remotely controlling the head
+  * @author tss (Creator)
+  * 
+  * $Author: ejt $
+  * $Name: HEAD $
+  * $Revision: 1.2 $
+  * $State: Exp $
+  * $Date: 2003/07/09 02:34:49 $
+  */
+ 
Index: AiboPup/Behaviors/Demos/HeadPointControllerBehavior.h
diff -c /dev/null AiboPup/Behaviors/Demos/HeadPointControllerBehavior.h:1.1
*** /dev/null	Tue Jul  8 22:31:39 2003
--- AiboPup/Behaviors/Demos/HeadPointControllerBehavior.h	Sun Jul  6 21:00:08 2003
***************
*** 0 ****
--- 1,92 ----
+ //-*-c++-*-
+ #ifndef INCLUDED_HeadPointControllerBehavior_h_
+ #define INCLUDED_HeadPointControllerBehavior_h_
+ 
+ #include <iostream>
+ #include "Wireless/Wireless.h"
+ #include "Behaviors/BehaviorBase.h"
+ #include "Motion/MotionManager.h"
+ #include "Motion/HeadPointerMC.h"
+ #include "Events/EventRouter.h"
+ #include "Events/EventBase.h"
+ #include "Shared/Config.h"
+ 
+ //! Listens to control commands coming in from the command port for remotely controlling the head
+ class HeadPointControllerBehavior : public BehaviorBase {
+ 
+  public:	
+ 	//! Points to the one HeadPointControllerBehavior object that the input
+ 	//! command stream is talking to. A kludge. Dunno how you're gonna
+ 	//! make sure you're not using this uninitialized.
+ 	static HeadPointControllerBehavior * theOne;
+ 	static int mechacmd_callback(char *buf, int bytes); //!< called by wireless when there's new data
+ 
+  protected:
+ 	MotionManager::MC_ID head_id;   //!< the HeadPointerMC to use
+  
+  private:
+ 	//!@name Command Bytes
+ 	static const char CMD_tilt  = 't'; //!< handy symbol for matching incoming communication
+ 	static const char CMD_pan   = 'p';
+ 	static const char CMD_roll  = 'r';
+ 	//@}
+ 
+ 	float t; //!< head parameter
+ 	float p; //!< head parameter
+ 	float r; //!< head parameter
+ 
+ 	//! The last HPCB object that was theOne, so we can restore it
+ 	//! to prominence when we die. This is a nice gesture, but it doesn't
+ 	//! really make sense since we're all using the same port. But just
+ 	//! in case something changes and we don't do that, this mechanism
+ 	//! is in place.
+ 	HeadPointControllerBehavior *theLastOne;
+ 
+ 	//! The input command stream socket
+ 	Socket *cmdsock;
+ 
+ 	//! Executes a command. Called by mechacmd_callback.
+ 	void runCommand(unsigned char *command);
+ 
+ 	HeadPointControllerBehavior(const HeadPointControllerBehavior&); //!< don't call
+ 	HeadPointControllerBehavior operator=(const HeadPointControllerBehavior&); //!< don't call
+ 
+  public:
+ 	//! constructor
+ 	HeadPointControllerBehavior() :
+ 	  BehaviorBase(),
+ 	  head_id(MotionManager::invalid_MC_ID),
+ 	  t(0), p(0), r(0),
+ 	  theLastOne(theOne),
+ 	  cmdsock(wireless->socket(SocketNS::SOCK_STREAM, 2048, 2048))
+ 	{ theOne = this; }
+ 	//! destructor
+ 	virtual ~HeadPointControllerBehavior() { theOne = theLastOne; }
+ 
+ 	virtual void DoStart();
+ 
+ 	virtual void DoStop();
+ 
+ 	//! The only event we could possibly receive is the stop-if-no-heartbeat timer.
+ 	virtual void processEvent(const EventBase &) {}
+ 
+ 	virtual std::string getName() const { return "Head Remote Control"; }
+ 	static std::string getClassDescription() {
+ 		char tmp[20];
+ 		sprintf(tmp,"%d",config->main.headControl_port);
+ 		return std::string("Listens to head control commands coming in from port ")+tmp;
+ 	}
+ };
+ 
+ /*! @file
+  * @brief Describes HeadPointControllerBehavior, listens to control commands coming in from the command port for remotely controlling the head
+  * @author tss (Creator)
+  * 
+  * $Author: ejt $
+  * $Name: HEAD $
+  * $Revision: 1.2 $
+  * $State: Exp $
+  * $Date: 2003/07/09 02:34:49 $
+  */
+ 
+ #endif 
Index: AiboPup/Behaviors/Demos/MechaControllerBehavior.cc
diff -c AiboPup/Behaviors/Demos/MechaControllerBehavior.cc:1.2 AiboPup/Behaviors/Demos/MechaControllerBehavior.cc:removed
*** AiboPup/Behaviors/Demos/MechaControllerBehavior.cc:1.2	Thu Jun 12 19:41:39 2003
--- AiboPup/Behaviors/Demos/MechaControllerBehavior.cc	Tue Jul  8 22:31:39 2003
***************
*** 1,159 ****
- #include "MechaControllerBehavior.h"
- 
- MechaControllerBehavior* MechaControllerBehavior::theOneMCB = NULL;
- 
- void MechaControllerBehavior::runCommand(unsigned char *command) {
- 	// First, turn off the stop-if-no-heartbeat timer
- 	erouter->removeTimer(this);
- 
- 	// Extract the command parameter
- 	float param;
- 	unsigned char *paramp = (unsigned char *) &param;
- 
- 	paramp[0] = command[1];
- 	paramp[1] = command[2];
- 	paramp[2] = command[3];
- 	paramp[3] = command[4];
- 
- 	// Find out what type of command this is
- 	switch(command[0]) {
- 	case CMD_fwd:
- 		dx = param;
- 		break;
- 	case CMD_roto:
- 		da = param;
- 		break;
- 	case CMD_side:
- 		dy = param;
- 		break;
- 	case CMD_opt0:
- 		{
- 			HeadPointerMC *head =
- 				(HeadPointerMC*)motman->checkoutMotion(head_id);
- 			head->setJoints(0,0,0);
- 			motman->checkinMotion(head_id);
- 			break;
- 		}
- 	case CMD_opt1:
- 	case CMD_opt2:
- 	case CMD_opt3:
- 	case CMD_opt4:
- 		cout << "MECHA: hey, reprogram this button!" << endl;
- 		break;
- 	case CMD_opt5:
- 		sndman->PlayFile("howl.wav");
- 		break;
- 	case CMD_opt6:
- 		sndman->PlayFile("yap.wav");
- 		break;
- 	case CMD_opt7:
- 		sndman->PlayFile("whimper.wav");
- 		break;
- 	case CMD_opt8:
- 		sndman->PlayFile("growl.wav");
- 		break;
- 	case CMD_opt9:
- 		sndman->PlayFile("barkmed.wav");
- 		break;
- 		// The options button commands.
- 	default:
- 		cout << "MECHA: unknown command " << command[0] << endl;
- 	}
- 
- 	// If the command was a new motion command, apply the
- 	// new motion parameters:
- 	switch(command[0]) {
- 	case CMD_fwd:
- 	case CMD_roto:
- 	case CMD_side:
- 		{
- 			WalkMC *walker =
- 			  (WalkMC*)motman->checkoutMotion(walker_id);
- 			walker->setTargetVelocity(dx,dy,da);
- 			motman->checkinMotion(walker_id);
- 		}
- 	}
- 
- 	// Reset the stop-if-no-heartbeat timer -- if we don't
- 	// hear from the mothership in three seconds, stop immediately.
- 	erouter->addTimer(this, 0, 3000, false);
- }
- 
- void MechaControllerBehavior::DoStart() {
- 	// Behavior startup
- 	BehaviorBase::DoStart();
- 	// We listen to timers
- 	erouter->addListener(this, EventBase::timerEGID);
- 	// Enable walker
- 	walker_id = motman->addMotion(SharedObject<WalkMC>());
- 	// Enable head control
- 	head_id = motman->addMotion(SharedObject<HeadPointerMC>());
- 	// Turn on wireless
- 	wireless->setReceiver(cmdsock->sock, mechacmd_callback);
- 	wireless->listen(cmdsock->sock, config->main.mecha_port);
- }
- 
- void MechaControllerBehavior::DoStop() {
- 	// Turn off timers
- 	erouter->forgetListener(this);
- 	// Close socket; turn wireless off
- 	wireless->close(cmdsock);
- 	// Stop moving
- 	WalkMC *walker = (WalkMC*)motman->checkoutMotion(walker_id);
- 	walker->setTargetVelocity(0,0,0);
- 	motman->checkinMotion(walker_id);
- 	// Disable walker
- 	motman->removeMotion(walker_id);
- 	// Disable head pointer
- 	motman->removeMotion(head_id);
- 	// Total behavior stop
- 	BehaviorBase::DoStop();
- }
- 
- // The command packet reassembly mechanism
- int MechaControllerBehavior::mechacmd_callback(char *buf, int bytes) {
-   static char cb_buf[5];
-   static int cb_buf_filled;
- 
-   // If there's an incomplete command in the command buffer, fill
-   // up as much of the command buffer as we can and then execute it
-   // if possible
-   if(cb_buf_filled) {
-     while((cb_buf_filled < 5) && bytes) {
-       cb_buf[cb_buf_filled++] = *buf++;	// copy incoming buffer byte
-       --bytes;				// decrement remaining byte ct.
-     }
-     // did we fill it? if so, execute! and mark buffer empty.
-     if(cb_buf_filled == 5) {
-       if(MechaControllerBehavior::theOneMCB) MechaControllerBehavior::theOneMCB->runCommand((unsigned char*) cb_buf);
-       cb_buf_filled = 0;
-     }
-   }
- 
-   // now execute all complete bytes in the incoming buffer
-   while(bytes >= 5) {
-     if(MechaControllerBehavior::theOneMCB) MechaControllerBehavior::theOneMCB->runCommand((unsigned char *) buf);
-     bytes -= 5;
-     buf += 5;
-   }
- 
-   // finally, store all remaining bytes in the command buffer
-   while(bytes) {
-     cb_buf[cb_buf_filled++] = *buf++;
-     --bytes;
-   }
- 
-   return 0;
- }
- 
- /*! @file
-  * @brief Implements MechaControllerBehavior, listens to mecha control commands coming in from the command port for remotely controlling the walk
-  * @author tss (Creator)
-  * 
-  * $Author: ejt $
-  * $Name: HEAD $
-  * $Revision: 1.2 $
-  * $State: Exp $
-  * $Date: 2003/07/09 02:34:49 $
-  */
- 
--- 0 ----
Index: AiboPup/Behaviors/Demos/MechaControllerBehavior.h
diff -c AiboPup/Behaviors/Demos/MechaControllerBehavior.h:1.5 AiboPup/Behaviors/Demos/MechaControllerBehavior.h:removed
*** AiboPup/Behaviors/Demos/MechaControllerBehavior.h:1.5	Thu Jun 12 19:41:40 2003
--- AiboPup/Behaviors/Demos/MechaControllerBehavior.h	Tue Jul  8 22:31:39 2003
***************
*** 1,106 ****
- //-*-c++-*-
- #ifndef INCLUDED_MechaControllerBehavior_h_
- #define INCLUDED_MechaControllerBehavior_h_
- 
- #include <iostream>
- #include "Wireless/Wireless.h"
- #include "Behaviors/BehaviorBase.h"
- #include "Motion/MotionManager.h"
- #include "Motion/WalkMC.h"
- #include "Motion/HeadPointerMC.h"
- #include "Events/EventRouter.h"
- #include "Events/EventBase.h"
- #include "SoundPlay/SoundManager.h"
- #include "Shared/Config.h"
- 
- //! Listens to mecha control commands coming in from the command port for remotely controlling the walk
- class MechaControllerBehavior : public BehaviorBase {
- 
-  public:	
- 	//! Points to the one MechaControllerBehavior object that the input
- 	//! command stream is talking to. A kludge. Dunno how you're gonna
- 	//! make sure you're not using this uninitialized.
- 	static MechaControllerBehavior * theOneMCB;
- 	static int mechacmd_callback(char *buf, int bytes); //!< called by wireless when there's new data
- 
-  protected:
- 	MotionManager::MC_ID walker_id; //!< the WalkMC to use
- 	MotionManager::MC_ID head_id;   //!< the HeadPointerMC to use
-  
-  private:
- 	//!@name Command Bytes
- 	static const char CMD_fwd  = 'f'; //!< handy symbol for matching incoming communication
- 	static const char CMD_roto = 'r';
- 	static const char CMD_side = 's';
- 	static const char CMD_opt0 = '0';
- 	static const char CMD_opt1 = '1';
- 	static const char CMD_opt2 = '2';
- 	static const char CMD_opt3 = '3';
- 	static const char CMD_opt4 = '4';
- 	static const char CMD_opt5 = '5';
- 	static const char CMD_opt6 = '6';
- 	static const char CMD_opt7 = '7';
- 	static const char CMD_opt8 = '8';
- 	static const char CMD_opt9 = '9';
- 	//@}
- 
- 	float dx; //!< Motion parameter
- 	float dy; //!< Motion parameter
- 	float da; //!< Motion parameter
- 
- 	//! The last MCB object that was theOneMCB, so we can restore it
- 	//! to prominence when we die. This is a nice gesture, but it doesn't
- 	//! really make sense since we're all using the same port. But just
- 	//! in case something changes and we don't do that, this mechanism
- 	//! is in place.
- 	MechaControllerBehavior *theLastOneMCB;
- 
- 	//! The input command stream socket
- 	Socket *cmdsock;
- 
- 	//! Executes a command. Called by mechacmd_callback.
- 	void runCommand(unsigned char *command);
- 
- 	MechaControllerBehavior(const MechaControllerBehavior&); //!< don't call
- 	MechaControllerBehavior operator=(const MechaControllerBehavior&); //!< don't call
- 
-  public:
- 	//! constructor
- 	MechaControllerBehavior() :
- 	  BehaviorBase(),
- 	  walker_id(MotionManager::invalid_MC_ID),
- 	  head_id(MotionManager::invalid_MC_ID),
- 	  dx(0), dy(0), da(0),
- 	  theLastOneMCB(theOneMCB),
- 	  cmdsock(wireless->socket(SocketNS::SOCK_STREAM, 2048, 2048))
- 	{ theOneMCB = this; }
- 	//! destructor
- 	virtual ~MechaControllerBehavior() { theOneMCB = theLastOneMCB; }
- 
- 	virtual void DoStart();
- 
- 	virtual void DoStop();
- 
- 	//! The only event we could possibly receive is the stop-if-no-heartbeat timer.
- 	virtual void processEvent(const EventBase &) {
- 		WalkMC *walker = (WalkMC*)motman->checkoutMotion(walker_id);
- 		walker->setTargetVelocity(0,0,0);
- 		motman->checkinMotion(walker_id);
- 	}
- 
- 	virtual std::string getName() const { return "MechaController"; }
- 	static std::string getClassDescription() { return "Listens to mecha control commands coming in from the command port."; }
- };
- 
- /*! @file
-  * @brief Describes MechaControllerBehavior, listens to mecha control commands coming in from the command port for remotely controlling the walk
-  * @author tss (Creator)
-  * 
-  * $Author: ejt $
-  * $Name: HEAD $
-  * $Revision: 1.2 $
-  * $State: Exp $
-  * $Date: 2003/07/09 02:34:49 $
-  */
- 
- #endif 
--- 0 ----
Index: AiboPup/Behaviors/Demos/ToggleHeadLightBehavior.h
diff -c /dev/null AiboPup/Behaviors/Demos/ToggleHeadLightBehavior.h:1.1
*** /dev/null	Tue Jul  8 22:31:39 2003
--- AiboPup/Behaviors/Demos/ToggleHeadLightBehavior.h	Sat Jun 28 14:03:57 2003
***************
*** 0 ****
--- 1,49 ----
+ //-*-c++-*-
+ #ifndef INCLUDED_ToggleHeadLightBehavior_h_
+ #define INCLUDED_ToggleHeadLightBehavior_h_
+ 
+ #include "Shared/SharedObject.h"
+ #include "Motion/PostureMC.h"
+ #include "Shared/ERS220Info.h"
+ 
+ //! opens or closes the head light on an ERS-220
+ class ToggleHeadLightBehavior : public BehaviorBase {
+ public:
+ 	//! constructor
+ 	ToggleHeadLightBehavior() : BehaviorBase(), light_id(MotionManager::invalid_MC_ID) {}
+ 
+ 	//! opens the head light
+ 	virtual void DoStart() {
+ 		BehaviorBase::DoStart();
+ 		if(state->robotDesign & WorldState::ERS220Mask) {
+ 			SharedObject<PostureMC> pose;
+ 			pose->setOutputCmd(ERS220Info::RetractableHeadLEDOffset,true);
+ 			light_id=motman->addMotion(pose,false);
+ 		}
+ 	}
+ 
+ 	//! resets the head light
+ 	virtual void DoStop() {
+ 		motman->removeMotion(light_id);
+ 	}
+ 
+ 	static std::string getClassDescription() { return "Opens or closes the head light on an ERS-220"; }
+ 
+ 	std::string getName() const { return "ToggleHeadLightBehavior"; }
+ 
+ protected:
+ 	MotionManager::MC_ID light_id;
+ };
+ 
+ /*! @file
+  * @brief Defines ToggleHeadLightBehavior, which will open or close the head light on an ERS-220
+  * @author ejt (Creator)
+  *
+  * $Author: ejt $
+  * $Name: HEAD $
+  * $Revision: 1.2 $
+  * $State: Exp $
+  * $Date: 2003/07/09 02:34:49 $
+  */
+ 
+ #endif
Index: AiboPup/Behaviors/Demos/WalkControllerBehavior.cc
diff -c /dev/null AiboPup/Behaviors/Demos/WalkControllerBehavior.cc:1.1
*** /dev/null	Tue Jul  8 22:31:39 2003
--- AiboPup/Behaviors/Demos/WalkControllerBehavior.cc	Sun Jul  6 21:00:08 2003
***************
*** 0 ****
--- 1,154 ----
+ #include "WalkControllerBehavior.h"
+ #include "Behaviors/Controller.h"
+ 
+ WalkControllerBehavior* WalkControllerBehavior::theOne = NULL;
+ 
+ void WalkControllerBehavior::runCommand(unsigned char *command) {
+ 	// First, turn off the stop-if-no-heartbeat timer
+ 	erouter->removeTimer(this);
+ 
+ 	// Extract the command parameter
+ 	float param;
+ 	unsigned char *paramp = (unsigned char *) &param;
+ 
+ 	paramp[0] = command[1];
+ 	paramp[1] = command[2];
+ 	paramp[2] = command[3];
+ 	paramp[3] = command[4];
+ 
+ 	// Find out what type of command this is
+ 	switch(command[0]) {
+ 	case CMD_fwd:
+ 		dx = param;
+ 		break;
+ 	case CMD_roto:
+ 		da = param;
+ 		break;
+ 	case CMD_side:
+ 		dy = param;
+ 		break;
+ 	case CMD_opt0:
+ 		{
+ 			/*			HeadPointerMC *head =
+ 				(HeadPointerMC*)motman->checkoutMotion(head_id);
+ 			head->setJoints(0,0,0);
+ 			motman->checkinMotion(head_id);*/
+ 			break;
+ 		}
+ 	case CMD_opt1:
+ 	case CMD_opt2:
+ 	case CMD_opt3:
+ 	case CMD_opt4:
+ 		cout << "MECHA: hey, reprogram this button!" << endl;
+ 		break;
+ 	case CMD_opt5:
+ 		sndman->PlayFile("howl.wav");
+ 		break;
+ 	case CMD_opt6:
+ 		sndman->PlayFile("yap.wav");
+ 		break;
+ 	case CMD_opt7:
+ 		sndman->PlayFile("whimper.wav");
+ 		break;
+ 	case CMD_opt8:
+ 		sndman->PlayFile("growl.wav");
+ 		break;
+ 	case CMD_opt9:
+ 		sndman->PlayFile("barkmed.wav");
+ 		break;
+ 		// The options button commands.
+ 	default:
+ 		cout << "MECHA: unknown command " << command[0] << endl;
+ 	}
+ 
+ 	// If the command was a new motion command, apply the
+ 	// new motion parameters:
+ 	switch(command[0]) {
+ 	case CMD_fwd:
+ 	case CMD_roto:
+ 	case CMD_side:
+ 		{
+ 			MMAccessor<WalkMC> walker(walker_id);
+ 			walker->setTargetVelocity(dx,dy,da);
+ 		}
+ 	}
+ 
+ 	// Reset the stop-if-no-heartbeat timer -- if we don't
+ 	// hear from the mothership in three seconds, stop immediately.
+ 	erouter->addTimer(this, 0, 3000, false);
+ }
+ 
+ void WalkControllerBehavior::DoStart() {
+ 	// Behavior startup
+ 	BehaviorBase::DoStart();
+ 	// We listen to timers
+ 	erouter->addListener(this, EventBase::timerEGID);
+ 	// Enable walker
+ 	walker_id = motman->addMotion(SharedObject<WalkMC>());
+ 	// Turn on wireless
+ 	wireless->setReceiver(cmdsock->sock, mechacmd_callback);
+ 	wireless->listen(cmdsock->sock, config->main.walkControl_port);
+ 	// Open the WalkGUI on the desktop
+ 	Controller::loadGUI("WalkGUI","WalkGUI",config->main.walkControl_port);
+ }
+ 
+ void WalkControllerBehavior::DoStop() {
+ 	// Close the GUI
+ 	Controller::closeGUI("WalkGUI");
+ 	// Turn off timers
+ 	erouter->forgetListener(this);
+ 	// Close socket; turn wireless off
+ 	wireless->close(cmdsock);
+ 	// Disable walker
+ 	motman->removeMotion(walker_id);
+ 	// Total behavior stop
+ 	BehaviorBase::DoStop();
+ }
+ 
+ // The command packet reassembly mechanism
+ int WalkControllerBehavior::mechacmd_callback(char *buf, int bytes) {
+   static char cb_buf[5];
+   static int cb_buf_filled;
+ 
+   // If there's an incomplete command in the command buffer, fill
+   // up as much of the command buffer as we can and then execute it
+   // if possible
+   if(cb_buf_filled) {
+     while((cb_buf_filled < 5) && bytes) {
+       cb_buf[cb_buf_filled++] = *buf++;	// copy incoming buffer byte
+       --bytes;				// decrement remaining byte ct.
+     }
+     // did we fill it? if so, execute! and mark buffer empty.
+     if(cb_buf_filled == 5) {
+       if(WalkControllerBehavior::theOne) WalkControllerBehavior::theOne->runCommand((unsigned char*) cb_buf);
+       cb_buf_filled = 0;
+     }
+   }
+ 
+   // now execute all complete bytes in the incoming buffer
+   while(bytes >= 5) {
+     if(WalkControllerBehavior::theOne) WalkControllerBehavior::theOne->runCommand((unsigned char *) buf);
+     bytes -= 5;
+     buf += 5;
+   }
+ 
+   // finally, store all remaining bytes in the command buffer
+   while(bytes) {
+     cb_buf[cb_buf_filled++] = *buf++;
+     --bytes;
+   }
+ 
+   return 0;
+ }
+ 
+ /*! @file
+  * @brief Implements WalkControllerBehavior, listens to mecha control commands coming in from the command port for remotely controlling the walk
+  * @author tss (Creator)
+  * 
+  * $Author: ejt $
+  * $Name: HEAD $
+  * $Revision: 1.2 $
+  * $State: Exp $
+  * $Date: 2003/07/09 02:34:49 $
+  */
+ 
Index: AiboPup/Behaviors/Demos/WalkControllerBehavior.h
diff -c /dev/null AiboPup/Behaviors/Demos/WalkControllerBehavior.h:1.1
*** /dev/null	Tue Jul  8 22:31:39 2003
--- AiboPup/Behaviors/Demos/WalkControllerBehavior.h	Sun Jul  6 21:00:08 2003
***************
*** 0 ****
--- 1,107 ----
+ //-*-c++-*-
+ #ifndef INCLUDED_WalkControllerBehavior_h_
+ #define INCLUDED_WalkControllerBehavior_h_
+ 
+ #include <iostream>
+ #include "Wireless/Wireless.h"
+ #include "Behaviors/BehaviorBase.h"
+ #include "Motion/MotionManager.h"
+ #include "Motion/WalkMC.h"
+ #include "Motion/MMAccessor.h"
+ #include "Events/EventRouter.h"
+ #include "Events/EventBase.h"
+ #include "SoundPlay/SoundManager.h"
+ #include "Shared/Config.h"
+ 
+ //! Listens to control commands coming in from the command port for remotely controlling the walk
+ class WalkControllerBehavior : public BehaviorBase {
+ 
+  public:	
+ 	//! Points to the one WalkControllerBehavior object that the input
+ 	//! command stream is talking to. A kludge. Dunno how you're gonna
+ 	//! make sure you're not using this uninitialized.
+ 	static WalkControllerBehavior * theOne;
+ 	static int mechacmd_callback(char *buf, int bytes); //!< called by wireless when there's new data
+ 
+  protected:
+ 	MotionManager::MC_ID walker_id; //!< the WalkMC to use
+  
+  private:
+ 	//!@name Command Bytes
+ 	static const char CMD_fwd  = 'f'; //!< handy symbol for matching incoming communication
+ 	static const char CMD_roto = 'r';
+ 	static const char CMD_side = 's';
+ 	static const char CMD_opt0 = '0';
+ 	static const char CMD_opt1 = '1';
+ 	static const char CMD_opt2 = '2';
+ 	static const char CMD_opt3 = '3';
+ 	static const char CMD_opt4 = '4';
+ 	static const char CMD_opt5 = '5';
+ 	static const char CMD_opt6 = '6';
+ 	static const char CMD_opt7 = '7';
+ 	static const char CMD_opt8 = '8';
+ 	static const char CMD_opt9 = '9';
+ 	//@}
+ 
+ 	float dx; //!< Motion parameter
+ 	float dy; //!< Motion parameter
+ 	float da; //!< Motion parameter
+ 
+ 	//! The last WCB object that was theOne, so we can restore it
+ 	//! to prominence when we die. This is a nice gesture, but it doesn't
+ 	//! really make sense since we're all using the same port. But just
+ 	//! in case something changes and we don't do that, this mechanism
+ 	//! is in place.
+ 	WalkControllerBehavior *theLastOne;
+ 
+ 	//! The input command stream socket
+ 	Socket *cmdsock;
+ 
+ 	//! Executes a command. Called by mechacmd_callback.
+ 	void runCommand(unsigned char *command);
+ 
+ 	WalkControllerBehavior(const WalkControllerBehavior&); //!< don't call
+ 	WalkControllerBehavior operator=(const WalkControllerBehavior&); //!< don't call
+ 
+  public:
+ 	//! constructor
+ 	WalkControllerBehavior() :
+ 	  BehaviorBase(),
+ 	  walker_id(MotionManager::invalid_MC_ID),
+ 	  dx(0), dy(0), da(0),
+ 	  theLastOne(theOne),
+ 	  cmdsock(wireless->socket(SocketNS::SOCK_STREAM, 2048, 2048))
+ 	{ theOne = this; }
+ 	//! destructor
+ 	virtual ~WalkControllerBehavior() { theOne = theLastOne; }
+ 
+ 	virtual void DoStart();
+ 
+ 	virtual void DoStop();
+ 
+ 	//! The only event we could possibly receive is the stop-if-no-heartbeat timer.
+ 	virtual void processEvent(const EventBase &) {
+ 		MMAccessor<WalkMC> walker(walker_id);
+ 		walker->setTargetVelocity(0,0,0);
+ 	}
+ 
+ 	virtual std::string getName() const { return "Walk Remote Control"; }
+ 	static std::string getClassDescription() {
+ 		char tmp[20];
+ 		sprintf(tmp,"%d",config->main.walkControl_port);
+ 		return std::string("Listens to walk control commands coming in from port ")+tmp;
+ 	}
+ };
+ 
+ /*! @file
+  * @brief Describes WalkControllerBehavior, listens to control commands coming in from the command port for remotely controlling the walk
+  * @author tss (Creator)
+  * 
+  * $Author: ejt $
+  * $Name: HEAD $
+  * $Revision: 1.2 $
+  * $State: Exp $
+  * $Date: 2003/07/09 02:34:49 $
+  */
+ 
+ #endif 
Index: AiboPup/Motion/HeadPointerMC.h
diff -c AiboPup/Motion/HeadPointerMC.h:1.4 AiboPup/Motion/HeadPointerMC.h:1.5
*** AiboPup/Motion/HeadPointerMC.h:1.4	Tue Mar  4 00:46:05 2003
--- AiboPup/Motion/HeadPointerMC.h	Sun Jul  6 21:00:08 2003
***************
*** 7,13 ****
  #include "Shared/RobotInfo.h"
  
  //! This class gives some quick and easy functions to point the head at things
- /*! @note This class does not autoprune by default, which is contrary to the default of most other MotionCommands. */
  class HeadPointerMC : public MotionCommand {
   public:
  	//! constructor, defaults to active, BodyRelative, all joints at 0
--- 7,12 ----
***************
*** 67,76 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.2 $
   * $State: Exp $
!  * $Date: 2003/07/09 02:34:49 $
   */
  
  #endif
--- 66,75 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.2 $
   * $State: Exp $
!  * $Date: 2003/07/09 02:34:49 $
   */
  
  #endif
Index: AiboPup/Motion/TailWagMC.h
diff -c AiboPup/Motion/TailWagMC.h:1.3 AiboPup/Motion/TailWagMC.h:1.4
*** AiboPup/Motion/TailWagMC.h:1.3	Thu Jun 12 19:41:40 2003
--- AiboPup/Motion/TailWagMC.h	Tue Jul  8 20:10:57 2003
***************
*** 18,24 ****
  	virtual int updateOutputs() {
  		if(active && state->robotDesign&WorldState::ERS210Mask) {
  			for(unsigned int i=0; i<NumFrames; i++)
! 				pans[i].set(sin((2*M_PI*(get_time()+i*FrameTime))/period)*magnitude)
  			motman->setOutput(this,ERS210Info::TailOffset+PanOffset,pans);
  			motman->setOutput(this,ERS210Info::TailOffset+TiltOffset,tilt);
  			return 1;
--- 18,24 ----
  	virtual int updateOutputs() {
  		if(active && state->robotDesign&WorldState::ERS210Mask) {
  			for(unsigned int i=0; i<NumFrames; i++)
! 				pans[i].set(sin((2*M_PI*(get_time()+i*FrameTime))/period)*magnitude); //bug fix thanks L.A.Olsson@herts.ac.uk
  			motman->setOutput(this,ERS210Info::TailOffset+PanOffset,pans);
  			motman->setOutput(this,ERS210Info::TailOffset+TiltOffset,tilt);
  			return 1;
***************
*** 51,60 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.2 $
   * $State: Exp $
!  * $Date: 2003/07/09 02:34:49 $
   */
  
  #endif
--- 51,60 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.2 $
   * $State: Exp $
!  * $Date: 2003/07/09 02:34:49 $
   */
  
  #endif
Index: AiboPup/Shared/Config.cc
diff -c AiboPup/Shared/Config.cc:1.12 AiboPup/Shared/Config.cc:1.14
*** AiboPup/Shared/Config.cc:1.12	Thu Jun 12 19:41:40 2003
--- AiboPup/Shared/Config.cc	Mon Jul  7 00:32:47 2003
***************
*** 99,106 ****
  					main.wsjoints_port=atoi(value);
  				} else if (strncasecmp(key,"wspids_port",29)==0) {
  					main.wspids_port=atoi(value);
! 				} else if (strncasecmp(key,"mecha_port",29)==0) {
! 					main.mecha_port=atoi(value);
  				} else if (strncasecmp(key,"aibo3d_port",29)==0) {
  					main.aibo3d_port=atoi(value);
  				} else if (strncasecmp(key,"use_VT100",29)==0) {
--- 99,110 ----
  					main.wsjoints_port=atoi(value);
  				} else if (strncasecmp(key,"wspids_port",29)==0) {
  					main.wspids_port=atoi(value);
! 				} else if (strncasecmp(key,"headControl_port",29)==0) {
! 					main.headControl_port=atoi(value);
! 				} else if (strncasecmp(key,"walkControl_port",29)==0) {
! 					main.walkControl_port=atoi(value);
! 				} else if (strncasecmp(key,"estopControl_port",29)==0) {
! 					main.estopControl_port=atoi(value);
  				} else if (strncasecmp(key,"aibo3d_port",29)==0) {
  					main.aibo3d_port=atoi(value);
  				} else if (strncasecmp(key,"use_VT100",29)==0) {
***************
*** 187,195 ****
   * @author alokl (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.2 $
   * $State: Exp $
!  * $Date: 2003/07/09 02:34:49 $
   */
  
--- 191,199 ----
   * @author alokl (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.2 $
   * $State: Exp $
!  * $Date: 2003/07/09 02:34:49 $
   */
  
Index: AiboPup/Shared/Config.h
diff -c AiboPup/Shared/Config.h:1.14 AiboPup/Shared/Config.h:1.16
*** AiboPup/Shared/Config.h:1.14	Thu Jun 12 14:06:11 2003
--- AiboPup/Shared/Config.h	Mon Jul  7 00:32:47 2003
***************
*** 61,75 ****
  		int verbose_level; //!< controls verbosity of info
  		int wsjoints_port; //!< port to send joint positions on
  		int wspids_port;   //!< port to send pid info on
! 		int mecha_port;	   //!< port for receiving mecha commands
      int aibo3d_port;   //!< port for send/receive of joint positions from Aibo 3D GUI
  		bool use_VT100;    //!< if true, enables VT100 console codes (currently only in Controller menus - 1.3)
  
  		//!constructor
  		main_config()
  			: console_port(0), stderr_port(0), error_level(0), debug_level(0),
! 				 verbose_level(0),wsjoints_port(0),wspids_port(0),mecha_port(0),
! 				aibo3d_port(0), use_VT100(true)
  		{ }
  	} main;
  
--- 61,77 ----
  		int verbose_level; //!< controls verbosity of info
  		int wsjoints_port; //!< port to send joint positions on
  		int wspids_port;   //!< port to send pid info on
! 		int headControl_port;	   //!< port for receiving head commands
! 		int walkControl_port;	   //!< port for receiving walk commands
! 		int estopControl_port;	   //!< port for receiving walk commands
      int aibo3d_port;   //!< port for send/receive of joint positions from Aibo 3D GUI
  		bool use_VT100;    //!< if true, enables VT100 console codes (currently only in Controller menus - 1.3)
  
  		//!constructor
  		main_config()
  			: console_port(0), stderr_port(0), error_level(0), debug_level(0),
! 				verbose_level(0),wsjoints_port(0),wspids_port(0),headControl_port(0),
! 				walkControl_port(0),estopControl_port(0),aibo3d_port(0), use_VT100(true)
  		{ }
  	} main;
  
***************
*** 152,161 ****
   * @author alokl (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.2 $
   * $State: Exp $
!  * $Date: 2003/07/09 02:34:49 $
   */
  
  #endif
--- 154,163 ----
   * @author alokl (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.2 $
   * $State: Exp $
!  * $Date: 2003/07/09 02:34:49 $
   */
  
  #endif
Index: AiboPup/TinyFTPD/Makefile
diff -c AiboPup/TinyFTPD/Makefile:1.2 AiboPup/TinyFTPD/Makefile:1.3
*** AiboPup/TinyFTPD/Makefile:1.2	Sat Mar  1 15:53:41 2003
--- AiboPup/TinyFTPD/Makefile	Mon Jul  7 14:08:12 2003
***************
*** 9,30 ****
  # implied warranties of fitness for a particular purpose.
  #
  
! PREFIX=/usr/local/OPEN_R_SDK
  INSTALLDIR=../ms
! CXX=$(PREFIX)/bin/mipsel-linux-g++
! LD=$(PREFIX)/bin/mipsel-linux-ld
! STRIP=$(PREFIX)/bin/mipsel-linux-strip
! MKBIN=$(PREFIX)/OPEN_R/bin/mkbin
! STUBGEN=$(PREFIX)/OPEN_R/bin/stubgen2
! MKBINFLAGS=-p $(PREFIX)
! LIBS=-L$(PREFIX)/OPEN_R/lib -lObjectComm -lOPENR -lInternet -lantMCOOP
  CXXFLAGS= \
  	-O2 \
  	-g \
  	-I. \
! 	-I$(PREFIX)/OPEN_R/include/R4000 \
! 	-I$(PREFIX)/OPEN_R/include/MCOOP \
! 	-I$(PREFIX)/OPEN_R/include
  
  #
  # When OPENR_DEBUG is defined, OSYSDEBUG() is available.
--- 9,30 ----
  # implied warranties of fitness for a particular purpose.
  #
  
! OPENRSDK_ROOT?=/usr/local/OPEN_R_SDK
  INSTALLDIR=../ms
! CXX=$(OPENRSDK_ROOT)/bin/mipsel-linux-g++
! LD=$(OPENRSDK_ROOT)/bin/mipsel-linux-ld
! STRIP=$(OPENRSDK_ROOT)/bin/mipsel-linux-strip
! MKBIN=$(OPENRSDK_ROOT)/OPEN_R/bin/mkbin
! STUBGEN=$(OPENRSDK_ROOT)/OPEN_R/bin/stubgen2
! MKBINFLAGS=-p $(OPENRSDK_ROOT)
! LIBS=-L$(OPENRSDK_ROOT)/OPEN_R/lib -lObjectComm -lOPENR -lInternet -lantMCOOP
  CXXFLAGS= \
  	-O2 \
  	-g \
  	-I. \
! 	-I$(OPENRSDK_ROOT)/OPEN_R/include/R4000 \
! 	-I$(OPENRSDK_ROOT)/OPEN_R/include/MCOOP \
! 	-I$(OPENRSDK_ROOT)/OPEN_R/include
  
  #
  # When OPENR_DEBUG is defined, OSYSDEBUG() is available.
Index: AiboPup/docs/doxygencfg
diff -c AiboPup/docs/doxygencfg:1.11 AiboPup/docs/doxygencfg:1.13
*** AiboPup/docs/doxygencfg:1.11	Wed Apr 30 22:53:38 2003
--- AiboPup/docs/doxygencfg	Tue Jul  8 17:33:12 2003
***************
*** 23,29 ****
  # This could be handy for archiving the generated documentation or 
  # if some version control system is used.
  
! PROJECT_NUMBER         = 1.2
  
  # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
  # base path where the generated documentation will be put. 
--- 23,29 ----
  # This could be handy for archiving the generated documentation or 
  # if some version control system is used.
  
! PROJECT_NUMBER         = 1.4
  
  # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
  # base path where the generated documentation will be put. 
Index: AiboPup/docs/profilerun_1.4.txt
diff -c /dev/null AiboPup/docs/profilerun_1.4.txt:1.2
*** /dev/null	Tue Jul  8 22:31:49 2003
--- AiboPup/docs/profilerun_1.4.txt	Tue Jul  8 20:00:24 2003
***************
*** 0 ****
--- 1,63 ----
+ Setup:
+   Default build for ERS-2xx
+   Pink ball in view (8.5in from snout)
+   Press power button, start timer
+   Telnet to system console (port 59000)
+   Launch StareAtBallBehavior (leave E-Stop ON)
+   Navigate to Status Reports -> Profiler
+   Wait until 5 minutes from initial press of power button.
+   Recorded profiler run shown below
+ 
+ ~~~ Main: ~~~
+ Profiling information since: 17.873253 to 297.798167
+ ReadySendJoints():
+         2173 calls
+         0.427711 ms avg
+         0.394695 ms exp.avg
+         0.000387 ms avg child time (0.000000%)
+         0.128443 ms avg inter (7.785550 fps)
+         0.127914 ms exp.avg (7.817783 fps)
+         Exec: 0 0 2106 64 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+         Inter: 0 1 1 0 0 0 1 0 0 0 2152 15 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 
+ GotSensorFrame():
+         8674 calls
+         0.530607 ms avg
+         0.449692 ms exp.avg
+         0.000000 ms avg child time (0.000000%)
+         0.032127 ms avg inter (31.126039 fps)
+         0.031453 ms exp.avg (31.793121 fps)
+         Exec: 0 0 7999 627 43 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+         Inter: 0 0 0 0 3 6 1704 5164 1794 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 
+ GotImage():
+         6923 calls
+         10.691804 ms avg
+         10.515949 ms exp.avg
+         0.000000 ms avg child time (0.000000%)
+         0.040262 ms avg inter (24.837369 fps)
+         0.039959 ms exp.avg (25.025801 fps)
+         Exec: 0 0 0 0 0 4241 2656 25 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+         Inter: 0 0 0 0 0 0 3 3 6915 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 
+ PowerEvent():
+         27 calls
+         54.375148 ms avg
+         21.879442 ms exp.avg
+         0.000000 ms avg child time (0.000000%)
+         10.274228 ms avg inter (0.097331 fps)
+         14.626130 ms exp.avg (0.068371 fps)
+         Exec: 0 0 23 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 
+         Inter: 0 0 0 0 0 0 0 0 0 0 0 1 0 3 0 0 0 0 0 0 3 6 0 0 0 1 0 2 0 2 0 8 
+ Bucket distribution (in ms):
+         0<0.00802, <0.133, <0.686, <2.2, <5.43, <11.4, <21.2, <36.4, <58.7, <90, <132, <188, <260, <352, <465, <604, <772, <973, <1.21e+03, <1.49e+03, <1.82e+03, <2.19e+03, <2.63e+03, <3.12e+03, <3.68e+03, <4.31e+03, <5.03e+03, <5.82e+03, <6.71e+03, <7.7e+03, <8.79e+03, <1e+04, 
+ ~~~ Motion: ~~~
+ Profiling information since: 17.873382 to 297.814179
+ ReadySendJoints():
+         8664 calls
+         2.678917 ms avg
+         2.826717 ms exp.avg
+         0.000000 ms avg child time (0.000000%)
+         0.032173 ms avg inter (31.082423 fps)
+         0.032117 ms exp.avg (31.136164 fps)
+         Exec: 0 0 0 5690 2934 11 1 2 0 19 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+         Inter: 0 0 0 0 0 2 3 8624 1 23 8 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+ Bucket distribution (in ms):
+         0<0.00802, <0.133, <0.686, <2.2, <5.43, <11.4, <21.2, <36.4, <58.7, <90, <132, <188, <260, <352, <465, <604, <772, <973, <1.21e+03, <1.49e+03, <1.82e+03, <2.19e+03, <2.63e+03, <3.12e+03, <3.68e+03, <4.31e+03, <5.03e+03, <5.82e+03, <6.71e+03, <7.7e+03, <8.79e+03, <1e+04, 
Index: AiboPup/docs/profilerun_supercore_1.4.txt
diff -c /dev/null AiboPup/docs/profilerun_supercore_1.4.txt:1.2
*** /dev/null	Tue Jul  8 22:31:49 2003
--- AiboPup/docs/profilerun_supercore_1.4.txt	Tue Jul  8 20:00:24 2003
***************
*** 0 ****
--- 1,63 ----
+ Setup:
+   Default build for ERS-2xx
+   Pink ball in view (8.5in from snout)
+   Press power button, start timer
+   Telnet to system console (port 59000)
+   Launch StareAtBallBehavior (leave E-Stop ON)
+   Navigate to Status Reports -> Profiler
+   Wait until 5 minutes from initial press of power button.
+   Recorded profiler run shown below
+ 
+ ~~~ Main: ~~~
+ Profiling information since: 16.514395 to 298.147164
+ ReadySendJoints():
+         2188 calls
+         0.217932 ms avg
+         0.213683 ms exp.avg
+         0.001279 ms avg child time (0.500000%)
+         0.128304 ms avg inter (7.794019 fps)
+         0.128021 ms exp.avg (7.811245 fps)
+         Exec: 0 0 2186 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+         Inter: 0 1 0 0 0 1 0 0 1 0 2182 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 
+ GotSensorFrame():
+         8739 calls
+         0.329321 ms avg
+         0.342395 ms exp.avg
+         0.000000 ms avg child time (0.000000%)
+         0.032102 ms avg inter (31.151004 fps)
+         0.031826 ms exp.avg (31.421064 fps)
+         Exec: 0 0 8640 93 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+         Inter: 0 0 0 0 0 1 1 8698 37 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 
+ GotImage():
+         6972 calls
+         4.063311 ms avg
+         4.000539 ms exp.avg
+         0.000000 ms avg child time (0.000000%)
+         0.040237 ms avg inter (24.852686 fps)
+         0.040477 ms exp.avg (24.705526 fps)
+         Exec: 0 0 0 0 6924 48 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+         Inter: 0 0 0 0 0 0 1 2 6967 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 
+ PowerEvent():
+         51 calls
+         21.837059 ms avg
+         0.561889 ms exp.avg
+         0.000000 ms avg child time (0.000000%)
+         4.992561 ms avg inter (0.200298 fps)
+         6.131495 ms exp.avg (0.163092 fps)
+         Exec: 0 0 44 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 
+         Inter: 0 0 0 0 0 0 0 0 0 0 0 0 0 9 0 0 0 0 1 0 5 15 0 0 1 2 0 6 0 1 0 10 
+ Bucket distribution (in ms):
+         0<0.00802, <0.133, <0.686, <2.2, <5.43, <11.4, <21.2, <36.4, <58.7, <90, <132, <188, <260, <352, <465, <604, <772, <973, <1.21e+03, <1.49e+03, <1.82e+03, <2.19e+03, <2.63e+03, <3.12e+03, <3.68e+03, <4.31e+03, <5.03e+03, <5.82e+03, <6.71e+03, <7.7e+03, <8.79e+03, <1e+04, 
+ ~~~ Motion: ~~~
+ Profiling information since: 16.514479 to 298.151038
+ ReadySendJoints():
+         8742 calls
+         1.298250 ms avg
+         1.066623 ms exp.avg
+         0.000000 ms avg child time (0.000000%)
+         0.032088 ms avg inter (31.164436 fps)
+         0.031972 ms exp.avg (31.277559 fps)
+         Exec: 0 0 4 8702 9 0 1 0 6 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+         Inter: 0 0 0 3 1 0 3 8700 9 23 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+ Bucket distribution (in ms):
+         0<0.00802, <0.133, <0.686, <2.2, <5.43, <11.4, <21.2, <36.4, <58.7, <90, <132, <188, <260, <352, <465, <604, <772, <973, <1.21e+03, <1.49e+03, <1.82e+03, <2.19e+03, <2.63e+03, <3.12e+03, <3.68e+03, <4.31e+03, <5.03e+03, <5.82e+03, <6.71e+03, <7.7e+03, <8.79e+03, <1e+04, 
Index: AiboPup/project/Makefile
diff -c AiboPup/project/Makefile:1.23 AiboPup/project/Makefile:1.24
*** AiboPup/project/Makefile:1.23	Fri Jun 13 01:35:44 2003
--- AiboPup/project/Makefile	Mon Jul  7 14:08:13 2003
***************
*** 80,101 ****
  PROC_BINS:=$(addprefix $(BUILDDIR)/,$(addsuffix $(BINSUFFIX),$(PROCESSES)))
  INSTALL_BINS:=$(addprefix $(INSTALLDIR)/,$(addsuffix $(BINSUFFIX),$(PROCESSES)))
  
! PREFIX=/usr/local/OPEN_R_SDK
! CXX=$(PREFIX)/bin/mipsel-linux-g++
! LD=$(PREFIX)/bin/mipsel-linux-ld
! STRIP=$(PREFIX)/bin/mipsel-linux-strip
! MKBIN=$(PREFIX)/OPEN_R/bin/mkbin
! STUBGEN=$(PREFIX)/OPEN_R/bin/stubgen2
  FILTERSYSWARN=$(TEKKOTSU_ROOT)/tools/filtersyswarn/filtersyswarn
! MKBINFLAGS=-p $(PREFIX)
  LIBS=-lObjectComm -lOPENR -lInternet -lantMCOOP
  CXXFLAGS= \
  	-g -O2 \
  	-Wall -W -Wshadow -Wlarger-than-8192 -Wpointer-arith -Wcast-qual \
  	-Woverloaded-virtual -Weffc++ -Winline -Wdeprecated \
  	-I. -I$(TEKKOTSU_ROOT) \
! 	-isystem $(PREFIX)/OPEN_R/include/MCOOP \
! 	-isystem $(PREFIX)/OPEN_R/include/R4000 -isystem $(PREFIX)/OPEN_R/include \
  	-DPLATFORM_APERIOS -DDEBUG -DOPENR_DEBUG -D$(TEKKOTSU_TARGET_MODEL) $(GLOBAL_MAP) \
  
  all: compile
--- 80,101 ----
  PROC_BINS:=$(addprefix $(BUILDDIR)/,$(addsuffix $(BINSUFFIX),$(PROCESSES)))
  INSTALL_BINS:=$(addprefix $(INSTALLDIR)/,$(addsuffix $(BINSUFFIX),$(PROCESSES)))
  
! OPENRSDK_ROOT?=/usr/local/OPEN_R_SDK
! CXX=$(OPENRSDK_ROOT)/bin/mipsel-linux-g++
! LD=$(OPENRSDK_ROOT)/bin/mipsel-linux-ld
! STRIP=$(OPENRSDK_ROOT)/bin/mipsel-linux-strip
! MKBIN=$(OPENRSDK_ROOT)/OPEN_R/bin/mkbin
! STUBGEN=$(OPENRSDK_ROOT)/OPEN_R/bin/stubgen2
  FILTERSYSWARN=$(TEKKOTSU_ROOT)/tools/filtersyswarn/filtersyswarn
! MKBINFLAGS=-p $(OPENRSDK_ROOT)
  LIBS=-lObjectComm -lOPENR -lInternet -lantMCOOP
  CXXFLAGS= \
  	-g -O2 \
  	-Wall -W -Wshadow -Wlarger-than-8192 -Wpointer-arith -Wcast-qual \
  	-Woverloaded-virtual -Weffc++ -Winline -Wdeprecated \
  	-I. -I$(TEKKOTSU_ROOT) \
! 	-isystem $(OPENRSDK_ROOT)/OPEN_R/include/MCOOP \
! 	-isystem $(OPENRSDK_ROOT)/OPEN_R/include/R4000 -isystem $(OPENRSDK_ROOT)/OPEN_R/include \
  	-DPLATFORM_APERIOS -DDEBUG -DOPENR_DEBUG -D$(TEKKOTSU_TARGET_MODEL) $(GLOBAL_MAP) \
  
  all: compile
***************
*** 109,120 ****
  compile: reportTarget Tekkotsu $(OBJS) $(PROC_BINS) $(INSTALL_BINS)
  	@image="$(BUILDDIR)/$(notdir $(MEMSTICK_ROOT))" ; \
  	if [ \! -d $$image ] ; then \
! 		if [ \! -d $(PREFIX)/OPEN_R/MS/WCONSOLE/nomemprot ] ; then \
  			echo "Could not find OPEN-R system binaries" ; \
  			exit 1 ; \
  		fi ; \
  		echo "Copying system files..." ; \
! 		cp -r $(PREFIX)/OPEN_R/MS/WCONSOLE/nomemprot $$image ; \
  		chmod -R u+w $$image ; \
  		$(CONVERTCASE) -r $$image ; \
  		rm -f $$image/open-r/mw/conf/connect.cfg $$image/open-r/mw/conf/object.cfg $$image/open-r/system/conf/wlandflt.txt ; \
--- 109,120 ----
  compile: reportTarget Tekkotsu $(OBJS) $(PROC_BINS) $(INSTALL_BINS)
  	@image="$(BUILDDIR)/$(notdir $(MEMSTICK_ROOT))" ; \
  	if [ \! -d $$image ] ; then \
! 		if [ \! -d $(OPENRSDK_ROOT)/OPEN_R/MS/WCONSOLE/nomemprot ] ; then \
  			echo "Could not find OPEN-R system binaries" ; \
  			exit 1 ; \
  		fi ; \
  		echo "Copying system files..." ; \
! 		cp -r $(OPENRSDK_ROOT)/OPEN_R/MS/WCONSOLE/nomemprot $$image ; \
  		chmod -R u+w $$image ; \
  		$(CONVERTCASE) -r $$image ; \
  		rm -f $$image/open-r/mw/conf/connect.cfg $$image/open-r/mw/conf/object.cfg $$image/open-r/system/conf/wlandflt.txt ; \
***************
*** 195,201 ****
  
  newstick:
  	$(TEKKOTSU_ROOT)/tools/mntmem $(MEMSTICK_ROOT)
! 	cp -r $(PREFIX)/OPEN_R/MS/WCONSOLE/nomemprot/* $(MEMSTICK_ROOT)
  	$(TEKKOTSU_ROOT)/tools/umntmem $(MEMSTICK_ROOT)
  
  $(FILTERSYSWARN):
--- 195,201 ----
  
  newstick:
  	$(TEKKOTSU_ROOT)/tools/mntmem $(MEMSTICK_ROOT)
! 	cp -r $(OPENRSDK_ROOT)/OPEN_R/MS/WCONSOLE/nomemprot/* $(MEMSTICK_ROOT)
  	$(TEKKOTSU_ROOT)/tools/umntmem $(MEMSTICK_ROOT)
  
  $(FILTERSYSWARN):
Index: AiboPup/project/StartupBehavior.cc
diff -c AiboPup/project/StartupBehavior.cc:1.31 AiboPup/project/StartupBehavior.cc:1.36
*** AiboPup/project/StartupBehavior.cc:1.31	Fri Jun 13 01:57:06 2003
--- AiboPup/project/StartupBehavior.cc	Tue Jul  8 18:29:11 2003
***************
*** 21,27 ****
  #include "Behaviors/Controls/SavePostureControl.h"
  #include "Behaviors/Controls/SaveWalkControl.h"
  #include "Behaviors/Controls/ShutdownControl.h"
- #include "Behaviors/Controls/ToggleHeadLightControl.h"
  #include "Behaviors/Controls/ValueEditControl.h"
  #include "Behaviors/Controls/ValueSetControl.h"
  
--- 21,26 ----
***************
*** 40,47 ****
  #include "Behaviors/Demos/WorldModel2Behavior.h"
  #include "Behaviors/Demos/DumbWM2Behavior.h"
  #include "Behaviors/Demos/SoundTestBehavior.h"
! #include "Behaviors/Demos/MechaControllerBehavior.h"
  #include "Behaviors/Demos/Aibo3DControllerBehavior.h"
  
  #include "Motion/MotionCommand.h"
  #include "Motion/PostureMC.h"
--- 39,50 ----
  #include "Behaviors/Demos/WorldModel2Behavior.h"
  #include "Behaviors/Demos/DumbWM2Behavior.h"
  #include "Behaviors/Demos/SoundTestBehavior.h"
! #include "Behaviors/Demos/ToggleHeadLightBehavior.h"
! #include "Behaviors/Demos/WalkControllerBehavior.h"
! #include "Behaviors/Demos/HeadPointControllerBehavior.h"
  #include "Behaviors/Demos/Aibo3DControllerBehavior.h"
+ #include "Behaviors/Demos/Aibo3DMonitorBehavior.h"
+ #include "Behaviors/Demos/EStopControllerBehavior.h"
  
  #include "Motion/MotionCommand.h"
  #include "Motion/PostureMC.h"
***************
*** 164,181 ****
  			mcsetup.top()->pushSlot(new BehaviorSwitchControl<WorldModel2Behavior>("WorldModel2Behavior",bg,false));
  			mcsetup.pop();
  		}
! 		mcsetup.top()->pushSlot(new ControlBase("Background Behaviors","Background daemons, servers, and monitors"));
  		{ 
  			mcsetup.push(mcsetup.top()->getSlots().back());
  			mcsetup.top()->pushSlot((new BehaviorSwitchControl<AutoGetupBehavior>("AutoGetupBehavior",false))->start());
  			mcsetup.top()->pushSlot((new BehaviorSwitchControl<BatteryMonitorBehavior>("BatteryMonitorBehavior",false))->start());
  			mcsetup.top()->pushSlot(new BehaviorSwitchControl<EvtRptBehavior>("EvtRptBehavior",false));
  			mcsetup.top()->pushSlot(new BehaviorSwitchControl<DumbWM2Behavior>("DumbWM2Behavior",false));
! 			mcsetup.top()->pushSlot((new BehaviorSwitchControl<MechaControllerBehavior>("MechaController",false))->start());
! 			mcsetup.top()->pushSlot((new BehaviorSwitchControl<Aibo3DControllerBehavior>("Aibo3DController",false))->start());
  			mcsetup.top()->pushSlot(new BehaviorSwitchControl<HeadLevelBehavior>("HeadLevelBehavior",false));
  			if(state->robotDesign & WorldState::ERS220Mask)
! 				mcsetup.top()->pushSlot(new ToggleHeadLightControl());
  			mcsetup.pop();
  		}
  		mcsetup.top()->pushSlot(new ControlBase("Status Reports","Displays information about the runtime environment on the console"));
--- 167,197 ----
  			mcsetup.top()->pushSlot(new BehaviorSwitchControl<WorldModel2Behavior>("WorldModel2Behavior",bg,false));
  			mcsetup.pop();
  		}
! 		mcsetup.top()->pushSlot(new ControlBase("Background Behaviors","Background daemons and monitors"));
  		{ 
  			mcsetup.push(mcsetup.top()->getSlots().back());
  			mcsetup.top()->pushSlot((new BehaviorSwitchControl<AutoGetupBehavior>("AutoGetupBehavior",false))->start());
  			mcsetup.top()->pushSlot((new BehaviorSwitchControl<BatteryMonitorBehavior>("BatteryMonitorBehavior",false))->start());
  			mcsetup.top()->pushSlot(new BehaviorSwitchControl<EvtRptBehavior>("EvtRptBehavior",false));
  			mcsetup.top()->pushSlot(new BehaviorSwitchControl<DumbWM2Behavior>("DumbWM2Behavior",false));
! 			BehaviorSwitchControlBase::BehaviorGroup * aibo3D_bg = new BehaviorSwitchControlBase::BehaviorGroup();
! 			mcsetup.top()->pushSlot((new BehaviorSwitchControl<Aibo3DControllerBehavior>("Aibo3DController",aibo3D_bg,false)));
! 			mcsetup.top()->pushSlot((new BehaviorSwitchControl<Aibo3DMonitorBehavior>("Aibo3DMonitor",aibo3D_bg,false)));
  			mcsetup.top()->pushSlot(new BehaviorSwitchControl<HeadLevelBehavior>("HeadLevelBehavior",false));
  			if(state->robotDesign & WorldState::ERS220Mask)
! 				mcsetup.top()->pushSlot(new BehaviorSwitchControl<ToggleHeadLightBehavior>("ToggleHeadLightBehavior",false));
! 			mcsetup.pop();
! 		}
! 		mcsetup.top()->pushSlot(new ControlBase("TekkotsuMon","Servers for GUIs"));
! 		{ 
! 			mcsetup.push(mcsetup.top()->getSlots().back());
! 			mcsetup.top()->pushSlot((new BehaviorSwitchControl<HeadPointControllerBehavior>("Head Remote Control",false)));
! 			mcsetup.top()->pushSlot((new BehaviorSwitchControl<WalkControllerBehavior>("Walk Remote Control",false)));
! 			BehaviorSwitchControlBase::BehaviorGroup * aibo3D_bg = new BehaviorSwitchControlBase::BehaviorGroup();
! 			mcsetup.top()->pushSlot((new BehaviorSwitchControl<Aibo3DControllerBehavior>("Aibo3D Controller",aibo3D_bg,false)));
! 			mcsetup.top()->pushSlot((new BehaviorSwitchControl<Aibo3DMonitorBehavior>("Aibo3D Monitor",aibo3D_bg,false)));
! 			EStopControllerBehavior * ESCB=new EStopControllerBehavior(stop_id);
! 			mcsetup.top()->pushSlot((new BehaviorSwitchControl<EStopControllerBehavior,Factory1Arg<EStopControllerBehavior,MotionManager::MC_ID,MotionManager::invalid_MC_ID> >("EStop Remote Control",ESCB))->start());
  			mcsetup.pop();
  		}
  		mcsetup.top()->pushSlot(new ControlBase("Status Reports","Displays information about the runtime environment on the console"));
Index: AiboPup/project/ms/config/tekkotsu.cfg
diff -c AiboPup/project/ms/config/tekkotsu.cfg:1.15 AiboPup/project/ms/config/tekkotsu.cfg:1.17
*** AiboPup/project/ms/config/tekkotsu.cfg:1.15	Mon Jun  9 04:05:15 2003
--- AiboPup/project/ms/config/tekkotsu.cfg	Mon Jul  7 00:32:47 2003
***************
*** 28,35 ****
  verbose_level=0
  wsjoints_port=10031
  wspids_port=10032
! mecha_port=10050
  aibo3d_port=10051
  use_VT100=true
  
  [Behaviors]
--- 28,37 ----
  verbose_level=0
  wsjoints_port=10031
  wspids_port=10032
! walkControl_port=10050
  aibo3d_port=10051
+ headControl_port=10052
+ estopControl_port=10053
  use_VT100=true
  
  [Behaviors]
Index: AiboPup/project/ms/open-r/mw/conf/passwd
diff -c AiboPup/project/ms/open-r/mw/conf/passwd:1.1 AiboPup/project/ms/open-r/mw/conf/passwd:1.3
*** AiboPup/project/ms/open-r/mw/conf/passwd:1.1	Sat Mar  1 16:08:29 2003
--- AiboPup/project/ms/open-r/mw/conf/passwd	Tue Jul  8 14:01:21 2003
***************
*** 1,2 ****
--- 1,5 ----
  #user pass /MS/
  #guest * /MS/OPEN-R/MW/
+ config config /MS/CONFIG/
+ data data /MS/DATA/
+ 
Index: AiboPup/project/ms/open-r/system/conf/wlandflt.txt
diff -c AiboPup/project/ms/open-r/system/conf/wlandflt.txt:1.9 AiboPup/project/ms/open-r/system/conf/wlandflt.txt:1.12
*** AiboPup/project/ms/open-r/system/conf/wlandflt.txt:1.9	Thu Jun 12 23:23:05 2003
--- AiboPup/project/ms/open-r/system/conf/wlandflt.txt	Sun Jul  6 21:00:09 2003
***************
*** 1,5 ****
! HOSTNAME=AIBO
! ETHER_IP=192.168.0.6
  ETHER_NETMASK=255.255.255.0
  IP_GATEWAY=192.168.0.1
  ESSID=AIBONET
--- 1,5 ----
! HOSTNAME=lycra
! ETHER_IP=192.168.0.5
  ETHER_NETMASK=255.255.255.0
  IP_GATEWAY=192.168.0.1
  ESSID=AIBONET
Index: AiboPup/tools/umntmem
diff -c AiboPup/tools/umntmem:1.4 AiboPup/tools/umntmem:1.5
*** AiboPup/tools/umntmem:1.4	Tue Apr 29 23:55:58 2003
--- AiboPup/tools/umntmem	Sat Jun 28 14:03:57 2003
***************
*** 7,13 ****
  
  case "`uname`" in
  	CYGWIN*)
! 		echo "Don't forget to stop your memory stick before removing it.";
  		exit 0;
  		;;
  	Darwin)
--- 7,13 ----
  
  case "`uname`" in
  	CYGWIN*)
! 		echo "Don't forget to stop your memory stick before removing it. (Unless you have XP)";
  		exit 0;
  		;;
  	Darwin)
Index: AiboPup/tools/aibo3d/Aibo3D.java
diff -c AiboPup/tools/aibo3d/Aibo3D.java:1.2 AiboPup/tools/aibo3d/Aibo3D.java:1.3
*** AiboPup/tools/aibo3d/Aibo3D.java:1.2	Fri Jun 13 01:15:31 2003
--- AiboPup/tools/aibo3d/Aibo3D.java	Sat Jun 28 14:03:57 2003
***************
*** 25,36 ****
  		int port=10031;
  		if(args.length>1)
  			port=Integer.parseInt(args[1]);
!     new Aibo3D(args[0],port);
    }
  
!   public Aibo3D(String host, int port) {
      super("Aibo 3D");
!     setSize(600,400);
  
      setup3DCanvas();
      loadLW3D("aibo3d.lws");
--- 25,36 ----
  		int port=10031;
  		if(args.length>1)
  			port=Integer.parseInt(args[1]);
!     new Aibo3D(args[0],port,null);
    }
  
!   public Aibo3D(String host, int port, String args[]) {
      super("Aibo 3D");
!     setSize(500,500);
  
      setup3DCanvas();
      loadLW3D("aibo3d.lws");
***************
*** 62,67 ****
--- 62,71 ----
    
  //    testLimits(forward.thigh_bl,50);
    }
+ 
+ 	void close() {
+ 		dispose();
+ 	}
  
    void testLimits(AiboJoint j) {
      float step;
Index: AiboPup/tools/aibo3d/Aibo3DPick.java
diff -c AiboPup/tools/aibo3d/Aibo3DPick.java:1.4 AiboPup/tools/aibo3d/Aibo3DPick.java:1.6
*** AiboPup/tools/aibo3d/Aibo3DPick.java:1.4	Fri Jun 13 01:15:31 2003
--- AiboPup/tools/aibo3d/Aibo3DPick.java	Thu Jul  3 06:01:49 2003
***************
*** 23,29 ****
    BranchGroup branchGroup;
    SimpleUniverse universe;
    BranchGroup root;
-   // com.tornadolabs.j3dtree.Java3dTree java3dTree;
    
    public static void main(String args[]) {
  		if(args.length<1) {
--- 23,28 ----
***************
*** 34,43 ****
  		int port=10051;
  		if(args.length>1)
  			port=Integer.parseInt(args[1]);
!     new Aibo3DPick(args[0],port);
    }
  
!   public Aibo3DPick(String host, int port) {
      super("Aibo 3D");
      setSize(600,400);
  
--- 33,42 ----
  		int port=10051;
  		if(args.length>1)
  			port=Integer.parseInt(args[1]);
!     new Aibo3DPick(args[0],port,null);
    }
  
!   public Aibo3DPick(String host, int port, String args[]) {
      super("Aibo 3D");
      setSize(600,400);
  
***************
*** 46,58 ****
      forward=new Aibo3DForward(scene);
      showScene();
  
-     // java3dTree = new com.tornadolabs.j3dtree.Java3dTree();
-     // java3dTree.recursiveApplyCapability(root);
-     // java3dTree.updateNodes(universe);
      picker.createPicker();
  		mirrorServer(host,port);
    }
  
    void mirrorListener(String host, int port) {
      WorldStateJointsListener wsj=
        new WorldStateJointsListener(host,port);
--- 45,58 ----
      forward=new Aibo3DForward(scene);
      showScene();
  
      picker.createPicker();
  		mirrorServer(host,port);
    }
  
+ 	void close() {
+ 		dispose();
+ 	}
+ 
    void mirrorListener(String host, int port) {
      WorldStateJointsListener wsj=
        new WorldStateJointsListener(host,port);
***************
*** 177,182 ****
--- 177,183 ----
  
      // recursively set the user data here
      // so we can find our objects when they are picked
+     
      java.util.Enumeration enumValues = namedObjects.elements( );
      java.util.Enumeration enumKeys = namedObjects.keys( );
      if( enumValues != null )
***************
*** 215,223 ****
--- 216,275 ----
        root.addChild(transformGroup);
      }
  
+     moveLights(scene.getSceneGroup(), root);
+ //    recursivePrintGroup(root);
+ 
      return root;
    }
+ 
+   void moveLights(Group from, Group to) {
+     from.setCapability(Group.ALLOW_CHILDREN_READ);
+ 
+     java.util.Enumeration enumKids = from.getAllChildren();
+     while( enumKids.hasMoreElements( ) != false ) {
+       Object o = enumKids.nextElement();
+       if (o instanceof Group) {
+         moveLights((Group)o, to);
+       } else if (o instanceof DirectionalLight || o instanceof PointLight) {
+         from.setCapability(Group.ALLOW_CHILDREN_WRITE);
+         to.setCapability(Group.ALLOW_CHILDREN_READ);
+         to.setCapability(Group.ALLOW_CHILDREN_WRITE);
+         from.removeChild((Node)o);
+         to.addChild((Node)o);
+       }
+     }
+ 
+   }
+ 
+   void recursivePrintGroup(Object sgo) {
+     recursivePrintGroup(sgo,"");
+   }
+ 
+   void recursivePrintGroup(Object sgo, String indent) {
+     if( sgo instanceof SceneGraphObject != false )
+     {
+       SceneGraphObject sg = (SceneGraphObject) sgo;
+                                                                                 
+       // recursively process group
+       if( sg instanceof Group )
+       {
+         Group g = (Group) sg;
+         g.setCapability(Group.ALLOW_CHILDREN_READ);
+                                                                                 
+         // recurse on child nodes
+         java.util.Enumeration enumKids = g.getAllChildren( );
+                                                                                 
+         while( enumKids.hasMoreElements( ) != false )
+           recursivePrintGroup( enumKids.nextElement( ), indent+"  ");
+       }
+       else if ( sg instanceof Node || sg instanceof NodeComponent)
+       {
+         System.out.println(indent+sg);
+       }
+     }
    
+   }
+ 
    void recursiveSetUserData( Object value, Object key )
    {
      if( value instanceof SceneGraphObject != false )
Index: AiboPup/tools/aibo3d/aibo3d-old.lws
diff -c AiboPup/tools/aibo3d/aibo3d-old.lws:1.1 AiboPup/tools/aibo3d/aibo3d-old.lws:removed
*** AiboPup/tools/aibo3d/aibo3d-old.lws:1.1	Thu May 29 16:02:11 2003
--- AiboPup/tools/aibo3d/aibo3d-old.lws	Tue Jul  8 22:31:52 2003
***************
*** 1,385 ****
- LWSC
- 1
- 
- FirstFrame 1
- LastFrame 60
- FrameStep 1
- PreviewFirstFrame 1
- PreviewLastFrame 60
- PreviewFrameStep 1
- FramesPerSecond 30.000000
- 
- LoadObject objects/body2.lwo
- ShowObject 8 7
- ObjectMotion (unnamed)
-   9
-   1
-   0 0.177 0.014 0 0 0 1 1 1
-   0 0 0 0 0
- EndBehavior 1
- ShadowOptions 7
- 
- LoadObject objects/ear-l.lwo
- ShowObject 8 7
- ObjectMotion (unnamed)
-   9
-   1
-   0.02704999 0.06610002 0.006099998 0 0 0 1 1 1
-   0 0 0 0 0
- EndBehavior 1
- LockedChannels 6
- ParentObject 7
- ShadowOptions 7
- 
- LoadObject objects/ear-r.lwo
- ShowObject 8 7
- ObjectMotion (unnamed)
-   9
-   1
-   -0.02705 0.06610002 0.006149998 0 0 0 1 1 1
-   0 0 0 0 0
- EndBehavior 1
- LockedChannels 7
- ParentObject 7
- ShadowOptions 7
- 
- LoadObject objects/foot-b-l.lwo
- ShowObject 8 7
- ObjectMotion (unnamed)
-   9
-   1
-   0 -0.07345001 0.02495 0 0 0 1 1 1
-   0 0 0 0 0
- EndBehavior 1
- ParentObject 17
- ShadowOptions 7
- 
- LoadObject objects/foot-b-r.lwo
- ShowObject 8 7
- ObjectMotion (unnamed)
-   9
-   1
-   0 -0.0735 0.025 0 0 0 1 1 1
-   0 0 0 0 0
- EndBehavior 1
- LockedChannels 1
- ParentObject 18
- ShadowOptions 7
- 
- LoadObject objects/foot-f-r.lwo
- ShowObject 8 7
- ObjectMotion (unnamed)
-   9
-   1
-   0 -0.0649 -0.0293 0 0 0 1 1 1
-   0 0 0 0 0
- EndBehavior 1
- LockedChannels 1
- ParentObject 22
- ShadowOptions 7
- 
- LoadObject objects/head.lwo
- ShowObject 8 7
- ObjectMotion (unnamed)
-   9
-   1
-   0 0.02689999 -0.0004500076 0 0 0 1 1 1
-   0 0 0 0 0
- EndBehavior 1
- ParentObject 25
- ShadowOptions 7
- 
- LoadObject objects/jaw.lwo
- ShowObject 8 7
- ObjectMotion (unnamed)
-   9
-   1
-   0 -0.00475 -0.02945 0 0 0 1 1 1
-   0 0 0 0 0
- EndBehavior 1
- ParentObject 7
- ShadowOptions 7
- 
- LoadObject objects/LED_g01.lwo
- ShowObject 8 7
- ObjectMotion (unnamed)
-   9
-   1
-   0 0 0 0 0 0 1 1 1
-   0 0 0 0 0
- EndBehavior 1
- ParentObject 7
- ShadowOptions 7
- 
- LoadObject objects/LED_g02.lwo
- ShowObject 8 7
- ObjectMotion (unnamed)
-   9
-   1
-   0 0 0 0 0 0 1 1 1
-   0 0 0 0 0
- EndBehavior 1
- ParentObject 7
- ShadowOptions 7
- 
- LoadObject objects/LED_g03.lwo
- ShowObject 8 7
- ObjectMotion (unnamed)
-   9
-   1
-   0 0 0 0 0 0 1 1 1
-   0 0 0 0 0
- EndBehavior 1
- ParentObject 7
- ShadowOptions 7
- 
- LoadObject objects/LED_r01.lwo
- ShowObject 8 7
- ObjectMotion (unnamed)
-   9
-   1
-   0 0 0 0 0 0 1 1 1
-   0 0 0 0 0
- EndBehavior 1
- ParentObject 7
- ShadowOptions 7
- 
- LoadObject objects/LED_r02.lwo
- ShowObject 8 7
- ObjectMotion (unnamed)
-   9
-   1
-   0 0 0 0 0 0 1 1 1
-   0 0 0 0 0
- EndBehavior 1
- ParentObject 7
- ShadowOptions 7
- 
- LoadObject objects/LED_r03.lwo
- ShowObject 8 7
- ObjectMotion (unnamed)
-   9
-   1
-   0 0 0 0 0 0 1 1 1
-   0 0 0 0 0
- EndBehavior 1
- ParentObject 7
- ShadowOptions 7
- 
- LoadObject objects/LED_r04.lwo
- ShowObject 8 7
- ObjectMotion (unnamed)
-   9
-   1
-   0 0 0 0 0 0 1 1 1
-   0 0 0 0 0
- EndBehavior 1
- ParentObject 7
- ShadowOptions 7
- 
- LoadObject objects/LED_tail.lwo
- ShowObject 8 7
- ObjectMotion (unnamed)
-   9
-   1
-   0 0 0 0 0 0 1 1 1
-   0 0 0 0 0
- EndBehavior 1
- ParentObject 26
- ShadowOptions 7
- 
- LoadObject objects/leg-b-low-l.lwo
- ShowObject 8 7
- ObjectMotion (unnamed)
-   9
-   1
-   -0.001850001 -0.09015001 0.0225 0 0 0 1 1 1
-   0 0 0 0 0
- EndBehavior 1
- LockedChannels 6
- ParentObject 19
- ShadowOptions 7
- 
- LoadObject objects/leg-b-low-r.lwo
- ShowObject 8 7
- ObjectMotion (unnamed)
-   9
-   1
-   0.00205 -0.09019998 0.0225 0 0 0 1 1 1
-   0 0 0 0 0
- EndBehavior 1
- LockedChannels 6
- ParentObject 20
- ShadowOptions 7
- 
- LoadObject objects/leg-b-up-l.lwo
- ShowObject 8 7
- ObjectMotion (unnamed)
-   9
-   1
-   0.07045 0.0033 0.06394999 0 0 0 1 1 1
-   0 0 0 0 0
- EndBehavior 1
- LockedChannels 6
- ParentObject 1
- ShadowOptions 7
- 
- LoadObject objects/leg-b-up-r.lwo
- ShowObject 8 7
- ObjectMotion (unnamed)
-   9
-   1
-   -0.07064998 0.003349999 0.06394999 0 0 0 1 1 1
-   0 0 0 0 0
- EndBehavior 1
- LockedChannels 6
- ParentObject 1
- ShadowOptions 7
- 
- LoadObject objects/leg-f-low-l.lwo
- ShowObject 8 7
- ObjectMotion (unnamed)
-   9
-   1
-   -0.00165 -0.09469999 -0.01165 0 0 0 1 1 1
-   0 0 0 0 0
- EndBehavior 1
- LockedChannels 6
- ParentObject 23
- ShadowOptions 7
- 
- LoadObject objects/leg-f-low-r.lwo
- ShowObject 8 7
- ObjectMotion (unnamed)
-   9
-   1
-   0.00105 -0.0948 -0.0116 0 0 0 1 1 1
-   0 0 0 0 0
- EndBehavior 1
- LockedChannels 6
- ParentObject 24
- ShadowOptions 7
- 
- LoadObject objects/leg-f-up-l.lwo
- ShowObject 8 7
- ObjectMotion (unnamed)
-   9
-   1
-   0.07045001 -0.0007499999 -0.07510001 0 0 0 1 1 1
-   0 0 0 0 0
- EndBehavior 1
- LockedChannels 6
- ParentObject 1
- ShadowOptions 7
- 
- LoadObject objects/leg-f-up-r.lwo
- ShowObject 8 7
- ObjectMotion (unnamed)
-   9
-   1
-   -0.07044999 -0.0006499998 -0.07515001 0 0 0 1 1 1
-   0 0 0 0 0
- EndBehavior 1
- LockedChannels 6
- ParentObject 1
- ShadowOptions 7
- 
- LoadObject objects/neck.lwo
- ShowObject 8 7
- ObjectMotion (unnamed)
-   9
-   1
-   0 0.0627 -0.10004999 0 0 0 1 1 1
-   0 0 0 0 0
- EndBehavior 1
- ParentObject 1
- ShadowOptions 7
- 
- LoadObject objects/tail2.lwo
- ShowObject 8 7
- ObjectMotion (unnamed)
-   9
-   1
-   0 0.05715 0.08279999 0 0 0 1 1 1
-   0 0 0 0 0
- EndBehavior 1
- ParentObject 1
- ShadowOptions 7
- 
- LoadObject objects/foot-f-l.lwo
- ShowObject 8 7
- ObjectMotion (unnamed)
-   9
-   1
-   0 -0.06485 -0.02929999 0 0 0 1 1 1
-   0 0 0 0 0
- EndBehavior 1
- LockedChannels 1
- ParentObject 21
- ShadowOptions 7
- 
- AmbientColor 255 255 255
- AmbIntensity 0.250000
- 
- AddLight
- LightName Light
- ShowLight 1 7
- LightMotion (unnamed)
-   9
-   1
-   -2 2 -2 45 35 0 1 1 1
-   0 0 0 0 0
- EndBehavior 1
- LightColor 255 255 255
- LgtIntensity 1.000000
- LightType 0
- ShadowType 1
- 
- ShowCamera 1 7
- CameraMotion (unnamed)
-   9
-   1
-   -0.6381658 0.5205013 -0.6771318 0 0 0 1 1 1
-   0 0 0 0 0
- EndBehavior 1
- TargetObject 1
- ZoomFactor 3.200000
- Resolution 1
- PixelAspectRatio 2
- SegmentMemory 2200000
- Antialiasing 0
- AdaptiveSampling 1
- AdaptiveThreshold 16
- FilmSize 2
- FieldRendering 0
- MotionBlur 0
- DepthOfField 0
- 
- SolidBackdrop 1
- BackdropColor 0 0 0
- ZenithColor 0 40 80
- SkyColor 120 180 240
- GroundColor 50 40 30
- NadirColor 100 80 60
- FogType 0
- DitherIntensity 1
- AnimatedDither 0
- 
- RenderMode 2
- RayTraceEffects 0
- ClipRayColors 0
- DataOverlayLabel  
- FullSceneParamEval 0
- 
- ViewMode 5
- ViewAimpoint -0.006362 0.165064 -0.119767
- ViewDirection 0.300197 -0.314159 0.000000
- ViewZoomFactor 0.526749
- GridNumber 40
- GridSize 0.010000
- ShowMotionPath 1
- ShowBGImage 0
- ShowFogRadius 0
- ShowRedraw 0
- ShowSafeAreas 0
- ShowFieldChart 0
--- 0 ----
Index: AiboPup/tools/aibo3d/aibo3d.lws
diff -c AiboPup/tools/aibo3d/aibo3d.lws:1.1 AiboPup/tools/aibo3d/aibo3d.lws:1.3
*** AiboPup/tools/aibo3d/aibo3d.lws:1.1	Thu May 29 16:02:12 2003
--- AiboPup/tools/aibo3d/aibo3d.lws	Thu Jul  3 06:01:26 2003
***************
*** 320,326 ****
  ShadowOptions 7
  
  AmbientColor 255 255 255
! AmbIntensity 0.250000
  
  AddLight
  LightName Light
--- 320,326 ----
  ShadowOptions 7
  
  AmbientColor 255 255 255
! AmbIntensity 0.50000
  
  AddLight
  LightName Light
***************
*** 332,338 ****
    0 0 0 0 0
  EndBehavior 1
  LightColor 255 255 255
! LgtIntensity 1.000000
  LightType 0
  ShadowType 1
  
--- 332,338 ----
    0 0 0 0 0
  EndBehavior 1
  LightColor 255 255 255
! LgtIntensity 0.700000
  LightType 0
  ShadowType 1
  
***************
*** 357,363 ****
  DepthOfField 0
  
  SolidBackdrop 1
! BackdropColor 0 0 0
  ZenithColor 0 40 80
  SkyColor 120 180 240
  GroundColor 50 40 30
--- 357,363 ----
  DepthOfField 0
  
  SolidBackdrop 1
! BackdropColor 80 80 180 
  ZenithColor 0 40 80
  SkyColor 120 180 240
  GroundColor 50 40 30
Index: AiboPup/tools/bandit-sim/bandit.java
diff -c /dev/null AiboPup/tools/bandit-sim/bandit.java:1.1
*** /dev/null	Tue Jul  8 22:31:53 2003
--- AiboPup/tools/bandit-sim/bandit.java	Sun Jun 22 13:11:53 2003
***************
*** 0 ****
--- 1,333 ----
+ /*
+ * @(#)SwingShapeMover.java   1.2 98/07/31
+ */
+ 
+ 
+ import java.awt.*;
+ import java.awt.event.*;
+ import java.awt.image.*;
+ import javax.swing.*;
+ import java.util.Random;
+ import javax.sound.sampled.*;
+ import java.io.File;
+ import java.io.IOException;
+ 
+ /*
+  * This applet allows the user to move a texture painted rectangle around the applet
+  * window.  The rectangle flickers and draws slowly because this applet does not use 
+  * double buffering.
+ */
+ 
+ public class bandit extends JApplet {
+     static protected JLabel label;
+     DPanel d;
+ 
+     public void init(){
+         getContentPane().setLayout(new BorderLayout());
+ 
+ 		getContentPane().setBackground(Color.black);
+ 
+         label = new JLabel("Press keys to play...");
+ 		label.setBackground(Color.black);
+ 		label.setForeground(Color.white);
+ 
+         d = new DPanel(label);
+         d.setBackground(Color.black);
+         getContentPane().add(d);
+ 
+         getContentPane().add("South", label);
+         
+         TextField tmp = new TextField(3);
+         tmp.setBackground(Color.black);
+         getContentPane().add("North",tmp);
+         
+         tmp.addKeyListener(d);
+         tmp.requestFocus();
+ 
+         (new MoveBall(d)).start();
+     }
+ 
+     public static void main(String s[]) {
+         JFrame f = new JFrame("k-Armed Bandit");
+         f.addWindowListener(new WindowAdapter() {
+             public void windowClosing(WindowEvent e) {System.exit(0);}
+         });
+         JApplet applet = new bandit();
+         f.getContentPane().add("Center", applet);
+         applet.init();
+         f.pack();
+         f.setSize(new Dimension(700,500));
+         f.show();
+     }
+     
+ }
+ 
+ class MoveBall extends Thread {
+ 	DPanel panel;
+ 	long last;
+ 	Random rand;
+ 	double perterb;
+ 	public MoveBall(DPanel dp) {
+ 		panel=dp;
+ 		last=System.currentTimeMillis();
+ 		rand = new Random(last);
+ 		perterb=20;
+ 	}
+ 	public void run() {
+ 		while(true) {
+ 			long now=System.currentTimeMillis();
+ 			double diff=(now-last)/1000.0;
+ 			last=now;
+ 			double d=panel.dx*diff;
+ 			panel.x=panel.x+(d>panel.maxd?panel.maxd:d);
+ 			d=panel.dy*diff;
+ 			panel.y=panel.y+(d>panel.maxd?panel.maxd:d);
+ 			if(panel.x+panel.r>panel.getSize().width) {
+ 				panel.dx=-Math.abs(panel.dx);
+ 				panel.x=panel.getSize().width-panel.r;
+ 				panel.dy=panel.dy+(rand.nextDouble()-.5)*perterb;
+ 			} else if(panel.x-panel.r<0) {
+ 				panel.dx=Math.abs(panel.dx);
+ 				panel.x=panel.r;
+ 				panel.dy=panel.dy+(rand.nextDouble()-.5)*perterb;
+ 			}
+ 			if(panel.y+panel.r>panel.getSize().height) {
+ 				panel.dy=-Math.abs(panel.dy);
+ 				panel.y=panel.getSize().height-panel.r;
+ 				panel.dx=panel.dx+(rand.nextDouble()-.5)*perterb;
+ 			} else if(panel.y-panel.r<0) {
+ 				panel.dy=Math.abs(panel.dy);
+ 				panel.y=panel.r;
+ 				panel.dx=panel.dx+(rand.nextDouble()-.5)*perterb;
+ 			}
+ 			panel.repaint();
+ 			try {
+ 				sleep(1000/30);
+ 			} catch(Exception e) {}
+ 		}
+ 	}
+ }
+ 
+ class ShowReward extends Thread {
+ 	DPanel panel;
+ 	public ShowReward(DPanel dp) {
+ 		panel=dp;
+ 	}
+ 	public void run() {
+ 		panel.reward=true;
+ 		try {
+ 			sleep(1500);
+ 		} catch(Exception e) {
+ 			interrupted();
+ 		}
+ 		panel.reward=false;
+ 		panel.showreward=null;
+ 	}
+ }
+ 
+ class DPanel extends JPanel implements KeyListener {
+ 	BufferedImage redball;
+ 	BufferedImage pinkball;
+ 	protected double dx,dy;
+ 	protected double x,y,r;
+ 	protected double maxd;
+ 	double probLeft,probRight;
+ 	long lastkeypress;
+ 	Random rand;
+ 	protected boolean reward;
+ 	protected ShowReward showreward;
+ 	int trial;
+ 	Clip rsnd;
+ 	Clip lsnd;
+ 
+ 	JLabel label;
+ 
+     public DPanel(JLabel l) {
+     	label=l;
+ 		dx=200;
+ 		dy=80;
+ 		x=130;
+ 		y=150;
+ 		r=150;
+ 		maxd=30;
+ 		probLeft=.2;
+ 		probRight=.7;
+ 		lastkeypress=0;
+ 		rand = new Random(System.currentTimeMillis());
+ 		reward=false;
+ 		showreward=new ShowReward(this);
+ 		trial=0;
+ 		DataLine.Info info;
+ 
+ 		redball = new BufferedImage((int)(r*2+maxd*2), (int)(r*2+maxd*2), BufferedImage.TYPE_INT_RGB);
+ 		Graphics2D big = redball.createGraphics();
+ 		big.setColor(new Color(220,44,0));
+ 		big.fillOval((int)maxd, (int)maxd, (int)(r*2), (int)(r*2));
+ 		pinkball = new BufferedImage((int)(r*2+maxd*2), (int)(r*2+maxd*2), BufferedImage.TYPE_INT_RGB);
+ 		big = pinkball.createGraphics();
+ 		big.setColor(new Color(255,0,0));
+ 		big.fillOval((int)maxd, (int)maxd, (int)(r*2), (int)(r*2));
+ 
+ 		try {
+ 			info = new DataLine.Info(Clip.class, AudioSystem.getAudioFileFormat(new File("reward.aif")).getFormat());
+ 		} catch(Exception e) {
+ 			System.out.println("Sound file not found: "+e);
+ 			return;
+ 		}
+ 		if (!AudioSystem.isLineSupported(info)) { System.out.println("Sound is screwy"); }
+ 		try {
+ 			rsnd = (Clip)AudioSystem.getLine(info);
+ 			rsnd.open(AudioSystem.getAudioInputStream(new File("reward.aif")));
+ 		} catch (Exception ex) {
+ 			System.out.println("Couldn't load reward sound"+ex);
+ 		}
+ 		try {
+ 			info = new DataLine.Info(Clip.class, AudioSystem.getAudioFileFormat(new File("loss.aif")).getFormat());
+ 		} catch(Exception e) {
+ 			System.out.println("Sound file not found: "+e);
+ 			return;
+ 		}
+ 		if (!AudioSystem.isLineSupported(info)) { System.out.println("Sound is screwy"); }
+ 		try {
+ 			lsnd = (Clip)AudioSystem.getLine(info);
+ 			lsnd.open(AudioSystem.getAudioInputStream(new File("loss.aif")));
+ 		} catch (Exception ex) {
+ 			System.out.println("Couldn't load loss sound"+ex);
+ 		}
+ 
+     }
+     public void paintComponent(Graphics g){
+ 		super.paintComponent(g);
+ 		Graphics2D g2 = (Graphics2D)g;
+ 		if(reward)
+     	    g2.drawImage(pinkball,null,(int)(x-maxd-r),(int)(y-maxd-r));
+         else
+ 	        g2.drawImage(redball,null,(int)(x-maxd-r),(int)(y-maxd-r));
+ 	}
+ 	public void keyPressed(KeyEvent e) {
+ 		char c=e.getKeyChar();
+ 		float x=getKeyboardPos(c);
+ 		if(x<0) {
+ 			if(c>='0' && c<='9') {
+ 				probLeft=(((char)c)-'0')/10.0;
+ 			} else {
+ 				switch(c) {
+ 					case '!':
+ 						probRight=.1; break;
+ 					case '@':
+ 						probRight=.2; break;
+ 					case '#':
+ 						probRight=.3; break;
+ 					case '$':
+ 						probRight=.4; break;
+ 					case '%':
+ 						probRight=.5; break;
+ 					case '^':
+ 						probRight=.6; break;
+ 					case '&':
+ 						probRight=.7; break;
+ 					case '*':
+ 						probRight=.8; break;
+ 					case '(':
+ 						probRight=.9; break;
+ 					case ')':
+ 						probRight=0; break;
+ 				}
+ 			}
+ 			label.setText("P(R|Left)="+probLeft+"  P(R|Right)="+probRight+"   Trial="+trial);
+ 		} else if(e.getWhen()-1500>lastkeypress){
+ 			double prob=(x>.5)?probRight:probLeft;
+ 			double choice=rand.nextDouble();
+ 			System.out.println(prob+" "+choice);
+ 			String text;
+ 			trial++;
+ 			if(choice<prob) {
+ 				text="Reward! :)";
+ 				if(showreward!=null)
+ 					showreward.interrupt();
+ 				showreward=new ShowReward(this);
+ 				showreward.start();
+ 				if(rsnd!=null) {
+ 						rsnd.setMicrosecondPosition(0);
+ 						rsnd.start();
+ 				}
+ 			} else {
+ 				text="No reward. :(";
+ 				if(showreward!=null)
+ 					showreward.interrupt();
+ 				if(lsnd!=null) {
+ 						lsnd.setMicrosecondPosition(0);
+ 						lsnd.start();
+ 				}
+ 			}
+ 			label.setText("P(R|Left)="+probLeft+"  P(R|Right)="+probRight+"   Trial="+trial+(x>.5?"     Right - ":"     Left - ")+text);
+ 			lastkeypress=e.getWhen();
+ 		}
+ 	}
+ 	public void keyReleased(KeyEvent e) {}
+ 	public void keyTyped(KeyEvent e) {}
+ 	float getKeyboardPos(char c) {
+ 		double x;
+ 		switch(c) {
+ 			case 'q':
+ 				x=0; break;
+ 			case 'a':
+ 				x=.5; break;
+ 			case 'w':
+ 			case 'z':
+ 				x=1; break;
+ 			case 's':
+ 				x=1.5; break;
+ 			case 'e':
+ 			case 'x':
+ 				x=2; break;
+ 			case 'd':
+ 				x=2.5; break;
+ 			case 'r':
+ 			case 'c':
+ 				x=3; break;
+ 			case 'f':
+ 				x=3.5; break;
+ 			case 't':
+ 			case 'v':
+ 				x=4; break;
+ 			case 'g':
+ 				x=4.5; break;
+ 			case 'y':
+ 			case 'b':
+ 				x=5; break;
+ 			case 'h':
+ 				x=5.5; break;
+ 			case 'u':
+ 			case 'n':
+ 				x=6; break;
+ 			case 'j':
+ 				x=6.5; break;
+ 			case 'i':
+ 			case 'm':
+ 				x=7; break;
+ 			case 'k':
+ 				x=7.5; break;
+ 			case 'o':
+ 			case ',':
+ 				x=8; break;
+ 			case 'l':
+ 				x=8.5; break;
+ 			case 'p':
+ 			case '.':
+ 				x=9; break;
+ 			case ';':
+ 				x=9.5; break;
+ 			case '[':
+ 			case '/':
+ 				x=10; break;
+ 			case '\'':
+ 				x=10.5; break;
+ 			case ']':
+ 				x=11; break;
+ 			default:
+ 				x=-11; break;
+ 		}
+ 		return (float)(x/11);
+ 	}
+ }
Index: AiboPup/tools/bandit-sim/loss.aif
Index: AiboPup/tools/bandit-sim/manifestheader
diff -c /dev/null AiboPup/tools/bandit-sim/manifestheader:1.1
*** /dev/null	Tue Jul  8 22:31:53 2003
--- AiboPup/tools/bandit-sim/manifestheader	Sun Jun 22 13:11:53 2003
***************
*** 0 ****
--- 1,2 ----
+ Manifest-Version: 1.0
+ Main-Class: bandit
Index: AiboPup/tools/bandit-sim/reward.aif
Index: AiboPup/tools/mon/ClassPathModifier.java
diff -c /dev/null AiboPup/tools/mon/ClassPathModifier.java:1.2
*** /dev/null	Tue Jul  8 22:31:53 2003
--- AiboPup/tools/mon/ClassPathModifier.java	Sun Jul  6 21:00:09 2003
***************
*** 0 ****
--- 1,32 ----
+ import java.lang.*;
+ import java.net.*;
+ import java.io.*;
+ import java.lang.reflect.*;
+ 
+ public class ClassPathModifier {
+   private static final Class[] parameters = new Class[]{URL.class};
+ 
+   public static void addFile(String s) throws IOException {
+     File f = new File(s);
+     addFile(f);
+   }
+ 
+   public static void addFile(File f) throws IOException {
+     addURL(f.toURL());
+   }
+ 
+   public static void addURL(URL u) throws IOException {
+     URLClassLoader sysloader =
+       (URLClassLoader)ClassLoader.getSystemClassLoader();
+ 
+ 		Class sysclass = URLClassLoader.class;
+ 
+     try {
+       Method method = sysclass.getDeclaredMethod("addURL",parameters);
+       method.setAccessible(true);
+       method.invoke(sysloader, new Object[]{ u });
+     } catch (Throwable t) {
+       throw new IOException("could not add "+u+" to classpath");
+ 		}
+   }
+ }
Index: AiboPup/tools/mon/ControllerGUI.java
diff -c AiboPup/tools/mon/ControllerGUI.java:1.15 AiboPup/tools/mon/ControllerGUI.java:1.21
*** AiboPup/tools/mon/ControllerGUI.java:1.15	Fri Jun 13 00:38:05 2003
--- AiboPup/tools/mon/ControllerGUI.java	Tue Jul  8 14:01:21 2003
***************
*** 1 ****
! import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.event.*;import java.beans.*;import java.util.*;//Admittedly a little sloppy, but I don't want to spend forever on this...public class ControllerGUI extends JFrame implements ActionListener {	JList menu;	JScrollPane menuScroll;	JLabel title;	JLabel status;	JList bookmarks;	ControllerListener comm;	JButton cancelBut;	JButton refreshBut;	JButton reconnectBut;	JTextField inputField;	boolean isUpdating=false;		ControllerGUI(String addr, int port) {		pack();		setLocation(50,50);		show();		comm = new ControllerListener(addr,port);		comm.listener=this;	}		// Disables the component if there's nothing selected to apply it to	public class AutoDisableListener implements PropertyChangeListener, ListSelectionListener {		JComponent target;		public AutoDisableListener(JComponent target, JList source) {			this.target=target;			source.addPropertyChangeListener(this);			source.addListSelectionListener(this);		}		public void propertyChange(PropertyChangeEvent evt) {			target.setEnabled(!((JList)evt.getSource()).isSelectionEmpty());		}		public void valueChanged(ListSelectionEvent evt) {			target.setEnabled(!((JList)evt.getSource()).isSelectionEmpty());		}	}		final static ImageIcon rarrow = new ImageIcon("images/rarrow.png");	final static ImageIcon larrow = new ImageIcon("images/larrow.png");	final static ImageIcon carrows = new ImageIcon("images/chasingarrows.png");	public class MyCellRenderer implements ListCellRenderer {		public Component getListCellRendererComponent(JList list,Object value,int index,boolean isSelected,boolean cellHasFocus) {			ControllerListener.MenuEntry me=(ControllerListener.MenuEntry)value;			/*			if(me.hasSubmenu) {						setIcon(rarrow);						setHorizontalTextPosition(SwingConstants.RIGHT);						setIconTextGap(5);						} else						setIconTextGap(5+rarrow.getIconWidth());			*/						//System.out.println(this.getText()+" "+me.selected+" "+isSelected);			int numpre=(int)(Math.log(list.getModel().getSize()-1)/Math.log(10))-(index==0?0:(int)(Math.log(index)/Math.log(10)));			StringBuffer pre=new StringBuffer();			for(int i=0;i<numpre;i++)				pre.append(" ");			JLabel title=new JLabel(pre.toString()+index+". "+me.title);			title.setBackground(me.selected?list.getSelectionBackground():list.getBackground());			title.setForeground(me.selected?list.getSelectionForeground():list.getForeground());			title.setEnabled(list.isEnabled());			title.setFont(list.getFont());			title.setOpaque(true);			title.setPreferredSize(new Dimension(list.getSize().width,title.getPreferredSize().height));			//Vector tmp2=new Vector();			//for(int i=0;i<1000000;i++) {tmp2.add(new Integer(0));tmp2.remove(tmp2.size()-1);}			if(me.hasSubmenu) {				Box tmp=Box.createHorizontalBox();				tmp.add(title);				//				tmp.add(Box.createHorizontalGlue());				JLabel arr=new JLabel(rarrow);				arr.setEnabled(list.isEnabled());				tmp.add(arr);				if(me.description.length()!=0)					tmp.setToolTipText(me.description);				return tmp;			} else {				Box tmp=Box.createHorizontalBox();				tmp.add(title);				tmp.add(Box.createHorizontalStrut(rarrow.getIconWidth()));				if(me.description.length()!=0)					tmp.setToolTipText(me.description);				return tmp;			}		}	} 	 	public class JListDoubleClick extends MouseAdapter {		ControllerGUI gui;		JListDoubleClick(ControllerGUI gui) { this.gui=gui; }		public void mouseClicked(MouseEvent e) {			if (e.getClickCount() == 2) {				int index = ((JList)e.getSource()).locationToIndex(e.getPoint());				gui.doubleClicked((JList)e.getSource(),index);			}		}	}	public class MySelectionListener implements ListSelectionListener {		ControllerGUI gui;		MySelectionListener(ControllerGUI gui) { this.gui=gui; }		public void valueChanged(ListSelectionEvent e) {			if(!gui.isUpdating && !e.getValueIsAdjusting())				gui.comm.sendSelection(((JList)e.getSource()).getSelectedIndices());		}	} 		public class EscFilter extends KeyAdapter {		JButton trigger;		EscFilter(JButton trigger) { this.trigger=trigger; }		public void keyReleased(KeyEvent evt) {			if(evt.getKeyChar()==(char)27)				trigger.doClick();		}	}	public class ReturnFilter extends KeyAdapter {		ControllerGUI gui;		ReturnFilter(ControllerGUI gui) { this.gui=gui; }		public void keyReleased(KeyEvent evt) {			if(evt.getKeyCode()==KeyEvent.VK_ENTER)				gui.doubleClicked((JList)evt.getSource(),0);		}	} 		void updated() {			//		System.out.println("updated");		isUpdating=true;		Point p=menuScroll.getViewport().getViewPosition();  		//		bookmarks.setEnabled(comm._isConnected);		cancelBut.setEnabled(comm._isConnected);		refreshBut.setEnabled(comm._isConnected);		inputField.setEnabled(comm._isConnected);		if(!comm._isConnected) {			title.setText("-");			menu.setListData(new Vector());			status.setText("Reconnecting...");		} else {			title.setText((String)comm._titles.lastElement());			Vector menuitems=(Vector)comm._menus.lastElement();			synchronized(menu) {				menu.setValueIsAdjusting(true);				menu.setListData(menuitems);				Vector sels=new Vector();				for(int i=0; i<menuitems.size(); i++)					if(((ControllerListener.MenuEntry)menuitems.get(i)).selected)						sels.add(new Integer(i));				int[] selsArr=new int[sels.size()];				for(int i=0; i<selsArr.length; i++)					selsArr[i]=((Integer)sels.get(i)).intValue();				menu.setSelectedIndices(selsArr);				menu.setValueIsAdjusting(false);			}			status.setText(comm._status.length()>0?comm._status:"Connected.");		}		menuScroll.getViewport().setViewPosition(p);		isUpdating=false;		comm._updatedFlag=false;	}	public void paint(Graphics g) {		if(comm!=null && comm._updatedFlag)			updated();		super.paint(g);	}		public void actionPerformed(ActionEvent evt) {		if(evt.getSource()==cancelBut) {			//System.out.println("cancel button clicked");			comm.sendReturn();		} else if(evt.getSource()==refreshBut) {			//System.out.println("refresh button clicked");			comm.sendRefresh();		} else if(evt.getSource()==inputField) {			//System.out.println("input: "+inputField.getText());			int[] sel=menu.getSelectedIndices();			if(sel.length==0 || inputField.getText().charAt(0)=='!')				comm.sendInput(inputField.getText());			else				comm.sendInput("!input "+inputField.getText());			/*else if(sel.length==1) {				comm.sendSelectionPath(comm.buildSelectionPath(sel[0]));				comm.sendInput(inputField.getText());			} else				for(int i=0; i<sel.length; i++)					comm.sendInput(inputField.getText(),comm.buildSelectionPath(sel[i]));			*/			inputField.setText("");		} else if(evt.getSource()==reconnectBut) {			int port=comm._port;			String addr=comm._host;			comm.kill();			comm = new ControllerListener(addr,port);			comm.listener=this;		}	}		public void doubleClicked(JList list, int index) {		if(list==menu) {			Vector items=(Vector)comm._menus.lastElement();			//System.out.println(items.get(index)+" selected");			comm.sendSelect();			/*			int[] sel=menu.getSelectedIndices();						if(sel.length==1) {						comm.sendSelectionPath(comm.buildSelectionPath(sel[0]));						} else if(sel.length>1) {						Vector selectionPaths=new Vector();						for(int i=0; i<sel.length; i++)						selectionPaths.add(comm.buildSelectionPath(sel[i]));						for(int i=0; i<selectionPaths.size(); i++)						comm.sendSelectionPath((Vector)selectionPaths.get(i));						}			*/			inputField.setText("");		} else if(list==bookmarks) {			//todo		} else {			System.out.println("Unknown list double-clicked");		}	}		public class ConstSizeJButton extends JButton {		Dimension dim;		ConstSizeJButton(String s, ImageIcon i, Dimension d) { super(s,i); dim=d; }		public Dimension getPreferredSize() { return dim; }		public Dimension getMinimumSize() { return dim; }		public Dimension getMaximumSize() { return dim; }		public Dimension getSize() { return dim; }	}	protected void frameInit() {		super.frameInit();				int spacer_size=10;					setTitle("Controller Menus");		getContentPane().setLayout(new BorderLayout());		getContentPane().add(Box.createHorizontalStrut(spacer_size),BorderLayout.WEST);		getContentPane().add(Box.createHorizontalStrut(spacer_size),BorderLayout.EAST);		getContentPane().add(Box.createVerticalStrut(spacer_size),BorderLayout.NORTH);		getContentPane().add(Box.createVerticalStrut(spacer_size),BorderLayout.SOUTH);				menu=new JList();		menu.setCellRenderer(new MyCellRenderer());		menu.setFixedCellWidth(165);		menu.addMouseListener(new JListDoubleClick(this)); 		menu.addListSelectionListener(new MySelectionListener(this));				JPanel content=new JPanel(new BorderLayout());		Box titleBox=Box.createVerticalBox();		title=new JLabel("-");		title.setFont(new Font(title.getFont().getFontName(),Font.BOLD,title.getFont().getSize()));		title.setAlignmentX(0);		titleBox.add(title);		titleBox.add(Box.createVerticalStrut(spacer_size));		content.add(titleBox,BorderLayout.NORTH);				Box menuBox=Box.createVerticalBox();		menuScroll=new JScrollPane(menu);		menuScroll.setAlignmentX(0.5f);		menuBox.add(menuScroll);		{			Box tmp=Box.createHorizontalBox();			cancelBut=new JButton("Cancel");			Dimension dim=new Dimension(cancelBut.getPreferredSize().width+larrow.getIconWidth()+cancelBut.getIconTextGap(),cancelBut.getPreferredSize().height);			tmp.add(cancelBut=new ConstSizeJButton("Cancel",larrow,dim));			cancelBut.setEnabled(false);			cancelBut.addActionListener(this);			cancelBut.setToolTipText("Returns to previous control");			tmp.add(refreshBut=new JButton("Refresh"));			refreshBut.setEnabled(false);			refreshBut.addActionListener(this);			refreshBut.setToolTipText("Requests a menu refresh (handy if item names are dynamic)");			tmp.setAlignmentX(0.5f);			menuBox.add(tmp);		}		content.add(menuBox,BorderLayout.CENTER);		Box statusbox=Box.createVerticalBox();		statusbox.add(Box.createVerticalStrut(spacer_size));		{			JSeparator sep=new JSeparator(SwingConstants.HORIZONTAL);			statusbox.add(sep);		}		statusbox.add(Box.createVerticalStrut(spacer_size-2));		{			Box tmp=Box.createHorizontalBox();			status=new JLabel("Connecting...");			tmp.add(status);			tmp.add(Box.createHorizontalGlue());			reconnectBut=new JButton(carrows);			reconnectBut.setPreferredSize(new Dimension(carrows.getIconWidth(),carrows.getIconHeight()));			reconnectBut.addActionListener(this);			reconnectBut.setToolTipText("Drop current connection and try again.");			tmp.add(reconnectBut);			statusbox.add(tmp);		}		content.add(statusbox, BorderLayout.SOUTH);				Box p=Box.createVerticalBox();		p.add(new JLabel("Send Input:"));		p.add(inputField=new JTextField());		inputField.setEnabled(false);		inputField.addActionListener(this);		inputField.setMaximumSize(new Dimension(inputField.getMaximumSize().width,inputField.getPreferredSize().height));		inputField.setToolTipText("Text from here is passed to selected controls, or the current control if no selection");		p.add(Box.createVerticalStrut(spacer_size));		{			JSeparator sep=new JSeparator(SwingConstants.HORIZONTAL);			sep.setMaximumSize(new Dimension(sep.getMaximumSize().width,spacer_size));			p.add(sep);		}		p.add(Box.createVerticalStrut(spacer_size-2));				{			Box tmp=Box.createHorizontalBox();			JButton but;			but=new JButton("Raw Cam");			but.setEnabled(false);			but.setToolTipText("Raw vision - Sorry not ready yet - check back next week!");			tmp.add(but);			but=new JButton("Seg. Cam");			but.setEnabled(false);			but.setToolTipText("Segmented vision - Sorry not ready yet - check back next week!");			tmp.add(but);			tmp.setAlignmentX(0.0f);			p.add(tmp);		}				p.add(Box.createVerticalStrut(spacer_size));		{			JSeparator sep=new JSeparator(SwingConstants.HORIZONTAL);			sep.setMaximumSize(new Dimension(sep.getMaximumSize().width,spacer_size));			p.add(sep);		}		p.add(Box.createVerticalStrut(spacer_size-2));				p.add(new JLabel("Bookmarks:"));		String[] test={"Not yet","implemented"};		bookmarks=new JList(test);		bookmarks.setEnabled(false);		{			JScrollPane tmp=new JScrollPane(bookmarks);			tmp.setAlignmentX(0);			p.add(tmp);		}		{			Box bbox=Box.createHorizontalBox();			bbox.setAlignmentX(0);			JButton tmp;			bbox.add(tmp=new JButton("Add"));			//			new AutoDisableListener(tmp,menu);			tmp.setEnabled(false);			bbox.add(tmp=new JButton("Remove"));			new AutoDisableListener(tmp,bookmarks);			tmp.setEnabled(false);			p.add(bbox);		}		{			JPanel p2=new JPanel(new BorderLayout());			p2.add(p,BorderLayout.EAST);			p2.add(Box.createHorizontalStrut(spacer_size),BorderLayout.WEST);			content.add(p2, BorderLayout.EAST);		}				getContentPane().add(content,BorderLayout.CENTER);		EscFilter esc=new EscFilter(cancelBut);		addKeyListener(esc);		inputField.addKeyListener(esc);		menu.addKeyListener(esc);		menu.addKeyListener(new ReturnFilter(this));			}		public void show() {		super.show();		menu.requestFocus();	}		public static void main(String s[]) throws java.lang.InterruptedException {		if(s.length<1) {			System.out.println("Usage: java ControllerGUI host [port]");			System.out.println("       if port is not specified, it defaults to 10020");			System.exit(2);		}		int port=10020;		if(s.length>1)			port=Integer.parseInt(s[1]);		ControllerGUI f = new ControllerGUI(s[0],port);		f.addWindowListener(new WindowAdapter() {				public void windowClosing(WindowEvent e) {System.exit(0);}			});	}}/*	public class MySelectionModel extends DefaultListSelectionModel {		Vector curmenu;		ControllerGUI gui;		public boolean isUpdate;		public MySelectionModel(ControllerGUI gui) {			this.gui=gui;		}		public void updated(Vector curmenu) {			this.curmenu=curmenu;			Vector sel=getSelection();			super.clearSelection();			//			super.removeSelectionInterval(0,curmenu.size());			for(int i=0; i<sel.size();i++) {				int s=((Integer)sel.get(i)).intValue();				super.addSelectionInterval(s,s);			}			isUpdate=false;		}		public boolean isSelectedIndex(int index) {			return ((ControllerListener.MenuEntry)curmenu.get(index)).selected;		}		public boolean isSelectionEmpty() {			return getSelection().size()>0;		}		public void clearSelection() {			if(!isUpdate)				gui.comm.sendSelection(new Vector());		}		public int getMinSelectionIndex() {			for(int i=0; i<curmenu.size(); i++)				if(((ControllerListener.MenuEntry)curmenu.get(i)).selected)					return i;			return -1;		}		public int getMaxSelectionIndex() {			for(int i=curmenu.size()-1; i>-1; i--)				if(((ControllerListener.MenuEntry)curmenu.get(i)).selected)					return i;			return -1;		}		public void addSelectionInterval(int index0, int index1) {			int min=index0<index1?index0:index1;			int max=index0>index1?index0:index1;			if(min<0) min=0;			if(max>curmenu.size()) max=curmenu.size()-1;			Vector ans=new Vector();			for(int i=0; i<min; i++)				if(((ControllerListener.MenuEntry)curmenu.get(i)).selected)					ans.add(new Integer(i));			for(int i=min; i<=max; i++)				ans.add(new Integer(i));			for(int i=max+1; i<curmenu.size(); i++)				if(((ControllerListener.MenuEntry)curmenu.get(i)).selected)					ans.add(new Integer(i));			if(!isUpdate)				gui.comm.sendSelection(ans);		}		public void removeSelectionInterval(int index0, int index1) {			int min=index0<index1?index0:index1;			int max=index0>index1?index0:index1;			if(min<0) min=0;			if(max>curmenu.size()) max=curmenu.size()-1;			Vector ans=new Vector();			for(int i=0; i<min; i++)				if(((ControllerListener.MenuEntry)curmenu.get(i)).selected)					ans.add(new Integer(i));			for(int i=max+1; i<curmenu.size(); i++)				if(((ControllerListener.MenuEntry)curmenu.get(i)).selected)					ans.add(new Integer(i));			if(!isUpdate)				gui.comm.sendSelection(ans);		}		public void setSelectionInterval(int index0, int index1) {			int min=index0<index1?index0:index1;			int max=index0>index1?index0:index1;			if(min<0) min=0;			if(max>curmenu.size()) max=curmenu.size()-1;			Vector ans=new Vector();			for(int i=min; i<=max; i++)				ans.add(new Integer(i));			if(!isUpdate)				gui.comm.sendSelection(ans);		}		private Vector getSelection() {			Vector ans=new Vector();			for(int i=0; i<curmenu.size(); i++)				if(((ControllerListener.MenuEntry)curmenu.get(i)).selected)					ans.add(new Integer(i));			return ans;		}	}	MySelectionModel selmodel;*/
\ No newline at end of file
--- 1 ----
! import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.event.*;import java.beans.*;import java.util.*;//Admittedly a little sloppy, but I don't want to spend forever on this...public class ControllerGUI extends JFrame implements ActionListener {	JList menu;	JScrollPane menuScroll;	JLabel title;	JLabel status;	JList bookmarks;	ControllerListener comm;	JButton cancelBut;	JButton refreshBut;	JButton reconnectBut;	EStopPanel estop;	JTextField inputField;	boolean isUpdating=false;		ControllerGUI(String addr, int port) {		super();		comm = new ControllerListener(addr,port);		comm.listener=this;		init();		pack();		setLocation(50,50);		show();	}		// Disables the component if there's nothing selected to apply it to	public class AutoDisableListener implements PropertyChangeListener, ListSelectionListener {		JComponent target;		public AutoDisableListener(JComponent target, JList source) {			this.target=target;			source.addPropertyChangeListener(this);			source.addListSelectionListener(this);		}		public void propertyChange(PropertyChangeEvent evt) {			target.setEnabled(!((JList)evt.getSource()).isSelectionEmpty());		}		public void valueChanged(ListSelectionEvent evt) {			target.setEnabled(!((JList)evt.getSource()).isSelectionEmpty());		}	}		final static ImageIcon rarrow = new ImageIcon("images/rarrow.png");	final static ImageIcon larrow = new ImageIcon("images/larrow.png");	final static ImageIcon carrows = new ImageIcon("images/chasingarrows.png");	public class MyCellRenderer implements ListCellRenderer {		public Component getListCellRendererComponent(JList list,Object value,int index,boolean isSelected,boolean cellHasFocus) {			ControllerListener.MenuEntry me=(ControllerListener.MenuEntry)value;			/*			if(me.hasSubmenu) {						setIcon(rarrow);						setHorizontalTextPosition(SwingConstants.RIGHT);						setIconTextGap(5);						} else						setIconTextGap(5+rarrow.getIconWidth());			*/						//System.out.println(this.getText()+" "+me.selected+" "+isSelected);			int numpre=(int)(Math.log(list.getModel().getSize()-1)/Math.log(10))-(index==0?0:(int)(Math.log(index)/Math.log(10)));			StringBuffer pre=new StringBuffer();			for(int i=0;i<numpre;i++)				pre.append(" ");			JLabel title=new JLabel(pre.toString()+index+". "+me.title);			title.setBackground(me.selected?list.getSelectionBackground():list.getBackground());			title.setForeground(me.selected?list.getSelectionForeground():list.getForeground());			title.setEnabled(list.isEnabled());			title.setFont(list.getFont());			title.setOpaque(true);			title.setPreferredSize(new Dimension(list.getSize().width,title.getPreferredSize().height));			//Vector tmp2=new Vector();			//for(int i=0;i<1000000;i++) {tmp2.add(new Integer(0));tmp2.remove(tmp2.size()-1);}			if(me.hasSubmenu) {				Box tmp=Box.createHorizontalBox();				tmp.add(title);				//				tmp.add(Box.createHorizontalGlue());				JLabel arr=new JLabel(rarrow);				arr.setEnabled(list.isEnabled());				tmp.add(arr);				if(me.description.length()!=0)					tmp.setToolTipText(me.description);				return tmp;			} else {				Box tmp=Box.createHorizontalBox();				tmp.add(title);				tmp.add(Box.createHorizontalStrut(rarrow.getIconWidth()));				if(me.description.length()!=0)					tmp.setToolTipText(me.description);				return tmp;			}		}	} 	 	public class JListDoubleClick extends MouseAdapter {		ControllerGUI gui;		JListDoubleClick(ControllerGUI gui) { this.gui=gui; }		public void mouseClicked(MouseEvent e) {			if (e.getClickCount() == 2) {				int index = ((JList)e.getSource()).locationToIndex(e.getPoint());				gui.doubleClicked((JList)e.getSource(),index);			}		}	}	public class MySelectionListener implements ListSelectionListener {		ControllerGUI gui;		MySelectionListener(ControllerGUI gui) { this.gui=gui; }		public void valueChanged(ListSelectionEvent e) {			if(!gui.isUpdating && !e.getValueIsAdjusting())				gui.comm.sendSelection(((JList)e.getSource()).getSelectedIndices());		}	} 		public class EscFilter extends KeyAdapter {		JButton trigger;		EscFilter(JButton trigger) { this.trigger=trigger; }		public void keyReleased(KeyEvent evt) {			if(evt.getKeyChar()==(char)27)				trigger.doClick();		}	}	public class ReturnFilter extends KeyAdapter {		ControllerGUI gui;		ReturnFilter(ControllerGUI gui) { this.gui=gui; }		public void keyReleased(KeyEvent evt) {			if(evt.getKeyCode()==KeyEvent.VK_ENTER)				gui.doubleClicked((JList)evt.getSource(),0);		}	} 		public class ReenableOnClose extends WindowAdapter {		JButton but;		public ReenableOnClose(JButton b) { but=b; }		public void windowClosing(WindowEvent e) {			e.getWindow().dispose();			but.setEnabled(true);		}	}	void updated() {			//		System.out.println("updated");		isUpdating=true;		Point p=menuScroll.getViewport().getViewPosition();  		//		bookmarks.setEnabled(comm._isConnected);		cancelBut.setEnabled(comm._isConnected);		refreshBut.setEnabled(comm._isConnected);		inputField.setEnabled(comm._isConnected);		if(!comm._isConnected) {			title.setText("-");			menu.setListData(new Vector());			status.setText("Reconnecting...");		} else {			synchronized(comm._menus) {				title.setText((String)comm._titles.lastElement());				Vector menuitems=(Vector)comm._menus.lastElement();				menu.setValueIsAdjusting(true);				menu.setListData(menuitems);				Vector sels=new Vector();				for(int i=0; i<menuitems.size(); i++)					if(((ControllerListener.MenuEntry)menuitems.get(i)).selected)						sels.add(new Integer(i));				int[] selsArr=new int[sels.size()];				for(int i=0; i<selsArr.length; i++)					selsArr[i]=((Integer)sels.get(i)).intValue();				menu.setSelectedIndices(selsArr);				menu.setValueIsAdjusting(false);			}			status.setText(comm._status.length()>0?comm._status:"Connected.");		}		menuScroll.getViewport().setViewPosition(p);		isUpdating=false;		comm._updatedFlag=false;	}	public void paint(Graphics g) {		if(comm!=null && comm._updatedFlag)			updated();		super.paint(g);	}		public void actionPerformed(ActionEvent evt) {		if(evt.getSource()==cancelBut) {			//System.out.println("cancel button clicked");			comm.sendReturn();		} else if(evt.getSource()==refreshBut) {			//System.out.println("refresh button clicked");			comm.sendRefresh();		} else if(evt.getSource()==inputField) {			//System.out.println("input: "+inputField.getText());			int[] sel=menu.getSelectedIndices();			if(sel.length==0 || inputField.getText().charAt(0)=='!')				comm.sendInput(inputField.getText());			else				comm.sendInput("!input "+inputField.getText());			/*else if(sel.length==1) {				comm.sendSelectionPath(comm.buildSelectionPath(sel[0]));				comm.sendInput(inputField.getText());			} else				for(int i=0; i<sel.length; i++)					comm.sendInput(inputField.getText(),comm.buildSelectionPath(sel[i]));			*/			inputField.setText("");		} else if(evt.getSource()==reconnectBut) {			int port=comm._port;			String addr=comm._host;			comm.kill();			comm = new ControllerListener(addr,port);			comm.listener=this;		} else if(evt.getActionCommand().compareTo("raw")==0 || evt.getActionCommand().compareTo("rle")==0) {			String[] tmp=new String[1];			tmp[0]=evt.getActionCommand();			VisionGUI vis=new VisionGUI(comm._host,tmp);			((JButton)evt.getSource()).setEnabled(false);			vis.addWindowListener(new ReenableOnClose((JButton)evt.getSource()));			vis.show();			vis.toFront();		}	}		public void doubleClicked(JList list, int index) {		if(list==menu) {			Vector items=(Vector)comm._menus.lastElement();			//System.out.println(items.get(index)+" selected");			comm.sendSelect();			/*			int[] sel=menu.getSelectedIndices();						if(sel.length==1) {						comm.sendSelectionPath(comm.buildSelectionPath(sel[0]));						} else if(sel.length>1) {						Vector selectionPaths=new Vector();						for(int i=0; i<sel.length; i++)						selectionPaths.add(comm.buildSelectionPath(sel[i]));						for(int i=0; i<selectionPaths.size(); i++)						comm.sendSelectionPath((Vector)selectionPaths.get(i));						}			*/			inputField.setText("");		} else if(list==bookmarks) {			//todo		} else {			System.out.println("Unknown list double-clicked");		}	}		public class ConstSizeJButton extends JButton {		Dimension dim;		ConstSizeJButton(String s, ImageIcon i, Dimension d) { super(s,i); dim=d; }		public Dimension getPreferredSize() { return dim; }		public Dimension getMinimumSize() { return dim; }		public Dimension getMaximumSize() { return dim; }		public Dimension getSize() { return dim; }	}	protected void init() {		int spacer_size=10;					setTitle("TekkotsuMon: Controller Menus");		getContentPane().setLayout(new BorderLayout());		getContentPane().add(Box.createHorizontalStrut(spacer_size),BorderLayout.WEST);		getContentPane().add(Box.createHorizontalStrut(spacer_size),BorderLayout.EAST);		getContentPane().add(Box.createVerticalStrut(spacer_size),BorderLayout.NORTH);		getContentPane().add(Box.createVerticalStrut(spacer_size),BorderLayout.SOUTH);				menu=new JList();		menu.setCellRenderer(new MyCellRenderer());		menu.setFixedCellWidth(165);		menu.addMouseListener(new JListDoubleClick(this)); 		menu.addListSelectionListener(new MySelectionListener(this));				JPanel content=new JPanel(new BorderLayout());		Box titleBox=Box.createVerticalBox();		title=new JLabel("-");		title.setFont(new Font(title.getFont().getFontName(),Font.BOLD,title.getFont().getSize()));		title.setAlignmentX(0);		titleBox.add(title);		titleBox.add(Box.createVerticalStrut(spacer_size));		content.add(titleBox,BorderLayout.NORTH);				Box menuBox=Box.createVerticalBox();		menuScroll=new JScrollPane(menu);		menuScroll.setAlignmentX(0.5f);		menuBox.add(menuScroll);		{			Box tmp=Box.createHorizontalBox();			cancelBut=new JButton("Cancel");			Dimension dim=new Dimension(cancelBut.getPreferredSize().width+larrow.getIconWidth()+cancelBut.getIconTextGap(),cancelBut.getPreferredSize().height);			tmp.add(cancelBut=new ConstSizeJButton("Cancel",larrow,dim));			cancelBut.setEnabled(false);			cancelBut.addActionListener(this);			cancelBut.setToolTipText("Returns to previous control");			tmp.add(refreshBut=new JButton("Refresh"));			refreshBut.setEnabled(false);			refreshBut.addActionListener(this);			refreshBut.setToolTipText("Requests a menu refresh (handy if item names are dynamic)");			tmp.setAlignmentX(0.5f);			menuBox.add(tmp);		}		content.add(menuBox,BorderLayout.CENTER);		Box statusbox=Box.createVerticalBox();		statusbox.add(Box.createVerticalStrut(spacer_size));		{			JSeparator sep=new JSeparator(SwingConstants.HORIZONTAL);			statusbox.add(sep);		}		statusbox.add(Box.createVerticalStrut(spacer_size-2));		{			JPanel tmp=new JPanel(new BorderLayout());			status=new JLabel("Connecting...");			tmp.add(status,BorderLayout.CENTER);			{				Box tmp2=Box.createHorizontalBox();				estop=new EStopPanel(new EStopListener(comm._host,EStopListener.defPort));				estop.setPreferredSize(new Dimension(15,15));				tmp2.add(estop);				tmp2.add(Box.createHorizontalStrut(spacer_size));				reconnectBut=new JButton(carrows);				reconnectBut.setPreferredSize(new Dimension(carrows.getIconWidth(),carrows.getIconHeight()));				reconnectBut.addActionListener(this);				reconnectBut.setToolTipText("Drop current connection and try again.");				tmp2.add(reconnectBut);				tmp.add(tmp2,BorderLayout.EAST);			}			statusbox.add(tmp);		}		content.add(statusbox, BorderLayout.SOUTH);				Box p=Box.createVerticalBox();		p.add(new JLabel("Send Input:"));		p.add(inputField=new JTextField());		inputField.setEnabled(false);		inputField.addActionListener(this);		inputField.setMaximumSize(new Dimension(inputField.getMaximumSize().width,inputField.getPreferredSize().height));		inputField.setToolTipText("Text from here is passed to selected controls, or the current control if no selection");		p.add(Box.createVerticalStrut(spacer_size));		{			JSeparator sep=new JSeparator(SwingConstants.HORIZONTAL);			sep.setMaximumSize(new Dimension(sep.getMaximumSize().width,spacer_size));			p.add(sep);		}		p.add(Box.createVerticalStrut(spacer_size-2));				{			Box tmp=Box.createHorizontalBox();			JButton but;			but=new JButton("Raw Cam");			but.setToolTipText("Raw vision");			but.addActionListener(this);			but.setActionCommand("raw");			tmp.add(but);			but=new JButton("Seg. Cam");			but.setToolTipText("Segmented vision");			but.addActionListener(this);			but.setActionCommand("rle");			tmp.add(but);			tmp.setAlignmentX(0.0f);			p.add(tmp);		}				p.add(Box.createVerticalStrut(spacer_size));		{			JSeparator sep=new JSeparator(SwingConstants.HORIZONTAL);			sep.setMaximumSize(new Dimension(sep.getMaximumSize().width,spacer_size));			p.add(sep);		}		p.add(Box.createVerticalStrut(spacer_size-2));				p.add(new JLabel("Bookmarks:"));		String[] test={"Not yet","implemented"};		bookmarks=new JList(test);		bookmarks.setEnabled(false);		{			JScrollPane tmp=new JScrollPane(bookmarks);			tmp.setAlignmentX(0);			p.add(tmp);		}		{			Box bbox=Box.createHorizontalBox();			bbox.setAlignmentX(0);			bbox.add(Box.createHorizontalGlue());			JButton tmp;			bbox.add(tmp=new JButton("Add"));			//			new AutoDisableListener(tmp,menu);			tmp.setEnabled(false);			bbox.add(tmp=new JButton("Remove"));			new AutoDisableListener(tmp,bookmarks);			tmp.setEnabled(false);			bbox.add(Box.createHorizontalGlue());			p.add(bbox);		}		{			JPanel p2=new JPanel(new BorderLayout());			p2.add(p,BorderLayout.EAST);			p2.add(Box.createHorizontalStrut(spacer_size),BorderLayout.WEST);			content.add(p2, BorderLayout.EAST);		}				getContentPane().add(content,BorderLayout.CENTER);		EscFilter esc=new EscFilter(cancelBut);		addKeyListener(esc);		inputField.addKeyListener(esc);		menu.addKeyListener(esc);		menu.addKeyListener(new ReturnFilter(this));			}		public void show() {		super.show();		menu.requestFocus();	}		public static void main(String s[]) throws java.lang.InterruptedException {		if(s.length<1) {			System.out.println("Usage: java ControllerGUI host [port]");			System.out.println("       if port is not specified, it defaults to 10020");			System.exit(2);		}		//    try { ClassPathModifier.addFile("../aibo3d"); }		//    catch (Exception ex) { System.out.println(ex); System.exit(1); }		int port=10020;		if(s.length>1)			port=Integer.parseInt(s[1]);		ControllerGUI f = new ControllerGUI(s[0],port);		f.addWindowListener(new WindowAdapter() {				public void windowClosing(WindowEvent e) {System.exit(0);}			});	}}/*	public class MySelectionModel extends DefaultListSelectionModel {		Vector curmenu;		ControllerGUI gui;		public boolean isUpdate;		public MySelectionModel(ControllerGUI gui) {			this.gui=gui;		}		public void updated(Vector curmenu) {			this.curmenu=curmenu;			Vector sel=getSelection();			super.clearSelection();			//			super.removeSelectionInterval(0,curmenu.size());			for(int i=0; i<sel.size();i++) {				int s=((Integer)sel.get(i)).intValue();				super.addSelectionInterval(s,s);			}			isUpdate=false;		}		public boolean isSelectedIndex(int index) {			return ((ControllerListener.MenuEntry)curmenu.get(index)).selected;		}		public boolean isSelectionEmpty() {			return getSelection().size()>0;		}		public void clearSelection() {			if(!isUpdate)				gui.comm.sendSelection(new Vector());		}		public int getMinSelectionIndex() {			for(int i=0; i<curmenu.size(); i++)				if(((ControllerListener.MenuEntry)curmenu.get(i)).selected)					return i;			return -1;		}		public int getMaxSelectionIndex() {			for(int i=curmenu.size()-1; i>-1; i--)				if(((ControllerListener.MenuEntry)curmenu.get(i)).selected)					return i;			return -1;		}		public void addSelectionInterval(int index0, int index1) {			int min=index0<index1?index0:index1;			int max=index0>index1?index0:index1;			if(min<0) min=0;			if(max>curmenu.size()) max=curmenu.size()-1;			Vector ans=new Vector();			for(int i=0; i<min; i++)				if(((ControllerListener.MenuEntry)curmenu.get(i)).selected)					ans.add(new Integer(i));			for(int i=min; i<=max; i++)				ans.add(new Integer(i));			for(int i=max+1; i<curmenu.size(); i++)				if(((ControllerListener.MenuEntry)curmenu.get(i)).selected)					ans.add(new Integer(i));			if(!isUpdate)				gui.comm.sendSelection(ans);		}		public void removeSelectionInterval(int index0, int index1) {			int min=index0<index1?index0:index1;			int max=index0>index1?index0:index1;			if(min<0) min=0;			if(max>curmenu.size()) max=curmenu.size()-1;			Vector ans=new Vector();			for(int i=0; i<min; i++)				if(((ControllerListener.MenuEntry)curmenu.get(i)).selected)					ans.add(new Integer(i));			for(int i=max+1; i<curmenu.size(); i++)				if(((ControllerListener.MenuEntry)curmenu.get(i)).selected)					ans.add(new Integer(i));			if(!isUpdate)				gui.comm.sendSelection(ans);		}		public void setSelectionInterval(int index0, int index1) {			int min=index0<index1?index0:index1;			int max=index0>index1?index0:index1;			if(min<0) min=0;			if(max>curmenu.size()) max=curmenu.size()-1;			Vector ans=new Vector();			for(int i=min; i<=max; i++)				ans.add(new Integer(i));			if(!isUpdate)				gui.comm.sendSelection(ans);		}		private Vector getSelection() {			Vector ans=new Vector();			for(int i=0; i<curmenu.size(); i++)				if(((ControllerListener.MenuEntry)curmenu.get(i)).selected)					ans.add(new Integer(i));			return ans;		}	}	MySelectionModel selmodel;*/
\ No newline at end of file
Index: AiboPup/tools/mon/ControllerListener.java
diff -c AiboPup/tools/mon/ControllerListener.java:1.6 AiboPup/tools/mon/ControllerListener.java:1.9
*** AiboPup/tools/mon/ControllerListener.java:1.6	Mon Jun  9 20:53:49 2003
--- AiboPup/tools/mon/ControllerListener.java	Sun Jul  6 21:00:09 2003
***************
*** 2,7 ****
--- 2,11 ----
  import java.net.Socket;
  import java.util.Vector;
  import java.lang.Integer;
+ import java.util.HashMap;
+ import java.lang.Class;
+ import java.lang.reflect.Method;
+ import java.lang.reflect.Constructor;
  
  public class ControllerListener extends TCPListener {
  	boolean _updatedFlag=false;
***************
*** 11,16 ****
--- 15,22 ----
  	String _status;
  	PrintStream _out;
  	ControllerGUI listener;
+ 	HashMap dynObjs=new HashMap();
+ 	InputStream sin;
  	
  	public class MenuEntry {
  		boolean hasSubmenu;
***************
*** 111,117 ****
  		_titles.add("Unset");
  		System.out.println("connection opened");
  		try {
! 			InputStream sin=socket.getInputStream();
  			_out=new PrintStream(socket.getOutputStream());
  			_out.println("!refresh");
  			while (true) {
--- 117,123 ----
  		_titles.add("Unset");
  		System.out.println("connection opened");
  		try {
! 			sin=socket.getInputStream();
  			_out=new PrintStream(socket.getOutputStream());
  			_out.println("!refresh");
  			while (true) {
***************
*** 160,167 ****
  					} else if(msgtype.equals("status")) {
  						_status=readLine(sin);
  						if(!_isConnected) break;
  					} else {
! 						System.err.println("ControllerListener - Invalid message type");
  					}
  					_updatedFlag=true;
  					if(listener!=null)
--- 166,211 ----
  					} else if(msgtype.equals("status")) {
  						_status=readLine(sin);
  						if(!_isConnected) break;
+ 					} else if(msgtype.equals("load")) {
+ 						String type=readLine(sin);
+ 						if(!_isConnected) break;
+ 						String name=readLine(sin);
+ 						if(!_isConnected) break;
+ 						int port=Integer.parseInt(readLine(sin));
+ 						if(!_isConnected) break;
+ 						String args=readLine(sin);
+ 						if(!_isConnected) break;
+ 						String[] argArr=parseArgs(args);
+ 						if(!_isConnected) break;
+ 						Class objClass=null;
+ 						try {
+ 							objClass=Class.forName(type);
+ 						} catch(Exception ex) { System.out.println("Could not load "+type+": "+ex); }
+ 						if(objClass!=null) {
+ 							Class[] consArgClasses=new Class[3];
+ 							Object[] consArgs=new Object[3];
+ 							consArgs[0]=_host;
+ 							consArgs[1]=new Integer(port);
+ 							consArgs[2]=argArr;
+ 							for(int i=0;i<consArgs.length;i++)
+ 								consArgClasses[i]=consArgs[i].getClass();
+ 							consArgClasses[1]=Integer.TYPE;
+ 							Constructor objCons=objClass.getConstructor(consArgClasses);
+ 							Object obj=objCons.newInstance(consArgs);
+ 							dynObjs.put(name,obj);
+ 						}
+ 					} else if(msgtype.equals("close")) {
+ 						String name=readLine(sin);
+ 						if(!_isConnected) break;
+ 						Object obj=dynObjs.get(name);
+ 						if(obj==null) {
+ 							System.out.println("ControllerGUI: error - could not close "+name+" - not loaded");
+ 						} else {
+ 							Method m=obj.getClass().getMethod("close",null);
+ 							m.invoke(obj,null);
+ 						}
  					} else {
! 						System.err.println("ControllerListener - Invalid message type:"+msgtype);
  					}
  					_updatedFlag=true;
  					if(listener!=null)
***************
*** 182,188 ****
  		if(listener!=null)
  			listener.repaint();
  		//The sleep is to get around the socket still listening after being closed thing
! 		System.out.println("connection closed... reconnect after 5 seconds");
  		try { Thread.sleep(5000); } catch (Exception ex) {}
  	}
   
--- 226,232 ----
  		if(listener!=null)
  			listener.repaint();
  		//The sleep is to get around the socket still listening after being closed thing
! 		System.out.println("ControllerGUI - connection closed... reconnect after 5 seconds");
  		try { Thread.sleep(5000); } catch (Exception ex) {}
  	}
   
***************
*** 192,197 ****
--- 236,302 ----
  
  	public boolean isConnected() {
  		return _isConnected;
+ 	}
+ 
+ 	public String[] parseArgs(String args) throws java.io.IOException {
+ 		Vector v=new Vector();
+ 		StringBuffer cur=new StringBuffer();
+ 		boolean isDoubleQuote=false;
+ 		boolean isSingleQuote=false;
+ 		do {
+ 			for(int i=0; i<args.length(); i++) {
+ 				char c=args.charAt(i);
+ 				switch(c) {
+ 				case ' ':
+ 					if(isSingleQuote || isDoubleQuote)
+ 						cur.append(c);
+ 					else {
+ 						v.add(cur.toString());
+ 						cur.setLength(0);
+ 					}
+ 					break;
+ 				case '\\':
+ 					if(i==args.length()-1) { //escaped line break
+ 						args=readLine(sin);  //get next line and continue
+ 						if(!isConnected()) {
+ 							if(cur.length()>0)
+ 								v.add(cur.toString());
+ 							return makeArray(v);
+ 						}
+ 						if(isSingleQuote || isDoubleQuote)
+ 							cur.append('\n');
+ 						i=-1;
+ 					} else
+ 						cur.append(args.charAt(++i));
+ 					break;
+ 				case '"':
+ 					if(isSingleQuote)
+ 						cur.append(c);
+ 					else
+ 						isDoubleQuote=!isDoubleQuote;
+ 					break;
+ 				case '\'':
+ 					if(isDoubleQuote)
+ 						cur.append(c);
+ 					else
+ 						isSingleQuote=!isSingleQuote;
+ 					break;
+ 				default:
+ 					cur.append(c);
+ 					break;
+ 				}
+ 			} 
+ 		} while(isDoubleQuote || isSingleQuote);
+ 		if(cur.length()>0)
+ 			v.add(cur.toString());
+ 		return makeArray(v);
+ 	}
+ 
+ 	protected String[] makeArray(Vector v) {
+ 		String[] ans=new String[v.size()];
+ 		for(int i=0; i<v.size(); i++)
+ 			ans[i]=(String)v.get(i);
+ 		return ans;
  	}
  
  	public ControllerListener() { super(); }
Index: AiboPup/tools/mon/ControllerMsg.java
diff -c /dev/null AiboPup/tools/mon/ControllerMsg.java:1.1
*** /dev/null	Tue Jul  8 22:31:53 2003
--- AiboPup/tools/mon/ControllerMsg.java	Sun Jul  6 21:00:09 2003
***************
*** 0 ****
--- 1,14 ----
+ import javax.swing.JOptionPane;
+ 
+ public class ControllerMsg {
+ 
+ 	public static void main(String args[]) {
+ 		new ControllerMsg("",0,args);
+ 	}
+ 
+ 	public ControllerMsg(String host, int port, String args[]) {
+ 		for(int i=0; i<args.length; i++)
+ 			System.out.println("<"+args[i]+">");
+ 		JOptionPane.showMessageDialog(null,args[1],args[0],JOptionPane.INFORMATION_MESSAGE);
+ 	}
+ }
Index: AiboPup/tools/mon/DogConfig.java
diff -c /dev/null AiboPup/tools/mon/DogConfig.java:1.1
*** /dev/null	Tue Jul  8 22:31:53 2003
--- AiboPup/tools/mon/DogConfig.java	Tue Jul  1 05:00:18 2003
***************
*** 0 ****
--- 1,169 ----
+ import java.util.*;
+ import java.io.*;
+ 
+ public class DogConfig {
+   List IPs;
+   String IP;
+   Hashtable config;
+ 
+   public static void main(String args[]) {
+     try { ClassPathModifier.addFile("ftp.jar"); }
+     catch (Exception ex) { System.out.println(ex); System.exit(1); }
+ 
+     DogConfig config=new DogConfig(args);
+   }
+ 
+   void usage() {
+     System.out.println("java DogConfig [Internet address [Internet address ...]]");
+   }
+ 
+   public DogConfig(String args[]) {
+     for (int i=0; i<args.length; i++) {
+       if (args[i].charAt(0)=='-') {
+         usage();
+         System.exit(0);
+       }
+     }
+ 
+     readConfig();
+     for (int i=0; i<args.length; i++) {
+       if (tryIP(args[i])) {
+         IP=args[i];
+         break;
+       }
+     }
+ 
+     if (IP==null) {
+       for (ListIterator iter = IPs.listIterator(); iter.hasNext(); ) {
+         String cline=(String)iter.next();
+         int clength=cline.length();
+         if (clength!=0 && cline.charAt(0)!='#') {
+           if (tryIP(cline)) {
+             IP=cline;
+             break;
+           }
+         }
+       }
+     } else {
+       int insertpos=0;
+       boolean ipbegun=false;
+ 
+       for (ListIterator iter = IPs.listIterator(); iter.hasNext(); ) {
+         String cline=(String)iter.next();
+         int clength=cline.length();
+ 
+         if (clength!=0 && cline.charAt(0)!='#') ipbegun=true;
+         else if (!ipbegun) insertpos++;
+ 
+         if (cline.compareToIgnoreCase(IP)==0) {
+           insertpos=-1;
+           break;
+         }
+       }
+       
+       if (insertpos>=0) {
+         IPs.add(insertpos,IP); 
+         writeConfig();
+       }
+     }
+   
+     if (IP==null) {
+       // pop up dialog box asking for IP address
+     }
+   }
+ 
+   boolean tryIP(String ip) {
+     DogConfigFTP dog_ftp=new DogConfigFTP(ip, 21, "config", "config");
+     System.out.print("Trying "+ip+" ... ");
+     System.out.flush();
+     if (dog_ftp.test()) {
+       System.out.println("found");
+       try {
+         readAiboConfig(dog_ftp.getFile("tekkotsu.cfg"));
+         return true;
+       } catch (Exception ex) {
+         System.out.println("ftp error: "+ ex);
+       }
+     } else {
+       System.out.println("not found");
+     }
+     return false;
+   }
+ 
+   public DogConfig() {
+     this(new String[0]);
+   }
+ 
+   public String getIP() {
+     return IP;
+   }
+ 
+   void readAiboConfig(String conf) {
+     String[] lines=conf.split("[\r\n]");
+     config=new Hashtable();
+     Hashtable current=config;
+ 
+     for (int i=0; i<lines.length; i++) {
+       String cline=lines[i];
+       int clength=cline.length();
+       if (clength!=0 && cline.charAt(0)!='#') {
+         if (cline.charAt(0)=='[' && cline.charAt(clength-1)==']') {
+           String category=cline.substring(1,clength-1);
+           current=new Hashtable();
+           config.put(category, current);
+         } else {
+           int ind=cline.indexOf('=');
+           if (ind<0) {
+             System.out.println("warning: line "+(i+1)+" ignored");
+             System.out.println("       > "+cline);
+           } else {
+             String key=cline.substring(0,ind);
+             String value=cline.substring(ind+1,clength);
+             current.put(key, value);
+           }
+         }
+       }
+     }
+   }
+ 
+   public String getValue(String section, String key) {
+     Hashtable sectionhash=(Hashtable)config.get(section);
+     if (sectionhash!=null)
+       return (String)sectionhash.get(key);
+     return null;
+   }
+ 
+   void readConfig() {
+     IPs=new ArrayList(10);
+     try {
+       BufferedReader in = new BufferedReader
+         ( new FileReader (".aibo_ip") );
+       String curLine=in.readLine();
+       while (curLine!=null) {
+         IPs.add(curLine);
+         curLine=in.readLine();
+       }
+       in.close();
+     } catch (FileNotFoundException ex) {
+       // we just start off with 0 IPs
+       // also creating a new file, so add an intro comment
+       IPs.add("# Ordered list of IPs to be used by Tekkotsu tools\n");
+     } catch (IOException ex) {
+       // we read what we could
+     }
+     // no real need for parsing and verifying correctness of IPs
+   }
+ 
+   void writeConfig() {
+     try {
+       PrintWriter out = new PrintWriter ( new BufferedWriter (
+             new FileWriter (".aibo_ip") ));
+       for (ListIterator iter = IPs.listIterator(); iter.hasNext(); ) {
+         out.println(iter.next());
+       }
+       out.close();
+     } catch (IOException ex) {
+       // can't do much about it
+     }
+   }
+ }
Index: AiboPup/tools/mon/DogConfigFTP.java
diff -c /dev/null AiboPup/tools/mon/DogConfigFTP.java:1.1
*** /dev/null	Tue Jul  8 22:31:53 2003
--- AiboPup/tools/mon/DogConfigFTP.java	Tue Jul  1 05:00:18 2003
***************
*** 0 ****
--- 1,67 ----
+ import com.enterprisedt.net.ftp.*;
+ import java.util.*;
+ import java.net.*;
+ import java.io.*;
+ 
+ public class DogConfigFTP {
+   String _ip;
+   int _port;
+   String _user;
+   String _pass;
+ 
+   public DogConfigFTP(String ip) {
+     this(ip, 21);
+   }
+ 
+   public DogConfigFTP(String ip, int port) {
+     _ip=ip;
+     _port=port;
+     _user="anonymous";
+     _pass="blah@tekkotsu.org";
+   }
+ 
+   public DogConfigFTP(String ip, int port, String user, String pass) {
+     this(ip, port);
+     _user=user;
+     _pass=pass;
+   }
+   
+   public boolean test() {
+     return test(500);
+   }
+ 
+   public boolean test(int millis) {
+     Socket _ftpSocket=new Socket();
+     try {
+       _ftpSocket.connect(new InetSocketAddress(_ip, _port), millis);
+     } catch (Exception ex) { }
+     if (_ftpSocket.isConnected()) {
+       try { _ftpSocket.close(); } catch (Exception ex) { }
+       return true;
+     } else {
+       return false;
+     }
+   }
+ 
+   public String getFile(String remotename) throws FTPException, IOException {
+     FTPClient ftp=new FTPClient(_ip, _port);
+     ftp.login(_user, _pass);
+     ftp.setConnectMode(FTPConnectMode.ACTIVE);
+     ftp.setType(FTPTransferType.ASCII);
+     String ret=new String(ftp.get(remotename));
+     ftp.quit();
+     return ret;
+   }
+ 
+   public String getFile(String user, String pass, String remotename)
+       throws FTPException, IOException {
+     _user=user;
+     _pass=pass;
+     return getFile(remotename);
+   }
+ 
+   public static void main(String args[]) {
+     System.out.println("This is an internal class - run DogConfig instead");
+     System.exit(0);
+   }
+ }
Index: AiboPup/tools/mon/EStopGUI.java
diff -c /dev/null AiboPup/tools/mon/EStopGUI.java:1.5
*** /dev/null	Tue Jul  8 22:31:53 2003
--- AiboPup/tools/mon/EStopGUI.java	Tue Jul  8 20:10:57 2003
***************
*** 0 ****
--- 1,117 ----
+ import javax.swing.*;
+ import java.awt.*;
+ import java.awt.event.WindowAdapter;
+ import java.awt.event.WindowEvent;
+ import java.awt.event.ActionListener;
+ import java.awt.event.ActionEvent;
+ 
+ public class EStopGUI extends JFrame implements ActionListener, EStopListener.UpdatedListener {
+ 	static int defPort=10053;
+ 	JLabel status;
+ 	JButton reconnectBut;
+ 	EStopPanel estop;
+ 	final static ImageIcon carrows = new ImageIcon("images/chasingarrows.png");
+ 
+ 	static public void main(String s[]) {
+ 		int port=defPort;
+ 		if(s.length<1)
+ 			usage();
+ 		if(s.length>1)
+ 			port=Integer.parseInt(s[1]);
+ 		String[] args=new String[s.length-1];
+ 		for(int i=0; i<s.length-1; i++)
+ 			args[i-1]=s[i];
+ 		JFrame frame=new EStopGUI(s[0],port,args);
+ 		frame.addWindowListener(new WindowAdapter() {
+ 			public void windowClosing(WindowEvent e) { System.exit(0); }
+ 			});
+ 	}
+ 
+ 	public static void usage() {
+ 		System.out.println("Usage: java EStopGUI host [port]");
+ 		System.out.println("			 if port is not specified, it defaults to "+EStopListener.defPort);
+ 		System.exit(2);
+ 	}
+ 
+ 	public EStopGUI(String host, int port, String args[]) {
+ 		super("TekkotsuMon: EStop Controller");
+ 		init(new EStopListener(host,port));
+ 	}
+ 
+ 	public EStopGUI(EStopListener comm) {
+ 		super();
+ 		init(comm);
+ 	}
+ 
+ 	protected void init(EStopListener comm) {
+ 		int spacer_size=10;
+ 		Container root = getContentPane();
+ 		root.setLayout(new BorderLayout());
+ 		root.add(estop=new EStopPanel(comm),BorderLayout.CENTER);
+ 		root.add(Box.createVerticalStrut(spacer_size),BorderLayout.NORTH);
+ 		root.add(Box.createHorizontalStrut(spacer_size),BorderLayout.EAST);
+ 		root.add(Box.createHorizontalStrut(spacer_size),BorderLayout.WEST);
+ 		
+ 		{
+ 			Box statusbox=Box.createVerticalBox();
+ 			statusbox.add(Box.createVerticalStrut(spacer_size));
+ 			{
+ 				JSeparator sep=new JSeparator(SwingConstants.HORIZONTAL);
+ 				statusbox.add(sep);
+ 			}
+ 			statusbox.add(Box.createVerticalStrut(spacer_size-2));
+ 			{
+ 				JPanel tmp=new JPanel(new BorderLayout());
+ 				status=new JLabel("Connecting...");
+ 				estopUpdated(comm);
+ 				tmp.add(Box.createHorizontalStrut(spacer_size),BorderLayout.WEST);
+ 				tmp.add(status,BorderLayout.CENTER);
+ 				{
+ 					Box tmp2=Box.createHorizontalBox();
+ 					reconnectBut=new JButton(carrows);
+ 					reconnectBut.setPreferredSize(new Dimension(carrows.getIconWidth(),carrows.getIconHeight()));
+ 					reconnectBut.addActionListener(this);
+ 					reconnectBut.setToolTipText("Drop current connection and try again.");
+ 					tmp2.add(reconnectBut);
+ 					tmp2.add(Box.createHorizontalStrut(spacer_size));
+ 					tmp.add(tmp2,BorderLayout.EAST);
+ 				}
+ 				statusbox.add(tmp);
+ 			}
+ 			statusbox.add(Box.createVerticalStrut(spacer_size));
+ 			root.add(statusbox, BorderLayout.SOUTH);
+ 		}
+ 		addWindowListener(new CloseEStopAdapter(this));
+ 		estop.setPreferredSize(new Dimension(150,150));
+ 		pack();
+ 		estop.setPreferredSize(null);
+ 		estop.comm.addUpdatedListener(this);
+ 		show();
+ 	}
+ 
+ 	public void actionPerformed(ActionEvent evt) {
+ 		if(evt.getSource()==reconnectBut) {
+ 			estop.close();
+ 			estop.open();
+ 		}
+ 	}
+ 	class CloseEStopAdapter extends WindowAdapter {
+ 		EStopGUI gui;
+ 		CloseEStopAdapter(EStopGUI gui) {this.gui=gui;}
+ 		public void windowClosing(WindowEvent e) {
+ 			gui.close();
+ 		}
+ 	}
+ 	public void close() {
+ 		estop.remove();
+ 		estop.comm.removeUpdatedListener(this);
+ 		dispose();
+ 	}
+ 	public void estopUpdated(EStopListener l) {
+ 		if(l.isConnected()) {
+ 			status.setText("Connected.");
+ 		} else {
+ 			status.setText("Reconnecting...");
+ 		}
+ 	}
+ }
Index: AiboPup/tools/mon/EStopListener.java
diff -c /dev/null AiboPup/tools/mon/EStopListener.java:1.3
*** /dev/null	Tue Jul  8 22:31:53 2003
--- AiboPup/tools/mon/EStopListener.java	Tue Jul  8 20:10:57 2003
***************
*** 0 ****
--- 1,101 ----
+ import java.lang.Integer;
+ import java.lang.String;
+ import java.io.PrintStream;
+ import java.io.InputStream;
+ import java.net.Socket;
+ import java.util.Vector;
+ import java.net.SocketException;
+ 
+ public class EStopListener extends TCPListener {
+   // The command output stream
+ 	static int defPort=10053;
+   PrintStream out;
+ 	boolean stopped=true;
+ 	boolean data=false;
+   Socket mysock;
+ 	Vector listeners=new Vector();
+ 	
+ 	public interface UpdatedListener {
+ 		public void estopUpdated(EStopListener mc);
+ 	}
+ 
+ 	void addUpdatedListener(UpdatedListener mcl) { listeners.add(mcl); }
+ 	void removeUpdatedListener(UpdatedListener mcl) {
+ 		listeners.remove(mcl);
+ 		if(listeners.size()==0)
+ 			kill();
+ 	}
+ 	void fireUpdated() {
+ 		data=true;
+ 		for(int i=0;i<listeners.size();i++)
+ 			((UpdatedListener)listeners.get(i)).estopUpdated(this);
+ 	}
+ 
+   // Connect to control socket
+   void connected(Socket socket) {
+     mysock = socket;
+ 		fireUpdated();
+     try {
+       out = new PrintStream(mysock.getOutputStream());
+ 			out.print("refresh\n");
+ 			InputStream sin=socket.getInputStream();
+ 			while (true) {
+ 				String msgtype=readLine(sin);
+ 				if(!_isConnected) break;
+ 				if(msgtype.equals("on")) {
+ 					if(!stopped) {
+ 						stopped=true;
+ 						fireUpdated();
+ 					}
+ 				} else if(msgtype.equals("off")) {
+ 					if(stopped) {
+ 						stopped=false;
+ 						fireUpdated();
+ 					}
+ 				} else {
+ 					System.out.println("Estop Unknown message: "+msgtype);
+ 				}
+ 			}
+     } catch(Exception e) {if((SocketException)e==null) e.printStackTrace();}
+ 
+ 		try { socket.close(); } catch (Exception ex) { }
+ 
+ 		_isConnected=false;
+ 		fireUpdated();
+ 		//The sleep is to get around the socket still listening after being closed thing
+ 		if(!destroy)
+ 			System.out.println("EStopGUI - connection closed... reconnect after 5 seconds");
+ 		try { Thread.sleep(5000); } catch (Exception ex) {}
+   }
+ 
+   // Disconnect from control socket
+   public void close() {
+ 		//    try { mysock.close(); } catch(Exception e) {}
+     //_isConnected = false;
+     super.close();
+ 		//we'll fire an event to the listeners when the readLine in connected finally fails
+   }
+ 
+ 	public void setEStop(boolean b) {
+ 		if(b!=stopped) {
+ 			out.print(b?"stop\n":"start\n");
+ 		}
+ 	}
+ 
+ 	public boolean getEStop() {
+ 		return stopped;
+ 	}
+ 
+ 	public void toggleEStop() {
+ 		setEStop(!stopped);
+ 	}
+ 
+   // Some state inquiry functions
+   public boolean hasData() { return data; }
+   public boolean isConnected() { return _isConnected; }
+ 
+   // Constructors
+   public EStopListener() { super(); }
+   public EStopListener(int port) { super(port); }
+   public EStopListener(String host, int port) { super(host, port); }
+ }
Index: AiboPup/tools/mon/EStopPanel.java
diff -c /dev/null AiboPup/tools/mon/EStopPanel.java:1.6
*** /dev/null	Tue Jul  8 22:31:53 2003
--- AiboPup/tools/mon/EStopPanel.java	Tue Jul  8 20:10:58 2003
***************
*** 0 ****
--- 1,187 ----
+ import javax.swing.JPanel;
+ import javax.swing.JFrame;
+ import java.awt.event.WindowAdapter;
+ import java.awt.event.WindowEvent;
+ import java.awt.geom.Ellipse2D;
+ import java.awt.geom.Rectangle2D;
+ import java.awt.*;
+ import java.awt.event.MouseEvent;
+ import java.awt.event.InputEvent;
+ 
+ public class EStopPanel extends JPanel implements EStopListener.UpdatedListener {
+ 	EStopListener comm;
+ 	int mode;
+ 	static final int STOPPED_MODE=0;
+ 	static final int NOTSTOPPED_MODE=1;
+ 	static final int DISABLED_MODE=2;
+ 	static final int MAX_MODE=3;
+ 	Shape shape[] = new Shape[MAX_MODE];
+ 	BasicStroke stroke[] = new BasicStroke[MAX_MODE];
+ 	Paint fill[] = new Color[MAX_MODE];
+ 	Paint line[] = new Color[MAX_MODE];
+ 	Paint textFill[] = new Color[MAX_MODE];
+ 	String text[] = new String[MAX_MODE];
+ 	float textSize[] = new float[MAX_MODE];
+ 	static final int res=1000;
+ 	
+ 	static public void main(String s[]) {
+ 		int port=EStopListener.defPort;
+ 		if(s.length<1)
+ 			usage();
+ 		if(s.length>1)
+ 			port=Integer.parseInt(s[1]);
+ 		String[] args=new String[s.length-1];
+ 		for(int i=0; i<s.length-1; i++)
+ 			args[i-1]=s[i];
+ 		JFrame frame=new JFrame("TekkotsuMon: EStop");
+ 		frame.setSize(new Dimension(200, 200)); 
+ 		EStopPanel estop=new EStopPanel(new EStopListener(s[0],port));
+ 		frame.getContentPane().add(estop);
+ 		frame.addWindowListener(new WindowAdapter() {
+ 				public void windowClosing(WindowEvent e) { System.exit(0); } });
+ 		frame.show();
+ 	}
+ 
+ 	public static void usage() {
+ 		System.out.println("Usage: java EStopPanel host [port]");
+ 		System.out.println("			 if port is not specified, it defaults to "+EStopListener.defPort);
+ 		System.exit(2);
+ 	}
+ 
+ 	public EStopPanel(EStopListener comm) {
+ 		super();
+ 		
+ 		this.comm=comm;
+ 		mode=comm.isConnected()?(comm.getEStop()?STOPPED_MODE:NOTSTOPPED_MODE):DISABLED_MODE;
+ 		setEnabled(mode!=DISABLED_MODE);
+ 		comm.addUpdatedListener(this);
+ 		
+ 		shape[NOTSTOPPED_MODE]=makeStopSign();
+ 		stroke[NOTSTOPPED_MODE]=new BasicStroke(res/30);
+ 		fill[NOTSTOPPED_MODE]=Color.RED;
+ 		line[NOTSTOPPED_MODE]=Color.BLACK;
+ 		text[NOTSTOPPED_MODE]="STOP";
+ 		textFill[NOTSTOPPED_MODE]=Color.WHITE;
+ 		textSize[NOTSTOPPED_MODE]=3.125f;
+ 
+ 		shape[STOPPED_MODE]=new Ellipse2D.Float(0,0,res,res);
+ 		stroke[STOPPED_MODE]=new BasicStroke(res/30);
+ 		fill[STOPPED_MODE]=Color.GREEN;
+ 		line[STOPPED_MODE]=Color.BLACK;
+ 		text[STOPPED_MODE]="GO";
+ 		textFill[STOPPED_MODE]=Color.BLACK;
+ 		textSize[STOPPED_MODE]=2.5f;
+ 
+ 		shape[DISABLED_MODE]=new Rectangle2D.Float(res/8,res/8,res*3/4,res*3/4);
+ 		stroke[DISABLED_MODE]=new BasicStroke(0);
+ 		fill[DISABLED_MODE]=null;
+ 		line[DISABLED_MODE]=null;
+ 		text[DISABLED_MODE]="><";
+ 		textFill[DISABLED_MODE]=Color.BLACK;
+ 		textSize[DISABLED_MODE]=1.5f;
+ 		
+ 		setToolTipText("Toggle Emergency Stop; alt-click to open new window");
+ 		enableEvents(AWTEvent.MOUSE_EVENT_MASK);
+ 	}
+ 
+ 	protected Shape makeStopSign() {
+ 		int x[] = new int[10];
+ 		int y[] = new int[10];
+ 		double l=res*Math.tan(22.5/180.0*Math.PI);
+ 		x[0]=res/2;
+ 		y[0]=0;
+ 		x[1]=(int)((res-l)/2+l);
+ 		y[1]=0;
+ 		x[2]=res;
+ 		y[2]=(int)((res-l)/2);
+ 		x[3]=res;
+ 		y[3]=x[1];
+ 		x[4]=x[1];
+ 		y[4]=res;
+ 		x[5]=y[2];
+ 		y[5]=res;
+ 		x[6]=0;
+ 		y[6]=y[3];
+ 		x[7]=0;
+ 		y[7]=y[2];
+ 		x[8]=y[2];
+ 		y[8]=y[0];
+ 		x[9]=x[0];
+ 		y[9]=y[0];
+ 		return new Polygon(x,y,10);
+ 	}
+ 	
+ 	public void close() {
+ 		comm.kill();
+ 		remove();
+ 	}
+ 	
+ 	public void remove() {
+ 		comm.removeUpdatedListener(this);
+ 	}
+ 	
+ 	public void open() {
+ 		comm.addUpdatedListener(this);
+ 		comm.startThread();
+ 	}
+ 
+ 	public void estopUpdated(EStopListener l) {
+ 		if(l.isConnected()) {
+ 			if(l.getEStop())
+ 				mode=STOPPED_MODE;
+ 			else
+ 				mode=NOTSTOPPED_MODE;
+ 		} else
+ 			mode=DISABLED_MODE;
+ 		setEnabled(l.isConnected());
+ 		repaint();
+ 	}
+ 	
+ 	public void processMouseEvent(MouseEvent e) {
+ 		if(e.getID()==MouseEvent.MOUSE_RELEASED) {
+ 			if((e.getModifiersEx()&InputEvent.ALT_DOWN_MASK)!=0) {
+ 				EStopGUI es=new EStopGUI(comm);
+ 			} else {
+ 				if(isEnabled()) {
+ 					comm.toggleEStop();
+ 				}
+ 			}
+ 		}
+ 		super.processMouseEvent(e);
+ 	}
+ 
+ 	public void paint(Graphics graphics) {
+ 		super.paint(graphics);
+ 		Graphics2D g=(Graphics2D)graphics;
+ 		g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
+ 		int w=getWidth();
+ 		int h=getHeight();
+ 		int cons=w>h?h:w;
+ 		int ex=(w>h?w:h)-cons;
+ 		double scale=cons/(double)(res+stroke[mode].getLineWidth());
+ 		if(w>h)
+ 			g.translate(ex/2.0,0);
+ 		else
+ 			g.translate(0,ex/2.0);
+ 		g.translate(stroke[mode].getLineWidth()/2*scale,stroke[mode].getLineWidth()/2*scale);
+ 		g.scale(scale,scale);
+ 		if(fill[mode]!=null) {
+ 			g.setPaint(fill[mode]);
+ 			g.fill(shape[mode]);
+ 		}
+ 		if(line[mode]!=null) {
+ 			g.setPaint(line[mode]);
+ 			g.setStroke(stroke[mode]);
+ 			g.draw(shape[mode]);
+ 		}
+ 		if(textFill[mode]!=null && cons/textSize[mode]>7) {
+ 			g.setPaint(textFill[mode]);
+ 			g.setFont(new Font("Arial",Font.BOLD,(int)(res/textSize[mode])));
+ 			FontMetrics fm=g.getFontMetrics();
+ 			float fw=(float)fm.getStringBounds(text[mode],g).getWidth();
+ 			float fa=fm.getLineMetrics(text[mode],g).getAscent();
+ 			float fd=fm.getLineMetrics(text[mode],g).getDescent();
+ 			g.drawString(text[mode],(res-fw)/2.0f,(res-fd+fa)/2.0f);
+ 		}
+ 	}
+ }
Index: AiboPup/tools/mon/HeadPointGUI.java
diff -c /dev/null AiboPup/tools/mon/HeadPointGUI.java:1.1
*** /dev/null	Tue Jul  8 22:31:53 2003
--- AiboPup/tools/mon/HeadPointGUI.java	Sun Jul  6 21:02:25 2003
***************
*** 0 ****
--- 1,333 ----
+ import javax.swing.*;
+ import java.awt.*;
+ import java.awt.geom.*;
+ import java.awt.event.*;
+ import javax.swing.event.*;
+ 
+ public class HeadPointGUI extends JFrame implements PointPick.PointPickedListener, ChangeListener, ActionListener, MouseListener, HeadPointListener.HeadPointUpdatedListener {
+ 	static int defPort=10052;
+ 	PointPick pp;
+ 	JSlider tslide;
+ 	JSlider pslide;
+ 	JSlider rslide;
+ 	JButton stopBut;
+ 	JRadioButton horizRollBut;
+ 	JRadioButton horizPanBut;
+ 	boolean horizButFake=false;
+ 	JCheckBox resetOnRelease;
+ 	JLabel status;
+ 	JButton reconnectBut;
+ 	HeadPointListener comm;
+ 	static int slidermax=10000;
+ 	final static ImageIcon carrows = new ImageIcon("images/chasingarrows.png");
+ 
+ 	static public void main(String s[]) {
+ 		int port=defPort;
+ 		if(s.length<1)
+ 			usage();
+ 		if(s.length>1)
+ 			port=Integer.parseInt(s[1]);
+ 		String[] args=new String[s.length-1];
+ 		for(int i=0; i<s.length-1; i++)
+ 			args[i-1]=s[i];
+ 		JFrame frame=new HeadPointGUI(s[0],port,args);
+ 		/*		frame.addWindowListener(new WindowAdapter() {
+ 			public void windowClosing(WindowEvent e) { System.exit(0); }
+ 			});*/
+ 	}
+ 	
+ 	public static void usage() {
+ 		System.out.println("Usage: java HeadPointGUI host [port]");
+ 		System.out.println("       if port is not specified, it defaults to: "+defPort);
+ 		System.exit(2);
+ 	}
+ 		
+ 	public HeadPointGUI(String host, int port, String args[]) {
+ 		super("TekkotsuMon: Head Pointer Control");
+ 		pack();
+ 		comm=new HeadPointListener(host,port);
+ 		comm.addHeadPointUpdatedListener(this);
+ 		show();
+ 	}
+ 
+ 	public void close() {
+ 		comm.kill();
+ 		dispose();
+ 	}
+ 	
+ 	class CloseHeadPointAdapter extends WindowAdapter {
+ 		HeadPointGUI gui;
+ 		CloseHeadPointAdapter(HeadPointGUI gui) {this.gui=gui;}
+ 		public void windowClosing(WindowEvent e) {
+ 			gui.close();
+ 		}
+ 	}
+ 
+ 	public void pointPicked(Point2D.Float p, MouseEvent e, PointPick pp) {
+ 		boolean isBut2=(e.getModifiersEx()&MouseEvent.BUTTON3_DOWN_MASK)==MouseEvent.BUTTON3_DOWN_MASK;
+ 		if(!horizButFake && isBut2) {
+ 			if(horizPanBut.isSelected())
+ 				horizRollBut.setSelected(true);
+ 			else
+ 				horizPanBut.setSelected(true);
+ 			horizButFake=isBut2;
+ 		}
+ 		if(horizRollBut.isSelected())
+ 			rslide.setValue((int)(slidermax*p.x));
+ 		if(horizPanBut.isSelected())
+ 			pslide.setValue((int)(slidermax*p.x));
+ 		tslide.setValue((int)(slidermax*p.y));
+ 	}
+ 
+ 	public void headPointUpdated(HeadPointListener comm) {
+ 		if(status!=null) {
+ 			pp.setEnabled(comm._isConnected);
+ 			tslide.setEnabled(comm._isConnected);
+ 			pslide.setEnabled(comm._isConnected);
+ 			rslide.setEnabled(comm._isConnected);
+ 			stopBut.setEnabled(comm._isConnected);
+ 			if(comm._isConnected)
+ 				status.setText("Connected.");
+ 			else
+ 				status.setText("Reconnecting...");
+ 		}
+ 	}
+ 
+ 	public void mouseClicked(MouseEvent e) {}
+ 	public void mouseEntered(MouseEvent e) {}
+ 	public void mouseExited(MouseEvent e) {}
+ 	public void mousePressed(MouseEvent e) {
+ 		boolean isBut2=(e.getModifiersEx()&MouseEvent.BUTTON3_DOWN_MASK)==MouseEvent.BUTTON3_DOWN_MASK;
+ 		if(!horizButFake && isBut2) {
+ 			if(horizPanBut.isSelected())
+ 				horizRollBut.setSelected(true);
+ 			else
+ 				horizPanBut.setSelected(true);
+ 			horizButFake=isBut2;
+ 			updatePP();
+ 		}
+ 	}
+ 	public void mouseReleased(MouseEvent e) {
+ 		boolean isBut1=(e.getModifiersEx()&MouseEvent.BUTTON1_DOWN_MASK)==MouseEvent.BUTTON1_DOWN_MASK;
+ 		boolean isBut2=(e.getModifiersEx()&MouseEvent.BUTTON3_DOWN_MASK)==MouseEvent.BUTTON3_DOWN_MASK;
+ 		if(horizButFake && !isBut2) {
+ 			if(horizPanBut.isSelected())
+ 				horizRollBut.setSelected(true);
+ 			else
+ 				horizPanBut.setSelected(true);
+ 			horizButFake=isBut2;
+ 			updatePP();
+ 		}
+ 		if(!isBut1 && !isBut2) {
+ 			if(resetOnRelease.isSelected())
+ 				stopBut.doClick();
+ 		}
+ 	}
+ 
+ 	public void stateChanged(ChangeEvent e) {
+ 		if(e.getSource()==tslide) {
+ 			comm.sendCommand("t",tslide.getValue()/(float)slidermax);
+ 			pp.doSetPoint(pp.getXValue(),tslide.getValue()/(float)slidermax);
+ 		} else if(e.getSource()==pslide) {
+ 			comm.sendCommand("p",-pslide.getValue()/(float)slidermax);
+ 			if(horizPanBut.isSelected())
+ 				pp.doSetPoint(pslide.getValue()/(float)slidermax,pp.getYValue());
+ 		} else if(e.getSource()==rslide) {
+ 			// Rotation is both fast and sensitive, so we'll exponentiate it to
+ 			// drag out the low end without sacrificing the high end
+ 			comm.sendCommand("r",rslide.getValue()/(float)slidermax);
+ 			float tmp=pp.getYValue();
+ 			if(horizRollBut.isSelected())
+ 				pp.doSetPoint(rslide.getValue()/(float)slidermax,pp.getYValue());
+ 		}
+ 	}
+ 
+ 	public void actionPerformed(ActionEvent e) {
+ 		if(e.getSource()==stopBut) {
+ 			tslide.setValue(0);
+ 			pslide.setValue(0);
+ 			rslide.setValue(0);
+ 		} else if(e.getSource()==horizRollBut) {
+ 			updatePP();
+ 		} else if(e.getSource()==horizPanBut) {
+ 			updatePP();
+ 		} else if(e.getSource()==reconnectBut) {
+ 			int port=comm._port;
+ 			String addr=comm._host;
+ 			comm.kill();
+ 			comm.removeHeadPointUpdatedListener(this);
+ 			comm = new HeadPointListener(comm._host,comm._port);
+ 			comm.addHeadPointUpdatedListener(this);
+ 		}
+ 	}
+ 	
+ 	public void updatePP() {
+ 		float x=0;
+ 		if(horizPanBut.isSelected())
+ 			x=pslide.getValue()/(float)slidermax;
+ 		else if(horizRollBut.isSelected())
+ 			x=rslide.getValue()/(float)slidermax;
+ 		pp.doSetPoint(x,tslide.getValue()/(float)slidermax);
+ 	}
+ 
+ 	public void frameInit() {
+ 		super.frameInit();
+ 		
+ 		int strutsize=10;
+ 		int sepsize=5;
+ 		getContentPane().setLayout(new BorderLayout());
+ 		getContentPane().add(Box.createHorizontalStrut(strutsize),BorderLayout.EAST);
+ 		getContentPane().add(Box.createHorizontalStrut(strutsize),BorderLayout.WEST);
+ 		getContentPane().add(Box.createVerticalStrut(strutsize),BorderLayout.NORTH);
+ 		JPanel p=new JPanel(new SquareRightLayout());
+ 		p.setLayout(new SquareRightLayout());
+ 		pp=new PointPick(false);
+ 		pp.addPointPickedListener(this);
+ 		pp.addMouseListener(this);
+ 		p.add(pp,SquareRightLayout.SQUARE);
+ 		Box tmp=Box.createHorizontalBox();
+ 		tmp.add(Box.createHorizontalStrut(strutsize));
+ 		JSeparator sep;
+ 		sep=new JSeparator(SwingConstants.VERTICAL);
+ 		sep.setMaximumSize(new Dimension(sepsize,slidermax));
+ 		tmp.add(sep);
+ 		tmp.add(Box.createHorizontalStrut(strutsize));
+ 		{
+ 			Box tmp2=Box.createVerticalBox();
+ 			tmp2.add(Box.createVerticalGlue());
+ 			int labwidth=45;
+ 			tmp2.add(new JLabel("Tilt:"));
+ 			{
+ 				Box tmp3=Box.createHorizontalBox();
+ 				tslide=new JSlider(-slidermax,slidermax,0);
+ 				tslide.addChangeListener(this);
+ 				JLabel lab;
+ 				lab=new JLabel("Down");
+ 				lab.setFont(lab.getFont().deriveFont(lab.getFont().getSize2D()-2));
+ 				lab.setHorizontalAlignment(SwingConstants.RIGHT);
+ 				lab.setPreferredSize(new Dimension(labwidth,lab.getFont().getSize()));
+ 				tmp3.add(lab);
+ 				tmp3.add(tslide);
+ 				lab=new JLabel("Up");
+ 				lab.setFont(lab.getFont().deriveFont(lab.getFont().getSize2D()-2));
+ 				lab.setHorizontalAlignment(SwingConstants.LEFT);
+ 				lab.setPreferredSize(new Dimension(labwidth,lab.getFont().getSize()));
+ 				tmp3.add(lab);
+ 				//tmp3.add(new JButton("Zero"));
+ 				tmp3.setAlignmentX(0);
+ 				tmp2.add(tmp3);
+ 			}
+ 			tmp2.add(Box.createVerticalStrut(strutsize));
+ 			tmp2.add(new JLabel("Pan:"));
+ 			{
+ 				Box tmp3=Box.createHorizontalBox();
+ 				pslide=new JSlider(-slidermax,slidermax,0);
+ 				pslide.addChangeListener(this);
+ 				JLabel lab;
+ 				lab=new JLabel("Left");
+ 				lab.setFont(lab.getFont().deriveFont(lab.getFont().getSize2D()-2));
+ 				lab.setHorizontalAlignment(SwingConstants.RIGHT);
+ 				lab.setPreferredSize(new Dimension(labwidth,lab.getFont().getSize()));
+ 				tmp3.add(lab);
+ 				tmp3.add(pslide);
+ 				lab=new JLabel("Right");
+ 				lab.setFont(lab.getFont().deriveFont(lab.getFont().getSize2D()-2));
+ 				lab.setHorizontalAlignment(SwingConstants.LEFT);
+ 				lab.setPreferredSize(new Dimension(labwidth,lab.getFont().getSize()));
+ 				tmp3.add(lab);
+ 				//tmp3.add(new JButton("Zero"));
+ 				tmp3.setAlignmentX(0);
+ 				tmp2.add(tmp3);
+ 			}
+ 			tmp2.add(Box.createVerticalStrut(strutsize));
+ 			tmp2.add(new JLabel("Roll:"));
+ 			{
+ 				Box tmp3=Box.createHorizontalBox();
+ 				rslide=new JSlider(-slidermax,slidermax,0);
+ 				rslide.addChangeListener(this);
+ 				JLabel lab;
+ 				lab=new JLabel("Counter");
+ 				lab.setFont(lab.getFont().deriveFont(lab.getFont().getSize2D()-2));
+ 				lab.setHorizontalAlignment(SwingConstants.RIGHT);
+ 				lab.setPreferredSize(new Dimension(labwidth,lab.getFont().getSize()));
+ 				tmp3.add(lab);
+ 				tmp3.add(rslide);
+ 				lab=new JLabel("Clock");
+ 				lab.setFont(lab.getFont().deriveFont(lab.getFont().getSize2D()-2));
+ 				lab.setHorizontalAlignment(SwingConstants.LEFT);
+ 				lab.setPreferredSize(new Dimension(labwidth,lab.getFont().getSize()));
+ 				tmp3.add(lab);
+ 				//tmp3.add(new JButton("Zero"));
+ 				tmp3.setAlignmentX(0);
+ 				tmp2.add(tmp3);
+ 			}
+ 			tmp2.add(Box.createVerticalStrut(strutsize));
+ 			{
+ 				Box tmp3=Box.createHorizontalBox();
+ 				tmp3.add(Box.createHorizontalGlue());
+ 				stopBut=new JButton("Center");
+ 				stopBut.addActionListener(this);
+ 				rootPane.setDefaultButton(stopBut);
+ 				tmp3.add(stopBut);
+ 				tmp3.add(Box.createHorizontalGlue());
+ 				tmp3.setAlignmentX(0);
+ 				tmp2.add(tmp3);
+ 			}
+ 			tmp2.add(Box.createVerticalStrut(strutsize));
+ 			ButtonGroup bg = new ButtonGroup();
+ 			horizPanBut=new JRadioButton("Horizontal is Pan");
+ 			horizPanBut.addActionListener(this);
+ 			horizPanBut.setSelected(true);
+ 			bg.add(horizPanBut);
+ 			tmp2.add(horizPanBut);
+ 			horizRollBut=new JRadioButton("Horizontal is Roll");
+ 			horizRollBut.addActionListener(this);
+ 			bg.add(horizRollBut);
+ 			tmp2.add(horizRollBut);
+ 			tmp2.add(Box.createVerticalStrut(strutsize));
+ 			tmp2.add(resetOnRelease=new JCheckBox("Center on release")); 
+ 			tmp2.add(Box.createVerticalGlue());
+ 			tmp.add(tmp2);
+ //			Dimension d=tmp2.getMinimumSize();
+ //			System.out.println(d);
+ //			pp.setSize(d);
+ //			pp.setMinimumSize(d);
+ //			pp.setPreferredSize(d);
+ //			pp.setMaximumSize(d);
+ 		}
+ 		p.add(tmp,SquareRightLayout.RIGHT);
+ 		getContentPane().add(p,BorderLayout.CENTER);
+ 		{
+ 			Box tmp2=Box.createHorizontalBox();
+ 			tmp2.add(Box.createHorizontalStrut(strutsize));
+ 			{
+ 				Box tmp3=Box.createVerticalBox();
+ 				tmp3.add(Box.createVerticalStrut(strutsize));
+ 				tmp3.add(new JSeparator());
+ 				tmp3.add(Box.createVerticalStrut(strutsize-sepsize));
+ 				{
+ 					Box tmp4=Box.createHorizontalBox();
+ 					tmp4.add(status=new JLabel("Connecting..."));
+ 					tmp4.add(Box.createHorizontalGlue());
+ 					reconnectBut=new JButton(carrows);
+ 					reconnectBut.setPreferredSize(new Dimension(carrows.getIconWidth(),carrows.getIconHeight()));
+ 					reconnectBut.addActionListener(this);
+ 					reconnectBut.setToolTipText("Drop current connection and try again.");
+ 					tmp4.add(reconnectBut);
+ 					tmp3.add(tmp4);
+ 				}
+ 				tmp3.add(Box.createVerticalStrut(strutsize));
+ 				tmp2.add(tmp3);
+ 			}
+ 			tmp2.add(Box.createHorizontalStrut(strutsize));
+ 			getContentPane().add(tmp2,BorderLayout.SOUTH);
+ 		}
+ 
+ 		pp.setEnabled(false);
+ 		tslide.setEnabled(false);
+ 		pslide.setEnabled(false);
+ 		rslide.setEnabled(false);
+ 		stopBut.setEnabled(false);
+ 		addWindowListener(new CloseHeadPointAdapter(this));
+ 	}
+ }
Index: AiboPup/tools/mon/HeadPointListener.java
diff -c /dev/null AiboPup/tools/mon/HeadPointListener.java:1.1
*** /dev/null	Tue Jul  8 22:31:53 2003
--- AiboPup/tools/mon/HeadPointListener.java	Sun Jul  6 21:02:26 2003
***************
*** 0 ****
--- 1,114 ----
+ // Sends "HeadPoint" command data from TekkotsuMon to the AIBO.
+ import java.lang.Integer;
+ import java.lang.String;
+ import java.lang.System;
+ import java.io.OutputStream;
+ import java.io.InputStream;
+ import java.net.Socket;
+ import javax.swing.Timer;
+ import java.awt.event.ActionEvent;
+ import java.awt.event.ActionListener;
+ import java.util.Vector;
+ import java.net.SocketException;
+ 
+ // The class itself. Brilliant that even though it does the talking,
+ // it extends TCP*Listener*.
+ public class HeadPointListener extends TCPListener implements ActionListener {
+   // The command output stream
+   OutputStream out;
+   Socket mysock;
+ 	double tilt=0;
+ 	double pan=0;
+ 	double roll=0;
+ 	Vector listeners=new Vector();
+ 	
+ 	public interface HeadPointUpdatedListener {
+ 		public void headPointUpdated(HeadPointListener mc);
+ 	}
+ 
+ 	void addHeadPointUpdatedListener(HeadPointUpdatedListener mcl) { listeners.add(mcl); }
+ 	void removeHeadPointUpdatedListener(HeadPointUpdatedListener mcl) { listeners.remove(mcl); }
+ 	void fireHeadPointUpdated() {
+ 		for(int i=0;i<listeners.size();i++)
+ 			((HeadPointUpdatedListener)listeners.get(i)).headPointUpdated(this);
+ 	}
+ 
+   // Connect to control socket
+   void connected(Socket socket) {
+     mysock = socket;
+ 		fireHeadPointUpdated();
+     try {
+       out = mysock.getOutputStream();
+ 			InputStream sin=socket.getInputStream();
+ 			while (true) { //not that we expect input, but will block until the socket is closed
+ 				String msgtype=readLine(sin);
+ 				if(!_isConnected) break;
+ 			}
+     } catch(Exception e) {if((SocketException)e==null) e.printStackTrace();}
+ 
+ 		try { socket.close(); } catch (Exception ex) { }
+ 
+ 		_isConnected=false;
+ 		fireHeadPointUpdated();
+ 		//The sleep is to get around the socket still listening after being closed thing
+ 		if(!destroy)
+ 			System.out.println("HeadPoint - connection closed... reconnect after 5 seconds");
+ 		try { Thread.sleep(5000); } catch (Exception ex) {}
+   }
+ 
+   // Disconnect from control socket
+   public void close() {
+ 		//    try { mysock.close(); } catch(Exception e) {}
+     //_isConnected = false;
+     super.close();
+ 		//we'll fire an event to the listeners when the readLine in connected finally fails
+   }
+ 
+ 	public void actionPerformed(ActionEvent e) {
+ 		if(_isConnected) {
+ 			sendCommand("t",tilt);
+ 			sendCommand("p",pan);
+ 			sendCommand("r",roll);
+ 		}
+ 	}
+ 
+   // Send a headPoint command
+   public void sendCommand(String command, double param) {
+ 		
+     // Extract command byte
+     byte cmdbytes[] = command.getBytes();
+ 		if(cmdbytes[0]=='t')
+ 			tilt=param;
+ 		else if(cmdbytes[0]=='p')
+ 			pan=param;
+ 		else if(cmdbytes[0]=='r')
+ 			roll=param;
+ 
+     // Construct the command sequence
+     byte sequence[] = new byte[5];
+     // The commmand byte is the first byte in cmdbytes. The remaining
+     // four bytes belong to the parameter. We have to convert the parameter
+     // (which we send as a float, not a double) to MIPS byte order thanks to
+     // (ahem) prior design decisions.
+     sequence[0] = cmdbytes[0];
+     int pbits = Float.floatToIntBits((float) param);
+     Integer i;
+     i = new Integer((pbits >> 24) & 0xff); sequence[4] = i.byteValue();
+     i = new Integer((pbits >> 16) & 0xff); sequence[3] = i.byteValue();
+     i = new Integer((pbits >>  8) & 0xff); sequence[2] = i.byteValue();
+     i = new Integer(pbits & 0xff);	   sequence[1] = i.byteValue();
+     // Now write the whole command.
+     try {
+       out.write(sequence, 0, 5);
+     } catch(Exception e) { close(); return; }
+   }
+ 
+   // Some state inquiry functions
+   public boolean hasData() { return false; }
+   public boolean isConnected() { return _isConnected; }
+ 
+   // Constructors
+   public HeadPointListener() { super(); }
+   public HeadPointListener(int port) { super(port); }
+   public HeadPointListener(String host, int port) { super(host, port); }
+ }
Index: AiboPup/tools/mon/ImageSequenceWriterThread.java
diff -c /dev/null AiboPup/tools/mon/ImageSequenceWriterThread.java:1.3
*** /dev/null	Tue Jul  8 22:31:54 2003
--- AiboPup/tools/mon/ImageSequenceWriterThread.java	Fri Jun 27 02:03:57 2003
***************
*** 0 ****
--- 1,141 ----
+ import java.awt.event.*;
+ import javax.swing.*;
+ import java.lang.String;
+ import java.util.LinkedList;
+ import java.awt.*;
+ import javax.imageio.ImageIO;
+ import java.awt.image.BufferedImage;
+ import java.awt.image.IndexColorModel;
+ import java.awt.image.DataBuffer;
+ import java.util.Date;
+ import java.io.PrintWriter;
+ import java.io.FileOutputStream;
+ 
+ public class ImageSequenceWriterThread extends Thread implements VisionUpdatedListener {
+ 	String dir;
+ 	String pre;
+ 	String post;
+ 	String fmt;
+ 	LinkedList imgBufs=new LinkedList();
+ 	int dig;
+ 	LinkedList q=new LinkedList();
+ 	int count=0;
+ 	VisionListener listen;
+ 	boolean stopping=false;
+ 	JButton but;
+ 
+ 	public ImageSequenceWriterThread(VisionListener l, JButton reenableBut) {
+ 		super("ImageSequenceWriter");
+ 		int initbufsize=500;
+ 		but=reenableBut;
+ 		listen=l;
+ 		l.addListener(this);
+ 		BufferedImage i=l.getImage();
+ 		if(i.getColorModel().getTransferType()!=DataBuffer.TYPE_BYTE)
+ 			for(int j=0;j<initbufsize;j++)
+ 				imgBufs.add(new BufferedImage(i.getWidth(),i.getHeight(),i.getType()));
+ 		else {
+ 			for(int j=0;j<initbufsize;j++)
+ 				imgBufs.add(new BufferedImage(i.getWidth(),i.getHeight(),i.getType(),(IndexColorModel)i.getColorModel()));
+ 		}
+ 	}
+ 
+ 	public void setDirectory(String directory) {
+ 		dir=directory;
+ 	}
+ 
+ 	public void setName(String prepend, int digits, String append, String format) {
+ 		pre=prepend;
+ 		post=append;
+ 		fmt=format;
+ 		dig=digits;
+ 	}
+ 
+ 	public void visionUpdated(VisionListener l) {
+ 		push(l.getImage(),l.getTimeStamp());
+ 	}
+ 
+ 	public void push(BufferedImage i, Date t) {
+ 		BufferedImage i2;
+ 		if(imgBufs.size()>0)
+ 			i2=(BufferedImage)imgBufs.removeFirst();
+ 		else {
+ 			if(i.getColorModel().getTransferType()!=BufferedImage.TYPE_BYTE_INDEXED)
+ 				i2=new BufferedImage(i.getWidth(),i.getHeight(),i.getType());
+ 			else
+ 				i2=new BufferedImage(i.getWidth(),i.getHeight(),i.getType(),(IndexColorModel)i.getColorModel());
+ 		}
+ 		i.copyData(i2.getRaster());
+ 		synchronized(q) {
+ 			q.addLast(i2);
+ 			q.addLast(t);
+ 		}
+ 	}
+ 
+ 	public void run() {
+ 		String tmp=null;
+ 		PrintWriter log;
+ 		try {
+ 			log=new PrintWriter(new FileOutputStream(dir+pre+post+".txt"));
+ 		} catch(Exception ex) { ex.printStackTrace(); return; }
+ 		Date start=null;
+ 		try {
+ 			while(true) {
+ 				while(q.size()>0) {
+ 					if(interrupted()) {
+ 						if(!stopping) {
+ 							stopping=true;
+ 							if(but!=null) {
+ 								but.setEnabled(false);
+ 								tmp=but.getText();
+ 								but.setText("Writing...");
+ 							}
+ 							listen.removeListener(this);
+ 						} else { //second interrupt... die!
+ 							break;
+ 						}
+ 					}
+ 					BufferedImage i;
+ 					Date t;
+ 					synchronized(q) {
+ 						i=(BufferedImage)q.removeFirst();
+ 						t=(Date)q.removeFirst();
+ 					}
+ 					if(start==null)
+ 						start=t;
+ 					long dt=t.getTime()-start.getTime();
+ 					String name=getFileName(dt);
+ 					log.println(name+"\t"+dt);
+ 					ImageIO.write(i,fmt,new FileOutputStream(dir+name));
+ 					imgBufs.addLast(i);
+ 					count++;
+ 				}
+ 				if(stopping)
+ 					break;
+ 				sleep(1000/25);
+ 			}
+ 		} catch(Exception ex) {}
+ 		log.close();
+ 		if(but!=null && tmp!=null) {
+ 			but.setEnabled(true);
+ 			if(but.getText().compareTo("Writing...")==0)
+ 				but.setText(tmp);
+ 		}
+ 	}
+ 
+ 	protected String getFileName(long dt) {
+ 		String ans=pre;
+ 		long c=count;
+ 		int digits=dig;
+ 		if(digits==0) {
+ 			c=dt;
+ 			digits=6;
+ 		}
+ 		for(int s=(int)Math.pow(10,digits-1); s>=1; s/=10) {
+ 			ans+=c/s;
+ 			c-=(c/s)*s;
+ 		}
+ 		ans+=post+"."+fmt;
+ 		return ans;
+ 	}
+ }
Index: AiboPup/tools/mon/Listener.java
diff -c AiboPup/tools/mon/Listener.java:1.5 AiboPup/tools/mon/Listener.java:1.7
*** AiboPup/tools/mon/Listener.java:1.5	Mon Jun  9 20:53:49 2003
--- AiboPup/tools/mon/Listener.java	Thu Jun 26 04:47:33 2003
***************
*** 5,157 ****
  import java.io.IOException;
  
  public abstract class Listener implements Runnable {
!   public Listener() { _port=-1; _isConnected=false; }
!   public Listener(int port) { this(); setPort(port); }
!   public Listener(String host, int port) { this(); setHostPort(host, port); }
! 
!   public void setPort(int port) {
!     _isServer=true;
!     _port=port;
!     startThread();
!   }
! 
!   public void setHostPort(String host, int port) {
!     _isServer=false;
!     _host=host;
!     _port=port;
!     startThread();
!   }
!   
!   public void startThread() {
!     _listenerThread=new Thread(this);
!     _listenerThread.start();
!   }
! 
!   public void run() {
!     if (_port >= 0) {
!       if (_isServer)
!         runServer();
!       else
!         runConnect();
!     } else {
!       System.out.println("can't start Listener without [host],port");
!     }
!   }
  
  	public void kill() {
  		destroy=true;
  		_isConnected=false;
! 		_listenerThread.interrupt();
  		close();
  	}
  
!   void frameTimer() {
!     _frametimer_numframes++;
!     if (System.currentTimeMillis()-_frametimer_timer>1000) {
!       System.out.println("updated at "+_frametimer_numframes+"hz");
!       _frametimer_numframes=0;
!       _frametimer_timer=System.currentTimeMillis();
!     }
!   }
! 
!   double readDouble(InputStream in) throws IOException {
!     return Double.longBitsToDouble(readLong(in));
!   }
! 
!   void writeDouble(OutputStream out, double x) throws IOException {
!     writeLong(out,Double.doubleToLongBits(x));
!   }
! 
!   long readLong(InputStream in) throws IOException {
!     int read=0;
!     int last=0;
!     byte[] buf=new byte[8];
!     while (read<8 && last>=0) { last=in.read(buf,read,8-read); read+=last; }
!     if(last<0)
!     	_isConnected=false;
!     return (b2l(buf[7])<<56) | (b2l(buf[6])<<48) |
!            (b2l(buf[5])<<40) | (b2l(buf[4])<<32) |
!            (b2l(buf[3])<<24) | (b2l(buf[2])<<16) |
!            (b2l(buf[1])<< 8) | b2l(buf[0]);
!   }
! 
!   void writeLong(OutputStream out, long x) throws IOException {
!     int bytelen=8;
!     byte[] buf=new byte[bytelen];
!     for(int i=0; i<bytelen; i++)
!       buf[i]=(new Long((x>>(8*i)) & 0xff)).byteValue();
!     out.write(buf,0,bytelen);
!   }
! 
!   float readFloat(InputStream in) throws IOException {
!     return Float.intBitsToFloat(readInt(in));
!   }
!   
!   void writeFloat(OutputStream out, float x) throws IOException {
!     writeInt(out,Float.floatToIntBits(x));
!   }
! 
!   int readInt(InputStream in) throws IOException {
!     int read=0;
!     int last=0;
!     byte[] buf=new byte[4];
!     while (read<4 && last>=0) { last=in.read(buf,read,4-read); read+=last; }
!     if(last<0)
!     	_isConnected=false;
!     return (b2i(buf[3])<<24) | (b2i(buf[2])<<16) |
!            (b2i(buf[1])<< 8) | b2i(buf[0]);
!   }
!   
!   void writeInt(OutputStream out, int x) throws IOException {
!     int bytelen=4;
!     byte[] buf=new byte[bytelen];
!     for(int i=0; i<bytelen; i++)
!       buf[i]=(new Integer((x>>(8*i)) & 0xff)).byteValue();
!     out.write(buf,0,bytelen);
!   }
! 
!   void readBytes(byte[] buf, InputStream in, int bytes) throws IOException {
!     int read=0;
!     int last=0;
!     while (read<bytes && last>=0) { last=in.read(buf, read, bytes-read); read+=last;}
!     if(last<0)
!     	_isConnected=false;
!   }
! 
!   String readLine(InputStream in) throws java.io.IOException{
!     StringBuffer sbuf=new StringBuffer();
!     int x=in.read();
!     if(x==-1) {
!       _isConnected=false;
!       return sbuf.toString();
!     }
!     char c=(char)x;
!     while(c!='\n') {
!       sbuf.append(c);
!       x=in.read();
!       if(x==-1) {
!         _isConnected=false;
!         return sbuf.toString();
!       }
!       c=(char)x;
!     }
!     return sbuf.toString();
!   }
!   
!   int b2i(byte b) { return (b>=0)?(int)b:((int)b)+256; }
!   long b2l(byte b) { return (b>=0)?(long)b:((long)b)+256; }
! 
!   abstract void runServer();
!   abstract void runConnect();
!   abstract public void close();
! 
!   boolean _isServer;
!   int _port;
!   String _host;
!   boolean _isConnected;
!   volatile Thread _listenerThread;
  	volatile boolean destroy=false;
  
!   int _frametimer_numframes=0;
!   long _frametimer_timer=System.currentTimeMillis();
  }
--- 5,162 ----
  import java.io.IOException;
  
  public abstract class Listener implements Runnable {
! 	public Listener() { _port=-1; _isConnected=false; }
! 	public Listener(int port) { this(); setPort(port); }
! 	public Listener(String host, int port) { this(); setHostPort(host, port); }
! 
! 	public void setPort(int port) {
! 		_isServer=true;
! 		_port=port;
! 		startThread();
! 	}
! 
! 	public void setHostPort(String host, int port) {
! 		_isServer=false;
! 		_host=host;
! 		_port=port;
! 		startThread();
! 	}
! 	
! 	public void startThread() {
! 		destroy=false;
! 		_listenerThread=new Thread(this);
! 		_listenerThread.start();
! 	}
! 
! 	public void run() {
! 		if (_port >= 0) {
! 			if (_isServer)
! 				runServer();
! 			else
! 				runConnect();
! 		} else {
! 			System.out.println("can't start Listener without [host],port");
! 		}
! 	}
  
  	public void kill() {
  		destroy=true;
  		_isConnected=false;
! 		if(_listenerThread!=null)
! 			_listenerThread.interrupt();
  		close();
  	}
  
! 	void frameTimer() {
! 		_frametimer_numframes++;
! 		if (System.currentTimeMillis()-_frametimer_timer>1000) {
! 			System.out.println("updated at "+_frametimer_numframes+"hz");
! 			_frametimer_numframes=0;
! 			_frametimer_timer=System.currentTimeMillis();
! 		}
! 	}
! 
! 	double readDouble(InputStream in) throws IOException {
! 		return Double.longBitsToDouble(readLong(in));
! 	}
! 
! 	void writeDouble(OutputStream out, double x) throws IOException {
! 		writeLong(out,Double.doubleToLongBits(x));
! 	}
! 
! 	long readLong(InputStream in) throws IOException {
! 		int read=0;
! 		int last=0;
! 		byte[] buf=new byte[8];
! 		while (read<8 && last>=0) { last=in.read(buf,read,8-read); read+=last; }
! 		if(last<0)
! 			_isConnected=false;
! 		return (b2l(buf[7])<<56) | (b2l(buf[6])<<48) |
! 					 (b2l(buf[5])<<40) | (b2l(buf[4])<<32) |
! 					 (b2l(buf[3])<<24) | (b2l(buf[2])<<16) |
! 					 (b2l(buf[1])<< 8) | b2l(buf[0]);
! 	}
! 
! 	void writeLong(OutputStream out, long x) throws IOException {
! 		int bytelen=8;
! 		byte[] buf=new byte[bytelen];
! 		for(int i=0; i<bytelen; i++)
! 			buf[i]=(new Long((x>>(8*i)) & 0xff)).byteValue();
! 		out.write(buf,0,bytelen);
! 	}
! 
! 	float readFloat(InputStream in) throws IOException {
! 		return Float.intBitsToFloat(readInt(in));
! 	}
! 	
! 	void writeFloat(OutputStream out, float x) throws IOException {
! 		writeInt(out,Float.floatToIntBits(x));
! 	}
! 
! 	int readInt(InputStream in) throws IOException {
! 		int read=0;
! 		int last=0;
! 		byte[] buf=new byte[4];
! 		while (read<4 && last>=0) { last=in.read(buf,read,4-read); read+=last; }
! 		if(last<0)
! 			_isConnected=false;
! 		return (b2i(buf[3])<<24) | (b2i(buf[2])<<16) |
! 					 (b2i(buf[1])<< 8) | b2i(buf[0]);
! 	}
! 	
! 	void writeInt(OutputStream out, int x) throws IOException {
! 		int bytelen=4;
! 		byte[] buf=new byte[bytelen];
! 		for(int i=0; i<bytelen; i++)
! 			buf[i]=(new Integer((x>>(8*i)) & 0xff)).byteValue();
! 		out.write(buf,0,bytelen);
! 	}
! 
! 	void readBytes(byte[] buf, InputStream in, int bytes) throws IOException {
! 		int read=0;
! 		int last=0;
! 		while (read<bytes && last>=0) {
! 			last=in.read(buf, read, bytes-read);
! 			read+=last;
! 		}
! 		if(last<0)
! 			_isConnected=false;
! 	}
! 
! 	String readLine(InputStream in) throws java.io.IOException{
! 		StringBuffer sbuf=new StringBuffer();
! 		int x=in.read();
! 		if(x==-1) {
! 			_isConnected=false;
! 			return sbuf.toString();
! 		}
! 		char c=(char)x;
! 		while(c!='\n') {
! 			sbuf.append(c);
! 			x=in.read();
! 			if(x==-1) {
! 				_isConnected=false;
! 				return sbuf.toString();
! 			}
! 			c=(char)x;
! 		}
! 		return sbuf.toString();
! 	}
! 	
! 	int b2i(byte b) { return (b>=0)?(int)b:((int)b)+256; }
! 	long b2l(byte b) { return (b>=0)?(long)b:((long)b)+256; }
! 
! 	abstract void runServer();
! 	abstract void runConnect();
! 	abstract public void close();
! 
! 	boolean _isServer;
! 	int _port;
! 	String _host;
! 	boolean _isConnected;
! 	volatile Thread _listenerThread;
  	volatile boolean destroy=false;
  
! 	int _frametimer_numframes=0;
! 	long _frametimer_timer=System.currentTimeMillis();
  }
Index: AiboPup/tools/mon/Makefile
diff -c AiboPup/tools/mon/Makefile:1.3 AiboPup/tools/mon/Makefile:1.7
*** AiboPup/tools/mon/Makefile:1.3	Thu Jun 12 23:57:55 2003
--- AiboPup/tools/mon/Makefile	Tue Jul  1 05:00:18 2003
***************
*** 4,24 ****
  
  CXX=javac
  CURDIR:=$(shell pwd | sed 's/.*\///')
! CXXFLAGS=-deprecation
  
  .PHONY: all clean msg
  
  all: msg $(OBJS)
  
  msg:
! 	@echo " ** These tools require the JDK 1.4 or higher.  1.3 should work, but isn't **"
! 	@echo " ** tested.  These files are _not_ necessary for development.  If errors   **"
! 	@echo " ** occur, you can remove the tools/mon/Makefile and continue without it.  **"
  
  %.class: %.java
  	$(if $(shell which $(CXX)), \
  		@echo "Compiling $< into $@..."; $(CXX) $(CXXFLAGS) $<, \
! 		@printf "\n\n  ***** WARNING: You don't have java... skipping TekkotsuMon *****\n\n\n" \
  	)
  
  clean:
--- 4,27 ----
  
  CXX=javac
  CURDIR:=$(shell pwd | sed 's/.*\///')
! 
! # SEP is to use ';' on windows and ':' on unix because windows is mentally deficient
! SEP:=$(shell if [ "`uname`" = "CYGWIN" -o "`uname`" \> "CYGWIN" -a "`uname`" \< "CYGWIO" ] ; then echo ";" ; else echo ":" ; fi )
! CXXFLAGS=-deprecation -classpath ".$(SEP)./ftp.jar$(SEP)../aibo3d"
  
  .PHONY: all clean msg
  
  all: msg $(OBJS)
  
  msg:
! 	@echo " **     These tools require the JDK 1.4 or higher.  These files         **"
! 	@echo " **     are _not_ necessary for development.  If errors occur, you      **"
! 	@echo " **     can remove the tools/mon/Makefile and continue without it.      **"
  
  %.class: %.java
  	$(if $(shell which $(CXX)), \
  		@echo "Compiling $< into $@..."; $(CXX) $(CXXFLAGS) $<, \
! 		@printf "  ***** WARNING: You don't have java... skipping TekkotsuMon *****\n" \
  	)
  
  clean:
Index: AiboPup/tools/mon/MechaController.java
diff -c AiboPup/tools/mon/MechaController.java:1.2 AiboPup/tools/mon/MechaController.java:1.4
*** AiboPup/tools/mon/MechaController.java:1.2	Tue Apr 15 16:02:43 2003
--- AiboPup/tools/mon/MechaController.java	Sun Jul  6 21:00:10 2003
***************
*** 3,41 ****
  import java.lang.String;
  import java.lang.System;
  import java.io.OutputStream;
  import java.net.Socket;
  
  // The class itself. Brilliant that even though it does the talking,
! // it extends TCP*Listener*. Note: TCPListener has not been modified
! // to send data--that's been taken care of here. Later we need a
! // centralized means of converting and sending data.
! public class MechaController extends TCPListener {
    // The command output stream
    OutputStream out;
    Socket mysock;
  
    // Connect to control socket
    void connected(Socket socket) {
      mysock = socket;
      try {
        out = mysock.getOutputStream();
!     } catch(Exception e) { return; }
  
!     _isConnected = true;
!     // Nothing else to do here
    }
  
    // Disconnect from control socket
    public void close() {
!     try { mysock.close(); } catch(Exception e) {}
!     _isConnected = false;
      super.close();
    }
  
    // Send a mecha command
    public void sendCommand(String command, double param) {
      // Extract command byte
      byte cmdbytes[] = command.getBytes();
  
      // Construct the command sequence
      byte sequence[] = new byte[5];
--- 3,92 ----
  import java.lang.String;
  import java.lang.System;
  import java.io.OutputStream;
+ import java.io.InputStream;
  import java.net.Socket;
+ import javax.swing.Timer;
+ import java.awt.event.ActionEvent;
+ import java.awt.event.ActionListener;
+ import java.util.Vector;
+ import java.net.SocketException;
  
  // The class itself. Brilliant that even though it does the talking,
! // it extends TCP*Listener*.
! public class MechaController extends TCPListener implements ActionListener {
    // The command output stream
    OutputStream out;
    Socket mysock;
+ 	Timer t=new Timer(1000,this);
+ 	double forward=0;
+ 	double strafe=0;
+ 	double rotate=0;
+ 	Vector listeners=new Vector();
+ 	
+ 	public interface MechaUpdatedListener {
+ 		public void mechaUpdated(MechaController mc);
+ 	}
+ 
+ 	void addMechaUpdatedListener(MechaUpdatedListener mcl) { listeners.add(mcl); }
+ 	void removeMechaUpdatedListener(MechaUpdatedListener mcl) { listeners.remove(mcl); }
+ 	void fireMechaUpdated() {
+ 		for(int i=0;i<listeners.size();i++)
+ 			((MechaUpdatedListener)listeners.get(i)).mechaUpdated(this);
+ 	}
  
    // Connect to control socket
    void connected(Socket socket) {
      mysock = socket;
+ 		t.start();
+ 		fireMechaUpdated();
      try {
        out = mysock.getOutputStream();
! 			InputStream sin=socket.getInputStream();
! 			while (true) { //not that we expect input, but will block until the socket is closed
! 				String msgtype=readLine(sin);
! 				if(!_isConnected) break;
! 			}
!     } catch(Exception e) {if((SocketException)e==null) e.printStackTrace();}
! 
! 		try { socket.close(); } catch (Exception ex) { }
  
! 		_isConnected=false;
! 		fireMechaUpdated();
! 		//The sleep is to get around the socket still listening after being closed thing
! 		if(!destroy)
! 			System.out.println("WalkGUI - connection closed... reconnect after 5 seconds");
! 		try { Thread.sleep(5000); } catch (Exception ex) {}
    }
  
    // Disconnect from control socket
    public void close() {
! 		//    try { mysock.close(); } catch(Exception e) {}
!     //_isConnected = false;
! 		t.stop();
      super.close();
+ 		//we'll fire an event to the listeners when the readLine in connected finally fails
    }
  
+ 	public void actionPerformed(ActionEvent e) {
+ 		if(_isConnected) {
+ 			sendCommand("f",forward);
+ 			sendCommand("s",strafe);
+ 			sendCommand("r",rotate);
+ 		}
+ 	}
+ 
    // Send a mecha command
    public void sendCommand(String command, double param) {
+ 		t.restart();
+ 		
      // Extract command byte
      byte cmdbytes[] = command.getBytes();
+ 		if(cmdbytes[0]=='f')
+ 			forward=param;
+ 		else if(cmdbytes[0]=='s')
+ 			strafe=param;
+ 		else if(cmdbytes[0]=='r')
+ 			rotate=param;
  
      // Construct the command sequence
      byte sequence[] = new byte[5];
Index: AiboPup/tools/mon/PointPick.java
diff -c /dev/null AiboPup/tools/mon/PointPick.java:1.2
*** /dev/null	Tue Jul  8 22:31:54 2003
--- AiboPup/tools/mon/PointPick.java	Sat Jun 21 21:30:05 2003
***************
*** 0 ****
--- 1,257 ----
+ import javax.swing.*;
+ import java.awt.*;
+ import java.awt.geom.*;
+ import java.awt.event.*;
+ import java.util.Vector;
+ 
+ public class PointPick extends JComponent {
+ 	static public void main(String s[]) {
+ 		JFrame frame=new JFrame("Point Pick Test");
+ 		frame.setSize(new Dimension(300, 300)); 
+ 		PointPick pp=new PointPick(true);
+ 		frame.getContentPane().setLayout(new BorderLayout());
+ 		frame.getContentPane().add(pp,BorderLayout.CENTER);
+ 		frame.addWindowListener(new WindowAdapter() {
+ 			public void windowClosing(WindowEvent e) { System.exit(0); }
+ 		});
+ 		frame.show();
+ 	}
+ 	
+ 	float x=0;
+ 	float y=0;
+ 	float dotsize=8;
+ 	float tracksize=14;
+ 	PPTic mdot;
+ 	PPTic track;
+ 	Vector listeners=new Vector();
+ 	Vector tics=new Vector();
+ 	boolean isCirc=true;
+ 	
+ 	public interface PointPickedListener {
+ 		public void pointPicked(Point2D.Float p, MouseEvent e, PointPick pp);
+ 	}
+ 	public void addPointPickedListener(PointPickedListener ppl) {
+ 		listeners.add(ppl);
+ 	}
+ 	public void removePointPickedListener(PointPickedListener ppl) {
+ 		listeners.remove(ppl);
+ 	}
+ 	public void firePointPicked(Point2D.Float p, MouseEvent e) {
+ 		for(int i=0; i<listeners.size(); i++)
+ 			((PointPickedListener)listeners.get(i)).pointPicked(p,e,this);
+ 	}
+ 	
+ 	public class PPTic extends JComponent {
+ 		float xp=1.0f;
+ 		float yp=1.0f;
+ 		BasicStroke s=new BasicStroke(1);
+ 		Color line=Color.BLACK;
+ 		Color fill=null;
+ 		boolean isCirc=true;
+ 		public PPTic() {}
+ 		public PPTic(float percent, BasicStroke s) {
+ 			xp=yp=percent;
+ 			this.s=s;
+ 		}
+ 		public PPTic(float percent, BasicStroke s, Color line, Color fill) {
+ 			xp=yp=percent;
+ 			this.s=s;
+ 			this.line=line;
+ 			this.fill=fill;
+ 		}
+ 		public void paint(Graphics graphics) {
+ 			Graphics2D g=(Graphics2D)graphics;
+ 			g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
+ 			float sw=s.getLineWidth();
+ 			float w=getWidth();
+ 			float h=getHeight();
+ 			float l=w*(1-xp)/2;
+ 			float r=l+w*xp;
+ 			float t=h*(1-yp)/2;
+ 			float b=t+h*yp;
+ 			l+=sw/2-.5;
+ 			r-=sw/2+.5;
+ 			t+=sw/2-.5;
+ 			b-=sw/2+.5;
+ 			if(fill!=null) {
+ 				g.setPaint(fill);
+ 				if(isCirc)
+ 					g.fill(new Ellipse2D.Float(l,t,r-l,b-t));
+ 				else
+ 					g.fill(new Rectangle2D.Float(l,t,r-l,b-t));
+ 			}
+ 			if(line!=null) {
+ 				g.setPaint(line);
+ 				g.setStroke(s);
+ 				if(isCirc)
+ 					g.draw(new Ellipse2D.Float(l,t,r-l,b-t));
+ 				else
+ 					g.draw(new Rectangle2D.Float(l,t,r-l,b-t));
+ 			}
+ 			super.paint(graphics);
+ 		}
+ 		public void setCircular(boolean circ) {
+ 			isCirc=circ;
+ 		}
+ 	}
+ 	
+ 	public PointPick(boolean circ) {
+ 		BasicStroke s=new BasicStroke(1);
+ 
+ 		track=new PPTic(1,new BasicStroke(2),Color.RED,null);
+ 		track.reshape((int)((getWidth()*(1+x)-tracksize)/2),(int)((getHeight()*(1+y)-tracksize)/2),(int)tracksize,(int)tracksize);
+ 		track.setVisible(false);
+ 		add(track);
+ 
+ 		mdot=new PPTic(1,s,null,isEnabled()?new Color(.7f,.0f,.0f):new Color(.4f,.4f,.4f));
+ 		mdot.reshape((int)((getWidth()*(1+x)-dotsize)/2),(int)((getHeight()*(1-y)-dotsize)/2),(int)dotsize,(int)dotsize);
+ 		add(mdot);
+ 
+ 		PPTic tmp,tmp2;
+ 		tmp=new PPTic(1.0f,new BasicStroke(2),isEnabled()?Color.BLACK:Color.GRAY,Color.WHITE);
+ 		tmp.reshape(0,0,getWidth(),getHeight());
+ 		tmp.setLayout(new BorderLayout());
+ 		add(tmp);
+ 		tics.add(tmp);
+ 		for(float f=.75f; f>0; f-=.25f) {
+ 			tmp2=new PPTic(f,s,Color.LIGHT_GRAY,null);
+ 			tmp2.setLayout(new BorderLayout());
+ 			tmp.add(tmp2,BorderLayout.CENTER);
+ 			tics.add(tmp2);
+ 			tmp=tmp2;
+ 		}
+ 		tmp2=new PPTic(.0175f,s,null,Color.LIGHT_GRAY);
+ 		tmp2.setLayout(new BorderLayout());
+ 		tmp.add(tmp2,BorderLayout.CENTER);
+ 		tics.add(tmp2);
+ 		tmp=tmp2;
+ 		
+ 		enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK+AWTEvent.MOUSE_EVENT_MASK);
+ 		
+ 		setCircular(circ);
+ 	}
+ 	
+ 	public void setCircular(boolean circ) {
+ 		if(isCirc!=circ) {
+ 			for(int i=0; i<tics.size(); i++) {
+ 				((PPTic)tics.get(i)).setCircular(circ);
+ 			}
+ 			setOpaque(!circ);
+ 			isCirc=circ;
+ 			repaint();
+ 		}
+ 	}
+ 
+ 	public void paint(Graphics graphics) {
+ 		super.paint(graphics);
+ 		int w=getWidth()-1;
+ 		int h=getHeight()-1;
+ //		Rectangle r=graphics.getClipBounds();
+ //		graphics.setColor(Color.WHITE);
+ //		graphics.fillRect(r.x,r.y,r.width,r.height);
+ 		graphics.setColor(isEnabled()?Color.BLACK:Color.GRAY);
+ 		graphics.drawLine(0,w/2,h,w/2);
+ 		graphics.drawLine(h/2,0,h/2,w);
+ //		graphics.setColor(isEnabled()?Color.DARK_GRAY:Color.LIGHT_GRAY);
+ //		graphics.fillOval((int)((getWidth()-dotsize+2)/2),(int)((getHeight()-dotsize+2)/2),(int)dotsize-2,(int)dotsize-2);
+ 	}
+ 
+ 	public void setEnabled(boolean b) {
+ 		((PPTic)tics.get(0)).line=b?Color.BLACK:Color.GRAY;
+ 		mdot.fill=b?new Color(.7f,.0f,.0f):new Color(.4f,.4f,.4f);
+ 		super.setEnabled(b);
+ 	}
+ 	
+ 	public void setBounds(int x, int y, int w, int h) {
+ 		if(w>h)
+ 			w=h;
+ 		if(h>w)
+ 			h=w;
+ 		((PPTic)tics.get(0)).setBounds(0,0,w,h);
+ 		mdot.setBounds((int)((w*(1+this.x)-dotsize)/2),(int)((h*(1-this.y)-dotsize)/2),(int)dotsize,(int)dotsize);
+ 		super.setBounds(x,y,w,h);
+ 	}
+ 	
+ 	public void processMouseEvent(MouseEvent e) {
+ 		if(isEnabled()) {
+ 			if(e.getID()==MouseEvent.MOUSE_PRESSED) {
+ 				Point2D.Float mp=screenToModel(e.getPoint());
+ 				Point sp=modelToScreen(mp);
+ 				sp.translate((int)(-tracksize/2),(int)(-tracksize/2));
+ 				track.setLocation(sp);
+ 				track.setVisible(true);
+ 				doSetPoint(mp);
+ 				firePointPicked(mp,e);
+ 			} else if(e.getID()==MouseEvent.MOUSE_RELEASED) {
+ 				if((e.getModifiersEx()&(MouseEvent.BUTTON1_DOWN_MASK|MouseEvent.BUTTON2_DOWN_MASK|MouseEvent.BUTTON3_DOWN_MASK))==0)
+ 					track.setVisible(false);
+ 			}
+ 		}
+ 		super.processMouseEvent(e);
+ 	}
+ 
+ 	public void processMouseMotionEvent(MouseEvent e) {
+ 		if(isEnabled()) {
+ 			if(e.getID()==MouseEvent.MOUSE_DRAGGED) {
+ 				Point2D.Float mp=screenToModel(e.getPoint());
+ 				Point sp=modelToScreen(mp);
+ 				sp.translate((int)(-tracksize/2),(int)(-tracksize/2));
+ 				track.setLocation(sp);
+ 				doSetPoint(mp);
+ 				firePointPicked(mp,e);
+ 			}
+ 		}
+ 		super.processMouseMotionEvent(e);
+ 	}
+ 	
+ 	public Point2D.Float getPoint() { return new Point2D.Float(x,y); }
+ 	public float getXValue() { return x; }
+ 	public float getYValue() { return y; }
+ 
+ 	public void setPoint(float x, float y) {
+ 		doSetPoint(x,y);
+ 		firePointPicked(new Point2D.Float(x,y),null);
+ 	}
+ 	
+ 	protected Point2D.Float screenToModel(Point p) {
+ 		return screenToModel(p.x,p.y);
+ 	}
+ 	protected Point2D.Float screenToModel(int x, int y) {
+ 		float fx=x/(float)getWidth()*2-1;
+ 		float fy=1-y/(float)getHeight()*2;
+ 		if(isCirc) {
+ 			if(fx*fx+fy*fy>1) {
+ 				double a=Math.atan2(fy,fx);
+ 				fx=(float)Math.cos(a);
+ 				fy=(float)Math.sin(a);
+ 			}
+ 		} else {
+ 			if(fx>1)
+ 				fx=1;
+ 			if(fx<-1)
+ 				fx=-1;
+ 			if(fy>1)
+ 				fy=1;
+ 			if(fy<-1)
+ 				fy=-1;
+ 		}
+ 		return new Point2D.Float(fx,fy);
+ 	}
+ 	protected Point modelToScreen(Point2D.Float p) {
+ 		return modelToScreen(p.x,p.y);
+ 	}
+ 	protected Point modelToScreen(float x, float y) {
+ 		return new Point((int)(getWidth()*(1+x)/2),(int)(getHeight()*(1-y)/2));
+ 	}
+ 	
+ 	public void doSetPoint(Point2D.Float p) {
+ 		doSetPoint(p.x,p.y);
+ 	}
+ 	public void doSetPoint(float x, float y) {
+ 		this.x=x;
+ 		this.y=y;
+ 		Point p=modelToScreen(x,y);
+ 		p.translate((int)(-dotsize/2),(int)(-dotsize/2));
+ 		mdot.setLocation(p);
+ 	}
+ }
Index: AiboPup/tools/mon/SquareRightLayout.java
diff -c /dev/null AiboPup/tools/mon/SquareRightLayout.java:1.1
*** /dev/null	Tue Jul  8 22:31:54 2003
--- AiboPup/tools/mon/SquareRightLayout.java	Sat Jun 21 17:49:55 2003
***************
*** 0 ****
--- 1,42 ----
+ import java.awt.*;
+ 
+ public class SquareRightLayout implements LayoutManager {
+ 	Component right;
+ 	Component square;
+ 	static String SQUARE="square";
+ 	static String RIGHT="right";
+ 	public void addLayoutComponent(String name, Component comp) {
+ 		if(name.compareTo(SQUARE)==0)
+ 			square=comp;
+ 		else if(name.compareTo(RIGHT)==0)
+ 			right=comp;
+ 	}
+ 	public void layoutContainer(Container parent) {
+ 		square.setBounds(0,0,parent.getHeight(),parent.getHeight());
+ 		right.setBounds(parent.getHeight(),0,parent.getWidth()-parent.getHeight(),parent.getHeight());
+ 	}
+ 	public Dimension minimumLayoutSize(Container parent) {
+ 		Dimension sq=square.getMinimumSize();
+ 		Dimension rt=right.getMinimumSize();
+ 		int minsq=sq.width>sq.height?sq.width:sq.height;
+ 		if(minsq<rt.height)
+ 			minsq=rt.height;
+ //			int minheight=minsq>rt.height?minsq:rt.height
+ 		return new Dimension(minsq+rt.width,minsq);
+ 	}
+ 	public Dimension preferredLayoutSize(Container parent) {
+ 		Dimension sq=square.getPreferredSize();
+ 		Dimension rt=right.getPreferredSize();
+ 		int prefsq=sq.width>sq.height?sq.width:sq.height;
+ 		if(prefsq<rt.height)
+ 			prefsq=rt.height;
+ //			int prefheight=minsq>rt.height?minsq:rt.height
+ 		return new Dimension(prefsq+rt.width,prefsq);
+ 	}
+ 	public void removeLayoutComponent(Component comp) {
+ 		if(square==comp)
+ 			square=null;
+ 		else if(right==comp)
+ 			right=null;
+ 	}
+ }
Index: AiboPup/tools/mon/TCPListener.java
diff -c AiboPup/tools/mon/TCPListener.java:1.6 AiboPup/tools/mon/TCPListener.java:1.10
*** AiboPup/tools/mon/TCPListener.java:1.6	Mon Jun  9 20:53:49 2003
--- AiboPup/tools/mon/TCPListener.java	Sun Jul  6 21:00:10 2003
***************
*** 2,60 ****
  import java.net.Socket;
  
  public abstract class TCPListener extends Listener {
!   abstract void connected(Socket socket);
  
!   void runServer() {
!     Thread me = Thread.currentThread();
!     try { _serverSocket=new ServerSocket(_port); }
!     catch (Exception ex) {
!       System.out.println("port "+_port+": "+ex);
!       return;
!     }
! 
!     while (me == _listenerThread && !destroy) {
!       try {
!         _socket=_serverSocket.accept();
!         connected(_socket);
!       } catch (Exception ex) { }
!     }
!   }
! 
!   void runConnect() {
!     int attempts=0;
!     Thread me = Thread.currentThread();
! 		System.err.println("TCPListener port "+_port+" - Connecting...");
!     while (me==_listenerThread && !destroy) {
!       try {
!         _socket=new Socket(_host,_port);
!         attempts=0;
!         connected(_socket);
! 				System.err.println("TCPListener port "+_port+" - Disconnected, attempting to reestablish...");
!       } catch (Exception ex) {}
!       attempts++;
  			if(destroy) {
! 				System.out.println("Connection closed.");
  				break;
  			}
!       if(attempts%10==0)
!         System.err.println("TCPListener port "+_port+" - Waiting for connection... ("+attempts+" attempts)");
!       try {
! 	      Thread.sleep(500);
!       } catch (Exception ex) {}
!     }
!   }
! 
!   public void close() {
!     _listenerThread=null;
!     try { _socket.close(); } catch (Exception ex) { }
!     if (_isServer)
!       try { _serverSocket.close(); } catch (Exception ex) { }
!   }
! 
!   public TCPListener() { super(); }
!   public TCPListener(int port) { super(port); }
!   public TCPListener(String host, int port) { super(host,port); }
  
!   Socket _socket;
!   ServerSocket _serverSocket;
  }
--- 2,69 ----
  import java.net.Socket;
  
  public abstract class TCPListener extends Listener {
! 	abstract void connected(Socket socket);
  
! 	void runServer() {
! 		Thread me = Thread.currentThread();
! 		try { _serverSocket=new ServerSocket(_port); }
! 		catch (Exception ex) {
! 			System.out.println("port "+_port+": "+ex);
! 			return;
! 		}
! 
! 		while (me == _listenerThread && !destroy) {
! 			try {
! 				_socket=_serverSocket.accept();
! 				connected(_socket);
! 			} catch (Exception ex) { }
! 		}
! 	}
! 
! 	void runConnect() {
! 		int attempts=0;
! 		Thread me = Thread.currentThread();
! 		while (me==_listenerThread && !destroy) {
! 			if(attempts==0) {
! 				//				if(attempts!=0)
! 				//					System.err.println("");
! 				System.err.print("TCPListener port "+_port+" - Connecting..");
! 			}
! 			try {
! 				System.err.print(".");
! 				_socket=new Socket(_host,_port);
! 				System.err.println(" connected.");
! 				attempts=0;
! 				_isConnected=true;
! 			} catch (Exception ex) {}
! 			if(_isConnected) {
! 				connected(_socket);
! 				if(!destroy)
! 					System.err.println("TCPListener port "+_port+" - Disconnected, attempting to reestablish...");
! 			}
! 			attempts++;
  			if(destroy) {
! 				System.err.println("TCPListener port "+_port+" - Connection closed.");
  				break;
  			}
! 			try {
! 				Thread.sleep(500);
! 			} catch (Exception ex) {}
! 		}
! 	}
! 
! 	public void close() {
! 		_listenerThread=null;
! 		_isConnected=false;
! 		try { _socket.close(); } catch (Exception ex) { }
! 		if (_isServer)
! 			try { _serverSocket.close(); } catch (Exception ex) { }
! 	}
! 
! 	public TCPListener() { super(); }
! 	public TCPListener(int port) { super(port); }
! 	public TCPListener(String host, int port) { super(host,port); }
  
! 	Socket _socket;
! 	ServerSocket _serverSocket;
  }
Index: AiboPup/tools/mon/VisionGUI.java
diff -c /dev/null AiboPup/tools/mon/VisionGUI.java:1.9
*** /dev/null	Tue Jul  8 22:31:54 2003
--- AiboPup/tools/mon/VisionGUI.java	Fri Jun 27 02:03:57 2003
***************
*** 0 ****
--- 1,374 ----
+ import java.awt.event.*;
+ import javax.swing.*;
+ import java.lang.String;
+ import java.util.LinkedList;
+ import java.awt.*;
+ import javax.imageio.ImageIO;
+ import java.awt.image.BufferedImage;
+ import java.awt.image.IndexColorModel;
+ import java.util.Date;
+ import java.io.PrintWriter;
+ import java.io.FileOutputStream;
+ 
+ public class VisionGUI extends JFrame implements ActionListener, VisionUpdatedListener {
+ 	VisionPanel vision;
+ 	JCheckBox aspectBut;
+ 	JButton freezeBut;
+ 	JButton saveImageBut;
+ 	JLabel status;
+ 	JButton reconnectBut;
+ 	float mspf=0;
+ 	float mspfGamma=.9f;
+ 	long lastFrameTime=0;
+ 	boolean isRaw=false;
+ 	boolean isRLE=false;
+ 	boolean connected=false;
+ 	boolean isFreezeFrame=false;
+ 	final static ImageIcon carrows = new ImageIcon("images/chasingarrows.png");
+ 	ImageSequenceWriterThread imgWrite=null;
+ 	String state="Connecting...";
+ 
+ 	public class StatusUpdateThread extends Thread {
+ 		VisionGUI gui;
+ 		public StatusUpdateThread(VisionGUI gui) { super("StatusUpdate"); this.gui=gui; setDaemon(true);}
+ 		public void run() {
+ 			VisionListener l=gui.vision.getListener();
+ 			while(true) {
+ 				String status=gui.state;
+ 				String recording=recordReport();
+ 				String fps=fpsReport();
+ 				if(fps.length()>0)
+ 					status+=" - "+fps;
+ 				if(recording.length()>0)
+ 					status+="; "+recording;
+ 				gui.status.setText(status);
+ 				try {
+ 					sleep(100);
+ 				} catch(Exception ex) {break;}
+ 			}
+ 		}
+ 		public String recordReport() {
+ 			if(gui.imgWrite!=null && (!gui.imgWrite.stopping || gui.imgWrite.isAlive())) {
+ 				String ans;
+ 				if(!gui.imgWrite.stopping) {
+ 					ans="Rec: ";
+ 					if(imgWrite.imgBufs.size()!=0)
+ 						ans+="Free="+imgWrite.imgBufs.size();
+ 				} else
+ 					ans="Writing";
+ 				ans+=" Queue="+imgWrite.q.size();
+ 				return ans;
+ 			} else
+ 				return "";
+ 		}
+ 		public String fpsReport() {
+ 				if(connected) {
+ 					int rnd=(int)(10000/gui.mspf);
+ 					return rnd/10.0f+" fps";
+ 				} else
+ 					return "";
+ 		}
+ 	}
+ 	
+ 	public static void main(String s[]) {
+ 		int port=-1;
+ 		if(s.length<2)
+ 			usage();
+ 		if(s[1].toUpperCase().compareTo("RLE")==0)
+ 			port=VisionRleListener.defPort;
+ 		else if(s[1].toUpperCase().compareTo("RAW")==0)
+ 			port=VisionRawListener.defPort;
+ 		else {
+ 			System.err.println("VisionGUI: Unrecognized format: "+s[1]);
+ 			usage();
+ 		}
+ 		if(s.length>2)
+ 			port=Integer.parseInt(s[1]);
+ 		String[] args=new String[1];
+ 		args[0]=s[1];
+ 		VisionGUI gui=new VisionGUI(s[0],port,args);
+ 		gui.addWindowListener(new WindowAdapter() {
+ 				public void windowClosing(WindowEvent e) { System.exit(0); } });
+ 		gui.show();
+ 	}
+ 		
+ 	public static void usage() {
+ 		System.out.println("Usage: java VisionGUI host (RLE|raw) [port]");
+ 		System.out.println("       if port is not specified, it defaults to:");
+ 		System.out.println("       "+VisionRawListener.defPort+" for raw");
+ 		System.out.println("       "+VisionRleListener.defPort+" for RLE.");
+ 		System.exit(2);
+ 	}
+ 			
+ 	public void actionPerformed(ActionEvent e) {
+ 		if(e.getActionCommand().compareTo("YUV")==0) {
+ 			VisionRaw v=(VisionRaw)vision;
+ 			if(v!=null)
+ 				v.setConvertRGB(false);
+ 		} else if(e.getActionCommand().compareTo("RGB")==0) {
+ 			VisionRaw v=(VisionRaw)vision;
+ 			if(v!=null)
+ 				v.setConvertRGB(true);
+ 		} else if(e.getActionCommand().compareTo("freeze")==0) {
+ 			isFreezeFrame=!isFreezeFrame;
+ 			if(!isFreezeFrame) {
+ 				state="Reconnecting...";
+ 				vision.open();
+ 			} else {
+ 				state="Disconnecting...";
+ 				vision.close();
+ 			}
+ 		} else if(e.getActionCommand().compareTo("aspect")==0) {
+ 			vision.setLockAspectRatio(((JCheckBox)e.getSource()).isSelected());
+ 		} else if(e.getActionCommand().compareTo("seq")==0) {
+ 			imgWrite=new ImageSequenceWriterThread(vision.getListener(), saveImageBut);
+ 			saveImageBut.setText("Stop Saving Sequence");
+ 			saveImageBut.setToolTipText("Click to stop buffering new frames - already captured frames will continue to be written (unless you close the window)");
+ 			saveImageBut.setActionCommand("stopseq");
+ 			Component cur=this;
+ 			while(cur.getParent()!=null) {
+ 				cur=cur.getParent();
+ 				System.out.println("VisionGUI Weird: "+cur);
+ 			}
+ 			FileDialog f=new FileDialog((Frame)cur,"Save Image Sequence",FileDialog.SAVE);
+ 			f.show();
+ 			if(f.getFile()==null || f.getFile().compareTo("")==0) {
+ 				saveImageBut.doClick();
+ 				return;
+ 			}
+ 			String base;
+ 			String format;
+ 			if(f.getFile().lastIndexOf('.')==-1) {
+ 				format="png";
+ 				base=f.getFile();
+ 			} else {
+ 				int i=f.getFile().lastIndexOf(".");
+ 				format=f.getFile().substring(i+1);
+ 				base=f.getFile().substring(0,i);
+ 			}
+ 			int first=base.indexOf('#');
+ 			int last=base.lastIndexOf('#');
+ 			boolean appendTime=(first==-1);
+ 			imgWrite.setDirectory(f.getDirectory());
+ 			f.dispose();
+ 			if(first!=-1)
+ 				imgWrite.setName(base.substring(0,first),last-first+1,base.substring(last+1),format);
+ 			else
+ 				imgWrite.setName(base,0,"",format);
+ 			imgWrite.start();
+ 		} else if(e.getActionCommand().compareTo("stopseq")==0) {
+ 			saveImageBut.setText("Save Image Sequence");
+ 			saveImageBut.setToolTipText("Saves to a series of files - use .jpg or .png extension to choose format; #'s will be replaced with index, otherwise timecode is appended");
+ 			saveImageBut.setActionCommand("seq");
+ 			imgWrite.interrupt();
+ 		} else if(e.getActionCommand().compareTo("img")==0) {
+ 			Component cur=this;
+ 			while(cur.getParent()!=null) {
+ 				cur=cur.getParent();
+ 				System.out.println("VisionGUI Weird: "+cur);
+ 			}
+ 			FileDialog f=new FileDialog((Frame)cur,"Save Image",FileDialog.SAVE);
+ 			f.show();
+ 			if(f.getFile()!=null && f.getFile().compareTo("")!=0) {
+ 				String format="png";
+ 				int i=f.getFile().lastIndexOf(".");
+ 				if(i!=-1)
+ 					format=f.getFile().substring(i+1);
+ 				try {
+ 					ImageIO.write(vision.getListener().getImage(),format,new FileOutputStream(f.getDirectory()+f.getFile()));
+ 				} catch(Exception ex) {}
+ 			}
+ 			f.dispose();
+ 		} else if(e.getSource()==reconnectBut) {
+ 			vision.close();
+ 			vision.open();
+ 		}
+ 	}
+ 
+ 	class CloseVisionAdapter extends WindowAdapter {
+ 		VisionGUI gui;
+ 		CloseVisionAdapter(VisionGUI gui) {this.gui=gui;}
+ 		public void windowClosing(WindowEvent e) {
+ 			gui.vision.close();
+ 			if(gui.imgWrite!=null && gui.imgWrite.isAlive()) {
+ 				if(!gui.imgWrite.isInterrupted() && !gui.imgWrite.stopping)
+ 					gui.imgWrite.interrupt();
+ 				while(gui.imgWrite.isInterrupted())
+ 					try { Thread.sleep(50); } catch(Exception ex) {}
+ 				if(!gui.imgWrite.stopping)
+ 					System.out.println("imgWrite refuses to stop");
+ 				gui.imgWrite.interrupt(); //this second one should kill it
+ 				while(gui.imgWrite.isAlive())
+ 					try { Thread.sleep(50); } catch(Exception ex) {}
+ 			}
+ 		}
+ 	}
+ 
+ 	public void visionUpdated(VisionListener l) {
+ 		if(l.isConnected()!=connected) {
+ 			connected=l.isConnected();
+ 			if(connected) {
+ 				freezeBut.setEnabled(true);
+ 				freezeBut.setText("Freeze Frame");
+ 				freezeBut.setToolTipText("Freezes current frame (disconnects from stream)");
+ 				isFreezeFrame=false;
+ 				saveImageBut.setEnabled(true);
+ 				saveImageBut.setText("Save Image Sequence");
+ 				saveImageBut.setToolTipText("Saves to a series of files - use .jpg or .png extension to choose format; #'s will be replaced with index, otherwise timecode is appended");
+ 				saveImageBut.setActionCommand("seq");
+ 				state="Connected.";
+ 			} else {
+ 				if(vision._image==null)
+ 					saveImageBut.setEnabled(false);
+ 				else {
+ 					saveImageBut.setText("Save Image");
+ 					saveImageBut.setToolTipText("Save current image shown - use .jpg or .png extension to choose format");
+ 					saveImageBut.setActionCommand("img");
+ 				}
+ 				if(isFreezeFrame) {
+ 					state="Disconnected.";
+ 					freezeBut.setText("Unfreeze");
+ 					freezeBut.setToolTipText("Reconnects to stream");
+ 				} else {
+ 					state="Reconnecting...";
+ 					freezeBut.setEnabled(false);
+ 				}
+ 			}
+ 		}
+ 		if(connected) {
+ 			if(lastFrameTime==0) {
+ 				if(l.getTimeStamp()!=null)
+ 					lastFrameTime=l.getTimeStamp().getTime();
+ 			} else {
+ 				long cur=l.getTimeStamp().getTime();
+ 				mspf=mspf*mspfGamma+(cur-lastFrameTime)*(1-mspfGamma);
+ 				lastFrameTime=cur;
+ 			}
+ 		} else {
+ 			lastFrameTime=0;
+ 		}
+ 	}
+ 	
+ 	public VisionGUI(String host, String[] args) {
+ 		super();
+ 		int port=-1;
+ 		for(int i=0; i<args.length; i++) {
+ 			if(args[i].toUpperCase().compareTo("RLE")==0) {
+ 				isRLE=true;
+ 				isRaw=false;
+ 			} else if(args[i].toUpperCase().compareTo("RAW")==0) {
+ 				isRaw=true;
+ 				isRLE=false;
+ 			} else
+ 				System.err.println("VisionGUI: Unrecognized argument: "+args[0]);
+ 		}
+ 		if(isRLE)
+ 			port=VisionRleListener.defPort;
+ 		else if(isRaw)
+ 			port=VisionRawListener.defPort;
+ 		init(host,port,args);
+ 	}
+ 	public VisionGUI(String host, int port, String[] args) {
+ 		super();
+ 		init(host,port,args);
+ 	}
+ 	public void init(String host, int port, String[] args) {
+ 		int strutsize=10;
+ 		int sepsize=5;
+ 		getContentPane().setLayout(new BorderLayout());
+ 		getContentPane().add(Box.createVerticalStrut(strutsize),BorderLayout.NORTH);
+ 		getContentPane().add(Box.createHorizontalStrut(strutsize),BorderLayout.WEST);
+ 		getContentPane().add(Box.createHorizontalStrut(strutsize),BorderLayout.EAST);
+ 		//always use RLE size for default - we'll assume it's full resolution
+ 		vision=null;
+ 		for(int i=0; i<args.length; i++) {
+ 			if(args[i].toUpperCase().compareTo("RLE")==0) {
+ 				setTitle("TekkotsuMon: Vision RLE");
+ 				vision=new VisionRle(new VisionRleListener(host,port));
+ 				isRLE=true;
+ 				isRaw=false;
+ 			} else if(args[i].toUpperCase().compareTo("RAW")==0) {
+ 				setTitle("TekkotsuMon: Vision Raw");
+ 				vision=new VisionRaw(new VisionRawListener(host,port));
+ 				isRaw=true;
+ 				isRLE=false;
+ 			} else
+ 				System.err.println("VisionGUI: Unrecognized argument: "+args[i]);
+ 		}
+ 		if(vision==null) {
+ 			System.err.println("VisionGUI: Error: Vision mode not specified");
+ 		} else {
+ 			vision.setMinimumSize(new Dimension(VisionRleListener.width/2, VisionRleListener.height/2));
+ 			vision.setPreferredSize(new Dimension(VisionRleListener.width*2, VisionRleListener.height*2));
+ 			vision.setLockAspectRatio(true);
+ 			getContentPane().add(vision,BorderLayout.CENTER);
+ 		}
+ 		{
+ 			Box tmp2=Box.createHorizontalBox();
+ 			tmp2.add(Box.createHorizontalStrut(strutsize));
+ 			{
+ 				Box tmp3=Box.createVerticalBox();
+ 				if(isRaw) {
+ 					Box tmp4=Box.createHorizontalBox();
+ 					ButtonGroup group=new ButtonGroup();
+ 					JRadioButton tmpRad;
+ 					tmpRad=new JRadioButton("RGB");
+ 					tmpRad.setSelected(true);
+ 					tmpRad.addActionListener(this);
+ 					tmpRad.setToolTipText("Shows RGB colorspace");
+ 					group.add(tmpRad);
+ 					tmp4.add(tmpRad);
+ 					tmpRad=new JRadioButton("YUV");
+ 					tmpRad.addActionListener(this);
+ 					tmpRad.setToolTipText("Shows YUV colorspace");
+ 					group.add(tmpRad);
+ 					tmp4.add(tmpRad);
+ 					tmp3.add(tmp4);
+ 				}
+ 				aspectBut=new JCheckBox("Lock 11:9 aspect");
+ 				aspectBut.setAlignmentX(0.5f);
+ 				aspectBut.addActionListener(this);
+ 				aspectBut.setActionCommand("aspect");
+ 				aspectBut.setSelected(true);
+ 				aspectBut.setToolTipText("Forces displayed image to hold transmitted image's aspect ratio");
+ 				tmp3.add(aspectBut);
+ 				freezeBut=new JButton("Freeze Frame");
+ 				freezeBut.setAlignmentX(0.5f);
+ 				freezeBut.addActionListener(this);
+ 				freezeBut.setActionCommand("freeze");
+ 				freezeBut.setEnabled(false);
+ 				freezeBut.setToolTipText("Freezes current frame (disconnects from stream)");
+ 				tmp3.add(freezeBut);
+ 				saveImageBut=new JButton("Save Image Sequence");
+ 				saveImageBut.setAlignmentX(0.5f);
+ 				saveImageBut.addActionListener(this);
+ 				saveImageBut.setActionCommand("seq");
+ 				saveImageBut.setEnabled(false);
+ 				saveImageBut.setToolTipText("Saves to a series of files - use .jpg or .png extension to choose format; #'s will be replaced with index, otherwise timecode is appended");
+ 				tmp3.add(saveImageBut);
+ 				tmp3.add(Box.createVerticalStrut(strutsize));
+ 				tmp3.add(new JSeparator());
+ 				tmp3.add(Box.createVerticalStrut(strutsize-sepsize));
+ 				{
+ 					Box tmp4=Box.createHorizontalBox();
+ 					tmp4.add(status=new JLabel(state));
+ 					tmp4.add(Box.createHorizontalGlue());
+ 					reconnectBut=new JButton(carrows);
+ 					reconnectBut.setPreferredSize(new Dimension(carrows.getIconWidth(),carrows.getIconHeight()));
+ 					reconnectBut.addActionListener(this);
+ 					reconnectBut.setToolTipText("Drop current connection and try again.");
+ 					tmp4.add(reconnectBut);
+ 					tmp3.add(tmp4);
+ 				}
+ 				tmp3.add(Box.createVerticalStrut(strutsize));
+ 				tmp2.add(tmp3);
+ 			}
+ 			tmp2.add(Box.createHorizontalStrut(strutsize));
+ 			getContentPane().add(tmp2,BorderLayout.SOUTH);
+ 		}
+ 		pack();
+ 		addWindowListener(new CloseVisionAdapter(this));
+ 		vision.getListener().addListener(this);
+ 		(new StatusUpdateThread(this)).start();
+ 	}
+ }
Index: AiboPup/tools/mon/VisionListener.java
diff -c /dev/null AiboPup/tools/mon/VisionListener.java:1.5
*** /dev/null	Tue Jul  8 22:31:54 2003
--- AiboPup/tools/mon/VisionListener.java	Thu Jun 26 18:45:57 2003
***************
*** 0 ****
--- 1,32 ----
+ import java.awt.image.BufferedImage;
+ import java.util.Vector;
+ import java.util.Date;
+ 
+ public abstract class VisionListener extends TCPListener {
+ 	boolean updatedFlag;
+ 	Date timestamp;
+ 
+ 	Vector listeners = new Vector();
+ 	void addListener(VisionUpdatedListener l) { listeners.add(l); }
+ 	void removeListener(VisionUpdatedListener l) { listeners.remove(l); }
+ 	void fireVisionUpdate() {
+ 		updatedFlag=true;
+ 		for(int i=0; i<listeners.size(); i++)
+ 			((VisionUpdatedListener)listeners.get(i)).visionUpdated(this);
+ 	}
+ 
+ 	public abstract BufferedImage getImage();
+ 	public Date getTimeStamp() { return timestamp; }
+ 
+ 	public boolean hasData() {
+ 		return updatedFlag;
+ 	}
+  
+ 	public boolean isConnected() {
+ 		return _isConnected;
+ 	}
+ 
+ 	public VisionListener() { super(); }
+ 	public VisionListener(int port) { super(port); }
+ 	public VisionListener(String host, int port) { super(host,port); }
+ }
Index: AiboPup/tools/mon/VisionPanel.java
diff -c /dev/null AiboPup/tools/mon/VisionPanel.java:1.1
*** /dev/null	Tue Jul  8 22:31:54 2003
--- AiboPup/tools/mon/VisionPanel.java	Thu Jun 26 18:57:41 2003
***************
*** 0 ****
--- 1,97 ----
+ import javax.swing.JPanel;
+ import java.awt.image.BufferedImage;
+ import java.awt.Graphics;
+ import java.awt.Color;
+ import java.awt.Dimension;
+ import java.awt.FontMetrics;
+ 
+ public class VisionPanel extends JPanel implements VisionUpdatedListener {
+ 	BufferedImage _image;
+ 	VisionListener _listener;
+ 	boolean lockAspect=false;
+ 	static float defAspectRatio=176/(float)144;
+ 	float tgtAspect=defAspectRatio;
+ 
+ 	protected VisionPanel(VisionListener listener) {
+ 		_listener=listener;
+ 		_listener.addListener(this);
+ 		setBackground(Color.BLACK);
+ 		setForeground(Color.WHITE);
+ 		setOpaque(!lockAspect);
+ 	}
+ 	
+ 	public VisionListener getListener() { return _listener; }
+ 	
+ 	public void close() {
+ 		_listener.kill();
+ 	}
+ 	
+ 	public void open() {
+ 		_listener.startThread();
+ 	}
+ 
+ 	public void visionUpdated(VisionListener l) {
+ 		repaint();
+ 	}
+ 	
+ 	public void setLockAspectRatio(boolean b) {
+ 		if(b!=lockAspect) {
+ 			lockAspect=b;
+ 			setOpaque(!lockAspect);
+ 			repaint();
+ 		}
+ 	}
+ 	
+ 	public boolean getLockAspectRatio() { return lockAspect; }
+ 
+ 	public void setAspectRatio(float asp) {
+ 		if(asp<=0)
+ 			tgtAspect=defAspectRatio;
+ 		else
+ 			tgtAspect=asp;
+ 		if(getLockAspectRatio())
+ 			repaint();
+ 	}
+ 	
+ 	public float getAspectRatio() { return tgtAspect; }
+ 
+ 	public void setLockAspectRatio(boolean b, float asp) {
+ 		setLockAspectRatio(b);
+ 		setAspectRatio(asp);
+ 	}
+ 	
+ 	public void paint(Graphics graphics) {
+ 		_image=_listener.getImage();
+ 		super.paint(graphics);
+ 		Dimension sz=getSize();
+ 		if(getLockAspectRatio()) {
+ 			float curasp=sz.width/(float)sz.height;
+ 			float tgtasp=getAspectRatio();
+ 			if(curasp>tgtasp) {
+ 				int width=(int)(sz.height*tgtasp);
+ 				drawImage(graphics,_image, (sz.width-width)/2, 0, width, sz.height);
+ 			} else if(curasp<tgtasp) {
+ 				int height=(int)(sz.width/tgtasp);
+ 				drawImage(graphics,_image, 0, (sz.height-height)/2, sz.width, height);
+ 			} else {
+ 				drawImage(graphics,_image, 0, 0, sz.width, sz.height);
+ 			}
+ 		} else
+ 			drawImage(graphics,_image, 0, 0, sz.width, sz.height);
+ 	}
+ 	
+ 	protected void drawImage(Graphics g, BufferedImage img, int x, int y, int w, int h) {
+ 		if(img!=null)
+ 			g.drawImage(img,x,y,w,h,null);
+ 		else {
+ 			g.setColor(getBackground());
+ 			g.fillRect(x,y,w,h);
+ 			FontMetrics tmp=g.getFontMetrics();
+ 			String msg="No image";
+ 			int strw=tmp.stringWidth(msg);
+ 			int strh=tmp.getHeight();
+ 			g.setColor(getForeground());
+ 			g.drawString(msg,(getSize().width-strw)/2,(getSize().height-strh)/2+tmp.getAscent());
+ 		}
+ 	}
+ }
\ No newline at end of file
Index: AiboPup/tools/mon/VisionRaw.java
diff -c /dev/null AiboPup/tools/mon/VisionRaw.java:1.7
*** /dev/null	Tue Jul  8 22:31:54 2003
--- AiboPup/tools/mon/VisionRaw.java	Thu Jun 26 04:47:33 2003
***************
*** 0 ****
--- 1,37 ----
+ import java.awt.image.*;
+ import java.awt.*;
+ import javax.swing.*;
+ import java.awt.event.*;
+ 
+ public class VisionRaw extends VisionPanel {
+ 	VisionRawListener _visionraw;
+ 	
+ 	public static void main(String s[]) {
+ 		int port=VisionRawListener.defPort;
+ 		if(s.length<1) {
+ 			System.out.println("Usage: java VisionRaw host [port]");
+ 			System.out.println("			 if port is not specified, it defaults to "+port);
+ 			System.exit(2);
+ 		}
+ 		if(s.length>1)
+ 			port=Integer.parseInt(s[1]);
+ 		JFrame frame=new JFrame("TekkotsuMon: Vision Raw");
+ 		frame.setBackground(Color.black);
+ 		//frame.getContentPane().setLayout(new FlowLayout());
+ 		frame.setSize(new Dimension(VisionRawListener.width*2, VisionRawListener.height*2)); 
+ 		VisionRaw vision=new VisionRaw(new VisionRawListener(s[0],port));
+ 		frame.getContentPane().add(vision);
+ 		frame.addWindowListener(new WindowAdapter() {
+ 				public void windowClosing(WindowEvent e) { System.exit(0); } });
+ 		frame.show();
+ 	}
+ 
+ 	public VisionRaw(VisionRawListener visionraw) {
+ 		super(visionraw);
+ 		_visionraw=visionraw;
+ 	}
+ 
+ 	public void setConvertRGB(boolean b) { _visionraw.setConvertRGB(b); }
+ 	public boolean getConvertRGB(boolean b) { return _visionraw.getConvertRGB(); }
+ }
+ 
Index: AiboPup/tools/mon/VisionRawListener.java
diff -c AiboPup/tools/mon/VisionRawListener.java:1.3 AiboPup/tools/mon/VisionRawListener.java:1.8
*** AiboPup/tools/mon/VisionRawListener.java:1.3	Thu Jun 12 23:57:55 2003
--- AiboPup/tools/mon/VisionRawListener.java	Thu Jun 26 18:45:57 2003
***************
*** 1,62 ****
  import java.io.InputStream;
  import java.net.Socket;
  import javax.swing.JFrame;
  
! public class VisionRawListener extends TCPListener {
!   byte[] _data;
!   byte[] _outd;
!   int imgWidth=88;
!   int imgHeight=72;
! 	int channels=3;
!   int pktSize=imgWidth*imgHeight*channels;
!   int bytesRead;
!   boolean _updatedFlag;
! 
!   void connected(Socket socket) {
!     try {
!       InputStream in=socket.getInputStream();
!        _data=new byte[pktSize];
!        _outd=new byte[pktSize];
!        _isConnected=true;
!       while (true) {
!         int br;
!         bytesRead=0;
!         while(bytesRead<pktSize) {
!           br=in.read(_data,bytesRead,
!                     (pktSize-bytesRead>1024)?1024:(pktSize-bytesRead));
!           bytesRead=bytesRead+br;
!         }
!         synchronized(_outd) {
!           byte[] temp=_data;
!           _data=_outd;
!           _outd=temp;
!           _updatedFlag=true;
!         }
!       }
!     } catch (Exception ex) { }
! 
!     try { socket.close(); } catch (Exception ex) { }
!     _isConnected=false;
!     _updatedFlag=true;
!   }
!  
!   public boolean hasData() {
!     return _updatedFlag;
!   }
!  
!   public byte[] getData() {
! //    frameTimer();
!     synchronized (_outd) {
!       _updatedFlag=false;
!       return _outd;
!     }
!   }
! 
!   public boolean isConnected() {
!     return _isConnected;
!   }
! 
!   public VisionRawListener() { super(); }
!   public VisionRawListener(int port) { super(port); }
!   public VisionRawListener(String host, int port) { super(host,port); }
  }
--- 1,115 ----
  import java.io.InputStream;
  import java.net.Socket;
  import javax.swing.JFrame;
+ import java.awt.Image;
+ import java.awt.image.BufferedImage;
+ import java.util.Date;
  
! public class VisionRawListener extends VisionListener {
! 	static int width=88;
! 	static int height=72;
! 	static int channels=3;
! 	int pktSize=width*height*channels;
! 	byte[] _data=new byte[pktSize];
! 	byte[] _outd=new byte[pktSize];
! 	int[] _pixels=new int[width*height];;
! 	BufferedImage img=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
! 	int bytesRead;
! 	boolean convertRGB=true;
! 	static int defPort=10011;
! 
! 	void connected(Socket socket) {
! 		_isConnected=true;
! 		fireVisionUpdate();
! 		try {
! 			InputStream in=socket.getInputStream();
! 			_isConnected=true;
! 			while (true) {
! 				int br;
! 				bytesRead=0;
! 				while(bytesRead<pktSize) {
! 					br=in.read(_data,bytesRead,(pktSize-bytesRead>1024)?1024:(pktSize-bytesRead));
! 					bytesRead=bytesRead+br;
! 				}
! 				synchronized(_outd) {
! 					byte[] temp=_data;
! 					_data=_outd;
! 					_outd=temp;
! 					timestamp=new Date();
! 				}
! 				fireVisionUpdate();
! 			}
! 		} catch (Exception ex) { }
! 		
! 		try { socket.close(); } catch (Exception ex) { }
! 		_isConnected=false;
! 		fireVisionUpdate();
! 	}
! 	
! 	public byte[] getData() {
! //		frameTimer();
! 		synchronized (_outd) {
! 			updatedFlag=false;
! 			return _outd;
! 		}
! 	}
! 
! 	public void setConvertRGB(boolean b) { 
! 		if(b!=convertRGB) {
! 			convertRGB=b;
! 			updatedFlag=true;
! 			for(int i=0; i<listeners.size(); i++)
! 				((VisionUpdatedListener)listeners.get(i)).visionUpdated(this);
! 		}
! 	}
! 	public boolean getConvertRGB() { return convertRGB; }
! 
! 	public int[] getYUVPixels() {
! 		synchronized(_outd) {
! 			byte[] data=getData();
! 			int offset=0;
! 			for (int i=0; i<width*height; i++) {
! 				int y=(int)data[offset++]&0xFF;
! 				int u=(int)data[offset++]&0xFF;
! 				int v=(int)data[offset++]&0xFF;
! 			_pixels[i]=(255<<24) | (y<<16) | (u<<8) | v;
! 			}
! 		}
! 		return _pixels;
! 	}
! 
! 	public int[] getRGBPixels() {
! 		synchronized(_outd) {
! 			byte[] data=getData();
! 			int offset=0;
! 			for (int i=0; i<width*height; i++) {
! 				int y=(int)data[offset++]&0xFF;
! 				int u=(int)data[offset++]&0xFF;
! 				int v=(int)data[offset++]&0xFF;
! 				u=u*2-255;
! 				v=v*2-255;
! 				int r=y+u;
! 				int b=y+v;
! 				u=u>>1;
! 				v=(v>>2)-(v>>4);
! 				int g=y-u-v;
! 				//			r=r&0xFF; g=g&0xFF; b=b&0xFF;
! 				if (r<0) r=0; if (g<0) g=0; if (b<0) b=0;
! 				if (r>255) r=255; if (g>255) g=255; if (b>255) b=255;
! 				
! 				_pixels[i]=(255<<24) | (r<<16) | (g<<8) | b;
! 			}
! 		}
! 		return _pixels;
! 	}
! 
! 	public BufferedImage getImage() {
! 		int[] data=getConvertRGB()?getRGBPixels():getYUVPixels();
! 		img.setRGB(0,0,width,height,data,0,width);
! 		return img;
! 	}
! 	
! 	public VisionRawListener() { super(); }
! 	public VisionRawListener(int port) { super(port); }
! 	public VisionRawListener(String host, int port) { super(host,port); }
  }
Index: AiboPup/tools/mon/VisionRle.java
diff -c /dev/null AiboPup/tools/mon/VisionRle.java:1.7
*** /dev/null	Tue Jul  8 22:31:54 2003
--- AiboPup/tools/mon/VisionRle.java	Fri Jun 27 02:03:57 2003
***************
*** 0 ****
--- 1,35 ----
+ import java.awt.image.*;
+ import java.awt.*;
+ import javax.swing.*;
+ import java.awt.event.*;
+ 
+ public class VisionRle extends VisionPanel {
+ 	VisionRleListener _visionrle;
+ 
+ 	public static void main(String[] s) { 
+ 		int port=VisionRleListener.defPort;
+ 		if(s.length<1) {
+ 			System.out.println("Usage: java VisionRLE host [port]");
+ 			System.out.println("			 if port is not specified, it defaults to "+port);
+ 			System.exit(2);
+ 		}
+ 		if(s.length>1)
+ 			port=Integer.parseInt(s[1]);
+ 		JFrame frame=new JFrame("TekkotsuMon: Vision Segmented");
+ 		frame.setBackground(Color.black);
+ 		//frame.getContentPane().setLayout(new FlowLayout());
+ 		frame.setSize(new Dimension(VisionRleListener.width, VisionRleListener.height)); 
+ 		VisionRle vision=new VisionRle(new VisionRleListener(s[0],port));
+ 		frame.getContentPane().add(vision);
+ 		frame.addWindowListener(new WindowAdapter() {
+ 				public void windowClosing(WindowEvent e) { System.exit(0); } });
+ 		frame.show();
+ 	}
+ 
+ 	public VisionRle(VisionRleListener visionrle) {
+ 		super(visionrle);
+ 		_visionrle=visionrle;
+ 	}
+ 	
+ }
+ 
Index: AiboPup/tools/mon/VisionRleListener.java
diff -c AiboPup/tools/mon/VisionRleListener.java:1.1 AiboPup/tools/mon/VisionRleListener.java:1.5
*** AiboPup/tools/mon/VisionRleListener.java:1.1	Thu Feb 20 14:51:18 2003
--- AiboPup/tools/mon/VisionRleListener.java	Thu Jun 26 18:45:57 2003
***************
*** 1,88 ****
  import java.io.InputStream;
  import java.net.Socket;
! 
! public class VisionRleListener extends TCPListener {
!   byte[] _data;
!   byte[] _outd;
!   byte[] _sizeb;
!   boolean updatedFlag;
!   int width=176;
!   int height=144;
!   static final boolean _debug=false;
! 
!   void connected(Socket socket) {
!     _data=new byte[22*144*3*2];
!     _outd=new byte[176*144];
!     _isConnected=true;
!     try {
!       InputStream in=socket.getInputStream();
!       while (true) {
!         int size=readInt(in);
!         size=size*3;
!         readBytes(_data, in, size);
!         decodeRLE(size);
!         updatedFlag=true;
!       }
!     } catch (Exception ex) { }
! 
!     try { socket.close(); } catch (Exception ex) { }
!     _isConnected=false;
!   }
! 
!   void decodeRLE(int pktSize) {
!     int curx=0, cury=0;
!     int dlength=pktSize;
!     int dpos=0;
! 
!     for (; dlength>=3 && cury<height;) {
!       byte color;
!       color=_data[dpos++];
!       color++;
!       int x=b2i(_data[dpos++]);
!       int len=b2i(_data[dpos++]);
!       dlength-=3;
!       if (x < curx) {
!         if (_debug) System.out.println("backwards x movement");
!         break;
!       }
! 
!       for (; curx < x; curx++)
!         _outd[cury*width+curx]=1;
! 
!       if (curx+len>width) {
!         if (_debug) System.out.println("run past end");
!         break;
!       }
! 
!       for (; len>0; len--, curx++)
!         _outd [cury*width+curx]=color;
!       if (curx==width) {
!         cury++;
!         curx=0;
!       }
!     }
!     if (cury!=height) {
!       if (_debug) System.out.println("early end of data\n");
!     }
!   }
! 
!   public boolean hasData() {
!     return updatedFlag;
!   }
!  
!   public byte[] getData() {
! //    frameTimer();
! //    synchronized (_outd) {
!       updatedFlag=false;
!       return _outd;
! //    }
!   }
! 
!   public boolean isConnected() {
!     return _isConnected;
!   }
! 
!   public VisionRleListener() { super(); }
!   public VisionRleListener(int port) { super(port); }
!   public VisionRleListener(String host, int port) { super(host,port); }
  }
--- 1,113 ----
  import java.io.InputStream;
  import java.net.Socket;
! import java.awt.Image;
! import java.awt.image.IndexColorModel;
! import java.awt.image.BufferedImage;
! import java.util.Date;
! 
! public class VisionRleListener extends VisionListener {
! 	static int width=176;
! 	static int height=144;
! 	byte[] _data=new byte[22*height*3*2];
! 	byte[] _outd=new byte[width*height];
! 	static int defPort=10012;
! 	static final boolean _debug=false;
! 
! 	//todo: read this from the same file the dog is using
! 	static final byte cmap[]={ (byte)  0, (byte)  0, (byte)  0,
! 	                           (byte)  0, (byte)  0, (byte)  0,
! 	                           (byte)  0, (byte)128, (byte)255,
! 	                           (byte)  0, (byte)128, (byte)  0,
! 	                           (byte)255, (byte)128, (byte)  0,
! 	                           (byte)  0, (byte)255, (byte)  0,
! 	                           (byte)128, (byte)  0, (byte)255,
! 	                           (byte)255, (byte)  0, (byte)  0,
! 	                           (byte)255, (byte)128, (byte)228,
! 	                           (byte)255, (byte)255, (byte)  0,
! 	                           (byte)200, (byte)200, (byte)228,
! 	                           (byte)200, (byte)100, (byte)  0  };
! 	IndexColorModel _cmodel=new IndexColorModel(7, 12, cmap, 0, false);
! 	BufferedImage img=new BufferedImage(width,height,BufferedImage.TYPE_BYTE_INDEXED,_cmodel);
! 
! 
! 	void connected(Socket socket) {
! 		_isConnected=true;
! 		fireVisionUpdate();
! 		try {
! 			InputStream in=socket.getInputStream();
! 			while (true) {
! 				int size=readInt(in);
! 				if(!_isConnected) break;
! 				size=size*3;
! 				readBytes(_data, in, size);
! 				if(!_isConnected) break;
! 				timestamp=new Date();
! 				decodeRLE(size);
! 				fireVisionUpdate();
! 			}
! 		} catch (Exception ex) { }
! 
! 		try { socket.close(); } catch (Exception ex) { }
! 		_isConnected=false;
! 		fireVisionUpdate();
! 	}
! 
! 	void decodeRLE(int pktSize) {
! 		int curx=0, cury=0;
! 		int dlength=pktSize;
! 		int dpos=0;
! 
! 		synchronized (_outd) {
! 			for (; dlength>=3 && cury<height;) {
! 				byte color;
! 				color=_data[dpos++];
! 				color++;
! 				int x=b2i(_data[dpos++]);
! 				int len=b2i(_data[dpos++]);
! 				dlength-=3;
! 				if (x < curx) {
! 					if (_debug) System.out.println("backwards x movement");
! 					break;
! 				}
! 
! 				for (; curx < x; curx++)
! 					_outd[cury*width+curx]=1;
! 
! 				if (curx+len>width) {
! 					if (_debug) System.out.println("run past end");
! 					break;
! 				}
! 
! 				for (; len>0; len--, curx++)
! 					_outd [cury*width+curx]=color;
! 				if (curx==width) {
! 					cury++;
! 					curx=0;
! 				}
! 			}
! 		}
! 		if (cury!=height) {
! 			if (_debug) System.out.println("early end of data\n");
! 		}
! 	}
! 
! 	public byte[] getData() {
! //		frameTimer();
! 		synchronized (_outd) {
! 			updatedFlag=false;
! 			return _outd;
! 		}
! 	}
! 
! 	public BufferedImage getImage() {
! 		synchronized (_outd) {
! 			byte[] data=getData();
! 			img.getRaster().setDataElements(0,0,width,height,data);
! 		}
! 		return img;
! 	}
! 
! 	public VisionRleListener() { super(); }
! 	public VisionRleListener(int port) { super(port); }
! 	public VisionRleListener(String host, int port) { super(host,port); }
  }
Index: AiboPup/tools/mon/VisionUpdatedListener.java
diff -c /dev/null AiboPup/tools/mon/VisionUpdatedListener.java:1.2
*** /dev/null	Tue Jul  8 22:31:54 2003
--- AiboPup/tools/mon/VisionUpdatedListener.java	Fri Jun 20 04:45:38 2003
***************
*** 0 ****
--- 1,4 ----
+ public interface VisionUpdatedListener {
+ 	public void visionUpdated(VisionListener comm);
+ }
+ 
Index: AiboPup/tools/mon/WalkGUI.java
diff -c /dev/null AiboPup/tools/mon/WalkGUI.java:1.5
*** /dev/null	Tue Jul  8 22:31:54 2003
--- AiboPup/tools/mon/WalkGUI.java	Sun Jul  6 21:00:10 2003
***************
*** 0 ****
--- 1,336 ----
+ import javax.swing.*;
+ import java.awt.*;
+ import java.awt.geom.*;
+ import java.awt.event.*;
+ import javax.swing.event.*;
+ 
+ public class WalkGUI extends JFrame implements PointPick.PointPickedListener, ChangeListener, ActionListener, MouseListener, MechaController.MechaUpdatedListener {
+ 	static int defPort=10050;
+ 	PointPick pp;
+ 	JSlider xslide;
+ 	JSlider yslide;
+ 	JSlider aslide;
+ 	JButton stopBut;
+ 	JRadioButton horizRotateBut;
+ 	JRadioButton horizStrafeBut;
+ 	boolean horizButFake=false;
+ 	JCheckBox resetOnRelease;
+ 	JLabel status;
+ 	JButton reconnectBut;
+ 	MechaController comm;
+ 	static int slidermax=10000;
+ 	final static ImageIcon carrows = new ImageIcon("images/chasingarrows.png");
+ 
+ 	static public void main(String s[]) {
+ 		int port=defPort;
+ 		if(s.length<1)
+ 			usage();
+ 		if(s.length>1)
+ 			port=Integer.parseInt(s[1]);
+ 		String[] args=new String[s.length-1];
+ 		for(int i=0; i<s.length-1; i++)
+ 			args[i-1]=s[i];
+ 		JFrame frame=new WalkGUI(s[0],port,args);
+ 		/*		frame.addWindowListener(new WindowAdapter() {
+ 			public void windowClosing(WindowEvent e) { frame.dispose(); }
+ 			});*/
+ 	}
+ 	
+ 	public static void usage() {
+ 		System.out.println("Usage: java WalkGUI host [port]");
+ 		System.out.println("       if port is not specified, it defaults to: "+defPort);
+ 		System.exit(2);
+ 	}
+ 		
+ 	public WalkGUI(String host, int port, String args[]) {
+ 		super("TekkotsuMon: Walk Remote Control");
+ 		pack();
+ 		comm=new MechaController(host,port);
+ 		comm.addMechaUpdatedListener(this);
+ 		show();
+ 	}
+ 
+ 	public void close() {
+ 		comm.kill();
+ 		dispose();
+ 	}
+ 	
+ 	class CloseWalkAdapter extends WindowAdapter {
+ 		WalkGUI gui;
+ 		CloseWalkAdapter(WalkGUI gui) {this.gui=gui;}
+ 		public void windowClosing(WindowEvent e) {
+ 			gui.close();
+ 		}
+ 	}
+ 
+ 	public void pointPicked(Point2D.Float p, MouseEvent e, PointPick pp) {
+ 		boolean isBut2=(e.getModifiersEx()&MouseEvent.BUTTON3_DOWN_MASK)==MouseEvent.BUTTON3_DOWN_MASK;
+ 		if(!horizButFake && isBut2) {
+ 			if(horizStrafeBut.isSelected())
+ 				horizRotateBut.setSelected(true);
+ 			else
+ 				horizStrafeBut.setSelected(true);
+ 			horizButFake=isBut2;
+ 		}
+ 		if(horizRotateBut.isSelected())
+ 			aslide.setValue((int)(slidermax*p.x));
+ 		if(horizStrafeBut.isSelected())
+ 			yslide.setValue((int)(slidermax*p.x));
+ 		xslide.setValue((int)(slidermax*p.y));
+ 	}
+ 
+ 	public void mechaUpdated(MechaController comm) {
+ 		if(status!=null) {
+ 			pp.setEnabled(comm._isConnected);
+ 			xslide.setEnabled(comm._isConnected);
+ 			yslide.setEnabled(comm._isConnected);
+ 			aslide.setEnabled(comm._isConnected);
+ 			stopBut.setEnabled(comm._isConnected);
+ 			if(comm._isConnected)
+ 				status.setText("Connected.");
+ 			else
+ 				status.setText("Reconnecting...");
+ 		}
+ 	}
+ 
+ 	public void mouseClicked(MouseEvent e) {}
+ 	public void mouseEntered(MouseEvent e) {}
+ 	public void mouseExited(MouseEvent e) {}
+ 	public void mousePressed(MouseEvent e) {
+ 		boolean isBut2=(e.getModifiersEx()&MouseEvent.BUTTON3_DOWN_MASK)==MouseEvent.BUTTON3_DOWN_MASK;
+ 		if(!horizButFake && isBut2) {
+ 			if(horizStrafeBut.isSelected())
+ 				horizRotateBut.setSelected(true);
+ 			else
+ 				horizStrafeBut.setSelected(true);
+ 			horizButFake=isBut2;
+ 			updatePP();
+ 		}
+ 	}
+ 	public void mouseReleased(MouseEvent e) {
+ 		boolean isBut1=(e.getModifiersEx()&MouseEvent.BUTTON1_DOWN_MASK)==MouseEvent.BUTTON1_DOWN_MASK;
+ 		boolean isBut2=(e.getModifiersEx()&MouseEvent.BUTTON3_DOWN_MASK)==MouseEvent.BUTTON3_DOWN_MASK;
+ 		if(horizButFake && !isBut2) {
+ 			if(horizStrafeBut.isSelected())
+ 				horizRotateBut.setSelected(true);
+ 			else
+ 				horizStrafeBut.setSelected(true);
+ 			horizButFake=isBut2;
+ 			updatePP();
+ 		}
+ 		if(!isBut1 && !isBut2) {
+ 			if(resetOnRelease.isSelected())
+ 				stopBut.doClick();
+ 		}
+ 	}
+ 
+ 	public void stateChanged(ChangeEvent e) {
+ 		if(e.getSource()==xslide) {
+ 			comm.sendCommand("f",xslide.getValue()/(float)slidermax*180.0f);
+ 			pp.doSetPoint(pp.getXValue(),xslide.getValue()/(float)slidermax);
+ 		} else if(e.getSource()==yslide) {
+ 			comm.sendCommand("s",yslide.getValue()/(float)slidermax*-140.0f);
+ 			if(horizStrafeBut.isSelected())
+ 				pp.doSetPoint(yslide.getValue()/(float)slidermax,pp.getYValue());
+ 		} else if(e.getSource()==aslide) {
+ 			// Rotation is both fast and sensitive, so we'll exponentiate it to
+ 			// drag out the low end without sacrificing the high end
+ 			float aval=aslide.getValue()/(float)slidermax;
+ 			aval*=(aval<0?-aval:aval);
+ 			comm.sendCommand("r",aval*-1.8f);
+ 			float tmp=pp.getYValue();
+ 			if(horizRotateBut.isSelected())
+ 				pp.doSetPoint(aslide.getValue()/(float)slidermax,pp.getYValue());
+ 		}
+ 	}
+ 
+ 	public void actionPerformed(ActionEvent e) {
+ 		if(e.getSource()==stopBut) {
+ 			xslide.setValue(0);
+ 			yslide.setValue(0);
+ 			aslide.setValue(0);
+ 		} else if(e.getSource()==horizRotateBut) {
+ 			updatePP();
+ 		} else if(e.getSource()==horizStrafeBut) {
+ 			updatePP();
+ 		} else if(e.getSource()==reconnectBut) {
+ 			int port=comm._port;
+ 			String addr=comm._host;
+ 			comm.kill();
+ 			comm.removeMechaUpdatedListener(this);
+ 			comm = new MechaController(comm._host,comm._port);
+ 			comm.addMechaUpdatedListener(this);
+ 		}
+ 	}
+ 	
+ 	public void updatePP() {
+ 		float x=0;
+ 		if(horizStrafeBut.isSelected())
+ 			x=yslide.getValue()/(float)slidermax;
+ 		else if(horizRotateBut.isSelected())
+ 			x=aslide.getValue()/(float)slidermax;
+ 		pp.doSetPoint(x,xslide.getValue()/(float)slidermax);
+ 	}
+ 
+ 	public void frameInit() {
+ 		super.frameInit();
+ 		
+ 		int strutsize=10;
+ 		int sepsize=5;
+ 		getContentPane().setLayout(new BorderLayout());
+ 		getContentPane().add(Box.createHorizontalStrut(strutsize),BorderLayout.EAST);
+ 		getContentPane().add(Box.createHorizontalStrut(strutsize),BorderLayout.WEST);
+ 		getContentPane().add(Box.createVerticalStrut(strutsize),BorderLayout.NORTH);
+ 		JPanel p=new JPanel(new SquareRightLayout());
+ 		p.setLayout(new SquareRightLayout());
+ 		pp=new PointPick(false);
+ 		pp.addPointPickedListener(this);
+ 		pp.addMouseListener(this);
+ 		p.add(pp,SquareRightLayout.SQUARE);
+ 		Box tmp=Box.createHorizontalBox();
+ 		tmp.add(Box.createHorizontalStrut(strutsize));
+ 		JSeparator sep;
+ 		sep=new JSeparator(SwingConstants.VERTICAL);
+ 		sep.setMaximumSize(new Dimension(sepsize,slidermax));
+ 		tmp.add(sep);
+ 		tmp.add(Box.createHorizontalStrut(strutsize));
+ 		{
+ 			Box tmp2=Box.createVerticalBox();
+ 			tmp2.add(Box.createVerticalGlue());
+ 			int labwidth=45;
+ 			tmp2.add(new JLabel("Forward:"));
+ 			{
+ 				Box tmp3=Box.createHorizontalBox();
+ 				xslide=new JSlider(-slidermax,slidermax,0);
+ 				xslide.addChangeListener(this);
+ 				JLabel lab;
+ 				lab=new JLabel("Aft");
+ 				lab.setFont(lab.getFont().deriveFont(lab.getFont().getSize2D()-2));
+ 				lab.setHorizontalAlignment(SwingConstants.RIGHT);
+ 				lab.setPreferredSize(new Dimension(labwidth,lab.getFont().getSize()));
+ 				tmp3.add(lab);
+ 				tmp3.add(xslide);
+ 				lab=new JLabel("Fore");
+ 				lab.setFont(lab.getFont().deriveFont(lab.getFont().getSize2D()-2));
+ 				lab.setHorizontalAlignment(SwingConstants.LEFT);
+ 				lab.setPreferredSize(new Dimension(labwidth,lab.getFont().getSize()));
+ 				tmp3.add(lab);
+ 				//tmp3.add(new JButton("Zero"));
+ 				tmp3.setAlignmentX(0);
+ 				tmp2.add(tmp3);
+ 			}
+ 			tmp2.add(Box.createVerticalStrut(strutsize));
+ 			tmp2.add(new JLabel("Strafe:"));
+ 			{
+ 				Box tmp3=Box.createHorizontalBox();
+ 				yslide=new JSlider(-slidermax,slidermax,0);
+ 				yslide.addChangeListener(this);
+ 				JLabel lab;
+ 				lab=new JLabel("Left");
+ 				lab.setFont(lab.getFont().deriveFont(lab.getFont().getSize2D()-2));
+ 				lab.setHorizontalAlignment(SwingConstants.RIGHT);
+ 				lab.setPreferredSize(new Dimension(labwidth,lab.getFont().getSize()));
+ 				tmp3.add(lab);
+ 				tmp3.add(yslide);
+ 				lab=new JLabel("Right");
+ 				lab.setFont(lab.getFont().deriveFont(lab.getFont().getSize2D()-2));
+ 				lab.setHorizontalAlignment(SwingConstants.LEFT);
+ 				lab.setPreferredSize(new Dimension(labwidth,lab.getFont().getSize()));
+ 				tmp3.add(lab);
+ 				//tmp3.add(new JButton("Zero"));
+ 				tmp3.setAlignmentX(0);
+ 				tmp2.add(tmp3);
+ 			}
+ 			tmp2.add(Box.createVerticalStrut(strutsize));
+ 			tmp2.add(new JLabel("Rotate:"));
+ 			{
+ 				Box tmp3=Box.createHorizontalBox();
+ 				aslide=new JSlider(-slidermax,slidermax,0);
+ 				aslide.addChangeListener(this);
+ 				JLabel lab;
+ 				lab=new JLabel("Counter");
+ 				lab.setFont(lab.getFont().deriveFont(lab.getFont().getSize2D()-2));
+ 				lab.setHorizontalAlignment(SwingConstants.RIGHT);
+ 				lab.setPreferredSize(new Dimension(labwidth,lab.getFont().getSize()));
+ 				tmp3.add(lab);
+ 				tmp3.add(aslide);
+ 				lab=new JLabel("Clock");
+ 				lab.setFont(lab.getFont().deriveFont(lab.getFont().getSize2D()-2));
+ 				lab.setHorizontalAlignment(SwingConstants.LEFT);
+ 				lab.setPreferredSize(new Dimension(labwidth,lab.getFont().getSize()));
+ 				tmp3.add(lab);
+ 				//tmp3.add(new JButton("Zero"));
+ 				tmp3.setAlignmentX(0);
+ 				tmp2.add(tmp3);
+ 			}
+ 			tmp2.add(Box.createVerticalStrut(strutsize));
+ 			{
+ 				Box tmp3=Box.createHorizontalBox();
+ 				tmp3.add(Box.createHorizontalGlue());
+ 				stopBut=new JButton("Stop!");
+ 				stopBut.addActionListener(this);
+ 				rootPane.setDefaultButton(stopBut);
+ 				tmp3.add(stopBut);
+ 				tmp3.add(Box.createHorizontalGlue());
+ 				tmp3.setAlignmentX(0);
+ 				tmp2.add(tmp3);
+ 			}
+ 			tmp2.add(Box.createVerticalStrut(strutsize));
+ 			ButtonGroup bg = new ButtonGroup();
+ 			horizRotateBut=new JRadioButton("Horizontal is Rotate");
+ 			horizRotateBut.addActionListener(this);
+ 			horizRotateBut.setSelected(true);
+ 			bg.add(horizRotateBut);
+ 			tmp2.add(horizRotateBut);
+ 			horizStrafeBut=new JRadioButton("Horizontal is Strafe");
+ 			horizStrafeBut.addActionListener(this);
+ 			bg.add(horizStrafeBut);
+ 			tmp2.add(horizStrafeBut);
+ 			tmp2.add(Box.createVerticalStrut(strutsize));
+ 			tmp2.add(resetOnRelease=new JCheckBox("Reset on release")); 
+ 			resetOnRelease.setSelected(true);
+ 			tmp2.add(Box.createVerticalGlue());
+ 			tmp.add(tmp2);
+ //			Dimension d=tmp2.getMinimumSize();
+ //			System.out.println(d);
+ //			pp.setSize(d);
+ //			pp.setMinimumSize(d);
+ //			pp.setPreferredSize(d);
+ //			pp.setMaximumSize(d);
+ 		}
+ 		p.add(tmp,SquareRightLayout.RIGHT);
+ 		getContentPane().add(p,BorderLayout.CENTER);
+ 		{
+ 			Box tmp2=Box.createHorizontalBox();
+ 			tmp2.add(Box.createHorizontalStrut(strutsize));
+ 			{
+ 				Box tmp3=Box.createVerticalBox();
+ 				tmp3.add(Box.createVerticalStrut(strutsize));
+ 				tmp3.add(new JSeparator());
+ 				tmp3.add(Box.createVerticalStrut(strutsize-sepsize));
+ 				{
+ 					Box tmp4=Box.createHorizontalBox();
+ 					tmp4.add(status=new JLabel("Connecting..."));
+ 					tmp4.add(Box.createHorizontalGlue());
+ 					reconnectBut=new JButton(carrows);
+ 					reconnectBut.setPreferredSize(new Dimension(carrows.getIconWidth(),carrows.getIconHeight()));
+ 					reconnectBut.addActionListener(this);
+ 					reconnectBut.setToolTipText("Drop current connection and try again.");
+ 					tmp4.add(reconnectBut);
+ 					tmp3.add(tmp4);
+ 				}
+ 				tmp3.add(Box.createVerticalStrut(strutsize));
+ 				tmp2.add(tmp3);
+ 			}
+ 			tmp2.add(Box.createHorizontalStrut(strutsize));
+ 			getContentPane().add(tmp2,BorderLayout.SOUTH);
+ 		}
+ 
+ 		pp.setEnabled(false);
+ 		xslide.setEnabled(false);
+ 		yslide.setEnabled(false);
+ 		aslide.setEnabled(false);
+ 		stopBut.setEnabled(false);
+ 		addWindowListener(new CloseWalkAdapter(this));
+ 	}
+ }
Index: AiboPup/tools/mon/c_DepthMap.m
diff -c AiboPup/tools/mon/c_DepthMap.m:1.1 AiboPup/tools/mon/c_DepthMap.m:1.3
*** AiboPup/tools/mon/c_DepthMap.m:1.1	Thu Mar  6 13:21:16 2003
--- AiboPup/tools/mon/c_DepthMap.m	Tue Jul  1 12:20:40 2003
***************
*** 23,29 ****
  end
  
  
- 
  function init
  global SDM
  SDM.fig = figure('Visible','off','NumberTitle','off',...
--- 23,28 ----
Index: AiboPup/tools/mon/c_MechaControl.m
diff -c AiboPup/tools/mon/c_MechaControl.m:1.2 AiboPup/tools/mon/c_MechaControl.m:1.3
*** AiboPup/tools/mon/c_MechaControl.m:1.2	Tue Apr 15 16:02:43 2003
--- AiboPup/tools/mon/c_MechaControl.m	Sat Jun 21 21:30:05 2003
***************
*** 203,209 ****
  global MC conf
  if(MC.locked == false)
    if(now - MC.lasttime > conf.mecha_autosend_interval)
!     real_iter;
    end
  end
  
--- 203,211 ----
  global MC conf
  if(MC.locked == false)
    if(now - MC.lasttime > conf.mecha_autosend_interval)
! %I moved this to the java layer - ethan
! %    real_iter;
!      MC.lasttime = now;
    end
  end
  
Index: AiboPup/tools/mon/ftp.jar
