Index: Tekkotsu/Behaviors/BehaviorBase.h
diff -c Tekkotsu/Behaviors/BehaviorBase.h:1.12 Tekkotsu/Behaviors/BehaviorBase.h:1.13
*** Tekkotsu/Behaviors/BehaviorBase.h:1.12	Sun Jan 18 05:16:55 2004
--- Tekkotsu/Behaviors/BehaviorBase.h	Mon Feb  9 17:45:28 2004
***************
*** 35,41 ****
  		}
  	}
  
! 	//! By default, subtracts from the reference counter, and deletes if zero; Note you should still call this when you override this; Warning call this at the end of your DoStop(), not beginning (it might @c delete @c this )
  	virtual void DoStop() {
  		//std::cout << getName() << " stopped " << this << std::endl;
  		if(started) {
--- 35,41 ----
  		}
  	}
  
! 	//! By default, subtracts from the reference counter (RemoveReference()), and thus may deletex if zero;  Don't forget to still call this when you override this; <b>Warning:</b> call this at the <i>end</i> of your DoStop(), not beginning (it might @c delete @c this )
  	virtual void DoStop() {
  		//std::cout << getName() << " stopped " << this << std::endl;
  		if(started) {
***************
*** 64,70 ****
  	//! Gives a short description of what this class of behaviors does... you should override this (but don't have to)
  	static std::string getClassDescription() { return ""; }
  
! 	//! Gives a short description of what this particular instantiation does (in case a more specific description is needed)
  	virtual std::string getDescription() const { return getClassDescription(); }
  
  	//! Returns true if the behavior is currently running
--- 64,70 ----
  	//! Gives a short description of what this class of behaviors does... you should override this (but don't have to)
  	static std::string getClassDescription() { return ""; }
  
! 	//! Gives a short description of what this particular instantiation does (in case a more specific description is needed on an individual basis)  By default simply returns getClassDescription()
  	virtual std::string getDescription() const { return getClassDescription(); }
  
  	//! Returns true if the behavior is currently running
***************
*** 79,88 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
--- 79,88 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
Index: Tekkotsu/Behaviors/Controller.cc
diff -c Tekkotsu/Behaviors/Controller.cc:1.35 Tekkotsu/Behaviors/Controller.cc:1.36
*** Tekkotsu/Behaviors/Controller.cc:1.35	Tue Jan 20 22:52:39 2004
--- Tekkotsu/Behaviors/Controller.cc	Mon Mar  1 16:16:48 2004
***************
*** 221,228 ****
  			incomplete+=s;
  			return 0;
  		}
! 		incomplete+=s.substr(0,endline);
! 		theOneController->takeLine(incomplete); //is now complete
  		incomplete.erase();
  		s=s.substr(endline+1);
  	}
--- 221,235 ----
  			incomplete+=s;
  			return 0;
  		}
! 		
! 		//strip a \r\n or a \n
! 		if(endline>0 && s[endline-1]=='\r')
! 			incomplete+=s.substr(0,endline-1);
! 		else
! 			incomplete+=s.substr(0,endline);
! 		
! 		//is now complete
! 		theOneController->takeLine(incomplete); 
  		incomplete.erase();
  		s=s.substr(endline+1);
  	}
***************
*** 245,252 ****
  			incomplete+=s;
  			return 0;
  		}
! 		incomplete+=s.substr(0,endline);
! 		//is now complete:
  		if(wireless->isConnected(theOneController->gui_comm->sock))
  			erouter->postEvent(new TextMsgEvent(incomplete));
  		else
--- 252,265 ----
  			incomplete+=s;
  			return 0;
  		}
! 
! 		//strip a \r\n or a \n
! 		if(endline>0 && s[endline-1]=='\r')
! 			incomplete+=s.substr(0,endline-1);
! 		else
! 			incomplete+=s.substr(0,endline);
! 		
! 		//is now complete
  		if(wireless->isConnected(theOneController->gui_comm->sock))
  			erouter->postEvent(new TextMsgEvent(incomplete));
  		else
***************
*** 439,446 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
--- 452,459 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
Index: Tekkotsu/Behaviors/Controller.h
diff -c Tekkotsu/Behaviors/Controller.h:1.27 Tekkotsu/Behaviors/Controller.h:1.28
*** Tekkotsu/Behaviors/Controller.h:1.27	Thu Feb  5 18:33:10 2004
--- Tekkotsu/Behaviors/Controller.h	Mon Feb  9 17:45:28 2004
***************
*** 23,33 ****
   *	- '<tt>!prev</tt>' - calls ControlBase::doPrevItem() of the current control
   *	- '<tt>!select</tt>' - calls ControlBase::doSelect() of the current control
   *	- '<tt>!cancel</tt>' - calls ControlBase::doCancel() of the current control
!  *	- '<tt>!msg </tt><i>text</i>' - broadcasts <i>text</i> as a TextMsgEvent
   *  - '<tt>!root </tt><i>text</i>' - calls ControlBase::takeInput(<i>text</i>) on the root control
   *  - '<tt>!hello</tt>' - responds with '<tt>hello\n</tt><i>count</i>' where <i>count</i> is the number of times '<tt>!hello</tt>' has been sent.  Good for detecting first connection after boot vs. a reconnect.
   *	- '<tt>!hilight</tt> [<i>n1</i> [<i>n2</i> [...]]]' - hilights zero, one, or more items in the menu
!  *	- '<tt>!input </tt><i>text</i>' - calls ControlBase::takeInput(<i>text</i>) on the currently hilighted control(s)
   *	- any text not beginning with '!' - sent to ControlBase::takeInput() of the current control
   *
   *  In return, to send the menus to the GUI, the following messages are sent: (newlines are required where shown)
--- 23,33 ----
   *	- '<tt>!prev</tt>' - calls ControlBase::doPrevItem() of the current control
   *	- '<tt>!select</tt>' - calls ControlBase::doSelect() of the current control
   *	- '<tt>!cancel</tt>' - calls ControlBase::doCancel() of the current control
!  *	- '<tt>!msg </tt><i>text</i>' - sends <i>text</i> out as a TextMsgEvent; also note that any text entered on the console port while a GUI is also connected will also be sent as a TextMsgEvent, without needing the !input.
   *  - '<tt>!root </tt><i>text</i>' - calls ControlBase::takeInput(<i>text</i>) on the root control
   *  - '<tt>!hello</tt>' - responds with '<tt>hello\n</tt><i>count</i>' where <i>count</i> is the number of times '<tt>!hello</tt>' has been sent.  Good for detecting first connection after boot vs. a reconnect.
   *	- '<tt>!hilight</tt> [<i>n1</i> [<i>n2</i> [...]]]' - hilights zero, one, or more items in the menu
!  *	- '<tt>!input </tt><i>text</i>' - calls ControlBase::takeInput(text) on the currently hilighted control(s)
   *	- any text not beginning with '!' - sent to ControlBase::takeInput() of the current control
   *
   *  In return, to send the menus to the GUI, the following messages are sent: (newlines are required where shown)
***************
*** 82,87 ****
--- 82,94 ----
   *  Model-View-Controller architecture, almost by necessity. (HCI
   *  happens to be my double major when I was an undergrad ;)
   *    
+  *  Also, the Controller is responsible for sending out TextMsgEvents
+  *  from user input it receives - either a !msg command from the
+  *  console or GUI, or <i>any text at all</i> which is received on the
+  *  console if there is already a GUI connected.
+  *
+  *  These TextMsgEvents are always status events, and the duration
+  *  field is always 0.
   */
  class Controller : public BehaviorBase, public EventTrapper {
  public:
***************
*** 203,212 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
--- 210,219 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
Index: Tekkotsu/Behaviors/Controls/BehaviorSwitchControl.h
diff -c Tekkotsu/Behaviors/Controls/BehaviorSwitchControl.h:1.12 Tekkotsu/Behaviors/Controls/BehaviorSwitchControl.h:1.13
*** Tekkotsu/Behaviors/Controls/BehaviorSwitchControl.h:1.12	Sat Dec 13 00:00:25 2003
--- Tekkotsu/Behaviors/Controls/BehaviorSwitchControl.h	Wed Feb 18 16:11:25 2004
***************
*** 46,51 ****
--- 46,52 ----
  
  	//! destructor
  	virtual ~BehaviorSwitchControlBase() {
+ 		//cout << "~BehaviorSwitchControlBase(): " << getName() << endl;
  		if(mybeh!=NULL)
  			stop();
  		if(behgrp!=NULL) {
***************
*** 78,86 ****
--- 79,91 ----
  
  	//! adds a status to the name: - if in memory, # if running
  	virtual std::string getName() const {
+ 		if(mybeh==NULL)
+ 			return ControlBase::getName();
  		return (mybeh->isActive()?'#':'-')+mybeh->getName();
  	}
  	virtual std::string getDescription() const {
+ 		if(mybeh==NULL)
+ 			return ControlBase::getDescription();
  		return mybeh->getDescription();
  	}
  	
***************
*** 258,267 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
--- 263,272 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
Index: Tekkotsu/Behaviors/Controls/ControlBase.h
diff -c Tekkotsu/Behaviors/Controls/ControlBase.h:1.17 Tekkotsu/Behaviors/Controls/ControlBase.h:1.20
*** Tekkotsu/Behaviors/Controls/ControlBase.h:1.17	Thu Jan  8 17:39:53 2004
--- Tekkotsu/Behaviors/Controls/ControlBase.h	Wed Feb 18 16:11:25 2004
***************
*** 11,30 ****
  #include <vector>
  
  //! Base class for all items in the Controller hierarchy.
! /*! These are similar to behaviors in that they can do processing and are told
!  *  when to start and stop.
   *
!  *  However, the important difference is that these have to follow a much
!  *  tighter set of guidelines for a more refined purpose - user interface.
!  *  Controls do not directly receive events - the Controller will process events
!  *  for them and call the appropriate functions at the appropriate times.
!  *  Controls are expected to fit into a heirarchical scheme, where each control
!  *  (except the root) has a parent which created it, and may return its own
!  *  children where appropriate.
!  *
!  *  This base class will do most of the work of maintain submenus for you, and
!  *  will call appropriate virtual functions which you can override.  Controls
!  *  generally live in Behaviors/Controls/ as the Controller itself is a
   *  behavior, and these controls merely its tools.
   *
   *  The ControlBase pointers which are returned at various points are the
--- 11,39 ----
  #include <vector>
  
  //! Base class for all items in the Controller hierarchy.
! /*! These are similar to behaviors in that they can do processing and
!  *  are told when to start and stop.
   *
!  *  However, the important difference is that these have to follow a
!  *  much tighter set of guidelines for a more refined purpose - user
!  *  interface.  Controls do not directly receive events - the
!  *  Controller will process events for them and call the appropriate
!  *  functions at the appropriate times.  Controls are expected to fit
!  *  into a heirarchical scheme, where each control (except the root)
!  *  has a parent which created it, and may return its own children
!  *  where appropriate.
!  *
!  *  Controls can be very powerful, and a class can be both a behavior
!  *  and a control.  This allows integrated user interface to
!  *  controlling a complex behavior.  Some controls may simply need
!  *  EventListener access instead to perform a few tricks.  Mix and
!  *  match as you see fit.  (multiple inheritance can be nice if it's
!  *  planned for, as these have been)
!  *
!  *  This base class will do most of the work of maintaining submenus
!  *  for you, and will call appropriate virtual functions which you are
!  *  expected to override.  Controls generally live in
!  *  <tt>Behaviors/Controls/</tt> as the Controller itself is a
   *  behavior, and these controls merely its tools.
   *
   *  The ControlBase pointers which are returned at various points are the
***************
*** 33,48 ****
   *
   *  GUI Theory: \n
   *  There are 3 levels to the user interface.
!  *  -# Robot/Local: Uses the LEDs and sounds for immediate feedback.  No external resources needed
   *  -# Text: Uses a console to display/request information.
!  *  -# GUI: Uses a graphical interface on an external screen
   *
   *  Obviously, higher levels require more technological resources, which also
   *  means there's more to go wrong and debug.  However, another important
   *  distinction between the first level and the others is that the first level
   *  does not require the user to lose direct contact with the robot.  Requiring
   *  the user to move back and forth from robot to computer can be much more
!  *  frustrating than decoding LED signals or press head buttons.  There are
   *  safety issues when triggering behaviors remotely if the robot is out of
   *  immediate reach.  But of course, having a GUI and text output is extremely
   *  valuable in terms of ease of use and efficiency.
--- 42,57 ----
   *
   *  GUI Theory: \n
   *  There are 3 levels to the user interface.
!  *  -# Robot/Local: Uses the buttons for input, and LEDs and sounds for immediate feedback.  No external resources needed
   *  -# Text: Uses a console to display/request information.
!  *  -# GUI: Uses a graphical interface on a desktop machine
   *
   *  Obviously, higher levels require more technological resources, which also
   *  means there's more to go wrong and debug.  However, another important
   *  distinction between the first level and the others is that the first level
   *  does not require the user to lose direct contact with the robot.  Requiring
   *  the user to move back and forth from robot to computer can be much more
!  *  frustrating than decoding LED signals or press head buttons.  There are also
   *  safety issues when triggering behaviors remotely if the robot is out of
   *  immediate reach.  But of course, having a GUI and text output is extremely
   *  valuable in terms of ease of use and efficiency.
***************
*** 57,62 ****
--- 66,73 ----
  class ControlBase {
  public:
  	
+ 	//! @name Constructors/Destructors
+ 
  	ControlBase() : name("(null name)"), description(), hilights(), options(), doRewrite(false), display_id(MotionManager::invalid_MC_ID), gui_comm(NULL) {} //!< Contructor
  	ControlBase(const std::string& n) : name(n), description(), hilights(), options(), doRewrite(false), display_id(MotionManager::invalid_MC_ID), gui_comm(NULL) {} //!< Contructor, initializes with a name
  	ControlBase(const std::string& n, const std::string& d) : name(n), description(d), hilights(), options(), doRewrite(false), display_id(MotionManager::invalid_MC_ID), gui_comm(NULL) {} //!< Contructor, initializes with a name
***************
*** 64,72 ****
--- 75,86 ----
  	//! Destructor
  	virtual ~ControlBase() {
  		//		deactivate();
+ 		//cout << "~ControlBase(): " << name << endl;
  		clearSlots();
  	}
  
+ 	//@}
+ 
  	//! You probably want to override some of these, call the ControlBase functions from your code if you want default sound effects (or look in Config::controller_config).
  	//! @name Controller Functions
  
***************
*** 76,104 ****
  	 *  @return a ControlBase pointer.  Return: @li @a this if the control should stay active (if it's not a one-shot command) @li @c NULL to return to parent @li other address to spawn a child control*/
  	virtual ControlBase * activate(MotionManager::MC_ID disp_id, Socket * gui);
  	virtual void pause();      //!< called when a control is being overriden by a child, or the control system is deactivating (e-stop being turned off)
! 	virtual void refresh();    //!< called when the child has died and this control should refresh its display, or some other event (such as the user pressing the refresh button) has happened to cause a refresh to be needed
  	virtual void deactivate(); //!< called when this control is being popped from the control stack
  
! 	virtual ControlBase * doSelect();   //!< when the user has trigger an "open selection" - default is to return the hilighted control
! 	virtual ControlBase * doNextItem(); //!< when the user wants to increment the control - default is to return the first non-null slot after the last hilight
! 	virtual ControlBase * doPrevItem(); //!< when the user wants to decrement the control - default is to return the last non-null slot before the first hilight
! 	virtual ControlBase * doCancel();   //!< when the user wants to cancel - you should almost always return NULL now unless you need to confirm something (e.g. "Save changes?")
! 	virtual ControlBase * doReadStdIn(const std::string& prompt=std::string()); //!< prompt the user for text input on the current input device (cin, tekkotsu console (sout), or GUI)
! 	virtual ControlBase * takeInput(const std::string& msg); //!< called when the user has supplied a text string (may not have been prompted by doReadStdIn()!)
! 	virtual bool validInput(const std::string& msg); //!< may be called before takeInput to verify this Control can make sense of msg
  	//@}
  	
  	virtual ControlBase& setName(const std::string& n) { name=n; return *this; } //!< sets the name of the control
  	virtual std::string getName() const { return name; } //!< returns the name of the control
  
  	virtual ControlBase& setDescription(const std::string d) { description=d; return *this; } //!< sets the description of the control
  	virtual std::string getDescription() const { return description; } //!< returns a short description of what the control does
  
! 	const std::vector<ControlBase*>& getSlots() const { return options; } //!< returns the vector of controls
  	std::string getSlotName(unsigned int i) const; //!< returns the string that will appear in slot @a i
  	unsigned int slotsSize() const { return options.size(); } //!< returns the number of options available
! 	void setSlot(unsigned int i,ControlBase* o); //!< sets @a i'th element of ::options to @a o
! 	void pushSlot(ControlBase* o); //!< sets next unused element of ::options to @a o
  	void clearSlots(); //!< deletes each slot item and clears the slots
  
  	virtual const std::vector<unsigned int>& getHilights() const { return hilights; } //!< returns a vector of the indicies of hilighted slots
--- 90,133 ----
  	 *  @return a ControlBase pointer.  Return: @li @a this if the control should stay active (if it's not a one-shot command) @li @c NULL to return to parent @li other address to spawn a child control*/
  	virtual ControlBase * activate(MotionManager::MC_ID disp_id, Socket * gui);
  	virtual void pause();      //!< called when a control is being overriden by a child, or the control system is deactivating (e-stop being turned off)
! 	virtual void refresh();    //!< called when the child has deactivated and this control should refresh its display, or some other event (such as the user pressing the refresh button) has happened to cause a refresh to be needed
  	virtual void deactivate(); //!< called when this control is being popped from the control stack
  
! 	//! when the user has trigger an "open selection" - default is to return the hilighted control*/
! 	/*! The value which is returned is then activate()ed and pushed on the Controller's stack*/
! 	virtual ControlBase * doSelect();
! 	//! when the user wants to increment the control - default is to hilight the first non-null slot after the last hilight, and return @c this
! 	/*! The value which is returned is then activate()ed and pushed on the Controller's stack, so you probably want to return @c this */
! 	virtual ControlBase * doNextItem();
! 	//! when the user wants to decrement the control - default is to hilight the last non-null slot before the first hilight, and return @c this
! 	/*! The value which is returned is then activate()ed and pushed on the Controller's stack, so you probably want to return @c this */
! 	virtual ControlBase * doPrevItem();
! 	//! when the user wants to cancel - you should almost always return NULL now unless you need to override the cancel in order to confirm something (e.g. "Save changes?")
! 	/*! The value which is returned is then activate()ed and pushed on the Controller's stack, you probably want to return @c NULL */
! 	virtual ControlBase * doCancel();
! 	//! prompt the user for text input on the current input device (cin, tekkotsu console (sout), or GUI)
! 	/*! The value which is returned is then activate()ed and pushed on the Controller's stack, so you probably want to return @c this */
! 	virtual ControlBase * doReadStdIn(const std::string& prompt=std::string());
! 	//! called when the user has supplied a text string (may or may not have been prompted by doReadStdIn()!  May not even be active yet - the user can direct the same input to a set of hilighted menus)
! 	/*! The value which is returned is then activate()ed and pushed on the Controller's stack*/
! 	virtual ControlBase * takeInput(const std::string& msg); 
! 	//! may be called before takeInput to verify this Control can make sense of msg
! 	virtual bool validInput(const std::string& msg); 
  	//@}
  	
+ 	//! @name Accessors
+ 
  	virtual ControlBase& setName(const std::string& n) { name=n; return *this; } //!< sets the name of the control
  	virtual std::string getName() const { return name; } //!< returns the name of the control
  
  	virtual ControlBase& setDescription(const std::string d) { description=d; return *this; } //!< sets the description of the control
  	virtual std::string getDescription() const { return description; } //!< returns a short description of what the control does
  
! 	const std::vector<ControlBase*>& getSlots() const { return options; } //!< returns the vector of sub-controls
  	std::string getSlotName(unsigned int i) const; //!< returns the string that will appear in slot @a i
  	unsigned int slotsSize() const { return options.size(); } //!< returns the number of options available
! 	void setSlot(unsigned int i,ControlBase* o); //!< sets @a i'th element of #options to @a o
! 	void pushSlot(ControlBase* o); //!< sets next unused element of #options to @a o
  	void clearSlots(); //!< deletes each slot item and clears the slots
  
  	virtual const std::vector<unsigned int>& getHilights() const { return hilights; } //!< returns a vector of the indicies of hilighted slots
***************
*** 108,113 ****
--- 137,144 ----
  	virtual MotionManager::MC_ID getDisplay() { return display_id; } //!< returns display being used
  	virtual ControlBase& setDisplay(MotionManager::MC_ID d) { display_id=d; return *this; } //!< sets display to use
  
+ 	//@}
+ 
  protected:
  		
  	//! clears the display (if use_VT100 is on)
***************
*** 137,145 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  #endif
--- 168,176 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  #endif
Index: Tekkotsu/Behaviors/Controls/LoadCalibration.h
diff -c Tekkotsu/Behaviors/Controls/LoadCalibration.h:1.2 Tekkotsu/Behaviors/Controls/LoadCalibration.h:1.3
*** Tekkotsu/Behaviors/Controls/LoadCalibration.h:1.2	Sun Jan 18 05:16:56 2004
--- Tekkotsu/Behaviors/Controls/LoadCalibration.h	Wed Feb 25 20:02:25 2004
***************
*** 3,33 ****
  #define INCLUDED_LoadCalibration_h_
  
  #include "FileBrowserControl.h"
  
  //! will load calibration parameters from a text file into a forward and backward matrix
! template<unsigned int ROWS, unsigned int COLS>
  class LoadCalibration : public FileBrowserControl {
  public:
  
  	//!Constructor
! 	LoadCalibration(float f_cal[ROWS][COLS],float b_cal[ROWS][COLS])
! 		: FileBrowserControl("Load Calibration...","","/ms/data/motion/"), forw_cal(f_cal), back_cal(b_cal)
  	{ setFilter("*.txt"); }
  	//!Constructor
! 	LoadCalibration(const std::string& n,float f_cal[ROWS][COLS],float b_cal[ROWS][COLS])
! 		: FileBrowserControl(n,"","/ms/data/motion/"), forw_cal(f_cal), back_cal(b_cal)
  	{ setFilter("*.txt"); }
  	//!Constructor
! 	LoadCalibration(const std::string& n, const std::string& d,float f_cal[ROWS][COLS],float b_cal[ROWS][COLS])
! 		: FileBrowserControl(n,d,"/ms/data/motion/"), forw_cal(f_cal), back_cal(b_cal)
  	{ setFilter("*.txt"); }
  
  protected:
  	//!calls readData() for each of the matrices
  	virtual ControlBase* selectedFile(const std::string& f) {
  		FILE * file=fopen(f.c_str(),"r");
! 		if(readData(file,forw_cal))
! 			readData(file,back_cal);
  		fclose(file);
  		FileBrowserControl::selectedFile(f);
  		return NULL;
--- 3,40 ----
  #define INCLUDED_LoadCalibration_h_
  
  #include "FileBrowserControl.h"
+ #include "Motion/WalkMC.h"
  
  //! will load calibration parameters from a text file into a forward and backward matrix
! /*! normally the calibration parameters are stored in the binary walk parameter file itself,
!  *  but this will load a new set of calibration parameters from a text file as written by
!  *  the tools/walk_calibration/WalkCalibration.m matlab script. */
  class LoadCalibration : public FileBrowserControl {
  public:
  
  	//!Constructor
! 	LoadCalibration(WalkMC::CalibrationParam* calp)
! 		: FileBrowserControl("Load Calibration...","","/ms/data/motion/"), cp(calp)
  	{ setFilter("*.txt"); }
  	//!Constructor
! 	LoadCalibration(const std::string& n,WalkMC::CalibrationParam* calp)
! 		: FileBrowserControl(n,"","/ms/data/motion/"), cp(calp)
  	{ setFilter("*.txt"); }
  	//!Constructor
! 	LoadCalibration(const std::string& n, const std::string& d,WalkMC::CalibrationParam* calp)
! 		: FileBrowserControl(n,d,"/ms/data/motion/"), cp(calp)
  	{ setFilter("*.txt"); }
  
  protected:
+ 	static const unsigned int ROWS=3;  //!< number of degrees of freedom of movement (probably won't change)
+ 	static const unsigned int COLS=11; //!< number of basis functions (may change)
+ 
  	//!calls readData() for each of the matrices
  	virtual ControlBase* selectedFile(const std::string& f) {
  		FILE * file=fopen(f.c_str(),"r");
! 		if(readMaxs(file))
! 			if(readData(file,cp->f_calibration))
! 				readData(file,cp->b_calibration);
  		fclose(file);
  		FileBrowserControl::selectedFile(f);
  		return NULL;
***************
*** 40,46 ****
  		for(unsigned int i=0; i<ROWS; i++) {
  			fgets(curs,curl,f);
  			if(feof(f)) {
! 				serr->printf("ERROR: short read, got %d lines.\n",(mat==forw_cal?i:i+ROWS));
  				return false;
  			} else {
  				char *c=curs;
--- 47,53 ----
  		for(unsigned int i=0; i<ROWS; i++) {
  			fgets(curs,curl,f);
  			if(feof(f)) {
! 				serr->printf("ERROR: short read, got %d lines.\n",1+(mat==cp->f_calibration?i:i+ROWS));
  				return false;
  			} else {
  				char *c=curs;
***************
*** 51,58 ****
  		return true;
  	}
  
! 	float (* forw_cal)[COLS]; //!< pointer to the forward calibration matrix
! 	float (* back_cal)[COLS]; //!< pointer to the backward calibration matrix
  
  private:
  	LoadCalibration(const LoadCalibration& ); //!< don't call
--- 58,80 ----
  		return true;
  	}
  
! 	//!reads the maximum forward, backward, strafe, and rotation velocities
! 	bool readMaxs(FILE * f) {
! 		const unsigned int curl=500;
! 		char curs[curl];
! 		fgets(curs,curl,f);
! 		if(feof(f)) {
! 			serr->printf("ERROR: short read, got %d lines.\n",0);
! 			return false;
! 		} else {
! 			char *c=curs;
! 			for(unsigned int col=0; col<WalkMC::CalibrationParam::NUM_DIM; col++)
! 				cp->max_vel[col]=strtod(c,&c);
! 		}
! 		return true;
! 	}
! 
! 	WalkMC::CalibrationParam * cp; //!< pointer to the calibration parameter structure
  
  private:
  	LoadCalibration(const LoadCalibration& ); //!< don't call
***************
*** 64,73 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
--- 86,95 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
Index: Tekkotsu/Behaviors/Controls/WalkCalibration.cc
diff -c Tekkotsu/Behaviors/Controls/WalkCalibration.cc:1.7 Tekkotsu/Behaviors/Controls/WalkCalibration.cc:1.8
*** Tekkotsu/Behaviors/Controls/WalkCalibration.cc:1.7	Mon Jan 19 17:03:58 2004
--- Tekkotsu/Behaviors/Controls/WalkCalibration.cc	Mon Mar  1 16:17:08 2004
***************
*** 88,98 ****
  	help->pushSlot(new NullControl(""));
  	help->pushSlot(new NullControl("Enter angular"));
  	help->pushSlot(new NullControl("measurements in"));
! 	help->pushSlot(new NullControl("degrees.  You will"));
! 	help->pushSlot(new NullControl("almost always enter"));
  	help->pushSlot(new NullControl("positive values for"));
  	help->pushSlot(new NullControl("all measurements."));
- 	help->pushSlot(new NullControl(""));
  	help->pushSlot(new NullControl("Enter negative"));
  	help->pushSlot(new NullControl("values only when"));
  	help->pushSlot(new NullControl("using cartesian"));
--- 88,101 ----
  	help->pushSlot(new NullControl(""));
  	help->pushSlot(new NullControl("Enter angular"));
  	help->pushSlot(new NullControl("measurements in"));
! 	help->pushSlot(new NullControl("degrees.  Enter"));
! 	help->pushSlot(new NullControl("distances as "));
! 	help->pushSlot(new NullControl("centimeters."));
! 	help->pushSlot(new NullControl(""));
! 	help->pushSlot(new NullControl("You will almost"));
! 	help->pushSlot(new NullControl("always enter"));
  	help->pushSlot(new NullControl("positive values for"));
  	help->pushSlot(new NullControl("all measurements."));
  	help->pushSlot(new NullControl("Enter negative"));
  	help->pushSlot(new NullControl("values only when"));
  	help->pushSlot(new NullControl("using cartesian"));
***************
*** 864,870 ****
  		std::vector<std::string> errmsg;
  		errmsg.push_back("Error");
  		errmsg.push_back(str);
! 		serr->printf(str.c_str());
  		Controller::loadGUI("org.tekkotsu.mon.ControllerErr","msg",0,errmsg);
  		sndman->PlayFile(config->controller.error_snd);
  		return;
--- 867,873 ----
  		std::vector<std::string> errmsg;
  		errmsg.push_back("Error");
  		errmsg.push_back(str);
! 		serr->printf("%s\n",str.c_str());
  		Controller::loadGUI("org.tekkotsu.mon.ControllerErr","msg",0,errmsg);
  		sndman->PlayFile(config->controller.error_snd);
  		return;
***************
*** 909,917 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
--- 912,920 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
Index: Tekkotsu/Events/EventBase.h
diff -c Tekkotsu/Events/EventBase.h:1.20 Tekkotsu/Events/EventBase.h:1.21
*** Tekkotsu/Events/EventBase.h:1.20	Mon Jan 19 02:56:06 2004
--- Tekkotsu/Events/EventBase.h	Mon Feb  9 17:45:28 2004
***************
*** 7,32 ****
  #include <string>
  
  //! The basis of events passed around the high level system
! /*! Contains the list of 'known' event generators in EventGeneratorID_t
!  *  and EventGeneratorNames[].  If you want to make a new generator, all
!  *  you have to do is add a new entry to the ID list (EventGeneratorID_t)
!  *  and then put it's name in the EventGeneratorNames[] array.
   *
   *  Alternatively, there is an 'unlicensed spectrum' available under
!  *  the unknownEGID.  You can send out events from that generator just
   *  like any other, but it should only be used for quick tests and hacking
   *  around...
   *
!  *  The SourceID is generator specific.  A SID of @a i from the button
!  *  generator will refer to a particular button, whereas a SID from vision
!  *  refers to seeing a particular object.  These SIDs are usually defined
!  *  in the generators themselves.  See the EventGeneratorID_t list for
!  *  links to the generators.
   *
!  *  The duration field is also generator specific - some may refer to
!  *  the time since the last activation event (e.g. button events) where 
!  *  as others refer to time since last status (e.g. sensors updates)
   *
   */
  class EventBase : public LoadSave {
   public:
--- 7,36 ----
  #include <string>
  
  //! The basis of events passed around the high level system
! /*! Contains the list of 'known' event generators in #EventGeneratorID_t
!  *  and #EventGeneratorNames[].  If you want to make a new generator, all
!  *  you have to do is add a new entry to the ID list (#EventGeneratorID_t)
!  *  and then put its name in the #EventGeneratorNames[] array.
   *
   *  Alternatively, there is an 'unlicensed spectrum' available under
!  *  the #unknownEGID.  You can send out events from that generator just
   *  like any other, but it should only be used for quick tests and hacking
   *  around...
   *
!  *  The #sourceID (just an unsigned int) is generator specific.  A SID
!  *  of @a i from the button generator (#buttonEGID) will refer to a
!  *  particular button, whereas a SID from a vision detector (say
!  *  #visObjEGID) refers to seeing a particular object.  These SIDs are
!  *  usually defined in the generators themselves.
   *
!  *  The #duration field is also generator specific - some may refer to
!  *  the time since the last activation event (e.g. button events)
!  *  where as others refer to time since last status (e.g. sensors
!  *  updates)
   *
+  *  The #EventGeneratorID_t list should contain links to the
+  *  generators' documentation, or will directly give information about
+  *  what to expect in events from that generator.
   */
  class EventBase : public LoadSave {
   public:
***************
*** 37,74 ****
  	enum EventGeneratorID_t {
  		unknownEGID=0,    //!< default EGID, used if you forget to set it, probably not a good idea to use this for anything except errors or testing quick hacks
  		aiEGID,           //!< not being used, yet (might use this when AI makes decisions?)
! 		audioEGID,        //!< Sends an event when a sound starts/ends playback, status events as chained sounds end
! 		buttonEGID,       //!< Sends activate event for button down, deactivate for button up.  Status events only for when pressure sensitive buttons' reading changes. (on sensorEGID updates); see ButtonSourceID::ButtonSourceID_t
! 		erouterEGID,      //!< Sends activate event on first listener, deactivate on last listener, and status on other listener changes.; source id is the generator ID affected
! 		estopEGID,        //!< Sends an event when the estop is turned on or off
! 		locomotionEGID,   //!< Sends events regarding transportation in the world; you can/should assume these will all be LocomotionEvent classes
! 		motmanEGID,       //!< Sends events when a MotionCommand is added or removed, source is is the MC_ID
  		powerEGID,        //!< Sends events for low power warnings, temperature, etc. see PowerSourceID::PowerSourceID_t
  		sensorEGID,       //!< Sends a status event when new sensor readings are available. see SensorSourceID::SensorSourceID_t
! 		stateMachineEGID, //!< Sends an event upon entering and leaving a StateNode.
!     textmsgEGID,      //!< Sends events when a text msg is received on console
! 		timerEGID,        //!< Sends timer events; you set timers explicitly, you don't have to listen as well. (See EventRouter::setTimer()) There's no cross-talk, only the listener which requested the timer will receive it.
! 		visOFbkEGID,      //!< Sends a DataEvent<OFbkImageVectorData> for every camera image received from the system
! 		visRawCameraEGID, //!< Sends a FilterBankEvent when new raw camera images are available
! 		visInterleaveEGID,//!< Sends a FilterBankEvent when new interleaved images are available
! 		visJPEGEGID,      //!< Sends a FilterBankEvent when JPEG compressed images are available
! 		visSegmentEGID,   //!< Sends a FilterBankEvent when color segmentated images are available
! 		visRLEEGID,       //!< Sends a FilterBankEvent when RLE encoded color segmentated images are available
! 		visRegionEGID,    //!< Sends a FilterBankEvent when color regions are available
! 		visObjEGID,       //!< Sends VisionObjectEvents for objects detected in camera images
  		wmVarEGID,        //!< Sends an event when a watched memory is changed; source id is pointer to WMEntry
  		worldModelEGID,   //!< not being used, yet (for when objects are detected/lost?)
  		numEGIDs          //!< the number of generators available
  	};
  
! 	//! Holds string versions of each of the generator's names, handy for debugging so you can output the events as readable strings
  	static const char* const EventGeneratorNames[numEGIDs];
  	
  	//! an event type id is used to denote whether it's the first in a sequence (button down), in a sequence (button still down), or last (button up)
  	enum EventTypeID_t {
! 		activateETID,   //!< e.g. button down
! 		statusETID,     //!< e.g. button still down
! 		deactivateETID, //!< e.g. button up
  		numETIDs        //!< the number of different event types
  	};
  
--- 41,78 ----
  	enum EventGeneratorID_t {
  		unknownEGID=0,    //!< default EGID, used if you forget to set it, probably not a good idea to use this for anything except errors or testing quick hacks
  		aiEGID,           //!< not being used, yet (might use this when AI makes decisions?)
! 		audioEGID,        //!< Sends an event when a sound starts/ends playback, status events as chained sounds end; SID is SoundManager::Play_ID; duration is playtime
! 		buttonEGID,       //!< Sends activate event for button down, deactivate for button up.  Status events only for when pressure sensitive buttons' reading changes. (on sensorEGID updates); SIDs are from ButtonOffset_t in the namespace of the target model (e.g. ERS210Info::ButtonOffset_t); duration is button down time
! 		erouterEGID,      //!< Sends activate event on first listener, deactivate on last listener, and status on other listener changes.; SID is the generator ID affected (NOT IMPLEMENTED YET)
! 		estopEGID,        //!< Sends an event when the estop is turned on or off; SID is the MotionManager::MC_ID of the EmergencyStopMC; duration is length of estop activation
! 		locomotionEGID,   //!< Sends events regarding transportation in the world; you can/should assume these will all be LocomotionEvent classes; SID is MotionManager::MC_ID of posting MotionCommand; duration is the time since last velocity change of that MC. (You could generate these for things other than walking...)
! 		motmanEGID,       //!< Sends events when a MotionCommand is added or removed, SID is is the MotionManager::MC_ID, duration is always 0
  		powerEGID,        //!< Sends events for low power warnings, temperature, etc. see PowerSourceID::PowerSourceID_t
  		sensorEGID,       //!< Sends a status event when new sensor readings are available. see SensorSourceID::SensorSourceID_t
! 		stateMachineEGID, //!< Sends an event upon entering and leaving a StateNode; SID is pointer to the StateNode; duration is always 0
!     textmsgEGID,      //!< Sends status events when a text msg is received on console; generated by the Controller, SID is always -1; durations is always 0 (see Controller for more information)
! 		timerEGID,        //!< Sends timer events; you set timers explicitly, you don't have to listen as well. (See EventRouter::addTimer()) There's no cross-talk, only the listener which requested the timer will receive it; SID is whatever you requested it to be; duration is the time (since boot, in ms) that the timer was supposed to go off; these are always status
! 		visOFbkEGID,      //!< Sends a DataEvent <OFbkImageVectorData> for every camera image received from the system; SID and duration are always 0 (This is generated by the MainObj instantiation of MMCombo)
! 		visRawCameraEGID, //!< Sends a FilterBankEvent when new raw camera images are available; SID is whatever value you gave during setup (typically in StartupBehavior_SetupVision.cc), duration is always 0
! 		visInterleaveEGID,//!< Sends a FilterBankEvent when new interleaved images are available; SID is whatever value you gave during setup (typically in StartupBehavior_SetupVision.cc), duration is always 0
! 		visJPEGEGID,      //!< Sends a FilterBankEvent when JPEG compressed images are available; SID is whatever value you gave during setup (typically in StartupBehavior_SetupVision.cc), duration is always 0
! 		visSegmentEGID,   //!< Sends a SegmentedColorFilterBankEvent when color segmentated images are available; SID is whatever value you gave during setup (typically in StartupBehavior_SetupVision.cc), duration is always 0
! 		visRLEEGID,       //!< Sends a SegmentedColorFilterBankEvent when RLE encoded color segmentated images are available; SID is whatever value you gave during setup (typically in StartupBehavior_SetupVision.cc), duration is always 0
! 		visRegionEGID,    //!< Sends a SegmentedColorFilterBankEvent when color regions are available; SID is whatever value you gave during setup (typically in StartupBehavior_SetupVision.cc), duration is always 0
! 		visObjEGID,       //!< Sends VisionObjectEvents for objects detected in camera images; SID is whatever value you gave during setup (typically in StartupBehavior_SetupVision.cc), duration is always 0
  		wmVarEGID,        //!< Sends an event when a watched memory is changed; source id is pointer to WMEntry
  		worldModelEGID,   //!< not being used, yet (for when objects are detected/lost?)
  		numEGIDs          //!< the number of generators available
  	};
  
! 	//! Holds string versions of each of the generator's names, handy for debugging so you can output the events as readable strings (you'll find this in EventBase.cc since it can't go in the header or we get multiply-defined errors during linking)
  	static const char* const EventGeneratorNames[numEGIDs];
  	
  	//! an event type id is used to denote whether it's the first in a sequence (button down), in a sequence (button still down), or last (button up)
  	enum EventTypeID_t {
! 		activateETID,   //!< Start of an event sequence, e.g. button down
! 		statusETID,     //!< Indicates a value has changed, e.g. new sensor readings
! 		deactivateETID, //!< Last of a series of events, e.g. button up
  		numETIDs        //!< the number of different event types
  	};
  
***************
*** 85,92 ****
  	virtual const std::string& getName() const { return stim_id; } //!< gets the name of the event - useful for debugging, outputs
  	virtual EventBase& setName(const std::string& n) { nameisgen=false; stim_id=n; return *this; } //!< sets name to a given string, prevents overwriting by generated names
  
! 	virtual float getMagnitude() const { return magnitude; } //!< gets "strength" of event - you might have useful values... used by AI
! 	virtual EventBase& setMagnitude(float m) { magnitude=m; return *this; }//!< sets "strength" of event - but you might have useful values... used by AI
  
  	virtual unsigned int getTimeStamp() const { return timestamp; } //!< time event was created
  
--- 89,96 ----
  	virtual const std::string& getName() const { return stim_id; } //!< gets the name of the event - useful for debugging, outputs
  	virtual EventBase& setName(const std::string& n) { nameisgen=false; stim_id=n; return *this; } //!< sets name to a given string, prevents overwriting by generated names
  
! 	virtual float getMagnitude() const { return magnitude; } //!< gets "strength" of event - by default 1 for activate and status events, 0 for deactivate events
! 	virtual EventBase& setMagnitude(float m) { magnitude=m; return *this; }//!< sets "strength" of event - you may want to override the default values (see getMagnitude())
  
  	virtual unsigned int getTimeStamp() const { return timestamp; } //!< time event was created
  
***************
*** 99,106 ****
  	virtual EventTypeID_t getTypeID() const { return typeID; } /*!< @brief gets the type ID @see EventTypeID_t */
  	virtual EventBase& setTypeID(EventTypeID_t tid) { typeID=tid; genName(); return *this; } /*!< @brief sets the type ID @see EventTypeID_t */
  
! 	virtual unsigned int getDuration() const { return duration; } /*!< @brief OPTIONAL gets the time since the beginning of this sequence (the timestamp of the activate event) @see duration */
! 	virtual EventBase& setDuration(unsigned int d) { duration = d; return *this; }/*!< @brief OPTIONAL gets the time since the beginning of this sequence (the timestamp of the activate event) @see duration */
  
  	virtual const std::string& resetName() { nameisgen=true; genName(); return stim_id; } //!< resets name to generated form, overwriting any previous name
  	virtual bool isCustomName() const { return !nameisgen; } //!< returns true if not using the generated name
--- 103,110 ----
  	virtual EventTypeID_t getTypeID() const { return typeID; } /*!< @brief gets the type ID @see EventTypeID_t */
  	virtual EventBase& setTypeID(EventTypeID_t tid) { typeID=tid; genName(); return *this; } /*!< @brief sets the type ID @see EventTypeID_t */
  
! 	virtual unsigned int getDuration() const { return duration; } /*!< @brief gets the time since the beginning of this sequence (the timestamp of the activate event) @see duration */
! 	virtual EventBase& setDuration(unsigned int d) { duration = d; return *this; }/*!< @brief sets the time since the beginning of this sequence (the timestamp of the activate event) @see duration */
  
  	virtual const std::string& resetName() { nameisgen=true; genName(); return stim_id; } //!< resets name to generated form, overwriting any previous name
  	virtual bool isCustomName() const { return !nameisgen; } //!< returns true if not using the generated name
***************
*** 140,147 ****
  													* Source IDs are defined by the generator that made it.  This should
  													* give authors flexibility to design their modules without having to
  													* worry about ID space collision */
! 	unsigned int duration; /*!< @brief the time since this sequence started (like, how long the button has been pressed)
! 													*   ideally, this would be 0 for activate, (activate.timestamp-get_time()) for status and deactivate */
  };
  
  /*! @file
--- 144,153 ----
  													* Source IDs are defined by the generator that made it.  This should
  													* give authors flexibility to design their modules without having to
  													* worry about ID space collision */
! 	unsigned int duration; /*!< @brief the time since this sequence started (like, how long the
! 													*   button has been pressed); not all generators will set this;
! 													*   Typically, this would be 0 for activate,
! 													*   (activate.timestamp-::get_time()) for status and deactivate */
  };
  
  /*! @file
***************
*** 149,158 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
--- 155,164 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
Index: Tekkotsu/Events/EventGeneratorBase.h
diff -c Tekkotsu/Events/EventGeneratorBase.h:1.4 Tekkotsu/Events/EventGeneratorBase.h:1.5
*** Tekkotsu/Events/EventGeneratorBase.h:1.4	Sun Jan 18 05:16:57 2004
--- Tekkotsu/Events/EventGeneratorBase.h	Wed Feb 18 16:12:18 2004
***************
*** 32,37 ****
--- 32,40 ----
  		: BehaviorBase(), myGenID(mgid), mySourceID(msid), autoListen(true), srcGenID(srcgid), srcSourceID(srcsid), myName(name)
  	{}
  	//@}
+ 
+ 	//! destructor - does nothing
+ 	virtual ~EventGeneratorBase() {}
  	
  	virtual void DoStart();
  	
***************
*** 81,90 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
--- 84,93 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
Index: Tekkotsu/MMCombo/MMCombo.cc
diff -c Tekkotsu/MMCombo/MMCombo.cc:1.49 Tekkotsu/MMCombo/MMCombo.cc:1.50
*** Tekkotsu/MMCombo/MMCombo.cc:1.49	Mon Feb  2 15:55:50 2004
--- Tekkotsu/MMCombo/MMCombo.cc	Tue Mar  2 22:37:03 2004
***************
*** 26,48 ****
  
  using namespace std;
  
- //Compatibility between Aperios versions for different models...
- #if ( TGT_ERS210 || TGT_ERS220 || TGT_ERS2xx )
- const OJointValue4 ojoint4_STATE0      = 0;
- const OJointValue4 ojoint4_STATE1      = 1;
- const ODataType odataLED_COMMAND3         =  263; // LED3 Command
- typedef word OLED3Mode;
- const OLED3Mode oled3_MODE_UNDEF = 0xffff;
- const OLED3Mode oled3_MODE_A     = 0;
- const OLED3Mode oled3_MODE_B     = 1;
- struct OLEDCommandValue3 {
-     sword      intensity;   // 0 - 255
-     OLED3Mode  mode;
-     word       period;      // 1 period : 1 frame (8ms)
-     word       reserved;    // Reserved for OVirtualRobot
- };
- #endif
- 
  MMCombo::MMCombo()
  	: OObject(), motmanMemRgn(NULL), worldStateMemRgn(NULL),
  		soundManagerMemRgn(NULL), eventTranslatorQueueMemRgn(NULL),
--- 26,31 ----
***************
*** 652,662 ****
  				if(open[j]) {
  					OCommandInfo* info = cmdVecData->GetInfo(used);
  					info->Set(odataJOINT_COMMAND4, primIDs[j], NumSlowFrames);
- #if !( TGT_ERS210 || TGT_ERS220 || TGT_ERS2xx )
  					OJointCommandValue4* jval = reinterpret_cast<OJointCommandValue4*>(cmdVecData->GetData(used)->value);
  					for(unsigned int frame=0; frame<NumFrames; frame++)
  						jval[frame].period = 1;
- #endif
  					used++;
  				}
  		} else {
--- 635,643 ----
***************
*** 730,739 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  
--- 711,720 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  
Index: Tekkotsu/Motion/EmergencyStopMC.cc
diff -c Tekkotsu/Motion/EmergencyStopMC.cc:1.19 Tekkotsu/Motion/EmergencyStopMC.cc:1.20
*** Tekkotsu/Motion/EmergencyStopMC.cc:1.19	Fri Jan 16 18:55:19 2004
--- Tekkotsu/Motion/EmergencyStopMC.cc	Fri Feb  6 18:13:46 2004
***************
*** 34,39 ****
--- 34,40 ----
  		ledengine.cycle(1<<(NumLEDs-1),period,1,0,period/2);
  		ledengine.cycle(1<<(NumLEDs-2),period,1);
  	}
+ 	takeSnapshot();
  }
  
  
***************
*** 52,73 ****
  		if((get_time()-timeoflastbtn)<duration)
  			setStopped(!paused);
  	}
! 	if(paused) {
! 		for(unsigned int i=0; i<NumPIDJoints; i++) {
! 			piddutyavgs[i]=static_cast<unsigned char>(piddutyavgs[i]*.8+fabs(state->pidduties[i])*255*.2);
! 			//reset if there's a force...
! 			if(piddutyavgs[i]>pidcutoff) {
! 				cmds[i].value-=state->pidduties[i]/10;
! 				//				cmds[i].value=state->outputs[i];
! 				//				cout << outputNames[i] << ' ' << state->pidduties[i] << ' ' << state->outputs[i] << endl;
! 			}
! 			//reset if there's just something out of place (perhaps we're being overridden)
! 			if(fabs(state->outputs[i]-cmds[i].value)>.1)
! 				cmds[i].value=state->outputs[i];
  		}
  	}
  	ledengine.updateLEDs(&cmds[LEDOffset]);
! 	if(paused && state->robotDesign&WorldState::ERS7Mask) {
  		//a special Battlestar Galactica inspired effect for the ERS-7
  		static float acts[5];
  		static bool first=true;
--- 53,74 ----
  		if((get_time()-timeoflastbtn)<duration)
  			setStopped(!paused);
  	}
! 	if(!paused)
! 		return 0;
! 	for(unsigned int i=0; i<NumPIDJoints; i++) {
! 		piddutyavgs[i]=static_cast<unsigned char>(piddutyavgs[i]*.8+fabs(state->pidduties[i])*255*.2);
! 		//reset if there's a force...
! 		if(piddutyavgs[i]>pidcutoff) {
! 			cmds[i].value-=state->pidduties[i]/10;
! 			//				cmds[i].value=state->outputs[i];
! 			//				cout << outputNames[i] << ' ' << state->pidduties[i] << ' ' << state->outputs[i] << endl;
  		}
+ 		//reset if there's just something out of place (perhaps we're being overridden)
+ 		if(fabs(state->outputs[i]-cmds[i].value)>.1)
+ 			cmds[i].value=state->outputs[i];
  	}
  	ledengine.updateLEDs(&cmds[LEDOffset]);
! 	if(state->robotDesign&WorldState::ERS7Mask) {
  		//a special Battlestar Galactica inspired effect for the ERS-7
  		static float acts[5];
  		static bool first=true;
***************
*** 202,210 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
--- 203,211 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
Index: Tekkotsu/Motion/Kinematics.cc
diff -c Tekkotsu/Motion/Kinematics.cc:1.4 Tekkotsu/Motion/Kinematics.cc:1.5
*** Tekkotsu/Motion/Kinematics.cc:1.4	Thu Sep 25 11:27:22 2003
--- Tekkotsu/Motion/Kinematics.cc	Wed Feb 25 20:02:49 2004
***************
*** 310,315 ****
--- 310,320 ----
  	if(leg % 2)
  		p.y = -p.y;
  }
+ void GetLegPosition(vector3d& p, const double* ang, BodyPosition &bp,int leg)
+ {
+ 	GetLegPosition(p,ang,leg);
+ 	p=p.rotate_y(bp.angle.y).rotate_z(-bp.angle.z)+bp.loc;
+ }
  
  
  void GetBodyLocation(vector3d &ball,vector3d &toe,const double *ang,int leg)
***************
*** 448,456 ****
   * @verbinclude CMPack_license.txt
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
!  * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
--- 453,461 ----
   * @verbinclude CMPack_license.txt
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
!  * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
Index: Tekkotsu/Motion/Kinematics.h
diff -c Tekkotsu/Motion/Kinematics.h:1.7 Tekkotsu/Motion/Kinematics.h:1.8
*** Tekkotsu/Motion/Kinematics.h:1.7	Thu Sep 25 11:27:22 2003
--- Tekkotsu/Motion/Kinematics.h	Wed Feb 25 20:02:49 2004
***************
*** 84,89 ****
--- 84,90 ----
  
  void GetLegAngles(double *angles,vector3d target,BodyPosition &bp,int leg);
  void GetLegPosition(vector3d& p,const double* ang,int leg);
+ void GetLegPosition(vector3d& p, const double* ang, BodyPosition &bp,int leg);
  
  void GetBodyLocation(vector3d &ball,vector3d &toe,const double *ang,int leg);
  
***************
*** 109,118 ****
   * @verbinclude CMPack_license.txt
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
!  * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
--- 110,119 ----
   * @verbinclude CMPack_license.txt
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
!  * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
Index: Tekkotsu/Motion/LedEngine.h
diff -c Tekkotsu/Motion/LedEngine.h:1.12 Tekkotsu/Motion/LedEngine.h:1.13
*** Tekkotsu/Motion/LedEngine.h:1.12	Mon Feb  2 20:17:57 2004
--- Tekkotsu/Motion/LedEngine.h	Mon Feb  9 17:45:28 2004
***************
*** 11,31 ****
  // LEDBitMask_t and associated constants are defined in RobotInfo.h
  
  //! Provides basic LED effects to anything that inherits from (recommended method for MotionCommands) or instantiates it (just in case you have reason to)
! /*! Provides a collection of special effects so that the code can be reused various places
!  *  as feedback to to the user.
   *
!  * Cycling ("pulsing") and single-value setting are mutually exclusive - one will cut off the other
   *
!  * A flash will invert and override the current setting, so that it will "reset" after the flash.
!  * Flashes change mid-range values to extremes to make the flash visible (ie not just (1-current))
!  * Normal invert will do simple inverses (just (1-current))
   *
   * getSetting() returns value of last set();
   * getValue() returns what's actually being returned to Motion at the moment
   *
!  * There's some nice functions for using the LEDs to display numbers.  This is handy for when
!  * you want to be free of the terminal.
   * <img src="NumberLEDs.jpg">
   */
  
  class LedEngine {
--- 11,38 ----
  // LEDBitMask_t and associated constants are defined in RobotInfo.h
  
  //! Provides basic LED effects to anything that inherits from (recommended method for MotionCommands) or instantiates it (just in case you have reason to)
! /*! Provides a collection of special effects so that the code can be
!  *  reused various places as feedback to to the user.
   *
!  * Cycling ("pulsing") and single-value setting are mutually exclusive
!  * - one will cut off the other
   *
!  * A flash will invert and override the current setting, so that it
!  * will "reset" after the flash.  Flashes change mid-range values to
!  * extremes to make the flash visible (ie not just (1-current)) Normal
!  * invert will do simple inverses (just (1-current))
   *
   * getSetting() returns value of last set();
   * getValue() returns what's actually being returned to Motion at the moment
   *
!  * There's some nice functions for using the LEDs to display numbers.
!  * This is handy for when you want to be free of the terminal.
   * <img src="NumberLEDs.jpg">
+  *
+  * The ERS-220 and ERS-7 have enough LEDs that they just use a "count
+  * the lights" style of display instead of this pseudo-arabic display.
+  * (look close to see that green bar LED at the top of the 210, this
+  * isn't actually too hard to read once you "see" it)
   */
  
  class LedEngine {
***************
*** 163,172 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
--- 170,179 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
Index: Tekkotsu/Motion/MMAccessor.h
diff -c Tekkotsu/Motion/MMAccessor.h:1.8 Tekkotsu/Motion/MMAccessor.h:1.9
*** Tekkotsu/Motion/MMAccessor.h:1.8	Fri Sep 12 17:38:46 2003
--- Tekkotsu/Motion/MMAccessor.h	Wed Feb 18 16:13:02 2004
***************
*** 52,76 ****
  	//! constructor, checks out by default
  	/*! @param id the motion command to check out
  	 *  @param ckout if true (default) will checkout upon creation.  otherwise it just gets current address (so you can peek at member fields, which should be safe) */
! 	MMAccessor(MotionManager::MC_ID id,bool ckout=true) : mc_id(id), mcptr(NULL) {
  		if(ckout)
  			checkout();
  		else
! 			mcptr=(MC_t*)motman->peekMotion(id);
  	}
  
  	//! constructor, allows objects to provide uniform access to MotionCommands, regardless of whether they are currently in the MotionManager
! 	MMAccessor(MotionCommand * ptr) : mc_id(invalid_MC_ID), mcptr(ptr) {}
  
! 	//! copy constructor - will reference the same mc_id - checkin/checkouts are independent between this and @a a - motman does counting of checkin/checkouts
! 	MMAccessor(const MMAccessor& a) : mc_id(a.mc_id), mcptr(a.mcptr) {
! 		if(motman->isOwner(mc_id))
  			checkout();
  	}
  
  	//! destructor, checks in if needed
  	~MMAccessor() {
! 		checkin();
  	}
  
  	//! allows assignment of MMAccessor's, similar to the copy constructor - the two MMAccessor's will control the same MotionCommand
--- 52,77 ----
  	//! constructor, checks out by default
  	/*! @param id the motion command to check out
  	 *  @param ckout if true (default) will checkout upon creation.  otherwise it just gets current address (so you can peek at member fields, which should be safe) */
! 	MMAccessor(MotionManager::MC_ID id,bool ckout=true) : mc_id(id), checkOutCnt(0), mcptr(NULL) {
  		if(ckout)
  			checkout();
  		else
! 			mcptr=static_cast<MC_t*>(motman->peekMotion(id));
  	}
  
  	//! constructor, allows objects to provide uniform access to MotionCommands, regardless of whether they are currently in the MotionManager
! 	MMAccessor(MotionCommand * ptr) : mc_id(invalid_MC_ID), checkOutCnt(0), mcptr(ptr) {}
  
! 	//! copy constructor - will reference the same mc_id - checkin/checkouts are independent between this and @a a; however, if @a a is checkout out, @c this will check itself out as well
! 	MMAccessor(const MMAccessor& a) : mc_id(a.mc_id), checkOutCnt(0), mcptr(a.mcptr) {
! 		if(a.checkOutCnt>0)
  			checkout();
  	}
  
  	//! destructor, checks in if needed
  	~MMAccessor() {
! 		while(checkOutCnt>0)
! 			checkin();
  	}
  
  	//! allows assignment of MMAccessor's, similar to the copy constructor - the two MMAccessor's will control the same MotionCommand
***************
*** 85,91 ****
  	//! So you can check out if not done by default (or you checked in already)
  	inline MC_t* checkout() {
  		if(mc_id!=MotionManager::invalid_MC_ID)
! 			mcptr=dynamic_cast<MC_t*>(motman->checkoutMotion(mc_id)); 
  		return mcptr;
  	}
  
--- 86,93 ----
  	//! So you can check out if not done by default (or you checked in already)
  	inline MC_t* checkout() {
  		if(mc_id!=MotionManager::invalid_MC_ID)
! 			mcptr=static_cast<MC_t*>(motman->checkoutMotion(mc_id));
! 		checkOutCnt++;
  		return mcptr;
  	}
  
***************
*** 95,104 ****
  	//! Checks in the motion
  	/*! Don't forget, you can also just limit the scope using extra { }'s */
  	inline void checkin() {
! 		if(motman->isOwner(mc_id)) {
  			motman->checkinMotion(mc_id);
! 			mcptr=NULL; // fail fast if we use it after checkin
  		}
  	}
  
  	//! Checks in the motion, passing through the value it is passed.
--- 97,108 ----
  	//! Checks in the motion
  	/*! Don't forget, you can also just limit the scope using extra { }'s */
  	inline void checkin() {
! 		if(checkOutCnt>0) {
  			motman->checkinMotion(mc_id);
! 			checkOutCnt--;
  		}
+ 		if(checkOutCnt==0)
+ 			mcptr=NULL; // fail fast if we use it after last checkin
  	}
  
  	//! Checks in the motion, passing through the value it is passed.
***************
*** 140,145 ****
--- 144,150 ----
  
   protected:
  	MotionManager::MC_ID mc_id; //!< the MC_ID that this Accessor was constructed with
+ 	unsigned int checkOutCnt;   //!< counter so we know how many times checkout was called
  	MC_t* mcptr;                //!< a pointer to the motion command, should always be valid even when not checked out so you can access member fields (which is reasonably safe)
  };
  
***************
*** 148,157 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
!  * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
--- 153,162 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
!  * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
Index: Tekkotsu/Motion/MotionCommand.h
diff -c Tekkotsu/Motion/MotionCommand.h:1.16 Tekkotsu/Motion/MotionCommand.h:1.17
*** Tekkotsu/Motion/MotionCommand.h:1.16	Mon Jul 28 01:55:16 2003
--- Tekkotsu/Motion/MotionCommand.h	Mon Feb  9 17:45:28 2004
***************
*** 13,67 ****
   *   <a href="../FirstMotionCommand.html">guide</a>
   * - <b>an instantiation</b> of a MotionCommand subclass, see MotionManager
   * 
!  * To create a new type of motion, you'll want to subclass this.  You don't need to do
!  * anything fancy, but just be sure to override the 3 abstract functions.
!  *
!  * When an output is set to a value, that value is retained until it is set to a new value,
!  * even if the MotionCommand that set it is pruned or stops using the output.  Outputs never
!  * "reset" to 0 or some other relatively arbitrary base value.
!  *
!  * However, PID values will reset to the default values if pruned or not set since these values
!  * do have a base value which you will want to use 99% of the time.
!  *
!  * Be aware that there is a delay between when you set a joint to a value and that actually
!  * is taken into account by the system - it's on the order of RobotInfo::FrameTime*RobotInfo::NumFrames
!  * (currently 8*4 = 32 ms, at most 2*8*4 = 64 ms) This is because the commands are double buffered.
!  * PIDs, on the other hand, seem to take effect more quickly.  This un-synchronization can sometimes
!  * cause annoying jerkiness (mainly on startup, where there's a large difference between desired
!  * and target values.)
   *
   * Here is the cycle of calls made by MotionManager to your command:
!  * -# shouldPrune() (by default, this will call isAlive() iff autoprune==true)
   * -# updateJointCmds() (assuming the MC wasn't pruned after the previous step)
   * 
!  * So, if you want to hold a joint at a value, each time your updateJointCmds() function is called,
!  * you should tell the MotionManager to keep the joint there (using one of MotionManager::setOutput()'s).
!  * If you do not set a joint after a call to updateJointCmds, the MotionManager will assume you
!  * are no longer using that joint and a lower priority MotionCommand may inherit it.
!  *
!  * MotionCommands which generate events should use the inherited postEvent() instead of trying
!  * to access a global erouter - the inherited version will properly handle sending the events,
!  * trying to access a non-shared global like erouter could cause problems.
   *
   * @warning <b>Be careful what you call in MotionManager</b> \n
!  * Some functions are marked MotionCommand-safe - this is another issue due to our "fake" fork.
!  * In short, when a function is called on a MotionCommand, it thinks it is still running in whatever
!  * process created it, not the process that actually made the function call.  Thus, when Motion
!  * calls updateOutputs(), calls that the MotionCommand makes are indistinguishable from concurrent
!  * calls from Main.  This can cause deadlock if a function is called which locks the MotionManager.
!  * To get around this, we need to pass the 'this' parameter on functions that require a lock, namely
!  * MotionManager::setOutputs().  This allows the MotionManager to figure out that it's the same
!  * MotionCommand it previously called updateOutputs() on, and thus avoid trying to lock itself again.
   *
   * @warning <b>Don't store pointers in motion commands!</b> \n
!  * Since motion commands are in shared memory, and these shared memory regions can have different
!  * base pointers in each process, pointers will only be valid in the process from which they were
!  * assigned.  In other processes, that address may point to something else, especially if it was
!  * pointing outside of the shared memory regions.\n
!  *  There are convoluted ways of getting around this.  If needed, MotionManager could be modified
!  * to hand out shared memory regions upon request.  Let's try to avoid this for now.  Keep MotionCommands
!  * simple, without dynamic memory.  Do more complicated stuff with behaviors, which only have to run in Main.
!  * @see REGDEF @see REGIMP
   */
  class MotionCommand : public MotionManagerMsg {
  	//!@nosubgrouping
--- 13,85 ----
   *   <a href="../FirstMotionCommand.html">guide</a>
   * - <b>an instantiation</b> of a MotionCommand subclass, see MotionManager
   * 
!  * To create a new type of motion, you'll want to subclass this.  You
!  * don't need to do anything fancy, but just be sure to override the 3
!  * abstract functions.
!  *
!  * When an output is set to a value, that output is held at that value
!  * until it is set to a new value, even if the MotionCommand that set
!  * it is pruned or stops using the output.  Outputs never "reset" to 0
!  * or some other relatively arbitrary base value if all the
!  * MotionCommands are removed.
!  *
!  * However, PID values will reset to the default values if pruned or
!  * not set since these values <i>do</i> have a base value which you
!  * will want to use 99% of the time.
!  *
!  * Be aware that there is a delay between when you set a joint to a
!  * value and that actually is taken into account by the system - it's
!  * on the order of FrameTime*NumFrames (currently 8*4 = 32 ms, so
!  * worse case 2*8*4 = 64 ms) This is because the commands are double
!  * buffered.  PIDs, on the other hand, seem to take effect more
!  * quickly.  This un-synchronization can sometimes cause a bit of
!  * jerkiness (mainly on startup, where there's a large difference
!  * between desired and target values.)
   *
   * Here is the cycle of calls made by MotionManager to your command:
!  * -# shouldPrune() (by default, this will return !isAlive() iff #autoprune==true)
   * -# updateJointCmds() (assuming the MC wasn't pruned after the previous step)
   * 
!  * So, if you want to hold a joint at a value, each time your
!  * updateJointCmds() function is called, you should tell the
!  * MotionManager to keep the joint there (using one of
!  * MotionManager::setOutput()'s).  If you do not set a joint after a
!  * call to updateJointCmds, the MotionManager will assume you are no
!  * longer using that joint and a lower priority MotionCommand may
!  * inherit it.
!  *
!  * MotionCommands which generate events should use the inherited
!  * postEvent() instead of trying to access a global #erouter - the
!  * inherited version will properly handle sending the events
!  * regardless of the current context, but trying to access a
!  * non-shared global like #erouter could cause problems.
   *
   * @warning <b>Be careful what you call in MotionManager</b> \n
!  * Some functions are marked MotionCommand-safe - this is another
!  * issue due to our "fake" fork.  In short, when a function is called
!  * on a MotionCommand, it uses the context of whatever process created
!  * it, not the process that actually made the function call.  Thus,
!  * when Motion calls updateOutputs(), calls that the MotionCommand
!  * makes are indistinguishable from concurrent calls from Main.  This
!  * can cause deadlock if a function is called which locks the
!  * MotionManager.  To get around this, we need to pass the 'this'
!  * parameter on functions that require a lock, namely
!  * MotionManager::setOutputs().  This allows the MotionManager to
!  * figure out that it's the same MotionCommand it previously called
!  * updateOutputs() on, and thus avoid trying to lock itself again.
   *
   * @warning <b>Don't store pointers in motion commands!</b> \n
!  * Since motion commands are in shared memory, and these shared memory
!  * regions can have different base pointers in each process, pointers
!  * will only be valid in the process from which they were assigned.
!  * In other processes, that address may point to something else,
!  * especially if it was pointing outside of the shared memory
!  * regions.\n
!  * There are convoluted ways of getting around this.  If needed,
!  * MotionManager could be modified to hand out shared memory regions
!  * upon request.  Let's try to avoid this for now.  Keep
!  * MotionCommands simple, without dynamic memory.  Do more complicated
!  * stuff with behaviors, which only have to worry about running in Main.
   */
  class MotionCommand : public MotionManagerMsg {
  	//!@nosubgrouping
***************
*** 72,87 ****
  	//        *****************
  
  	//! is called once per update cycle, can do any processing you need to change your priorities or set output commands on the MotionManager
! 	/*! @return zero if no changes were made, non-zero otherwise @see RobotInfo::NumFrames @see RobotInfo::FrameTime */
  	virtual int updateOutputs()=0;
  
  	//! not used by MotionManager at the moment, but could be used to reduce recomputation, and you may find it useful
! 	/*! @return zero if none of the commands have changed since last getJointCmd(), else non-zero */
  	virtual int isDirty()=0;
  
  	//! used to prune "dead" motions from the MotionManager
! 	/*! note that a motion could be "paused" or inactive and therefore not dirty, 
! 	 * but still alive, biding its time to "strike" ;)
  	 * @return zero if the motion is still processing, non-zero otherwise */
  	virtual int isAlive()=0;
  
--- 90,107 ----
  	//        *****************
  
  	//! is called once per update cycle, can do any processing you need to change your priorities or set output commands on the MotionManager
! 	/*! @return zero if no changes were made, non-zero otherwise
! 	 *  @see RobotInfo::NumFrames @see RobotInfo::FrameTime */
  	virtual int updateOutputs()=0;
  
  	//! not used by MotionManager at the moment, but could be used to reduce recomputation, and you may find it useful
! 	/*! @return zero if none of the commands have changed since last
! 	 *  getJointCmd(), else non-zero */
  	virtual int isDirty()=0;
  
  	//! used to prune "dead" motions from the MotionManager
! 	/*! note that a motion could be "paused" or inactive and therefore
! 	 * not dirty, but still alive, biding its time to "strike" ;)
  	 * @return zero if the motion is still processing, non-zero otherwise */
  	virtual int isAlive()=0;
  
***************
*** 166,175 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
!  * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
--- 186,195 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
!  * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
Index: Tekkotsu/Motion/MotionManager.cc
diff -c Tekkotsu/Motion/MotionManager.cc:1.33 Tekkotsu/Motion/MotionManager.cc:1.34
*** Tekkotsu/Motion/MotionManager.cc:1.33	Wed Jan 14 15:45:01 2004
--- Tekkotsu/Motion/MotionManager.cc	Fri Feb  6 20:02:29 2004
***************
*** 62,74 ****
  
  void
  MotionManager::setOutput(const MotionCommand* caller, unsigned int output, const OutputCmd& cmd) {
!     if (output >= NumOutputs) return; 
  
  	if(caller==NULL || caller->getID()!=cur_cmd)
  		func_begin();
  	if(cur_cmd==invalid_MC_ID) {
! 		if(cmd.weight>0)
! 			cmdSums[output]=cmd.value;
  	} else if(getPriority(cur_cmd)>=kBackgroundPriority) {
  		cmdstatelist_t& curstatelist=cmdstates[output];
  		cmdstatelist_t::index_t ent=curstatelist.begin();
--- 62,76 ----
  
  void
  MotionManager::setOutput(const MotionCommand* caller, unsigned int output, const OutputCmd& cmd) {
! 	if(output >= NumOutputs)
! 		return;
! 	if(cmd.weight<=0)
! 		return;
  
  	if(caller==NULL || caller->getID()!=cur_cmd)
  		func_begin();
  	if(cur_cmd==invalid_MC_ID) {
! 		cmdSums[output]=cmd.value;
  	} else if(getPriority(cur_cmd)>=kBackgroundPriority) {
  		cmdstatelist_t& curstatelist=cmdstates[output];
  		cmdstatelist_t::index_t ent=curstatelist.begin();
***************
*** 84,96 ****
  
  void
  MotionManager::setOutput(const MotionCommand* caller, unsigned int output, const OutputCmd& cmd, unsigned int frame) {
!     if (output >= NumOutputs) return; 
  
  	if(caller==NULL || caller->getID()!=cur_cmd)
  		func_begin();
  	if(cur_cmd==invalid_MC_ID) {
! 		if(cmd.weight>0)
! 			cmdSums[output]=cmd.value;
  	} else if(getPriority(cur_cmd)>=kBackgroundPriority) {
  		cmdstatelist_t& curstatelist=cmdstates[output];
  		cmdstatelist_t::index_t ent=curstatelist.begin();
--- 86,100 ----
  
  void
  MotionManager::setOutput(const MotionCommand* caller, unsigned int output, const OutputCmd& cmd, unsigned int frame) {
! 	if(output >= NumOutputs)
! 		return;
! 	if(cmd.weight<=0)
! 		return;
  
  	if(caller==NULL || caller->getID()!=cur_cmd)
  		func_begin();
  	if(cur_cmd==invalid_MC_ID) {
! 		cmdSums[output]=cmd.value;
  	} else if(getPriority(cur_cmd)>=kBackgroundPriority) {
  		cmdstatelist_t& curstatelist=cmdstates[output];
  		cmdstatelist_t::index_t ent=curstatelist.begin();
***************
*** 105,117 ****
  
  void 
  MotionManager::setOutput(const MotionCommand* caller, unsigned int output, const OutputCmd ocmds[NumFrames]) {
!     if (output >= NumOutputs) return; 
  
  	if(caller==NULL || caller->getID()!=cur_cmd)
  		func_begin();
  	if(cur_cmd==invalid_MC_ID) {
! 		if(ocmds[NumFrames-1].weight>0)
! 			cmdSums[output]=ocmds[NumFrames-1].value;
  	} else if(getPriority(cur_cmd)>=kBackgroundPriority) {
  		cmdstatelist_t& curstatelist=cmdstates[output];
  		cmdstatelist_t::index_t ent=curstatelist.begin();
--- 109,130 ----
  
  void 
  MotionManager::setOutput(const MotionCommand* caller, unsigned int output, const OutputCmd ocmds[NumFrames]) {
! 	if(output >= NumOutputs)
! 		return;
! 	unsigned int hasWeight=NumFrames;
! 	for(unsigned int i=NumFrames-1; i!=0; i--)
! 		if(ocmds[i].weight>0) {
! 			hasWeight=i;
! 			break;
! 		}
! 	if(hasWeight==NumFrames)
! 		return;
! 	
  
  	if(caller==NULL || caller->getID()!=cur_cmd)
  		func_begin();
  	if(cur_cmd==invalid_MC_ID) {
! 		cmdSums[output]=ocmds[hasWeight].value;
  	} else if(getPriority(cur_cmd)>=kBackgroundPriority) {
  		cmdstatelist_t& curstatelist=cmdstates[output];
  		cmdstatelist_t::index_t ent=curstatelist.begin();
***************
*** 127,133 ****
  
  void
  MotionManager::setOutput(const MotionCommand* caller, unsigned int output, const OutputPID& pid) {
!     if (output >= NumOutputs) return; 
  
  	if(caller==NULL || caller->getID()!=cur_cmd)
  		func_begin();
--- 140,147 ----
  
  void
  MotionManager::setOutput(const MotionCommand* caller, unsigned int output, const OutputPID& pid) {
! 	if(output >= NumOutputs)
! 		return;
  
  	if(caller==NULL || caller->getID()!=cur_cmd)
  		func_begin();
***************
*** 147,153 ****
  
  void
  MotionManager::setOutput(const MotionCommand* caller, unsigned int output, const OutputCmd& cmd, const OutputPID& pid) {
!     if (output >= NumOutputs) return; 
  
  	if(caller==NULL || caller->getID()!=cur_cmd)
  		func_begin();
--- 161,168 ----
  
  void
  MotionManager::setOutput(const MotionCommand* caller, unsigned int output, const OutputCmd& cmd, const OutputPID& pid) {
! 	if(output >= NumOutputs)
! 		return;
  
  	if(caller==NULL || caller->getID()!=cur_cmd)
  		func_begin();
***************
*** 172,178 ****
  
  void
  MotionManager::setOutput(const MotionCommand* caller, unsigned int output, const OutputCmd ocmds[NumFrames], const OutputPID& pid) {
!     if (output >= NumOutputs) return; 
  
  	if(caller==NULL || caller->getID()!=cur_cmd)
  		func_begin();
--- 187,194 ----
  
  void
  MotionManager::setOutput(const MotionCommand* caller, unsigned int output, const OutputCmd ocmds[NumFrames], const OutputPID& pid) {
! 	if(output >= NumOutputs)
! 		return;
  
  	if(caller==NULL || caller->getID()!=cur_cmd)
  		func_begin();
***************
*** 744,753 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  
--- 760,769 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  
Index: Tekkotsu/Motion/MotionManager.h
diff -c Tekkotsu/Motion/MotionManager.h:1.19 Tekkotsu/Motion/MotionManager.h:1.20
*** Tekkotsu/Motion/MotionManager.h:1.19	Sun Jan 18 05:16:57 2004
--- Tekkotsu/Motion/MotionManager.h	Mon Feb  9 17:45:28 2004
***************
*** 22,39 ****
  #include <OPENR/OObject.h>
  #endif
  
! //! The purpose of this class is to serialize access to the MotionCommands and simplify their sharing between memory spaces
! /*! Since MotionObject and MainObject run as separate processes, they could potentially try to access the
!  *  same motion command at the same time, leading to unpredictable behavior.  The MotionManager enforces
!  *  a set of locks to solve this\n
!  *  The other problem is that we are sharing between processes.  MotionManager will do what's necessary to distribute new
!  *  MotionCommand's to all the processes (currently just MainObj and MotoObj)\n
!  *  You should be able to create and add a new motion in one line:
   *  @code
   *  motman->addMotion(SharedObject<YourMC>([arg1,[arg2,...]]) [, priority [, autoprune] ]);
   *  @endcode
!  *  But if you want to do some more initializations not handled by the constructor (the @p arg1, @p arg2, ...
!  *  params) then you would want to do something like the following:
   *  @code
   *  SharedObject<YourMC> tmpvar([arg1,[arg2,...]]);
   *  tmpvar->cmd1();
--- 22,47 ----
  #include <OPENR/OObject.h>
  #endif
  
! //! The purpose of this class is to provide mutually exclusive access to the MotionCommands and simplify their sharing between memory spaces
! /*! Since MotionObject and MainObject run as separate processes, they
!  *  could potentially try to access the same motion command at the
!  *  same time, leading to unpredictable behavior.  The MotionManager
!  *  enforces a set of locks to solve this.
!  *
!  *  The other problem is that we are sharing between processes.
!  *  MotionManager will do what's necessary to distribute new
!  *  MotionCommand's to all the processes (currently just MainObj and
!  *  MotoObj)\n You should be able to create and add a new motion in
!  *  one line:
!  *
   *  @code
   *  motman->addMotion(SharedObject<YourMC>([arg1,[arg2,...]]) [, priority [, autoprune] ]);
   *  @endcode
!  *  
!  *  But if you want to do some more initializations not handled by the
!  *  constructor (the @p arg1, @p arg2, ...  params) then you would
!  *  want to do something like the following:
!  *  
   *  @code
   *  SharedObject<YourMC> tmpvar([arg1,[arg2,...]]);
   *  tmpvar->cmd1();
***************
*** 42,63 ****
   *  motman->addMotion(tmpvar [, ...]);
   *  @endcode
   *
!  *  Notice that tmpvar is of type SharedObject, but you're calling YourMC functions on it...
!  *  SharedObject is a "smart pointer" which will pass your function calls on to the
!  *  underlying templated type.  Isn't C++ great? :)
   *
   *  @warning Once the MotionCommand has been added you must check it
   *  out to modify it or risk concurrent access problems.
   *
   *  @see MotionCommand for information on creating new motion primitives.
   *
!  *  @see MMAccessor for information on accessing motions after you've added them to MotionManager.
   */
  class MotionManager {
  public:
  	//! This is the number of processes which will be accessing the MotionManager
! 	/*! Probably just MainObject and MotionObject
! 	 *  Isn't really a hard maximum, but should be actual expected, need to know when they're all connected */
  	static const unsigned int MAX_ACCESS=2;
  
  	static const unsigned int MAX_MOTIONS=64;   //!< This is the maximum number of Motions which can be managed, can probably be increased reasonably without trouble
--- 50,74 ----
   *  motman->addMotion(tmpvar [, ...]);
   *  @endcode
   *
!  *  Notice that tmpvar is of type SharedObject, but you're calling @c
!  *  YourMC functions on it...  SharedObject is a "smart pointer" which
!  *  will pass your function calls on to the underlying templated type.
!  *  Isn't C++ great? :)
   *
   *  @warning Once the MotionCommand has been added you must check it
   *  out to modify it or risk concurrent access problems.
   *
   *  @see MotionCommand for information on creating new motion primitives.
   *
!  *  @see MMAccessor for information on accessing motions after you've
!  *  added them to MotionManager.
   */
  class MotionManager {
  public:
  	//! This is the number of processes which will be accessing the MotionManager
! 	/*! Probably just MainObject and MotionObject... This isn't really a
! 	 *  hard maximum, but should be actual expected, need to know when
! 	 *  they're all connected */
  	static const unsigned int MAX_ACCESS=2;
  
  	static const unsigned int MAX_MOTIONS=64;   //!< This is the maximum number of Motions which can be managed, can probably be increased reasonably without trouble
***************
*** 65,77 ****
  	typedef MotionManagerMsg::MC_ID MC_ID;      //!< use this type when referring to the ID numbers that MotionManager hands out
  	static const MC_ID invalid_MC_ID=MotionManagerMsg::invalid_MC_ID; //!< for errors and undefined stuff
  
! 	//!Just to give you a general idea what values to use for different priority levels
  	//!@name Priority Level Constants
  	static const float kIgnoredPriority;    //!< won't be expressed, handy if you want to temporarily pause something
  	static const float kBackgroundPriority; //!< will only be expressed if *nothing* else is using that joint
  	static const float kLowPriority;        //!< for stuff that's not background but lower than standard
  	static const float kStdPriority;        //!< for every-day commands
! 	static const float kHighPriority;       //!< for stuff that should over ride standard stuff
  	static const float kEmergencyPriority;  //!< for really important stuff, such as the emergency stop
  	//@}
  
--- 76,88 ----
  	typedef MotionManagerMsg::MC_ID MC_ID;      //!< use this type when referring to the ID numbers that MotionManager hands out
  	static const MC_ID invalid_MC_ID=MotionManagerMsg::invalid_MC_ID; //!< for errors and undefined stuff
  
! 	//!Just to give you some guidelines for what values to use for different priority levels, but you can pick any value you like (that's why they are floats)
  	//!@name Priority Level Constants
  	static const float kIgnoredPriority;    //!< won't be expressed, handy if you want to temporarily pause something
  	static const float kBackgroundPriority; //!< will only be expressed if *nothing* else is using that joint
  	static const float kLowPriority;        //!< for stuff that's not background but lower than standard
  	static const float kStdPriority;        //!< for every-day commands
! 	static const float kHighPriority;       //!< for stuff that should override standard stuff
  	static const float kEmergencyPriority;  //!< for really important stuff, such as the emergency stop
  	//@}
  
***************
*** 234,243 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
--- 245,254 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
Index: Tekkotsu/Motion/MotionSequenceMC.h
diff -c Tekkotsu/Motion/MotionSequenceMC.h:1.11 Tekkotsu/Motion/MotionSequenceMC.h:1.12
*** Tekkotsu/Motion/MotionSequenceMC.h:1.11	Mon Jan  5 22:19:29 2004
--- Tekkotsu/Motion/MotionSequenceMC.h	Thu Feb 19 18:08:09 2004
***************
*** 28,35 ****
   *  whereever the body happens to be (or already doing)
   *
   *  To fade out at the end, set a frame with 0 weight for everything.
!  *  Otherwise it will simply die suddenly.  (Currently, will still jerk
!  *  between priority level shifts - can only fade within a priority level)
   *
   *  Currently, MotionSequence's are intended mainly for building, 
   *  not editing.  It's easy to add keyframes, but hard/impossible to
--- 28,36 ----
   *  whereever the body happens to be (or already doing)
   *
   *  To fade out at the end, set a frame with 0 weight for everything.
!  *  Otherwise it will simply die suddenly.  When a joint reaches its
!  *  last keyframe, it will be set to 0 weight for all future
!  *  updateOutputs() (unless of course the playhead is reset)
   *
   *  Currently, MotionSequence's are intended mainly for building, 
   *  not editing.  It's easy to add keyframes, but hard/impossible to
***************
*** 289,298 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
--- 290,299 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
Index: Tekkotsu/Motion/PostureMC.h
diff -c Tekkotsu/Motion/PostureMC.h:1.6 Tekkotsu/Motion/PostureMC.h:1.7
*** Tekkotsu/Motion/PostureMC.h:1.6	Thu Feb  5 23:07:12 2004
--- Tekkotsu/Motion/PostureMC.h	Tue Mar  2 22:37:13 2004
***************
*** 62,72 ****
  	//!@name PostureEngine Stuff
  	inline virtual void takeSnapshot() { dirty=true; PostureEngine::takeSnapshot(); }
  	inline virtual void clear() { dirty=true; PostureEngine::clear(); }
! 	inline virtual PostureMC& setOverlay(const PostureEngine& pe) { dirty=true; PostureEngine::setOverlay(pe); return *this; }
! 	inline virtual PostureMC& setUnderlay(const PostureEngine& pe) { dirty=true; PostureEngine::setUnderlay(pe); return *this; }
! 	inline virtual PostureMC& setAverage(const PostureEngine& pe,float w=0.5) { dirty=true; PostureEngine::setAverage(pe,w); return *this; }
! 	inline virtual PostureMC& setCombine(const PostureEngine& pe) { dirty=true; PostureEngine::setCombine(pe); return *this; }
! 	inline PostureMC& setOutputCmd(unsigned int i, const OutputCmd& c) { dirty=true; PostureEngine::setOutputCmd(i,c); return *this; }
  	inline virtual unsigned int LoadBuffer(const char buf[], unsigned int len) { dirty=true; return PostureEngine::LoadBuffer(buf,len); }
  	//@}
  
--- 62,72 ----
  	//!@name PostureEngine Stuff
  	inline virtual void takeSnapshot() { dirty=true; PostureEngine::takeSnapshot(); }
  	inline virtual void clear() { dirty=true; PostureEngine::clear(); }
! 	inline virtual PostureEngine& setOverlay(const PostureEngine& pe) { dirty=true; PostureEngine::setOverlay(pe); return *this; }
! 	inline virtual PostureEngine& setUnderlay(const PostureEngine& pe) { dirty=true; PostureEngine::setUnderlay(pe); return *this; }
! 	inline virtual PostureEngine& setAverage(const PostureEngine& pe,float w=0.5) { dirty=true; PostureEngine::setAverage(pe,w); return *this; }
! 	inline virtual PostureEngine& setCombine(const PostureEngine& pe) { dirty=true; PostureEngine::setCombine(pe); return *this; }
! 	inline PostureEngine& setOutputCmd(unsigned int i, const OutputCmd& c) { dirty=true; PostureEngine::setOutputCmd(i,c); return *this; }
  	inline virtual unsigned int LoadBuffer(const char buf[], unsigned int len) { dirty=true; return PostureEngine::LoadBuffer(buf,len); }
  	//@}
  
***************
*** 87,96 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
--- 87,96 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
Index: Tekkotsu/Motion/WalkMC.cc
diff -c Tekkotsu/Motion/WalkMC.cc:1.21 Tekkotsu/Motion/WalkMC.cc:1.23
*** Tekkotsu/Motion/WalkMC.cc:1.21	Mon Jan 19 15:36:06 2004
--- Tekkotsu/Motion/WalkMC.cc	Wed Feb 25 20:02:49 2004
***************
*** 109,117 ****
    body_loc.init(vector3d(0,0,wp.body_height),vector3d(0,0,0));
    body_angle.init(vector3d(0,wp.body_angle,0),vector3d(0,0,0));
  
!   for(unsigned int i=0; i<4; i++){
      legw[i].air = false;
-   }
  
  	if(pfile!=NULL)
  		LoadFile(pfile);
--- 109,116 ----
    body_loc.init(vector3d(0,0,wp.body_height),vector3d(0,0,0));
    body_angle.init(vector3d(0,wp.body_angle,0),vector3d(0,0,0));
  
!   for(unsigned int i=0; i<NumLegs; i++)
      legw[i].air = false;
  
  	if(pfile!=NULL)
  		LoadFile(pfile);
***************
*** 121,128 ****
  	double zeros[JointsPerLeg];
  	for(unsigned int i=0; i<JointsPerLeg; i++)
  		zeros[i]=0;
! 	for(unsigned int i=0; i<NumLegs; i++)
! 		GetLegPosition(legpos[i],zeros,i);
  
  	//	cmds[HeadOffset+TiltOffset].set(.3333,1);
  }
--- 120,126 ----
  	double zeros[JointsPerLeg];
  	for(unsigned int i=0; i<JointsPerLeg; i++)
  		zeros[i]=0;
! 	resetLegPos();
  
  	//	cmds[HeadOffset+TiltOffset].set(.3333,1);
  }
***************
*** 130,140 ****
  // tss "SmoothWalk" addition follows
  int WalkMC::isDirty()
  {
!   if(isPaused) return false;
    if((target_vel_xya.x == 0) && (target_vel_xya.y == 0) && (target_vel_xya.z == 0)) {
! 	if((vel_xya.x != 0) || (vel_xya.y != 0) || (vel_xya.z != 0)) return true
! ;
! 	else return false;
    }
    return true;
  }
--- 128,138 ----
  // tss "SmoothWalk" addition follows
  int WalkMC::isDirty()
  {
!   if(isPaused)
! 		return false;
    if((target_vel_xya.x == 0) && (target_vel_xya.y == 0) && (target_vel_xya.z == 0)) {
! 		// we may stopping, but not stopped yet...
! 		return ((vel_xya.x != 0) || (vel_xya.y != 0) || (vel_xya.z != 0));
    }
    return true;
  }
***************
*** 223,228 ****
--- 221,231 ----
  	if(!isDirty())
  		return 0;
  
+ 	if(vel_xya.sqlength()==0) {
+ 		// we had been stopped - better check someone else didn't move the legs while we weren't using them...
+ 		resetLegPos(); 
+ 	}
+ 
  	unsigned int curT=get_time();
  	if(last_target_vel_xya!=target_vel_xya) {
  		last_target_vel_xya=target_vel_xya;
***************
*** 235,241 ****
    double t = TimeStep * slowmo / 1000;
  
  	vector3d cal_target_vel_xya(target_vel_xya);
! 	cal_target_vel_xya.x/=cp.max_vel[CalibrationParam::forward];
  	cal_target_vel_xya.y/=cp.max_vel[CalibrationParam::strafe];
  	cal_target_vel_xya.z/=cp.max_vel[CalibrationParam::rotate];
  	if(cal_target_vel_xya.sqlength()>.0025)
--- 238,247 ----
    double t = TimeStep * slowmo / 1000;
  
  	vector3d cal_target_vel_xya(target_vel_xya);
! 	if(target_vel_xya.x<0)
! 		cal_target_vel_xya.x/=cp.max_vel[CalibrationParam::reverse];
! 	else
! 		cal_target_vel_xya.x/=cp.max_vel[CalibrationParam::forward];
  	cal_target_vel_xya.y/=cp.max_vel[CalibrationParam::strafe];
  	cal_target_vel_xya.z/=cp.max_vel[CalibrationParam::rotate];
  	if(cal_target_vel_xya.sqlength()>.0025)
***************
*** 244,252 ****
  		else
  			applyCalibration(cp.f_calibration,target_vel_xya,cal_target_vel_xya);
  
!   vel_xya.x = bound(cal_target_vel_xya.x, vel_xya.x-max_accel_xya.x*t, vel_xya.x+max_accel_xya.x*t);
    vel_xya.y = bound(cal_target_vel_xya.y, vel_xya.y-max_accel_xya.y*t, vel_xya.y+max_accel_xya.y*t);
    vel_xya.z = bound(cal_target_vel_xya.z, vel_xya.z-max_accel_xya.z*t, vel_xya.z+max_accel_xya.z*t);
  
    BodyPosition delta;
    delta.loc.set(vel_xya.x*t,vel_xya.y*t,0);
--- 250,262 ----
  		else
  			applyCalibration(cp.f_calibration,target_vel_xya,cal_target_vel_xya);
  
!   //software accel:
! 	vel_xya.x = bound(cal_target_vel_xya.x, vel_xya.x-max_accel_xya.x*t, vel_xya.x+max_accel_xya.x*t);
    vel_xya.y = bound(cal_target_vel_xya.y, vel_xya.y-max_accel_xya.y*t, vel_xya.y+max_accel_xya.y*t);
    vel_xya.z = bound(cal_target_vel_xya.z, vel_xya.z-max_accel_xya.z*t, vel_xya.z+max_accel_xya.z*t);
+ 	//no software accel:
+ 	//vel_xya=cal_target_vel_xya;
+ 	//<end>
  
    BodyPosition delta;
    delta.loc.set(vel_xya.x*t,vel_xya.y*t,0);
***************
*** 299,310 ****
  
  			if(air != legw[i].air){
  				if(air){
  					t = wp.period/1000.0 * 0.75;
  					vector3d vfp;
  					vfp.x = bound(cal_target_vel_xya.x, vel_xya.x-max_accel_xya.x*t, vel_xya.x+max_accel_xya.x*t);
  					vfp.y = bound(cal_target_vel_xya.y, vel_xya.y-max_accel_xya.y*t, vel_xya.y+max_accel_xya.y*t);
- 					vfp.z = 0.0;
  					double vfa   = bound(cal_target_vel_xya.z, vel_xya.z-max_accel_xya.z*t, vel_xya.z+max_accel_xya.z*t);
  					double b = (wp.period/1000.0) * (1.0 - air_f) / 2.0;
  					vector3d target = (wp.leg[i].neutral + vfp*b).rotate_z(vfa*b);
  					legw[i].airpath.create(legpos[i],target,wp.leg[i].lift_vel,wp.leg[i].down_vel);
--- 309,334 ----
  
  			if(air != legw[i].air){
  				if(air){
+ 					/*
+ 						cout << i << ":   ";
+ 						cout << legpos[i].x << ' ' << legpos[i].y << ' ' << legpos[i].z << "  ->  ";
+ 						GetLegAngles(nextlegangles,legpos[i],nextpos,i);
+ 						for(unsigned int j=0; j<JointsPerLeg; j++)
+ 							cout << nextlegangles[j] << ' ';
+ 						cout << endl;
+ 					*/
  					t = wp.period/1000.0 * 0.75;
  					vector3d vfp;
+ 					//software accel:
  					vfp.x = bound(cal_target_vel_xya.x, vel_xya.x-max_accel_xya.x*t, vel_xya.x+max_accel_xya.x*t);
  					vfp.y = bound(cal_target_vel_xya.y, vel_xya.y-max_accel_xya.y*t, vel_xya.y+max_accel_xya.y*t);
  					double vfa   = bound(cal_target_vel_xya.z, vel_xya.z-max_accel_xya.z*t, vel_xya.z+max_accel_xya.z*t);
+ 					//no software accel:
+ 					//vfp.x=cal_target_vel_xya.x;
+ 					//vfp.y=cal_target_vel_xya.y;
+ 					//double vfa=cal_target_vel_xya.z;
+ 					//<end>
+ 					vfp.z = 0.0;
  					double b = (wp.period/1000.0) * (1.0 - air_f) / 2.0;
  					vector3d target = (wp.leg[i].neutral + vfp*b).rotate_z(vfa*b);
  					legw[i].airpath.create(legpos[i],target,wp.leg[i].lift_vel,wp.leg[i].down_vel);
***************
*** 327,333 ****
  				// with velocity.
  				double velfraction_x = fabs(vel_xya.x / MAX_DX);
  				double velfraction_y = fabs(vel_xya.y / MAX_DY);
! 				double velfraction_a = fabs(vel_xya.z / MAX_DA);
  
  				// Choose the biggest velfraction
  				double velfraction =
--- 351,357 ----
  				// with velocity.
  				double velfraction_x = fabs(vel_xya.x / MAX_DX);
  				double velfraction_y = fabs(vel_xya.y / MAX_DY);
! 				double velfraction_a = fabs(vel_xya.z / MAX_DA * 2); //rotation seems more sensitive
  
  				// Choose the biggest velfraction
  				double velfraction =
***************
*** 367,378 ****
  }
  
  void WalkMC::resetLegPos() {
  	for(unsigned int i=0; i<NumLegs; i++) {
  		double tmp[JointsPerLeg];
  		for(unsigned int j=0; j<JointsPerLeg; j++)
  			tmp[j]=state->outputs[LegOffset+i*JointsPerLeg+j];
! 		GetLegPosition(legpos[i],tmp,i);
  	}
  }
  
  unsigned int checksum(const char *data,int num)
--- 391,411 ----
  }
  
  void WalkMC::resetLegPos() {
+ 	BodyPosition nextpos;
+ 	nextpos.loc.set(0,0,wp.body_height);
+ 	nextpos.angle.set(0,wp.body_angle,0);
  	for(unsigned int i=0; i<NumLegs; i++) {
  		double tmp[JointsPerLeg];
  		for(unsigned int j=0; j<JointsPerLeg; j++)
  			tmp[j]=state->outputs[LegOffset+i*JointsPerLeg+j];
! 		GetLegPosition(legpos[i],tmp,nextpos,i);
! 		/*
! 			for(unsigned int j=0; j<JointsPerLeg; j++)
! 			cout << state->outputs[LegOffset+i*JointsPerLeg+j] << ' ';
! 			cout << "  ->  " << legpos[i].x << ' ' << legpos[i].y << ' ' << legpos[i].z << endl;
! 		*/
  	}
+ 	//cout << "----------------------" << endl;
  }
  
  unsigned int checksum(const char *data,int num)
***************
*** 396,402 ****
  	inmat[2]=in.z;
  	inmat[3]=fabs(in.y);
  	inmat[4]=fabs(in.z);
! 	inmat[5]=atan2(in.y,inmat[3]);
  	inmat[6]=in.x*in.x+in.y*in.y;
  	inmat[7]=in.x*in.z;
  	inmat[8]=in.y*in.x;
--- 429,435 ----
  	inmat[2]=in.z;
  	inmat[3]=fabs(in.y);
  	inmat[4]=fabs(in.z);
! 	inmat[5]=exp(-.5f*in.z*in.z)*sin(in.z*2.5f);
  	inmat[6]=in.x*in.x+in.y*in.y;
  	inmat[7]=in.x*in.z;
  	inmat[8]=in.y*in.x;
***************
*** 419,427 ****
   * @verbinclude CMPack_license.txt
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
--- 452,460 ----
   * @verbinclude CMPack_license.txt
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
Index: Tekkotsu/Motion/WalkMC.h
diff -c Tekkotsu/Motion/WalkMC.h:1.19 Tekkotsu/Motion/WalkMC.h:1.21
*** Tekkotsu/Motion/WalkMC.h:1.19	Sun Jan 18 05:16:57 2004
--- Tekkotsu/Motion/WalkMC.h	Wed Mar  3 13:42:16 2004
***************
*** 44,49 ****
--- 44,70 ----
  /*! Moves the feet through a looping path in order to walk - default parameters use
   *  a walk low to the ground so you don't walk over the ball.
   *
+  *  There are around 50 parameters which control the walk - these are
+  *  loaded from a file and can modify almost every aspect of the the
+  *  gait.  It's a binary file format, I recommend using our Walk Edit
+  *  menu to edit the parameters in real time and get immediate
+  *  feedback.  It's a tricky job to find a good set of parameters.
+  *
+  *  And then, once you have it walking, there's a whole different
+  *  problem of actually moving at the speed that's requested.  That's
+  *  what the calibration parameters do - map the requested target
+  *  speed to the command to pass to the engine so the resulting motion
+  *  will hopefully match what you asked for.
+  *
+  *  You'll probably want to take a look at the setTargetVelocity()
+  *  function to control the direction of the walk.
+  *
+  *  This class is in some dire need of some cleanup - we (Tekkotsu)
+  *  didn't write it, never really bothered to get a deep understanding
+  *  of it, but have none the less hacked around and added stuff on top
+  *  of it.  So pardon the mess, unless you're feeling ambitious to
+  *  write your own ;)
+  *
   *  This portion of the code falls under CMPack's license:
   *  @verbinclude CMPack_license.txt
   *
***************
*** 96,103 ****
  			NUM_DIM
  		};
  
! 		float f_calibration[3][11]; //!< matrix of calibration parameters; 3 columns for f,s,r speeds, 2 columns for abs s,r speeds, 1 squared planar speed, 1 planar bearing, 3 columns for f*r,s*f,r*s, and 1 column for offset
! 		float b_calibration[3][11]; //!< matrix of calibration parameters; 3 columns for f,s,r speeds, 2 columns for abs s,r speeds, 1 squared planar speed, 1 planar bearing, 3 columns for f*r,s*f,r*s, and 1 column for offset
  
  		float max_accel[NUM_DIM]; //!< maximum achievable acceleration, 0 for infinite (mm/s^2)
  		float max_vel[NUM_DIM]; //!< maximum achievable velocity (mm/s)
--- 117,124 ----
  			NUM_DIM
  		};
  
! 		float f_calibration[3][11]; //!< matrix of calibration parameters; 3 columns for f,s,r speeds, 2 columns for abs s,r speeds, 1 gabor function, 1 squared planar speed, 3 columns for f*r,s*f,r*s, and 1 column for offset
! 		float b_calibration[3][11]; //!< matrix of calibration parameters; 3 columns for f,s,r speeds, 2 columns for abs s,r speeds, 1 gabor function, 1 squared planar speed, 3 columns for f*r,s*f,r*s, and 1 column for offset
  
  		float max_accel[NUM_DIM]; //!< maximum achievable acceleration, 0 for infinite (mm/s^2)
  		float max_vel[NUM_DIM]; //!< maximum achievable velocity (mm/s)
***************
*** 168,174 ****
  	static void applyCalibration(const float mat[3][11], const vector3d& in, vector3d& out);
  
   protected:
! 	//! does some setup stuff, calls load(pfile)
  	void init(const char* pfile);
  
  	bool isPaused; //!< true if we are paused
--- 189,195 ----
  	static void applyCalibration(const float mat[3][11], const vector3d& in, vector3d& out);
  
   protected:
! 	//! does some setup stuff, calls LoadFile(pfile)
  	void init(const char* pfile);
  
  	bool isPaused; //!< true if we are paused
***************
*** 241,250 ****
   * @verbinclude CMPack_license.txt
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
--- 262,271 ----
   * @verbinclude CMPack_license.txt
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
Index: Tekkotsu/Shared/ERS210Info.h
diff -c Tekkotsu/Shared/ERS210Info.h:1.11 Tekkotsu/Shared/ERS210Info.h:1.12
*** Tekkotsu/Shared/ERS210Info.h:1.11	Tue Jan 20 22:53:01 2004
--- Tekkotsu/Shared/ERS210Info.h	Mon Feb  9 17:45:28 2004
***************
*** 33,39 ****
  	const unsigned int NumSlowFrames=1;    //!< the number of frames per buffer being sent to ears (double buffered as well)
  	const unsigned int SoundBufferTime=32; //!< the number of milliseconds per sound buffer... I'm not sure if this can be changed
  	
! 	//!Corresponds to entries in PrimitiveName, defined at the end of this file, these are the primary grouping
  	/*!Right now all binary joints are slow, but perhaps this won't always be the case... hence the IsFast/Slow bitmasks to select which type, in order to be more general */
  	//!@name Output Types Information
  	const unsigned NumPIDJoints   = 18; //!< The number of joints which use PID motion - everything except ears
--- 33,39 ----
  	const unsigned int NumSlowFrames=1;    //!< the number of frames per buffer being sent to ears (double buffered as well)
  	const unsigned int SoundBufferTime=32; //!< the number of milliseconds per sound buffer... I'm not sure if this can be changed
  	
! 	//!Corresponds to entries in ERS210Info::PrimitiveName, defined at the end of this file, these are the primary grouping
  	/*!Right now all binary joints are slow, but perhaps this won't always be the case... hence the IsFast/Slow bitmasks to select which type, in order to be more general */
  	//!@name Output Types Information
  	const unsigned NumPIDJoints   = 18; //!< The number of joints which use PID motion - everything except ears
***************
*** 42,48 ****
  	const unsigned NumOutputs     = NumPIDJoints + NumBinJoints + NumLEDs; //!< the total number of outputs
  
  	const bool IsFastOutput[NumOutputs] = { true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false }; //!< true for joints which can be updated every 32 ms (all but the ears)
! 	//! we need this so you can tell programmatically which joints are "real" and which are "fake" in compatability mode
  	const bool IsRealERS210[NumOutputs] = { true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true };
  	//@}
  
--- 42,48 ----
  	const unsigned NumOutputs     = NumPIDJoints + NumBinJoints + NumLEDs; //!< the total number of outputs
  
  	const bool IsFastOutput[NumOutputs] = { true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false }; //!< true for joints which can be updated every 32 ms (all but the ears)
! 	//! we need this so you can tell programmatically which joints are "real" and which are "fake" in ERS-2xx target mode
  	const bool IsRealERS210[NumOutputs] = { true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true };
  	//@}
  
***************
*** 53,60 ****
  	const unsigned NumTailJoints  =  2; //!< The number of joints assigned to the tail
  	const unsigned NumMouthJoints =  1; //!< the number of joints that control the mouth
  	const unsigned NumEarJoints   =  2; //!< The number of joints which control the ears (NOT per ear, is total)
! 	const unsigned NumButtons     =  8; //!< the number of buttons that are available, see ButtonOffset_t
! 	const unsigned NumSensors     =  1+3+1+5;  //!< 1 dist, 3 accel, 1 thermo, 5 from power, see SensorOffset_t
  	
  
  	// *******************************
--- 53,60 ----
  	const unsigned NumTailJoints  =  2; //!< The number of joints assigned to the tail
  	const unsigned NumMouthJoints =  1; //!< the number of joints that control the mouth
  	const unsigned NumEarJoints   =  2; //!< The number of joints which control the ears (NOT per ear, is total)
! 	const unsigned NumButtons     =  8; //!< the number of buttons that are available, see ERS210Info::ButtonOffset_t
! 	const unsigned NumSensors     =  1+3+1+5;  //!< 1 dist, 3 accel, 1 thermo, 5 from power, see ERS210Info::SensorOffset_t
  	
  
  	// *******************************
***************
*** 62,68 ****
  	// *******************************
  
  
! 	//!Corresponds to entries in PrimitiveName, defined at the end of this file
  	//!@name Output Offsets
  
  	const unsigned PIDJointOffset = 0; //!< The beginning of the PID Joints
--- 62,68 ----
  	// *******************************
  
  
! 	//!Corresponds to entries in ERS210Info::PrimitiveName, defined at the end of this file
  	//!@name Output Offsets
  
  	const unsigned PIDJointOffset = 0; //!< The beginning of the PID Joints
***************
*** 86,92 ****
  	
  	//@}
  	
! 	//! The offsets of the individual LEDs on the head and tail.  Note that L/R are robot's POV.  See also LEDBitMask_t
  	enum LEDOffset_t {
  		BotLLEDOffset = LEDOffset,//!< bottom left (red - sad)
  		BotRLEDOffset, //!< bottom right (red - sad)
--- 86,92 ----
  	
  	//@}
  	
! 	//! The offsets of the individual LEDs on the head and tail.  Note that left/right are robot's point of view.  See also LEDBitMask_t
  	enum LEDOffset_t {
  		BotLLEDOffset = LEDOffset,//!< bottom left (red - sad)
  		BotRLEDOffset, //!< bottom right (red - sad)
***************
*** 110,116 ****
  		TailLeftLEDOffset = TlBluLEDOffset        //!< alias for 220 cross-compatibility
  	};
  	
! 	//! Bitmasks for use when specifying combinations of LEDs (see LEDEngine ) Note that L/R are robot's POV
  	//!@name LED Bitmasks
  	typedef unsigned int LEDBitMask_t; //!< So you can be clear when you're refering to a LED bitmask
  	const LEDBitMask_t BotLLEDMask = 1<<(BotLLEDOffset-LEDOffset); //!< bottom left (red - sad)
--- 110,116 ----
  		TailLeftLEDOffset = TlBluLEDOffset        //!< alias for 220 cross-compatibility
  	};
  	
! 	//! Bitmasks for use when specifying combinations of LEDs (see LedEngine ) Note that left/right are robot's point of view
  	//!@name LED Bitmasks
  	typedef unsigned int LEDBitMask_t; //!< So you can be clear when you're refering to a LED bitmask
  	const LEDBitMask_t BotLLEDMask = 1<<(BotLLEDOffset-LEDOffset); //!< bottom left (red - sad)
***************
*** 368,374 ****
  	#define __RI_RAD_FLAG
  	#endif
  	
! 	//! Defines the min and max index of entries in #outputRanges and #mechanicalLimits
  	enum MinMaxRange_t { MinRange,MaxRange };
  
  	//! This table holds the software limits of each of the outputs
--- 368,374 ----
  	#define __RI_RAD_FLAG
  	#endif
  	
! 	//! Defines the indexes to use to access the min and max entries of ERS210Info::outputRanges and ERS210Info::mechanicalLimits
  	enum MinMaxRange_t { MinRange,MaxRange };
  
  	//! This table holds the software limits of each of the outputs
***************
*** 417,424 ****
  #endif //TGT_ERS2xx check
  
  	/*! @name CPC IDs
! 	 * values defined by OPEN-R, used to interface with lower level OPEN-R code to read sensors - DOESN'T correspond to ::PrimitiveName */
! 	static const int CPCJointNeckTilt           =  0; //!< Head
  	static const int CPCJointNeckPan            =  1;
  	static const int CPCJointNeckRoll           =  2;
  	static const int CPCSensorHeadBackPressure  =  3;
--- 417,424 ----
  #endif //TGT_ERS2xx check
  
  	/*! @name CPC IDs
! 	 * values defined by OPEN-R, used to interface with lower level OPEN-R code to read sensors - DOESN'T correspond to ERS210Info::PrimitiveName */
! 	static const int CPCJointNeckTilt           =  0; // Head
  	static const int CPCJointNeckPan            =  1;
  	static const int CPCJointNeckRoll           =  2;
  	static const int CPCSensorHeadBackPressure  =  3;
***************
*** 426,448 ****
  	static const int CPCSensorPSD               =  5;
  	static const int CPCJointMouth              =  6;
  	static const int CPCSensorChinSwitch        =  7;
! 	static const int CPCJointLFRotator          =  8; //!< Left front leg
  	static const int CPCJointLFElevator         =  9;
  	static const int CPCJointLFKnee             = 10;
  	static const int CPCSensorLFPaw             = 11;
! 	static const int CPCJointLHRotator          = 12; //!< Left hind leg
  	static const int CPCJointLHElevator         = 13;
  	static const int CPCJointLHKnee             = 14;
  	static const int CPCSensorLHPaw             = 15;
! 	static const int CPCJointRFRotator          = 16; //!< Right front leg
  	static const int CPCJointRFElevator         = 17;
  	static const int CPCJointRFKnee             = 18;
  	static const int CPCSensorRFPaw             = 19;
! 	static const int CPCJointRHRotator          = 20; //!< Right hind leg
  	static const int CPCJointRHElevator         = 21;
  	static const int CPCJointRHKnee             = 22;
  	static const int CPCSensorRHPaw             = 23;
! 	static const int CPCJointTailPan            = 24; //!< Tail
  	static const int CPCJointTailTilt           = 25;
  	static const int CPCSensorThermoSensor      = 26;
  	static const int CPCSensorBackSwitch        = 27;
--- 426,448 ----
  	static const int CPCSensorPSD               =  5;
  	static const int CPCJointMouth              =  6;
  	static const int CPCSensorChinSwitch        =  7;
! 	static const int CPCJointLFRotator          =  8; // Left front leg
  	static const int CPCJointLFElevator         =  9;
  	static const int CPCJointLFKnee             = 10;
  	static const int CPCSensorLFPaw             = 11;
! 	static const int CPCJointLHRotator          = 12; // Left hind leg
  	static const int CPCJointLHElevator         = 13;
  	static const int CPCJointLHKnee             = 14;
  	static const int CPCSensorLHPaw             = 15;
! 	static const int CPCJointRFRotator          = 16; // Right front leg
  	static const int CPCJointRFElevator         = 17;
  	static const int CPCJointRFKnee             = 18;
  	static const int CPCSensorRFPaw             = 19;
! 	static const int CPCJointRHRotator          = 20; // Right hind leg
  	static const int CPCJointRHElevator         = 21;
  	static const int CPCJointRHKnee             = 22;
  	static const int CPCSensorRHPaw             = 23;
! 	static const int CPCJointTailPan            = 24; // Tail
  	static const int CPCJointTailTilt           = 25;
  	static const int CPCSensorThermoSensor      = 26;
  	static const int CPCSensorBackSwitch        = 27;
***************
*** 458,467 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
--- 458,467 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
Index: Tekkotsu/Shared/ERS220Info.h
diff -c Tekkotsu/Shared/ERS220Info.h:1.11 Tekkotsu/Shared/ERS220Info.h:1.12
*** Tekkotsu/Shared/ERS220Info.h:1.11	Tue Jan 20 22:53:01 2004
--- Tekkotsu/Shared/ERS220Info.h	Mon Feb  9 17:45:28 2004
***************
*** 36,42 ****
  	const unsigned int NumSlowFrames=1;    //!< the number of frames per buffer being sent to ears (double buffered as well)
  	const unsigned int SoundBufferTime=32; //!< the number of milliseconds per sound buffer... I'm not sure if this can be changed
  	
! 	//!Corresponds to entries in PrimitiveName, defined at the end of this file, these are the primary grouping
  	/*!Right now all binary joints are slow, but perhaps this won't always be the case... hence the IsFast/Slow bitmasks to select which type, in order to be more general */
  	//!@name Output Types Information
  	const unsigned NumPIDJoints   = 15; //!< The number of joints which use PID motion - everything
--- 36,42 ----
  	const unsigned int NumSlowFrames=1;    //!< the number of frames per buffer being sent to ears (double buffered as well)
  	const unsigned int SoundBufferTime=32; //!< the number of milliseconds per sound buffer... I'm not sure if this can be changed
  	
! 	//!Corresponds to entries in ERS220Info::PrimitiveName, defined at the end of this file, these are the primary grouping
  	/*!Right now all binary joints are slow, but perhaps this won't always be the case... hence the IsFast/Slow bitmasks to select which type, in order to be more general */
  	//!@name Output Types Information
  	const unsigned NumPIDJoints   = 15; //!< The number of joints which use PID motion - everything
***************
*** 63,69 ****
  		// for binary joints (none supported/exist on 220)
  	}; //!< true for joints which can be updated every 32 ms (all but the ears on a 210)
  
! 	//! we need this so you can tell programmatically which joints are "real" and which are "fake" in compatability mode
  	const bool IsRealERS220[NumOutputs] = {
  		// for PID joints
  		true, true, true,
--- 63,69 ----
  		// for binary joints (none supported/exist on 220)
  	}; //!< true for joints which can be updated every 32 ms (all but the ears on a 210)
  
! 	//! we need this so you can tell programmatically which joints are "real" and which are "fake" in ERS-2xx target mode
  	const bool IsRealERS220[NumOutputs] = {
  		// for PID joints
  		true, true, true,
***************
*** 90,97 ****
  	const unsigned NumTailJoints  =  0; //!< The number of joints assigned to the tail
  	const unsigned NumMouthJoints =  0; //!< the number of joints that control the mouth
  	const unsigned NumEarJoints   =  0; //!< The number of joints which control the ears (NOT per ear, is total)
! 	const unsigned NumButtons     =  11; //!< the number of buttons that are available, see ButtonOffset_t
! 	const unsigned NumSensors     =  1+3+1+5;  //!< 1 dist, 3 accel, 1 thermo, 5 from power, see SensorOffset_t
  	
  
  	// *******************************
--- 90,97 ----
  	const unsigned NumTailJoints  =  0; //!< The number of joints assigned to the tail
  	const unsigned NumMouthJoints =  0; //!< the number of joints that control the mouth
  	const unsigned NumEarJoints   =  0; //!< The number of joints which control the ears (NOT per ear, is total)
! 	const unsigned NumButtons     =  11; //!< the number of buttons that are available, see ERS220Info::ButtonOffset_t
! 	const unsigned NumSensors     =  1+3+1+5;  //!< 1 dist, 3 accel, 1 thermo, 5 from power, see ERS220Info::SensorOffset_t
  	
  
  	// *******************************
***************
*** 99,105 ****
  	// *******************************
  
  
! 	//!Corresponds to entries in PrimitiveName, defined at the end of this file
  	//!@name Output Offsets
  	const unsigned PIDJointOffset = 0; //!< The beginning of the PID Joints
  	const unsigned LegOffset   = PIDJointOffset;           //!< the offset of the beginning of the leg joints
--- 99,105 ----
  	// *******************************
  
  
! 	//!Corresponds to entries in ERS220Info::PrimitiveName, defined at the end of this file
  	//!@name Output Offsets
  	const unsigned PIDJointOffset = 0; //!< The beginning of the PID Joints
  	const unsigned LegOffset   = PIDJointOffset;           //!< the offset of the beginning of the leg joints
***************
*** 119,125 ****
  	
  	//@}
  	
! 	//! The offsets of the individual LEDs on the head and tail.  Note that L/R are robot's POV.  See also LEDBitMask_t
  	enum LEDOffset_t {
  		FaceFrontLeftLEDOffset = LEDOffset, //!< head face side light (front left - blue)
  		FaceFrontRightLEDOffset,    //!< head face side light (front right - blue)
--- 119,125 ----
  	
  	//@}
  	
! 	//! The offsets of the individual LEDs on the head and tail.  Note that left/right are robot's point of view.  See also LEDBitMask_t
  	enum LEDOffset_t {
  		FaceFrontLeftLEDOffset = LEDOffset, //!< head face side light (front left - blue)
  		FaceFrontRightLEDOffset,    //!< head face side light (front right - blue)
***************
*** 154,160 ****
  		TlRedLEDOffset = TailRightLEDOffset,      //!< red tail light (ERS-210)
  	};
  	
! 	//! Bitmasks for use when specifying combinations of LEDs (see LEDEngine ) Note that L/R are robot's POV
  	//!@name LED Bitmasks
  	typedef unsigned int LEDBitMask_t; //!< So you can be clear when you're refering to a LED bitmask
  	const LEDBitMask_t FaceFrontLeftLEDMask   = 1<<(FaceFrontLeftLEDOffset-LEDOffset);
--- 154,160 ----
  		TlRedLEDOffset = TailRightLEDOffset,      //!< red tail light (ERS-210)
  	};
  	
! 	//! Bitmasks for use when specifying combinations of LEDs (see LedEngine ) Note that left/right are robot's point of view
  	//!@name LED Bitmasks
  	typedef unsigned int LEDBitMask_t; //!< So you can be clear when you're refering to a LED bitmask
  	const LEDBitMask_t FaceFrontLeftLEDMask   = 1<<(FaceFrontLeftLEDOffset-LEDOffset);
***************
*** 470,476 ****
  #define __RI_RAD_FLAG
  #endif
  
! 	//! Defines the min and max index of entries in #outputRanges and #mechanicalLimits
  	enum MinMaxRange_t { MinRange,MaxRange };
  
  	//! This table holds the software limits of each of the outputs
--- 470,476 ----
  #define __RI_RAD_FLAG
  #endif
  
! 	//! Defines the indexes to use to access the min and max entries of ERSInfo::outputRanges and ERS7Info::mechanicalLimits
  	enum MinMaxRange_t { MinRange,MaxRange };
  
  	//! This table holds the software limits of each of the outputs
***************
*** 521,527 ****
  #endif //TGT_ERS2xx check
  
  	/*! @name CPC IDs
! 	 * values defined by OPEN-R, used to interface with lower level OPEN-R code to read sensors - DOESN'T correspond to ::PrimitiveName */
      static const int CPCJointNeckTilt           =  0; // PRM:/r1/c1-Joint2:j1
      static const int CPCJointNeckPan            =  1; // PRM:/r1/c1/c2-Joint2:j2
      static const int CPCJointNeckRoll           =  2; // PRM:/r1/c1/c2/c3-Joint2:j3
--- 521,527 ----
  #endif //TGT_ERS2xx check
  
  	/*! @name CPC IDs
! 	 * values defined by OPEN-R, used to interface with lower level OPEN-R code to read sensors - DOESN'T correspond to ERS220Info::PrimitiveName */
      static const int CPCJointNeckTilt           =  0; // PRM:/r1/c1-Joint2:j1
      static const int CPCJointNeckPan            =  1; // PRM:/r1/c1/c2-Joint2:j2
      static const int CPCJointNeckRoll           =  2; // PRM:/r1/c1/c2/c3-Joint2:j3
***************
*** 562,571 ****
   * @author Daishi MORI (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
--- 562,571 ----
   * @author Daishi MORI (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
Index: Tekkotsu/Shared/ERS2xxInfo.h
diff -c Tekkotsu/Shared/ERS2xxInfo.h:1.7 Tekkotsu/Shared/ERS2xxInfo.h:1.8
*** Tekkotsu/Shared/ERS2xxInfo.h:1.7	Tue Jan 20 22:53:01 2004
--- Tekkotsu/Shared/ERS2xxInfo.h	Mon Feb  9 17:45:28 2004
***************
*** 32,38 ****
  	const unsigned int NumSlowFrames=1;    //!< the number of frames per buffer being sent to ears (double buffered as well)
  	const unsigned int SoundBufferTime=32; //!< the number of milliseconds per sound buffer... I'm not sure if this can be changed
  	
! 	//!Corresponds to entries in PrimitiveName, defined at the end of this file, these are the primary grouping
  	/*!Right now all binary joints are slow, but perhaps this won't always be the case... hence the IsFast/Slow bitmasks to select which type, in order to be more general */
  	//!@name Output Types Information
  	const unsigned NumPIDJoints   = 18; //!< The number of joints which use PID motion - everything
--- 32,38 ----
  	const unsigned int NumSlowFrames=1;    //!< the number of frames per buffer being sent to ears (double buffered as well)
  	const unsigned int SoundBufferTime=32; //!< the number of milliseconds per sound buffer... I'm not sure if this can be changed
  	
! 	//!Corresponds to entries in ERS2xxInfo::PrimitiveName, defined at the end of this file, these are the primary grouping
  	/*!Right now all binary joints are slow, but perhaps this won't always be the case... hence the IsFast/Slow bitmasks to select which type, in order to be more general */
  	//!@name Output Types Information
  	const unsigned NumPIDJoints   = 18; //!< The number of joints which use PID motion - everything
***************
*** 118,125 ****
  	const unsigned NumTailJoints  =  2; //!< The number of joints assigned to the tail
  	const unsigned NumMouthJoints =  1; //!< the number of joints that control the mouth
  	const unsigned NumEarJoints   =  2; //!< The number of joints which control the ears (NOT per ear, is total)
! 	const unsigned NumButtons     =  11; //!< the number of buttons that are available, see ButtonOffset_t
! 	const unsigned NumSensors     =  1+3+1+5;  //!< 1 dist, 3 accel, 1 thermo, 5 from power, see SensorOffset_t
  	
  
  	// *******************************
--- 118,125 ----
  	const unsigned NumTailJoints  =  2; //!< The number of joints assigned to the tail
  	const unsigned NumMouthJoints =  1; //!< the number of joints that control the mouth
  	const unsigned NumEarJoints   =  2; //!< The number of joints which control the ears (NOT per ear, is total)
! 	const unsigned NumButtons     =  11; //!< the number of buttons that are available, see ERS2xxInfo::ButtonOffset_t
! 	const unsigned NumSensors     =  1+3+1+5;  //!< 1 dist, 3 accel, 1 thermo, 5 from power, see ERS2xxInfo::SensorOffset_t
  	
  
  	// *******************************
***************
*** 127,133 ****
  	// *******************************
  
  
! 	//!Corresponds to entries in PrimitiveName, defined at the end of this file
  	//!@name Output Offsets
  	const unsigned PIDJointOffset = 0; //!< The beginning of the PID Joints
  	const unsigned LegOffset   = PIDJointOffset;           //!< the offset of the beginning of the leg joints
--- 127,133 ----
  	// *******************************
  
  
! 	//!Corresponds to entries in ERS2xxInfo::PrimitiveName, defined at the end of this file
  	//!@name Output Offsets
  	const unsigned PIDJointOffset = 0; //!< The beginning of the PID Joints
  	const unsigned LegOffset   = PIDJointOffset;           //!< the offset of the beginning of the leg joints
***************
*** 150,156 ****
  	
  	//@}
  	
! 	//! The offsets of the individual LEDs on the head and tail.  Note that L/R are robot's POV.  See also LEDBitMask_t
  	enum LEDOffset_t {
  		FaceFrontLeftLEDOffset = LEDOffset, //!< head face side light (front left - blue) (ERS-220)
  		FaceFrontRightLEDOffset,    //!< head face side light (front right - blue) (ERS-220)
--- 150,156 ----
  	
  	//@}
  	
! 	//! The offsets of the individual LEDs on the head and tail.  Note that left/right are robot's point of view.  See also LEDBitMask_t
  	enum LEDOffset_t {
  		FaceFrontLeftLEDOffset = LEDOffset, //!< head face side light (front left - blue) (ERS-220)
  		FaceFrontRightLEDOffset,    //!< head face side light (front right - blue) (ERS-220)
***************
*** 186,192 ****
  		TopBrLEDOffset = ModeLEDOffset,           //!< top bar (green) (ERS-210)
  	};
  	
! 	//! Bitmasks for use when specifying combinations of LEDs (see LEDEngine ) Note that L/R are robot's POV
  	//!@name LED Bitmasks
  	typedef unsigned int LEDBitMask_t; //!< So you can be clear when you're refering to a LED bitmask
  	const LEDBitMask_t FaceFrontLeftLEDMask   = 1<<(FaceFrontLeftLEDOffset-LEDOffset);
--- 186,192 ----
  		TopBrLEDOffset = ModeLEDOffset,           //!< top bar (green) (ERS-210)
  	};
  	
! 	//! Bitmasks for use when specifying combinations of LEDs (see LEDEngine ) Note that left/right are robot's point of view
  	//!@name LED Bitmasks
  	typedef unsigned int LEDBitMask_t; //!< So you can be clear when you're refering to a LED bitmask
  	const LEDBitMask_t FaceFrontLeftLEDMask   = 1<<(FaceFrontLeftLEDOffset-LEDOffset);
***************
*** 535,541 ****
  #define __RI_RAD_FLAG
  #endif
  
! 	//! Defines the min and max index of entries in #outputRanges and #mechanicalLimits
  	enum MinMaxRange_t { MinRange,MaxRange };
  
  	//! This table holds the software limits of each of the outputs
--- 535,541 ----
  #define __RI_RAD_FLAG
  #endif
  
! 	//! Defines the indexes to use to access the min and max entries of ERS2xxInfo::outputRanges and ERS2xxInfo::mechanicalLimits
  	enum MinMaxRange_t { MinRange,MaxRange };
  
  	//! This table holds the software limits of each of the outputs
***************
*** 604,613 ****
   * @author Daishi MORI (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
--- 604,613 ----
   * @author Daishi MORI (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
Index: Tekkotsu/Shared/ERS7Info.h
diff -c Tekkotsu/Shared/ERS7Info.h:1.8 Tekkotsu/Shared/ERS7Info.h:1.9
*** Tekkotsu/Shared/ERS7Info.h:1.8	Tue Jan 20 22:53:01 2004
--- Tekkotsu/Shared/ERS7Info.h	Mon Feb  9 17:45:28 2004
***************
*** 22,32 ****
  
  	const unsigned int FrameTime=8;        //!< time between frames in the motion system (milliseconds)
  	const unsigned int NumFrames=4;        //!< the number of frames per buffer (don't forget also double buffered)
! 	const unsigned int SlowFrameTime=128;  //!< time between frames for the ears (which move slower for some reason, don't want to mix with other outputs) (milliseconds)
! 	const unsigned int NumSlowFrames=1;    //!< the number of frames per buffer being sent to ears (double buffered as well)
  	const unsigned int SoundBufferTime=32; //!< the number of milliseconds per sound buffer... I'm not sure if this can be changed
  	
! 	//!Corresponds to entries in PrimitiveName, defined at the end of this file, these are the primary grouping
  	/*!Right now all binary joints are slow, but perhaps this won't always be the case... hence the IsFast/Slow bitmasks to select which type, in order to be more general */
  	//!@name Output Types Information
  	const unsigned NumPIDJoints   = 18; //!< The number of joints which use PID motion - everything except ears
--- 22,32 ----
  
  	const unsigned int FrameTime=8;        //!< time between frames in the motion system (milliseconds)
  	const unsigned int NumFrames=4;        //!< the number of frames per buffer (don't forget also double buffered)
! 	const unsigned int SlowFrameTime=8;  //!< time between frames for the ears (ERS-7 doesn't seem to have any "slow" joints; this only applied for the ears on the ERS-210)
! 	const unsigned int NumSlowFrames=4;    //!< the number of frames per buffer being sent to ears (double buffered as well)
  	const unsigned int SoundBufferTime=32; //!< the number of milliseconds per sound buffer... I'm not sure if this can be changed
  	
! 	//!Corresponds to entries in ERS7Info::PrimitiveName, defined at the end of this file, these are the primary grouping
  	/*!Right now all binary joints are slow, but perhaps this won't always be the case... hence the IsFast/Slow bitmasks to select which type, in order to be more general */
  	//!@name Output Types Information
  	const unsigned NumPIDJoints   = 18; //!< The number of joints which use PID motion - everything except ears
***************
*** 55,62 ****
  	const unsigned NumTailJoints  =  2; //!< The number of joints assigned to the tail
  	const unsigned NumMouthJoints =  1; //!< the number of joints that control the mouth
  	const unsigned NumEarJoints   =  2; //!< The number of joints which control the ears (NOT per ear, is total)
! 	const unsigned NumButtons     =  2+4+3+1; //!< the number of buttons that are available, 2 head, 4 paws, 3 back, 1 underbelly see ButtonOffset_t
! 	const unsigned NumSensors     =  3+3+5;  //!< 3 IR (distance), 3 accel (force), 5 from power, see SensorOffset_t
  	
  
  	// *******************************
--- 55,62 ----
  	const unsigned NumTailJoints  =  2; //!< The number of joints assigned to the tail
  	const unsigned NumMouthJoints =  1; //!< the number of joints that control the mouth
  	const unsigned NumEarJoints   =  2; //!< The number of joints which control the ears (NOT per ear, is total)
! 	const unsigned NumButtons     =  2+4+3+1; //!< the number of buttons that are available, 2 head, 4 paws, 3 back, 1 underbelly see ERS7Info::ButtonOffset_t
! 	const unsigned NumSensors     =  3+3+5;  //!< 3 IR (distance), 3 accel (force), 5 from power, see ERS7Info::SensorOffset_t
  	
  
  	// *******************************
***************
*** 64,70 ****
  	// *******************************
  
  
! 	//!Corresponds to entries in PrimitiveName, defined at the end of this file
  	//!@name Output Offsets
  
  	const unsigned PIDJointOffset = 0; //!< The beginning of the PID Joints
--- 64,70 ----
  	// *******************************
  
  
! 	//!Corresponds to entries in ERS7Info::PrimitiveName, defined at the end of this file
  	//!@name Output Offsets
  
  	const unsigned PIDJointOffset = 0; //!< The beginning of the PID Joints
***************
*** 88,94 ****
  	
  	//@}
  	
! 	//! The offsets of the individual LEDs on the head and tail.  Note that L/R are robot's POV.  See also LEDBitMask_t
  	enum LEDOffset_t {
  		HeadColorLEDOffset = LEDOffset,
  		HeadWhiteLEDOffset,
--- 88,94 ----
  	
  	//@}
  	
! 	//! The offsets of the individual LEDs on the head and tail.  Note that left/right are robot's point of view.  See also LEDBitMask_t
  	enum LEDOffset_t {
  		HeadColorLEDOffset = LEDOffset,
  		HeadWhiteLEDOffset,
***************
*** 117,123 ****
  		TlBluLEDOffset= FrBackColorLEDOffset //!< blue tail light
  	};
  	
! 	//! Bitmasks for use when specifying combinations of LEDs (see LEDEngine ) Note that L/R are robot's POV
  	//!@name LED Bitmasks
  	typedef unsigned int LEDBitMask_t; //!< So you can be clear when you're refering to a LED bitmask
  	
--- 117,123 ----
  		TlBluLEDOffset= FrBackColorLEDOffset //!< blue tail light
  	};
  	
! 	//! Bitmasks for use when specifying combinations of LEDs (see LedEngine ) Note that left/right are robot's point of view
  	//!@name LED Bitmasks
  	typedef unsigned int LEDBitMask_t; //!< So you can be clear when you're refering to a LED bitmask
  	
***************
*** 408,414 ****
  	#define __RI_RAD_FLAG
  	#endif
  	
! 	//! Defines the min and max index of entries in #outputRanges and #mechanicalLimits
  	enum MinMaxRange_t { MinRange,MaxRange };
  
  	//! This table holds the software limits of each of the outputs
--- 408,414 ----
  	#define __RI_RAD_FLAG
  	#endif
  	
! 	//! Defines the indexes to use to access the min and max entries of ERS7Info::outputRanges and ERS7Info::mechanicalLimits
  	enum MinMaxRange_t { MinRange,MaxRange };
  
  	//! This table holds the software limits of each of the outputs
***************
*** 459,465 ****
  
  
  	/*! @name CPC IDs
! 	 * values defined by OPEN-R, used to interface with lower level OPEN-R code to read sensors - DOESN'T correspond to ::PrimitiveName */
  	static const int CPCJointMouth      =  0; //!< Mouth                           
  	static const int CPCSwitchChin      =  1; //!< Chin sensor                     
  	static const int CPCJointNeckNod    =  2; //!< Neck tilt2                      
--- 459,465 ----
  
  
  	/*! @name CPC IDs
! 	 * values defined by OPEN-R, used to interface with lower level OPEN-R code to read sensors - DOESN'T correspond to ERS7Info::PrimitiveName */
  	static const int CPCJointMouth      =  0; //!< Mouth                           
  	static const int CPCSwitchChin      =  1; //!< Chin sensor                     
  	static const int CPCJointNeckNod    =  2; //!< Neck tilt2                      
***************
*** 503,512 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
--- 503,512 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
Index: Tekkotsu/Shared/MutexLock.h
diff -c Tekkotsu/Shared/MutexLock.h:1.8 Tekkotsu/Shared/MutexLock.h:1.9
*** Tekkotsu/Shared/MutexLock.h:1.8	Thu Sep 25 11:31:53 2003
--- Tekkotsu/Shared/MutexLock.h	Thu Feb 12 12:48:59 2004
***************
*** 18,26 ****
   *  same time.  Also, by using a template parameter, all data structures are
   *  contained within the class's memory allocation, so no pointers are involved.
   *
!  *  Locks in this class can be recursive.  If you lock 5 times and then unlock()
!  *  once, the lock is released.  If you want to have releases match locks, call
!  *  release() instead of unlock().
   *
   *  Note that there is no check that the process doing the unlocking is the one
   *  that actually has the lock.  Be careful about this.
--- 18,30 ----
   *  same time.  Also, by using a template parameter, all data structures are
   *  contained within the class's memory allocation, so no pointers are involved.
   *
!  *  Locks in this class can be recursive or non-recursive, depending
!  *  whether you call release() or unlock().  If you lock 5 times, then
!  *  you should call release() 5 times as well before it will be
!  *  unlocked.  However, if you lock 5 times, just one call to unlock()
!  *  will undo all 5 levels of locking.
!  *
!  *  Just remember, release() releases one level.  But unlock() completely unlocks.
   *
   *  Note that there is no check that the process doing the unlocking is the one
   *  that actually has the lock.  Be careful about this.
***************
*** 256,265 ****
   * @author ejt (Creator), Edward A. Lycklama, Vassos Hadzilacos (paper from which this was based)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
!  * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
--- 260,269 ----
   * @author ejt (Creator), Edward A. Lycklama, Vassos Hadzilacos (paper from which this was based)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
!  * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
Index: Tekkotsu/Shared/ReferenceCounter.h
diff -c Tekkotsu/Shared/ReferenceCounter.h:1.5 Tekkotsu/Shared/ReferenceCounter.h:1.6
*** Tekkotsu/Shared/ReferenceCounter.h:1.5	Thu Aug 21 18:33:00 2003
--- Tekkotsu/Shared/ReferenceCounter.h	Mon Feb  9 17:45:28 2004
***************
*** 23,31 ****
  			std::cout << "*** WARNING RefCounter was deleted with " << references << " references" << std::endl;
  	}
  
! 	//! adds one to references
  	virtual void AddReference() { references++; }
! 	//! subtracts one from references AND DELETES the object IF ZERO
  	virtual void RemoveReference() {
  		if(--references==0) {
  			if(RC_autodelete)
--- 23,31 ----
  			std::cout << "*** WARNING RefCounter was deleted with " << references << " references" << std::endl;
  	}
  
! 	//! adds one to #references
  	virtual void AddReference() { references++; }
! 	//! subtracts one from #references AND DELETES the object IF ZERO
  	virtual void RemoveReference() {
  		if(--references==0) {
  			if(RC_autodelete)
***************
*** 37,43 ****
  	/*! @return references */
  	virtual unsigned int GetReferences() { return references; }
  
! 	//! if true, next time a RemoveReference() causes references to hit 0, the object will delete itself
  	void SetAutoDelete(bool b) {RC_autodelete=b;}
  
  	bool GetAutoDelete() { return RC_autodelete; } //!< returns RC_autodelete
--- 37,43 ----
  	/*! @return references */
  	virtual unsigned int GetReferences() { return references; }
  
! 	//! if true, next time a RemoveReference() causes #references to hit 0, the object will delete itself
  	void SetAutoDelete(bool b) {RC_autodelete=b;}
  
  	bool GetAutoDelete() { return RC_autodelete; } //!< returns RC_autodelete
***************
*** 46,52 ****
  	//! the current number of references
  	unsigned int references;
  
! 	//! prevents deletion when counter hits 0
  	bool RC_autodelete;
  };
  
--- 46,52 ----
  	//! the current number of references
  	unsigned int references;
  
! 	//! if false, prevents deletion when counter hits 0
  	bool RC_autodelete;
  };
  
***************
*** 73,82 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
!  * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
--- 73,82 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
!  * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
Index: Tekkotsu/Shared/RobotInfo.h
diff -c Tekkotsu/Shared/RobotInfo.h:1.14 Tekkotsu/Shared/RobotInfo.h:1.15
*** Tekkotsu/Shared/RobotInfo.h:1.14	Tue Dec 23 01:33:43 2003
--- Tekkotsu/Shared/RobotInfo.h	Mon Feb  9 17:45:28 2004
***************
*** 19,25 ****
  /*! This is just a wrapper for whichever namespace corresponds to the current
   *  robot target setting (one of TGT_ERS210, TGT_ERS220, TGT_ERS7, or the default, TGT_ERS2xx)
   *
!  *  You probably should look at ERS210Info, ERS220Info, or ERS2xxInfo for the actual
   *  constants used for each model. */
  namespace RobotInfo {
  
--- 19,25 ----
  /*! This is just a wrapper for whichever namespace corresponds to the current
   *  robot target setting (one of TGT_ERS210, TGT_ERS220, TGT_ERS7, or the default, TGT_ERS2xx)
   *
!  *  You probably should look at ERS210Info, ERS220Info, ERS2xxInfo, or ERS7Info for the actual
   *  constants used for each model. */
  namespace RobotInfo {
  
***************
*** 41,50 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
--- 41,50 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
Index: Tekkotsu/Shared/WorldState.h
diff -c Tekkotsu/Shared/WorldState.h:1.24 Tekkotsu/Shared/WorldState.h:1.25
*** Tekkotsu/Shared/WorldState.h:1.24	Mon Jan 19 15:36:48 2004
--- Tekkotsu/Shared/WorldState.h	Mon Feb  9 17:45:28 2004
***************
*** 19,55 ****
  
  //The following SourceIDs are for events created by WorldState's event generators
  
! //! holds source ID types for sensor events; see EventBase, see SensorSourceID_t
  namespace SensorSourceID {
  	//! holds source ID types for sensor events
  	enum SensorSourceID_t {
- 		//may want to add a proximity alarm for IR distance?
- 		//probably should do it from a separate generator to avoid
- 		//screwing up behaviors relying on the current setup
  		UpdatedSID //!< sends status event as last event after processing a frame
  	};
  }
  
! //! holds source ID types for power events; see EventBase, see PowerSourceID_t
  namespace PowerSourceID {
  	//! holds source ID types for power events
! 	/*! Also serve as offsets into ::powerFlags[]
! 	 *  I've never seen a lot of these events thrown by the OS.  NS means never-seen, which
! 	 *  could simply be because i haven't put it in that situation (don't have a station-type power
! 	 *  charger) or because the OS doesn't actually support sending that flag.
  	 *
! 	 *  Under normal conditions, you'll see MotorPowerSID, BatteryConnectSID, DischargingSID, and
! 	 *  PowerGoodSID always active with occasional VibrationSID and UpdateSID. When the chest
! 	 *  button is pushed, PauseSID is activated and MotorPowerSID is deactivated.
  	 *
! 	 *  The BatteryMonitorBehavior will give a warning once power begins getting low.  The OS won't
! 	 *  boot off a battery with less than 15% power remaining (which is when the LowPowerWarnSID is
! 	 *  thrown)
  	 *
! 	 *  @note there's not a one-to-one correspondance of the events from the
! 	 *  OPENR power system... i map several OPENR events to fewer Tekkotsu events, check the name
! 	 *  if you want to know the specific source (say if low battery is low current and/or low voltage)
! 	 *  Status ETIDS are only generated when one of a related group goes on/off but others are still active*/
  	enum PowerSourceID_t {
  		PauseSID=0, //!< the chest button was pushed (this is not a normal button, it kills power to the motors in hardware)
  		MotorPowerSID, //!< active while the motors have power
--- 19,63 ----
  
  //The following SourceIDs are for events created by WorldState's event generators
  
! //! holds source ID types for sensor events; see EventBase, see #SensorSourceID_t
  namespace SensorSourceID {
  	//! holds source ID types for sensor events
+ 	/*! May want to add a proximity alarm for IR distance?  Probably
+ 	 *  should do it from a separate generator to avoid screwing up
+ 	 *  behaviors relying on the current setup
+ 	 */
  	enum SensorSourceID_t {
  		UpdatedSID //!< sends status event as last event after processing a frame
  	};
  }
  
! //! holds source ID types for power events; see EventBase, see #PowerSourceID_t
  namespace PowerSourceID {
  	//! holds source ID types for power events
! 	/*! Also serve as offsets into WorldState::powerFlags[].
  	 *
! 	 *  I've never seen a lot of these events thrown by the OS.  'NS'
! 	 *  means never-seen, which could simply be because i haven't put it
! 	 *  in that situation (don't have a station-type power charger) or
! 	 *  because the OS doesn't actually support sending that flag.
  	 *
! 	 *  Under normal conditions, you'll see MotorPowerSID,
! 	 *  BatteryConnectSID, DischargingSID, and PowerGoodSID always
! 	 *  active with occasional VibrationSID and UpdateSID.  When the
! 	 *  chest button is pushed, PauseSID is activated and MotorPowerSID
! 	 *  is deactivated.
  	 *
! 	 *  The BatteryMonitorBehavior will give a warning once power begins
! 	 *  getting low.  The OS won't boot off a battery with less than 15%
! 	 *  power remaining (which is when the LowPowerWarnSID is thrown)
! 	 *
! 	 *  @note there's not a one-to-one correspondance of the events from
! 	 *  the OPENR power system... i map several OPENR events to fewer
! 	 *  Tekkotsu events, check the event's name if you want to know the
! 	 *  specific source (say if low battery is low current and/or low
! 	 *  voltage) Status ETIDS are only generated when one of a related
! 	 *  group goes on/off but others are still active
! 	 */
  	enum PowerSourceID_t {
  		PauseSID=0, //!< the chest button was pushed (this is not a normal button, it kills power to the motors in hardware)
  		MotorPowerSID, //!< active while the motors have power
***************
*** 79,101 ****
  		SpecialModeSID, //!< ? NS
  		BMNDebugModeSID, //!< ? NS
  		PlungerSID, //!< I think this is in reference to having a memorystick (?) NS
! 		UpdatedSID, //!<sent as last event after processing a frame
  		NumPowerSIDs
  	};
  }
  	
  //! The state of the robot and its environment
! /* Contains sensor readings, current joint positions, etc.\n
!  * This is a shared memory region between MainObj, MotoObj, and possibly others in the future\n
!  * Be very careful about including structures that use pointers in this class... they will only be valid
!  * from the OObject that created them, others may cause a crash if they try to access them.
   *
!  * WorldState takes power and sensor updates from the system and maintains the last known
!  * values in its member fields.  It throws events when some of these values change, listed in
!  * the ButtonSourceID, SensorSourceID, and PowerSourceID namespaces.
   *
!  * Status events for buttons are always generated unless the WorldState::alwaysGenerateStatus flag
!  * is turned off, in which case they are only generated when a value has changed (the top head buttons)
   */
  class WorldState {
  public:
--- 87,115 ----
  		SpecialModeSID, //!< ? NS
  		BMNDebugModeSID, //!< ? NS
  		PlungerSID, //!< I think this is in reference to having a memorystick (?) NS
! 		UpdatedSID, //!< sent as last event after processing a frame
  		NumPowerSIDs
  	};
  }
  	
  //! The state of the robot and its environment
! /*! Contains sensor readings, current joint positions, etc.\n
!  * This is a shared memory region between MainObj, MotoObj, and possibly others in the future
!  *
!  * Be very careful about including structures that use pointers in
!  * this class... they will only be valid from the OObject that created
!  * them, others may cause a crash if they try to access them.
   *
!  * WorldState takes power and sensor updates from the system and
!  * maintains the last known values in its member fields.  It throws
!  * events when some of these values change, listed in the
!  * ButtonSourceID, SensorSourceID, and PowerSourceID namespaces.
   *
!  * Status events for buttons only generated if the
!  * WorldState::alwaysGenerateStatus flag is turned on, otherwise, by
!  * default, they are only generated when a value has changed
!  * (i.e. when the pressure sensitive buttons get a new pressure
!  * reading)
   */
  class WorldState {
  public:
***************
*** 104,123 ****
  
  	bool alwaysGenerateStatus; //!< controls whether status events are generated for the boolean buttons
  
! 	float outputs[NumOutputs];     //!< last sensed positions of joints, for ears, x<.5 is up, x>=.5 is down
! 	float buttons[NumButtons];     //!< magnitude is pressure for some, 0/1 for others
! 	float sensors[NumSensors];     //!< IR, Accel, Thermo, Power stuff
! 	float pids[NumPIDJoints][3];   //!< current PID settings
! 	float pidduties[NumPIDJoints]; //!< duty cycles - -1 means the motor is trying to move full power in negative direction, 1 means full power in positive direction, in practice, these values stay rather small - 0.15 is significant force.
  	
! 	float vel_x; //!< the current, egocentric rate of forward travel
! 	float vel_y; //!< the current, egocentric rate of sideways (leftward is positive) travel
! 	float vel_a; //!< the current, egocentric rate of rotational (counterclockwise is positive) travel
  	unsigned int vel_time; //!< the time at which we began moving along the current velocity vector
  
  	unsigned int robotStatus;       //!< bitmask, see OPENR/OPower.h
  	unsigned int batteryStatus;     //!< bitmask, see OPENR/OPower.h
! 	unsigned int powerFlags[PowerSourceID::NumPowerSIDs]; //!< bitmasks of similarly-grouped items from previous two masks, corresponds to the PowerSourceID_t's
  
  	unsigned int button_times[NumButtons]; //!< value is time of current press, 0 if not down
  	
--- 118,137 ----
  
  	bool alwaysGenerateStatus; //!< controls whether status events are generated for the boolean buttons
  
! 	float outputs[NumOutputs];     //!< last sensed positions of joints, for ears (or other future "boolean joints"), x<.5 is up, x>=.5 is down; indexes (aka offsets) are defined in the target model's namespace (e.g. ERS210Info)
! 	float buttons[NumButtons];     //!< magnitude is pressure for some, 0/1 for others; indexes are defined in the ButtonOffset_t of the target model's namespace (e.g. ERS210Info::ButtonOffset_t)
! 	float sensors[NumSensors];     //!< IR, Accel, Thermo, Power stuff; indexes are defined in SensorOffset_t of the target model's namespace (e.g. ERS210Info::SensorOffset_t)
! 	float pids[NumPIDJoints][3];   //!< current PID settings (same ordering as the #outputs)
! 	float pidduties[NumPIDJoints]; //!< duty cycles - -1 means the motor is trying to move full power in negative direction, 1 means full power in positive direction, in practice, these values stay rather small - 0.15 is significant force. (same ordering as the #outputs)
  	
! 	float vel_x; //!< the current, egocentric rate of forward locomotion
! 	float vel_y; //!< the current, egocentric rate of sideways (leftward is positive) locomotion
! 	float vel_a; //!< the current, egocentric rate of rotational (counterclockwise is positive) locomotion
  	unsigned int vel_time; //!< the time at which we began moving along the current velocity vector
  
  	unsigned int robotStatus;       //!< bitmask, see OPENR/OPower.h
  	unsigned int batteryStatus;     //!< bitmask, see OPENR/OPower.h
! 	unsigned int powerFlags[PowerSourceID::NumPowerSIDs]; //!< bitmasks of similarly-grouped items from previous two masks, corresponds to the PowerSourceID::PowerSourceID_t's
  
  	unsigned int button_times[NumButtons]; //!< value is time of current press, 0 if not down
  	
***************
*** 135,150 ****
  #endif
  
  	//! bitmask corresponding to OPENR::GetRobotDesign()
! 	/*! This allows you to efficiently test different combinations, like any
! 	 *  2x0 model vs. any 7 model or any 3xx model (when/if the 3xx's are supported).\n
! 	 *  Testing this will give more accurate feedback as to whether features
! 	 *  exist than checking RobotInfo values - to achieve dual booting, RobotInfo
! 	 *  may, for instance, tell you there are two ears, but if you're running on a
! 	 *  220 the value you set them to will be ignored */
  	unsigned int robotDesign;  
! 	static const unsigned int ERS210Mask=1<<0;  //!< use this to test for ERS210 features
! 	static const unsigned int ERS220Mask=1<<1;  //!< use this to test for ERS220 features
! 	static const unsigned int ERS7Mask=1<<2;  //!< use this to test for ERS220 features
  
  protected:
  	unsigned int curtime; //!< set by read(OSensorFrameVectorData& sensor, EventRouter* er) for chkEvent() so each call doesn't have to
--- 149,167 ----
  #endif
  
  	//! bitmask corresponding to OPENR::GetRobotDesign()
! 	/*! This allows you to efficiently test different combinations, like
! 	 *  any 2x0 model vs. any 7 model or any 3xx model (when/if the
! 	 *  3xx's are supported).
! 	 *
! 	 *  Testing this will give more accurate feedback as to whether
! 	 *  features exist than checking RobotInfo values - to achieve dual
! 	 *  booting, RobotInfo may, for instance, tell you there are two
! 	 *  ears, but if you're running on a 220 the value you set them to
! 	 *  will be ignored */
  	unsigned int robotDesign;  
! 	static const unsigned int ERS210Mask=1<<0;  //!< use this to test for ERS-210 features
! 	static const unsigned int ERS220Mask=1<<1;  //!< use this to test for ERS-220 features
! 	static const unsigned int ERS7Mask=1<<2;  //!< use this to test for ERS-7 features
  
  protected:
  	unsigned int curtime; //!< set by read(OSensorFrameVectorData& sensor, EventRouter* er) for chkEvent() so each call doesn't have to
***************
*** 153,159 ****
  	void chkEvent(EventRouter* er, unsigned int off, float newval, const char* name);
  
  	//! sets the names of the flags that will be generating events
! 	/*! note that this function does not actually do the event posting */
  	void chkPowerEvent(unsigned int sid, unsigned int cur, unsigned int mask, const char* name, 
  										 std::string actname[PowerSourceID::NumPowerSIDs],
  										 std::string dename[PowerSourceID::NumPowerSIDs],
--- 170,177 ----
  	void chkEvent(EventRouter* er, unsigned int off, float newval, const char* name);
  
  	//! sets the names of the flags that will be generating events
! 	/*! note that this function does not actually do the event posting,
! 	 *  unlike chkEvent() */
  	void chkPowerEvent(unsigned int sid, unsigned int cur, unsigned int mask, const char* name, 
  										 std::string actname[PowerSourceID::NumPowerSIDs],
  										 std::string dename[PowerSourceID::NumPowerSIDs],
***************
*** 192,201 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
--- 210,219 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
Index: Tekkotsu/SoundPlay/SoundManager.h
diff -c Tekkotsu/SoundPlay/SoundManager.h:1.10 Tekkotsu/SoundPlay/SoundManager.h:1.11
*** Tekkotsu/SoundPlay/SoundManager.h:1.10	Sun Jan 18 05:16:58 2004
--- Tekkotsu/SoundPlay/SoundManager.h	Mon Feb  9 17:45:28 2004
***************
*** 16,33 ****
  class ONotifyEvent;
  
  //! Provides sound effects and caching services, as well as mixing buffers for the SoundPlay process
! /*! Provides easy methods for playing back sounds, either from files on the memory stick,
!  *  or from dynamically generated buffers.  You can chain playback commands so that when
!  *  one sound finishes, another picks up automatically.  This might be handy if, say, someone
!  *  wants to write an MP3 player ;)  The sounds would be too large to load into memory all at
!  *  once, but you could load a block at a time and chain them so it seamlessly moves from one
!  *  to the other.
   *  
!  *  All functions will attempt to lock the SoundManager.
   *
!  *  @todo Volume control, variable playback speed, support more wav file formats (all go together)
   *  
!  *  @todo Add functions to hand out regions to be filled out to avoid copying into the buffer.
   */
  class SoundManager {
  public:
--- 16,52 ----
  class ONotifyEvent;
  
  //! Provides sound effects and caching services, as well as mixing buffers for the SoundPlay process
! /*! Provides easy methods for playing back sounds, either from files
!  *  on the memory stick, or from dynamically generated buffers.  You
!  *  can chain playback commands so that when one sound finishes,
!  *  another picks up automatically.  This might be handy if, say,
!  *  someone wants to write an MP3 player ;) The sounds would be too
!  *  large to load into memory all at once, but you could load a block
!  *  at a time and chain them so it seamlessly moves from one to the
!  *  other.
   *  
!  *  You can also preload sounds (LoadFile()) before playing them so
!  *  there's no delay while loading after you request a sound to be
!  *  played.  Just be sure to release the file (ReleaseFile()) again
!  *  when you're done with it ;)
   *
!  *  All functions will attempt to lock the SoundManager.  Remember,
!  *  this is running in a shared memory region, accessible by the
!  *  SoundPlay process and both the Main and Motion processes (so
!  *  MotionCommands can play sounds!)
!  *
!  *  One could be tempted to draw parallels to the MotionManager, and
!  *  envision a system with SoundCommands that are handed over and can
!  *  dynamically compute sound buffers as needed.  If you have the time
!  *  and inclination, the job's all yours... (Midi players, speech
!  *  synthesizer, ...?)
!  *
!  *  @todo Volume control, variable playback speed, support more wav
!  *  file formats (latter two are the same thing if you think about it
!  *  - need to be able to resample on the fly)
   *  
!  *  @todo Add functions to hand out regions to be filled out to avoid
!  *  copying into the buffer.
   */
  class SoundManager {
  public:
***************
*** 232,241 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
--- 251,260 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
Index: Tekkotsu/Vision/BallDetectionGenerator.h
diff -c Tekkotsu/Vision/BallDetectionGenerator.h:1.3 Tekkotsu/Vision/BallDetectionGenerator.h:1.4
*** Tekkotsu/Vision/BallDetectionGenerator.h:1.3	Sun Jan 18 05:16:58 2004
--- Tekkotsu/Vision/BallDetectionGenerator.h	Mon Feb  9 17:45:28 2004
***************
*** 7,17 ****
  class FilterBankEvent;
  
  //! Uses segmented color region information to detect round objects
! /*! This expects its events to come from a BallDetectionGenerator (or
!  *  its subclass)
   *  
!  *  Sends an event only for the largest ball found.
   *
   */
  class BallDetectionGenerator : public EventGeneratorBase {
  public:
--- 7,24 ----
  class FilterBankEvent;
  
  //! Uses segmented color region information to detect round objects
! /*! This expects its events to come from a RegionGenerator (or a
!  *  compatable subclass)
   *  
!  *  Sends a VisionObjectEvent only for the largest ball found (if one
!  *  @e is found)
   *
+  *  You can set the index of the color of the ball to look for in the
+  *  constructor, so you can have several of these running looking for
+  *  balls of different colors.
+  *
+  *  This is one of our oldest code segments, and has been hacked on a
+  *  lot, so apologies for a bit of a mess...
   */
  class BallDetectionGenerator : public EventGeneratorBase {
  public:
***************
*** 82,91 ****
   * reviewed the code, so I guess it's all ours...
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
--- 89,98 ----
   * reviewed the code, so I guess it's all ours...
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
Index: Tekkotsu/Vision/CDTGenerator.cc
diff -c Tekkotsu/Vision/CDTGenerator.cc:1.5 Tekkotsu/Vision/CDTGenerator.cc:1.6
*** Tekkotsu/Vision/CDTGenerator.cc:1.5	Sun Jan 18 05:16:59 2004
--- Tekkotsu/Vision/CDTGenerator.cc	Wed Feb 18 16:13:32 2004
***************
*** 12,25 ****
  #include "Shared/debuget.h"
  
  CDTGenerator::CDTGenerator(unsigned int numRawLayers, unsigned int numCalcLayers, EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid)
! 	: FilterBankGenerator("CDTGenerator",numCalcLayers,NUM_CHANNELS,gid,sid,EventBase::visSegmentEGID,mysid), numRealLayers(numRawLayers), layers(NULL), imageInfos(NULL)
  {
! 	setNumImages(numLayers,numChannels);
! }
! 
! CDTGenerator::~CDTGenerator() {
! 	freeCaches();
! 	destruct();
  }
  
  /*! The const casts in this function are regretable but necessary
--- 12,20 ----
  #include "Shared/debuget.h"
  
  CDTGenerator::CDTGenerator(unsigned int numRawLayers, unsigned int numCalcLayers, EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid)
! 	: FilterBankGenerator("CDTGenerator",gid,sid,EventBase::visSegmentEGID,mysid), numRealLayers(numRawLayers), layers(NULL), imageInfos(NULL)
  {
! 	setNumImages(numCalcLayers,NUM_CHANNELS);
  }
  
  /*! The const casts in this function are regretable but necessary
***************
*** 153,158 ****
--- 148,155 ----
  
  void
  CDTGenerator::setNumImages(unsigned int nLayers, unsigned int nChannels) {
+ 	if(nLayers==numLayers && nChannels==numChannels)
+ 		return;
  	FilterBankGenerator::setNumImages(nLayers,nChannels);
  	layers=new unsigned char*[numLayers];
  	imageInfos=new const OFbkImageInfo*[numLayers];
***************
*** 236,244 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
--- 233,241 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
Index: Tekkotsu/Vision/CDTGenerator.h
diff -c Tekkotsu/Vision/CDTGenerator.h:1.2 Tekkotsu/Vision/CDTGenerator.h:1.3
*** Tekkotsu/Vision/CDTGenerator.h:1.2	Sun Jan 18 05:16:59 2004
--- Tekkotsu/Vision/CDTGenerator.h	Wed Feb 18 16:13:32 2004
***************
*** 47,54 ****
  	CDTGenerator(unsigned int numRawLayers, unsigned int numCalcLayers, EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid);
  
  	//! destructor
! 	virtual ~CDTGenerator();
! 
  	static std::string getClassDescription() { return "Extracts the segmented image channel (CDT) from the system's OFbkImageVectorData"; }
  
  	//! holds id values for specifying image channel/bands
--- 47,57 ----
  	CDTGenerator(unsigned int numRawLayers, unsigned int numCalcLayers, EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid);
  
  	//! destructor
! 	virtual ~CDTGenerator() {
! 		freeCaches();
! 		destruct();
! 	}
! 	
  	static std::string getClassDescription() { return "Extracts the segmented image channel (CDT) from the system's OFbkImageVectorData"; }
  
  	//! holds id values for specifying image channel/bands
***************
*** 94,103 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
--- 97,106 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
Index: Tekkotsu/Vision/FilterBankGenerator.cc
diff -c Tekkotsu/Vision/FilterBankGenerator.cc:1.5 Tekkotsu/Vision/FilterBankGenerator.cc:1.6
*** Tekkotsu/Vision/FilterBankGenerator.cc:1.5	Thu Feb  5 14:11:41 2004
--- Tekkotsu/Vision/FilterBankGenerator.cc	Wed Feb 18 16:13:32 2004
***************
*** 1,4 ****
--- 1,5 ----
  #include "FilterBankGenerator.h"
+ #include "Events/FilterBankEvent.h"
  #include "Events/EventRouter.h"
  
  unsigned char *
***************
*** 30,35 ****
--- 31,49 ----
  	    imageValids[i][j]=false;
  }
  
+ void
+ FilterBankGenerator::processEvent(const EventBase & event) {
+ 	const FilterBankEvent& fbkevent=dynamic_cast<const FilterBankEvent& >(event);
+ 	src=fbkevent.getSource();
+ 	frameNumber=src->getFrameNumber();
+ 	setNumImages(src->getNumLayers(),src->getNumChannels());
+ 	if(numLayers>0 && (src->getWidth(numLayers-1)!=getWidth(numLayers-1) || src->getHeight(numLayers-1)!=getHeight(numLayers-1))) {
+ 		ASSERT(widths[numLayers-1]==0,"Strange, the image dim changed after initial setting" << widths[numLayers-1] << ' ' << heights[numLayers-1]);
+ 		setDimensions();
+ 	}
+ 	invalidateCaches();
+ 	framesProcessed++;
+ }
  
  unsigned int FilterBankGenerator::getBinSize() const {
  	unsigned int used=0;
***************
*** 76,81 ****
--- 90,97 ----
  
  void
  FilterBankGenerator::setNumImages(unsigned int nLayers, unsigned int nChannels) {
+ 	if(nLayers==numLayers && nChannels==numChannels)
+ 		return;
  	freeCaches();
  	destruct();
  	numLayers=nLayers;
***************
*** 103,108 ****
--- 119,134 ----
  }
  
  void
+ FilterBankGenerator::setDimensions() {
+ 	if(src==NULL)
+ 		return;
+ 	for(unsigned int i=0; i<numLayers; i++) {
+ 		widths[i]=src->getWidth(i);
+ 		heights[i]=src->getHeight(i);
+ 	}
+ }
+ 
+ void
  FilterBankGenerator::destruct() {
  	delete [] widths;
  	widths=NULL;
***************
*** 132,140 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
--- 158,166 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
Index: Tekkotsu/Vision/FilterBankGenerator.h
diff -c Tekkotsu/Vision/FilterBankGenerator.h:1.12 Tekkotsu/Vision/FilterBankGenerator.h:1.13
*** Tekkotsu/Vision/FilterBankGenerator.h:1.12	Thu Feb  5 18:33:48 2004
--- Tekkotsu/Vision/FilterBankGenerator.h	Wed Feb 18 16:13:32 2004
***************
*** 111,143 ****
   */
  class FilterBankGenerator : public EventGeneratorBase, public LoadSave {
  public:
- 	//! constructor, calls setNumImages(1,1)
- 	FilterBankGenerator()
- 		: EventGeneratorBase(), numLayers(0), numChannels(0), widths(NULL), heights(NULL), skips(NULL), strides(NULL), increments(NULL), images(NULL), imageValids(NULL), selectedSaveLayer(0), selectedSaveChannel(0), frameNumber(0), framesProcessed(0)
- 	{
- 		setNumImages(1,1);
- 	}
- 
  	//! constructor
! 	FilterBankGenerator(unsigned int layers, unsigned int channels)
! 		: EventGeneratorBase(), numLayers(0), numChannels(0), widths(NULL), heights(NULL), skips(NULL), strides(NULL), increments(NULL), images(NULL), imageValids(NULL), selectedSaveLayer(0), selectedSaveChannel(0), frameNumber(0), framesProcessed(0)
! 	{
! 		setNumImages(layers,channels);
! 	}
  
  	//! constructor
! 	FilterBankGenerator(const std::string& name,unsigned int layers, unsigned int channels, EventBase::EventGeneratorID_t srcgid, unsigned int srcsid, EventBase::EventGeneratorID_t mgid, unsigned int msid)
! 		: EventGeneratorBase(name,mgid,msid,srcgid,srcsid), numLayers(0), numChannels(0), widths(NULL), heights(NULL), skips(NULL), strides(NULL), increments(NULL), images(NULL), imageValids(NULL), selectedSaveLayer(0), selectedSaveChannel(0), frameNumber(0), framesProcessed(0)
! 	{
! 		setNumImages(layers,channels);
! 	}
  
  	//! destructor
! 	~FilterBankGenerator() {
  		freeCaches();
  		destruct();
  	}
  
  	//! returns the number of image layers (e.g. different resolutions available)
  	virtual unsigned int getNumLayers() const { return numLayers; }
  
--- 111,145 ----
   */
  class FilterBankGenerator : public EventGeneratorBase, public LoadSave {
  public:
  	//! constructor
! 	FilterBankGenerator()
! 		: EventGeneratorBase(), src(NULL), numLayers(0), numChannels(0), widths(NULL), heights(NULL), skips(NULL), strides(NULL), increments(NULL), images(NULL), imageValids(NULL), selectedSaveLayer(0), selectedSaveChannel(0), frameNumber(0), framesProcessed(0)
! 	{	}
  
  	//! constructor
! 	FilterBankGenerator(const std::string& name,EventBase::EventGeneratorID_t srcgid, unsigned int srcsid, EventBase::EventGeneratorID_t mgid, unsigned int msid)
! 		: EventGeneratorBase(name,mgid,msid,srcgid,srcsid), src(NULL), numLayers(0), numChannels(0), widths(NULL), heights(NULL), skips(NULL), strides(NULL), increments(NULL), images(NULL), imageValids(NULL), selectedSaveLayer(0), selectedSaveChannel(0), frameNumber(0), framesProcessed(0)
! 	{ }
  
  	//! destructor
! 	/*! Your own subclasses should also have destructors which call
! 	 *  freeCaches() and destruct().  Otherwise, if you override these
! 	 *  functions to delete any custom memory you allocate, those
! 	 *  implementations won't be called by this destructor... a
! 	 *  destructor ignores virtual functions, only calls at its own
! 	 *  class level.\n
! 	 *  So it really doesn't matter if you aren't allocating any extra
! 	 *  memory other than what's in the image cache, but it's still good
! 	 *  form just in case you add stuff later so you won't forget and
! 	 *  leak memory everywhere */
! 	virtual ~FilterBankGenerator() {
  		freeCaches();
  		destruct();
  	}
  
+ 	//! returns the generator this is receiving its events from (or the last one anyway)
+ 	virtual const FilterBankGenerator * getSourceGenerator() const { return src; }
+ 
  	//! returns the number of image layers (e.g. different resolutions available)
  	virtual unsigned int getNumLayers() const { return numLayers; }
  
***************
*** 179,186 ****
  	/*! You probably want to call this right before you send the FilterBankEvent */
  	virtual void invalidateCaches();
  
! 	//! default implementation ignore events, just so you don't have to define it if you don't receive events
! 	virtual void processEvent(const EventBase & /*event*/) {}
  	
  	//!@name LoadSave interface
  
--- 181,195 ----
  	/*! You probably want to call this right before you send the FilterBankEvent */
  	virtual void invalidateCaches();
  
! 	//! default implementation does a few common housekeeping chores for you - probably should just take a look at its code
! 	/*! It doesn't throw any events for you - that's probably the main
! 	 *  reason you'd still want to override it\n
! 	 *  Also, if your class has a set number of layers or channels - for
! 	 *  instance, always 1 channel like InterleavedYUVGenerator, you
! 	 *  should override setNumImages() to enforce that constraint by
! 	 *  throwing away the appropriate argument and passing the your own
! 	 *  value to the superclass implementation.*/
! 	virtual void processEvent(const EventBase & event);
  	
  	//!@name LoadSave interface
  
***************
*** 208,216 ****
  	 *  some pubic accessor functions which call this.  In general, the
  	 *  included subclasses should be able to handle being resized, but
  	 *  there's no reason to do so since the system won't be changing
! 	 *  its available resolutions at run time. */
  	virtual void setNumImages(unsigned int nLayers, unsigned int nChannels);
  
  	//! create new image data storage area for the cache - this called by getImage() only when the corresponding entry in images is NULL
  	/*! You should return the pointer you want stored in images to be
  	 *  returned by any calls to getFirstRow.  Interpretation of the
--- 217,232 ----
  	 *  some pubic accessor functions which call this.  In general, the
  	 *  included subclasses should be able to handle being resized, but
  	 *  there's no reason to do so since the system won't be changing
! 	 *  its available resolutions at run time. 
! 	 *
! 	 *  The default implementation is a no-op if(numLayers==nLayers && numChannels==nChannels)
! 	 */
  	virtual void setNumImages(unsigned int nLayers, unsigned int nChannels);
  
+ 	//! resets width and height parameters to that of the #src
+ 	/*! You'll probably want to override this to also set #skip and #stride */
+ 	virtual void setDimensions();
+ 	
  	//! create new image data storage area for the cache - this called by getImage() only when the corresponding entry in images is NULL
  	/*! You should return the pointer you want stored in images to be
  	 *  returned by any calls to getFirstRow.  Interpretation of the
***************
*** 225,230 ****
--- 241,248 ----
  	//! deletes the arrays
  	virtual void destruct();
  
+ 	const FilterBankGenerator * src; //!< the generator of the last FilterBankEvent received
+ 
  	unsigned int numLayers;   //!< current number of layers available
  	unsigned int numChannels; //!< current number of channels available
  
***************
*** 252,258 ****
  	 *  up, so there's no way they can be processed.
  	 */
  	unsigned int frameNumber; 
! 	unsigned int framesProcessed; //!< subclasses should increment this any time they make a new filter bank available (probably by throwing an event)
  
  private:
  	FilterBankGenerator(const FilterBankGenerator& fbk); //!< don't call
--- 270,279 ----
  	 *  up, so there's no way they can be processed.
  	 */
  	unsigned int frameNumber; 
! 
! 	//! subclasses should increment this any time they make a new filter bank available
! 	/*! this is automatically incremented if you use the FilterBankGenerator::processEvent() */
! 	unsigned int framesProcessed; 
  
  private:
  	FilterBankGenerator(const FilterBankGenerator& fbk); //!< don't call
***************
*** 264,273 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
--- 285,294 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
Index: Tekkotsu/Vision/InterleavedYUVGenerator.cc
diff -c Tekkotsu/Vision/InterleavedYUVGenerator.cc:1.7 Tekkotsu/Vision/InterleavedYUVGenerator.cc:1.8
*** Tekkotsu/Vision/InterleavedYUVGenerator.cc:1.7	Fri Jan 16 02:39:50 2004
--- Tekkotsu/Vision/InterleavedYUVGenerator.cc	Wed Feb 18 16:13:32 2004
***************
*** 7,44 ****
  #include "Shared/debuget.h"
  
  InterleavedYUVGenerator::InterleavedYUVGenerator(EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid)
! 	: FilterBankGenerator("InterleavedYUVGenerator",0,1,gid,sid,EventBase::visInterleaveEGID,mysid), src(NULL), srcYChan(0), srcUChan(1), srcVChan(2)
! {
! 	setNumImages(numLayers,numChannels);
! }
  
  InterleavedYUVGenerator::InterleavedYUVGenerator(EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid, unsigned int syc, unsigned int suc, unsigned int svc)
! 	: FilterBankGenerator("InterleavedYUVGenerator",0,1,gid,sid,EventBase::visInterleaveEGID,mysid), src(NULL), srcYChan(syc), srcUChan(suc), srcVChan(svc)
! {
! 	setNumImages(numLayers,numChannels);
! }
! 
! /*
! InterleavedYUVGenerator::~InterleavedYUVGenerator() {
! 	freeCaches();
! 	destruct();
! }
! */
  
  void
  InterleavedYUVGenerator::processEvent(const EventBase& event) {
! 	const FilterBankEvent& fbkevent=dynamic_cast<const FilterBankEvent& >(event);
! 	src=fbkevent.getSource();
! 	frameNumber=src->getFrameNumber();
! 	if(src->getNumLayers()!=numLayers || src->getNumChannels()!=numChannels)
! 		setNumImages(src->getNumLayers(),1);
! 	if(src->getWidth(numLayers-1)!=getWidth(numLayers-1)) {
! 		ASSERT(widths[numLayers-1]==0,"Strange, the image width changed after initial setting" << widths[numLayers-1]);
! 		setDimensions();
! 	}
! 
! 	invalidateCaches();
! 	framesProcessed++;
  	erouter->postEvent(new FilterBankEvent(this,getGeneratorID(),getSourceID()));
  }
  
--- 7,22 ----
  #include "Shared/debuget.h"
  
  InterleavedYUVGenerator::InterleavedYUVGenerator(EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid)
! 	: FilterBankGenerator("InterleavedYUVGenerator",gid,sid,EventBase::visInterleaveEGID,mysid), srcYChan(0), srcUChan(1), srcVChan(2)
! { }
  
  InterleavedYUVGenerator::InterleavedYUVGenerator(EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid, unsigned int syc, unsigned int suc, unsigned int svc)
! 	: FilterBankGenerator("InterleavedYUVGenerator",gid,sid,EventBase::visInterleaveEGID,mysid), srcYChan(syc), srcUChan(suc), srcVChan(svc)
! { }
  
  void
  InterleavedYUVGenerator::processEvent(const EventBase& event) {
! 	FilterBankGenerator::processEvent(event);
  	erouter->postEvent(new FilterBankEvent(this,getGeneratorID(),getSourceID()));
  }
  
***************
*** 46,55 ****
  InterleavedYUVGenerator::getBinSize() const {
  	unsigned int used=FilterBankGenerator::getBinSize();
  	used+=strlen("InterleavedYUVImage")+LoadSave::stringpad;
- 	//if(selectedSaveChannel==CHAN_YUV)
  	used+=widths[selectedSaveLayer]*heights[selectedSaveLayer]*3;
- 	//else
- 	//used+=widths[selectedSaveLayer]*heights[selectedSaveLayer];
  	return used;
  }
  
--- 24,30 ----
***************
*** 66,72 ****
  		serr->printf("Unhandled image type for InterleavedYUVGenerator: %s",tmp.c_str());
  		return 0;
  	} else {
- 		//if(selectedSaveChannel==CHAN_YUV) {
  		used=widths[selectedSaveLayer]*heights[selectedSaveLayer]*3;
  		if(used>len)
  			return 0;
--- 41,46 ----
***************
*** 78,103 ****
  		memcpy(img,buf,used);
  		len-=used; buf+=used;
  		imageValids[selectedSaveLayer][selectedSaveChannel]=true;
- 		/*
- 		} else {
- 			used=widths[selectedSaveLayer]*heights[selectedSaveLayer];
- 			if(used>len)
- 				return 0;
- 			unsigned char* img=getImage(selectedSaveLayer,selectedSaveChannel);
- 			if(img==NULL)
- 				return 0;
- 			unsigned int inc=getIncrement(selectedSaveLayer);
- 			for(unsigned int y=0; y<heights[selectedSaveLayer]; y++) {
- 				unsigned char* const rowend=img+widths[selectedSaveLayer]*inc;
- 				while(img!=rowend) {
- 					*img=*buf++;
- 					img+=inc;
- 				}
- 				img+=getSkip(selectedSaveLayer);
- 			}
- 			len-=used; buf+=used;
- 		}
- 		*/
  		return origlen-len;	
  	}
  }
--- 52,57 ----
***************
*** 111,117 ****
  	if(0==(used=encode("InterleavedYUVImage",buf,len))) return 0;
  	len-=used; buf+=used;
  	
- 	//if(selectedSaveChannel==CHAN_YUV) {
  	used=widths[selectedSaveLayer]*heights[selectedSaveLayer]*3;
  	if(used>len)
  		return 0;
--- 65,70 ----
***************
*** 120,197 ****
  		return 0;
  	memcpy(buf,img,used);
  	len-=used;
- 	/*
- 	} else {
- 		used=widths[selectedSaveLayer]*heights[selectedSaveLayer];
- 		if(used>len)
- 			return 0;
- 		unsigned char* img=getImage(selectedSaveLayer,selectedSaveChannel);
- 		if(img==NULL)
- 			return 0;
- 		unsigned int inc=getIncrement(selectedSaveLayer);
- 		for(unsigned int y=0; y<heights[selectedSaveLayer]; y++) {
- 			unsigned char* const rowend=img+widths[selectedSaveLayer]*inc;
- 			while(img!=rowend) {
- 				*buf++=*img;
- 				img+=inc;
- 			}
- 			img+=getSkip(selectedSaveLayer);
- 		}
- 		len-=used; buf+=used;
- 	}
- 	*/
  	return origlen-len;
  }
  
- /*
- void 
- InterleavedYUVGenerator::freeCaches() {
- 	for(unsigned int i=0; i<numLayers; i++) {
- 		for(unsigned int j=0; j<numChannels-1; j++) {
- 			images[i][j]=NULL;
- 			imageValids[i][j]=false;
- 		}
- 	}
- 	FilterBankGenerator::freeCaches();
- }
- */
- 
  void
  InterleavedYUVGenerator::setDimensions() {
! 	for(unsigned int i=0; i<numLayers; i++) {
! 		widths[i]=src->getWidth(i);
! 		heights[i]=src->getHeight(i);
! 		skips[i]=0;
  		strides[i]=widths[i]*3;
- 	}	
  }
  
  void
  InterleavedYUVGenerator::setNumImages(unsigned int nLayers, unsigned int nChannels) {
! 	ASSERT(nChannels==1,"we can only handle a single channel...");
! 	FilterBankGenerator::setNumImages(nLayers,nChannels);
  	for(unsigned int res=0; res<numLayers; res++)
  		increments[res]=3;
  }
  
- /*
- unsigned char *
- InterleavedYUVGenerator::createImageCache(unsigned int layer, unsigned int chan) const {
- 	unsigned char* yuv=new unsigned char[widths[layer]*heights[layer]*3];
- 	for(unsigned int i=0; i<numChannels-1; i++) {
- 		ASSERT(images[layer][i]==NULL,"memory leak?");
- 		images[layer][i]=yuv+i;
- 	}
- 	ASSERT(images[layer][CHAN_YUV]==NULL,"memory leak?");
- 	images[layer][CHAN_YUV]=yuv;
- 	if(chan==CHAN_YUV) {
- 		return yuv;
- 	} else {
- 		return yuv+chan;
- 	}
- }
- */
- 
  unsigned char *
  InterleavedYUVGenerator::createImageCache(unsigned int layer, unsigned int /*chan*/) const {
  	return new unsigned char[widths[layer]*heights[layer]*3];
--- 73,97 ----
  		return 0;
  	memcpy(buf,img,used);
  	len-=used;
  	return origlen-len;
  }
  
  void
  InterleavedYUVGenerator::setDimensions() {
! 	FilterBankGenerator::setDimensions();
! 	for(unsigned int i=0; i<numLayers; i++)
  		strides[i]=widths[i]*3;
  }
  
  void
  InterleavedYUVGenerator::setNumImages(unsigned int nLayers, unsigned int nChannels) {
! 	if(nLayers==numLayers && nChannels==numChannels)
! 		return;
! 	FilterBankGenerator::setNumImages(nLayers,1);
  	for(unsigned int res=0; res<numLayers; res++)
  		increments[res]=3;
  }
  
  unsigned char *
  InterleavedYUVGenerator::createImageCache(unsigned int layer, unsigned int /*chan*/) const {
  	return new unsigned char[widths[layer]*heights[layer]*3];
***************
*** 227,235 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
--- 127,135 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
Index: Tekkotsu/Vision/InterleavedYUVGenerator.h
diff -c Tekkotsu/Vision/InterleavedYUVGenerator.h:1.10 Tekkotsu/Vision/InterleavedYUVGenerator.h:1.11
*** Tekkotsu/Vision/InterleavedYUVGenerator.h:1.10	Thu Feb  5 18:33:48 2004
--- Tekkotsu/Vision/InterleavedYUVGenerator.h	Wed Feb 18 16:13:32 2004
***************
*** 39,44 ****
--- 39,50 ----
  	//! constructor, you can pass which channels to interleave
  	InterleavedYUVGenerator(EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid, unsigned int syc, unsigned int suc, unsigned int svc);
  
+ 	//! destructor
+ 	virtual ~InterleavedYUVGenerator() {
+ 		freeCaches();
+ 		destruct();
+ 	}
+ 
  	static const unsigned int CHAN_YUV=0; //!< so you can refer to the YUV channel symbolically.
  
  	static std::string getClassDescription() { return "Converts a FilterBankGenerator's data into interleaved format"; }
***************
*** 54,64 ****
  
  protected:
  	virtual void setNumImages(unsigned int nLayers, unsigned int nChannels);
! 	virtual void setDimensions(); //!< resets width, height, skip and stride parameters
  	virtual unsigned char * createImageCache(unsigned int layer, unsigned int chan) const;
  	virtual void calcImage(unsigned int layer, unsigned int chan) const;
  
- 	const FilterBankGenerator * src; //!< the generator of the last FilterBankEvent received
  	unsigned int srcYChan; //!< the channel of the source's Y channel
  	unsigned int srcUChan; //!< the channel of the source's U channel
  	unsigned int srcVChan; //!< the channel of the source's V channel
--- 60,69 ----
  
  protected:
  	virtual void setNumImages(unsigned int nLayers, unsigned int nChannels);
! 	virtual void setDimensions(); //!< resets stride parameter (to correspond to width*3 from FilterBankGenerator::setDimensions())
  	virtual unsigned char * createImageCache(unsigned int layer, unsigned int chan) const;
  	virtual void calcImage(unsigned int layer, unsigned int chan) const;
  
  	unsigned int srcYChan; //!< the channel of the source's Y channel
  	unsigned int srcUChan; //!< the channel of the source's U channel
  	unsigned int srcVChan; //!< the channel of the source's V channel
***************
*** 73,82 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
--- 78,87 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
Index: Tekkotsu/Vision/JPEGGenerator.cc
diff -c Tekkotsu/Vision/JPEGGenerator.cc:1.7 Tekkotsu/Vision/JPEGGenerator.cc:1.8
*** Tekkotsu/Vision/JPEGGenerator.cc:1.7	Mon Jan 19 02:56:41 2004
--- Tekkotsu/Vision/JPEGGenerator.cc	Wed Feb 18 16:13:32 2004
***************
*** 14,23 ****
  #include "Shared/debuget.h"
  
  JPEGGenerator::JPEGGenerator(EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid)
! 	: FilterBankGenerator("JPEGGenerator",0,0,gid,sid,EventBase::visJPEGEGID,mysid), src(NULL), srcMode(SRC_AUTO), curMode(SRC_AUTO), bytesUsed(NULL), cinfo(), jerr(), quality(-1U)
  {
- 	setNumImages(numLayers,numChannels);
- 
  	// We set the err object before we create the compress...  the idea
  	// is if the creation fails, we can still get the error as to why it
  	// failed.
--- 14,21 ----
  #include "Shared/debuget.h"
  
  JPEGGenerator::JPEGGenerator(EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid)
! 	: FilterBankGenerator("JPEGGenerator",gid,sid,EventBase::visJPEGEGID,mysid), srcMode(SRC_AUTO), curMode(SRC_AUTO), bytesUsed(NULL), cinfo(), jerr(), quality(-1U)
  {
  	// We set the err object before we create the compress...  the idea
  	// is if the creation fails, we can still get the error as to why it
  	// failed.
***************
*** 26,35 ****
  }
  
  JPEGGenerator::JPEGGenerator(EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid, src_mode_t mode)
! 	: FilterBankGenerator("JPEGGenerator",0,0,gid,sid,EventBase::visJPEGEGID,mysid), src(NULL), srcMode(mode), curMode(SRC_AUTO), bytesUsed(NULL), cinfo(), jerr(), quality(-1U)
  {
- 	setNumImages(numLayers,numChannels);
- 
  	// We set the err object before we create the compress...  the idea
  	// is if the creation fails, we can still get the error as to why it
  	// failed.
--- 24,31 ----
  }
  
  JPEGGenerator::JPEGGenerator(EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid, src_mode_t mode)
! 	: FilterBankGenerator("JPEGGenerator",gid,sid,EventBase::visJPEGEGID,mysid), srcMode(mode), curMode(SRC_AUTO), bytesUsed(NULL), cinfo(), jerr(), quality(-1U)
  {
  	// We set the err object before we create the compress...  the idea
  	// is if the creation fails, we can still get the error as to why it
  	// failed.
***************
*** 50,73 ****
   */
  void
  JPEGGenerator::processEvent(const EventBase& event) {
! 	const FilterBankEvent& fbkevent=dynamic_cast<const FilterBankEvent& >(event);
! 	src=fbkevent.getSource();
! 	frameNumber=src->getFrameNumber();
  	if(getSourceMode()==SRC_AUTO) { //if not auto, curMode was already set when srcMode was set
  		if(dynamic_cast<const InterleavedYUVGenerator*>(src)!=NULL)
  			curMode=SRC_COLOR;
  		else
  			curMode=SRC_GRAYSCALE;
  	}
- 	if(src->getNumLayers()!=numLayers || src->getNumChannels()!=numChannels)
- 		setNumImages(src->getNumLayers(),src->getNumChannels());
- 	if(src->getWidth(numLayers-1)!=getWidth(numLayers-1)) {
- 		ASSERT(widths[numLayers-1]==0,"Strange, the image width changed after initial setting" << widths[numLayers-1]);
- 		setDimensions();
- 	}
- 
- 	invalidateCaches();
- 	framesProcessed++;
  	erouter->postEvent(new FilterBankEvent(this,getGeneratorID(),getSourceID()));
  }
  
--- 46,58 ----
   */
  void
  JPEGGenerator::processEvent(const EventBase& event) {
! 	FilterBankGenerator::processEvent(event);
  	if(getSourceMode()==SRC_AUTO) { //if not auto, curMode was already set when srcMode was set
  		if(dynamic_cast<const InterleavedYUVGenerator*>(src)!=NULL)
  			curMode=SRC_COLOR;
  		else
  			curMode=SRC_GRAYSCALE;
  	}
  	erouter->postEvent(new FilterBankEvent(this,getGeneratorID(),getSourceID()));
  }
  
***************
*** 151,167 ****
  }
  
  void
- JPEGGenerator::setDimensions() {
- 	for(unsigned int i=0; i<numLayers; i++) {
- 		widths[i]=src->getWidth(i);
- 		heights[i]=src->getHeight(i);
- 		strides[i]=skips[i]=0;
- 	}	
- }
- 
- void
  JPEGGenerator::setNumImages(unsigned int nLayers, unsigned int nChannels) {
  	FilterBankGenerator::setNumImages(nLayers,nChannels);
  	bytesUsed=new unsigned int*[numLayers];
  	for(unsigned int res=0; res<numLayers; res++) {
  		increments[res]=3;
--- 136,147 ----
  }
  
  void
  JPEGGenerator::setNumImages(unsigned int nLayers, unsigned int nChannels) {
+ 	if(nLayers==numLayers && nChannels==numChannels)
+ 		return;
  	FilterBankGenerator::setNumImages(nLayers,nChannels);
+ 	for(unsigned int i=0; i<numLayers; i++)
+ 		strides[i]=skips[i]=0;
  	bytesUsed=new unsigned int*[numLayers];
  	for(unsigned int res=0; res<numLayers; res++) {
  		increments[res]=3;
***************
*** 259,267 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
--- 239,247 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
Index: Tekkotsu/Vision/JPEGGenerator.h
diff -c Tekkotsu/Vision/JPEGGenerator.h:1.6 Tekkotsu/Vision/JPEGGenerator.h:1.7
*** Tekkotsu/Vision/JPEGGenerator.h:1.6	Mon Jan 19 02:56:41 2004
--- Tekkotsu/Vision/JPEGGenerator.h	Wed Feb 18 16:13:32 2004
***************
*** 83,94 ****
  
  protected:
  	virtual void setNumImages(unsigned int nLayers, unsigned int nChannels);
- 	virtual void setDimensions(); //!< resets width, height, skip and stride parameters
  	virtual unsigned char * createImageCache(unsigned int layer, unsigned int chan) const;
  	virtual void calcImage(unsigned int layer, unsigned int chan) const;
  	virtual void destruct();
  
- 	const FilterBankGenerator * src; //!< the generator of the last FilterBankEvent received
  	src_mode_t srcMode;   //!< how to interpret source channel of next filter bank event
  	src_mode_t curMode;   //!< how to interpret getImage's current image
  
--- 83,92 ----
***************
*** 109,118 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
--- 107,116 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
Index: Tekkotsu/Vision/RLEGenerator.cc
diff -c Tekkotsu/Vision/RLEGenerator.cc:1.6 Tekkotsu/Vision/RLEGenerator.cc:1.7
*** Tekkotsu/Vision/RLEGenerator.cc:1.6	Wed Feb  4 21:37:09 2004
--- Tekkotsu/Vision/RLEGenerator.cc	Wed Feb 18 16:13:32 2004
***************
*** 7,35 ****
  #include "Shared/debuget.h"
  
  RLEGenerator::RLEGenerator(EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid)
! 	: FilterBankGenerator("RLEGenerator",0,0,gid,sid,EventBase::visRLEEGID,mysid), src(NULL), numRuns(NULL), maxRuns(NULL)
! {
! 	setNumImages(numLayers,numChannels);
! }
! 
! RLEGenerator::~RLEGenerator() {
! 	freeCaches();
! 	destruct();
! }
  
  void
  RLEGenerator::processEvent(const EventBase& event) {
! 	const FilterBankEvent& fbkevent=dynamic_cast<const FilterBankEvent& >(event);
! 	src=fbkevent.getSource();
! 	frameNumber=src->getFrameNumber();
! 	if(src->getNumLayers()!=numLayers || src->getNumChannels()!=numChannels)
! 		setNumImages(src->getNumLayers(),src->getNumChannels());
! 	if(src->getWidth(numLayers-1)!=getWidth(numLayers-1))
! 		setDimensions();
! 
! 	invalidateCaches();
! 	framesProcessed++;
! 	if(const SegmentedColorFilterBankEvent * segsrc=dynamic_cast<const SegmentedColorFilterBankEvent *>(&fbkevent))
  		erouter->postEvent(new SegmentedColorFilterBankEvent(this,getGeneratorID(),getSourceID(),*segsrc));
  	else
  		erouter->postEvent(new FilterBankEvent(this,getGeneratorID(),getSourceID()));
--- 7,19 ----
  #include "Shared/debuget.h"
  
  RLEGenerator::RLEGenerator(EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid)
! 	: FilterBankGenerator("RLEGenerator",gid,sid,EventBase::visRLEEGID,mysid), numRuns(NULL), maxRuns(NULL)
! { }
  
  void
  RLEGenerator::processEvent(const EventBase& event) {
! 	FilterBankGenerator::processEvent(event);
! 	if(const SegmentedColorFilterBankEvent * segsrc=dynamic_cast<const SegmentedColorFilterBankEvent *>(&event))
  		erouter->postEvent(new SegmentedColorFilterBankEvent(this,getGeneratorID(),getSourceID(),*segsrc));
  	else
  		erouter->postEvent(new FilterBankEvent(this,getGeneratorID(),getSourceID()));
***************
*** 114,129 ****
  
  void
  RLEGenerator::setDimensions() {
! 	for(unsigned int i=0; i<numLayers; i++) {
! 		widths[i]=src->getWidth(i);
! 		heights[i]=src->getHeight(i);
  		maxRuns[i]=calcExpMaxRuns(i);
- 	}	
  }
  
  void
  RLEGenerator::setNumImages(unsigned int nLayers, unsigned int nChannels) {
! 	FilterBankGenerator::setNumImages(nLayers,nChannels);
  	maxRuns=new unsigned int[numLayers];
  	numRuns=new unsigned int*[numLayers];
  	for(unsigned int i=0; i<numLayers; i++) {
--- 98,113 ----
  
  void
  RLEGenerator::setDimensions() {
! 	FilterBankGenerator::setDimensions();
! 	for(unsigned int i=0; i<numLayers; i++)
  		maxRuns[i]=calcExpMaxRuns(i);
  }
  
  void
  RLEGenerator::setNumImages(unsigned int nLayers, unsigned int nChannels) {
! 	if(nLayers==numLayers && nChannels==numChannels)
! 		return;
! 	FilterBankGenerator::setNumImages(nLayers,nChannels); //calls destruct()...
  	maxRuns=new unsigned int[numLayers];
  	numRuns=new unsigned int*[numLayers];
  	for(unsigned int i=0; i<numLayers; i++) {
***************
*** 163,171 ****
   * @author ejt (reorganized)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
--- 147,155 ----
   * @author ejt (reorganized)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
Index: Tekkotsu/Vision/RLEGenerator.h
diff -c Tekkotsu/Vision/RLEGenerator.h:1.6 Tekkotsu/Vision/RLEGenerator.h:1.7
*** Tekkotsu/Vision/RLEGenerator.h:1.6	Thu Feb  5 18:33:48 2004
--- Tekkotsu/Vision/RLEGenerator.h	Wed Feb 18 16:13:32 2004
***************
*** 68,75 ****
  	
  	//! constructor
  	RLEGenerator(EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid);
  	//! destructor
! 	virtual ~RLEGenerator();
  
  	static std::string getClassDescription() { return "Compresses a FilterBankGenerator's channels using run length encoding"; }
  
--- 68,79 ----
  	
  	//! constructor
  	RLEGenerator(EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid);
+ 	
  	//! destructor
! 	virtual ~RLEGenerator() {
! 		freeCaches();
! 		destruct();
! 	}
  
  	static std::string getClassDescription() { return "Compresses a FilterBankGenerator's channels using run length encoding"; }
  
***************
*** 87,95 ****
  	//! returns a specific run of the specified image
  	virtual const run& getRun(unsigned int layer, unsigned int chan, unsigned int i) const { return reinterpret_cast<const run*>(getImage(layer,chan))[i]; }
  	
- 	//! returns the generator this is receiving its events from (or the last one anyway)
- 	virtual FilterBankGenerator * getSourceGenerator() const { return src; }
- 
  protected:
  	static const unsigned int MIN_EXP_RUN_LENGTH=8; //!< The expected minimum average length of each run
  	static const unsigned int XMIT_BYTES_PER_RUN=sizeof(cmap_t)+sizeof(short)+sizeof(short); //!< number of bytes needed to send each run
--- 91,96 ----
***************
*** 102,109 ****
  	//! uses a heuristic to predict the maximum number of runs expected per layer
  	unsigned int calcExpMaxRuns(unsigned int layer) const { return getWidth(layer)*getHeight(layer)/MIN_EXP_RUN_LENGTH; }
  
- 	FilterBankGenerator * src; //!< the generator of the last FilterBankEvent received
- 
  	unsigned int ** numRuns; //!< a matrix of ints, holds the number of used runs for each image
  	unsigned int * maxRuns; //!< the maximum number of runs possible for each layer
  
--- 103,108 ----
***************
*** 118,127 ****
   * @author ejt (reorganized)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
--- 117,126 ----
   * @author ejt (reorganized)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
Index: Tekkotsu/Vision/RawCameraGenerator.cc
diff -c Tekkotsu/Vision/RawCameraGenerator.cc:1.14 Tekkotsu/Vision/RawCameraGenerator.cc:1.15
*** Tekkotsu/Vision/RawCameraGenerator.cc:1.14	Thu Feb  5 19:06:31 2004
--- Tekkotsu/Vision/RawCameraGenerator.cc	Wed Feb 18 16:13:32 2004
***************
*** 12,25 ****
  #include "Shared/debuget.h"
  
  RawCameraGenerator::RawCameraGenerator(unsigned int numRawLayers, unsigned int numCalcLayers, EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid)
! 	: FilterBankGenerator("RawCameraGenerator",numCalcLayers,NUM_CHANNELS,gid,sid,EventBase::visRawCameraEGID,mysid), numRealLayers(numRawLayers), layers(NULL), imageInfos(NULL)
  {
! 	setNumImages(numLayers,numChannels);
! }
! 
! RawCameraGenerator::~RawCameraGenerator() {
! 	freeCaches();
! 	destruct();
  }
  
  /*! The const casts in this function are regretable but necessary
--- 12,20 ----
  #include "Shared/debuget.h"
  
  RawCameraGenerator::RawCameraGenerator(unsigned int numRawLayers, unsigned int numCalcLayers, EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid)
! 	: FilterBankGenerator("RawCameraGenerator",gid,sid,EventBase::visRawCameraEGID,mysid), numRealLayers(numRawLayers), layers(NULL), imageInfos(NULL)
  {
! 	setNumImages(numCalcLayers,NUM_CHANNELS);
  }
  
  /*! The const casts in this function are regretable but necessary
***************
*** 226,231 ****
--- 221,228 ----
  
  void
  RawCameraGenerator::setNumImages(unsigned int nLayers, unsigned int nChannels) {
+ 	if(nLayers==numLayers && nChannels==numChannels)
+ 		return;
  	FilterBankGenerator::setNumImages(nLayers,nChannels);
  	layers=new unsigned char*[numLayers];
  	imageInfos=new const OFbkImageInfo*[numLayers];
***************
*** 341,360 ****
  
  	unsigned char * cur=images[dblLayer][chan];
  	ASSERTRET(cur!=NULL,"destination layer is NULL");
! 	unsigned char * src=getImage(srcLayer,chan);
! 	ASSERTRET(cur!=NULL,"source layer is NULL");
  
  	unsigned char * const imgend=cur+width*height;
  	while(cur!=imgend) {
  		unsigned char * const row=cur;
  		unsigned char * const rowend=cur+width;
  		while(cur!=rowend) {
! 			*cur++=*src;
! 			*cur++=*src++;
  		}
  		memcpy(cur,row,width);
  		cur+=width;
! 		src+=getSkip(srcLayer);
  	}
  }
  
--- 338,357 ----
  
  	unsigned char * cur=images[dblLayer][chan];
  	ASSERTRET(cur!=NULL,"destination layer is NULL");
! 	unsigned char * orig=getImage(srcLayer,chan);
! 	ASSERTRET(orig!=NULL,"source layer is NULL");
  
  	unsigned char * const imgend=cur+width*height;
  	while(cur!=imgend) {
  		unsigned char * const row=cur;
  		unsigned char * const rowend=cur+width;
  		while(cur!=rowend) {
! 			*cur++=*orig;
! 			*cur++=*orig++;
  		}
  		memcpy(cur,row,width);
  		cur+=width;
! 		orig+=getSkip(srcLayer);
  	}
  }
  
***************
*** 425,433 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
--- 422,430 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
Index: Tekkotsu/Vision/RawCameraGenerator.h
diff -c Tekkotsu/Vision/RawCameraGenerator.h:1.13 Tekkotsu/Vision/RawCameraGenerator.h:1.14
*** Tekkotsu/Vision/RawCameraGenerator.h:1.13	Thu Feb  5 18:33:48 2004
--- Tekkotsu/Vision/RawCameraGenerator.h	Wed Feb 18 16:13:32 2004
***************
*** 30,36 ****
  	RawCameraGenerator(unsigned int numRawLayers, unsigned int numCalcLayers, EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid);
  
  	//! destructor
! 	virtual ~RawCameraGenerator();
  
  	static std::string getClassDescription() { return "Translates OFbkImageVectorData objects from the system into a slightly more accessible FilterBankEvent for further processing"; }
  
--- 30,39 ----
  	RawCameraGenerator(unsigned int numRawLayers, unsigned int numCalcLayers, EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid);
  
  	//! destructor
! 	virtual ~RawCameraGenerator() {
! 		freeCaches();
! 		destruct();
! 	}
  
  	static std::string getClassDescription() { return "Translates OFbkImageVectorData objects from the system into a slightly more accessible FilterBankEvent for further processing"; }
  
***************
*** 112,121 ****
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
--- 115,124 ----
   * @author ejt (Creator)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
Index: Tekkotsu/Vision/RegionGenerator.cc
diff -c Tekkotsu/Vision/RegionGenerator.cc:1.6 Tekkotsu/Vision/RegionGenerator.cc:1.7
*** Tekkotsu/Vision/RegionGenerator.cc:1.6	Wed Feb  4 21:46:41 2004
--- Tekkotsu/Vision/RegionGenerator.cc	Wed Feb 18 16:13:32 2004
***************
*** 8,22 ****
  #include "Shared/debuget.h"
  
  RegionGenerator::RegionGenerator(EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid)
! 	: FilterBankGenerator("RegionGenerator",0,0,gid,sid,EventBase::visRegionEGID,mysid), src(NULL), srcNumColors(0), srcColors(0), regions(NULL)
! {
! 	setNumImages(numLayers,numChannels);
! }
! 
! RegionGenerator::~RegionGenerator() {
! 	freeCaches();
! 	destruct();
! }
  
  void
  RegionGenerator::freeCaches() {
--- 8,15 ----
  #include "Shared/debuget.h"
  
  RegionGenerator::RegionGenerator(EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid)
! 	: FilterBankGenerator("RegionGenerator",gid,sid,EventBase::visRegionEGID,mysid), srcNumColors(0), srcColors(0), regions(NULL)
! { }
  
  void
  RegionGenerator::freeCaches() {
***************
*** 30,38 ****
  
  void
  RegionGenerator::processEvent(const EventBase& event) {
! 	const FilterBankEvent& fbkevent=dynamic_cast<const FilterBankEvent& >(event);
! 	src=fbkevent.getSource();
! 	frameNumber=src->getFrameNumber();
  	const RLEGenerator * rle=dynamic_cast<const RLEGenerator*>(src);
  	if(NULL==rle) {
  		serr->printf("RegionGenerator's event %s is not from RLEGenerator\n",event.getName().c_str());
--- 23,29 ----
  
  void
  RegionGenerator::processEvent(const EventBase& event) {
! 	FilterBankGenerator::processEvent(event);
  	const RLEGenerator * rle=dynamic_cast<const RLEGenerator*>(src);
  	if(NULL==rle) {
  		serr->printf("RegionGenerator's event %s is not from RLEGenerator\n",event.getName().c_str());
***************
*** 47,59 ****
  		freeCaches();
  	srcNumColors=segev->getNumColors();
  	srcColors=segev->getColors();
- 	if(src->getNumLayers()!=numLayers || src->getNumChannels()!=numChannels)
- 		setNumImages(src->getNumLayers(),src->getNumChannels());
- 	if(src->getWidth(numLayers-1)!=getWidth(numLayers-1))
- 		setDimensions();
- 
- 	invalidateCaches();
- 	framesProcessed++;
  	erouter->postEvent(new SegmentedColorFilterBankEvent(this,getGeneratorID(),getSourceID(),*segev));
  }
  
--- 38,43 ----
***************
*** 192,197 ****
--- 176,183 ----
  
  void
  RegionGenerator::setNumImages(unsigned int nLayers, unsigned int nChannels) {
+ 	if(nLayers==numLayers && nChannels==numChannels)
+ 		return;
  	FilterBankGenerator::setNumImages(nLayers,nChannels);
  	regions = new region**[numLayers];
  	for(unsigned int i=0; i<numLayers; i++) {
***************
*** 201,215 ****
  	}
  }
  
- 
- void
- RegionGenerator::setDimensions() {
- 	for(unsigned int i=0; i<numLayers; i++) {
- 		widths[i]=src->getWidth(i);
- 		heights[i]=src->getHeight(i);
- 	}	
- }
- 
  unsigned char *
  RegionGenerator::createImageCache(unsigned int layer, unsigned int chan) const {
  	//this is where we'll store the linked list of regions for this image
--- 187,192 ----
***************
*** 260,268 ****
   * @author ejt (reorganized)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
--- 237,245 ----
   * @author ejt (reorganized)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
Index: Tekkotsu/Vision/RegionGenerator.h
diff -c Tekkotsu/Vision/RegionGenerator.h:1.4 Tekkotsu/Vision/RegionGenerator.h:1.5
*** Tekkotsu/Vision/RegionGenerator.h:1.4	Wed Feb  4 21:46:41 2004
--- Tekkotsu/Vision/RegionGenerator.h	Wed Feb 18 16:13:32 2004
***************
*** 32,39 ****
  	
  	//! constructor
  	RegionGenerator(EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid);
  	//! destructor
! 	virtual ~RegionGenerator();
  
  	static std::string getClassDescription() { return "Connects runs in an RLE compressed image into regions"; }
  
--- 32,43 ----
  	
  	//! constructor
  	RegionGenerator(EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid);
+ 	
  	//! destructor
! 	virtual ~RegionGenerator() {
! 		freeCaches();
! 		destruct();
! 	}
  
  	static std::string getClassDescription() { return "Connects runs in an RLE compressed image into regions"; }
  
***************
*** 46,66 ****
  	virtual unsigned int LoadBuffer(const char buf[], unsigned int len);
  	virtual unsigned int SaveBuffer(char buf[], unsigned int len) const;
  
- 	//! returns the FilterBankGenerator this is receiving events from
- 	virtual const FilterBankGenerator * getSourceGenerator() const { return src; }
- 
  protected:
  	typedef SegmentedColorFilterBankEvent::color_class_state color_class_state; //!< use the same color info as SegmentedColorFilterBankEvent (since that's what's supplying the color info)
  	static const unsigned int MAX_REGIONS=176*144/16;  //!< maximum number of regions, value is from historical Vision sources
  
- 	virtual void setDimensions(); //!< resets the width, height, skip and stride parameters
  	virtual void setNumImages(unsigned int nLayers, unsigned int nChannels);
  	virtual unsigned char * createImageCache(unsigned int layer, unsigned int chan) const;
  	virtual void calcImage(unsigned int layer, unsigned int chan) const;
  	virtual void destruct();
  
- 	const FilterBankGenerator * src; //!< the generator of the last FilterBankEvent received
- 	
  	unsigned int srcNumColors; //!< number of colors available (from src->src, which should be SegmentedColorGenerator...)
  	color_class_state * srcColors; //!< colors information (from src->src, which should be SegmentedColorGenerator...)
  	region *** regions; //!< data storage for region information
--- 50,64 ----
***************
*** 76,85 ****
   * @author ejt (reorganized)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
--- 74,83 ----
   * @author ejt (reorganized)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
Index: Tekkotsu/Vision/SegmentedColorGenerator.cc
diff -c Tekkotsu/Vision/SegmentedColorGenerator.cc:1.5 Tekkotsu/Vision/SegmentedColorGenerator.cc:1.6
*** Tekkotsu/Vision/SegmentedColorGenerator.cc:1.5	Fri Jan 16 02:39:51 2004
--- Tekkotsu/Vision/SegmentedColorGenerator.cc	Wed Feb 18 16:13:32 2004
***************
*** 7,41 ****
  #include "Shared/debuget.h"
  
  SegmentedColorGenerator::SegmentedColorGenerator(EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid)
! 	: FilterBankGenerator("SegmentedColorGenerator",0,0,gid,sid,EventBase::visSegmentEGID,mysid), src(NULL), srcYChan(0), srcUChan(1), srcVChan(2), tmaps(), tmapNames(), numColors(0), colorNames()
! {
! 	setNumImages(numLayers,numChannels);
! }
  
  SegmentedColorGenerator::SegmentedColorGenerator(EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid, unsigned int syc, unsigned int suc, unsigned int svc)
! 	: FilterBankGenerator("SegmentedColorGenerator",0,0,gid,sid,EventBase::visSegmentEGID,mysid), src(NULL), srcYChan(syc), srcUChan(suc), srcVChan(svc), tmaps(), tmapNames(), numColors(0), colorNames()
! {
! 	setNumImages(numLayers,numChannels);
! }
  
  SegmentedColorGenerator::~SegmentedColorGenerator() {
  	for(unsigned int i=0; i<tmaps.size(); i++)
  		delete [] tmaps[i];
! 	// todo - i think we're leaking the color names memory
  }
  
  void
  SegmentedColorGenerator::processEvent(const EventBase& event) {
! 	const FilterBankEvent& fbkevent=dynamic_cast<const FilterBankEvent& >(event);
! 	src=fbkevent.getSource();
! 	frameNumber=src->getFrameNumber();
! 	if(src->getNumLayers()!=numLayers || src->getNumChannels()!=numChannels)
! 		setNumImages(src->getNumLayers(),1);
! 	if(src->getWidth(numLayers-1)!=getWidth(numLayers-1))
! 		setDimensions();
! 
! 	invalidateCaches();
! 	framesProcessed++;
  	erouter->postEvent(new SegmentedColorFilterBankEvent(this,getGeneratorID(),getSourceID(),this,getNumColors(),getColors(),&colorNames));
  }
  
--- 7,36 ----
  #include "Shared/debuget.h"
  
  SegmentedColorGenerator::SegmentedColorGenerator(EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid)
! 	: FilterBankGenerator("SegmentedColorGenerator",gid,sid,EventBase::visSegmentEGID,mysid), srcYChan(0), srcUChan(1), srcVChan(2), tmaps(), tmapNames(), numColors(0), colorNames()
! { }
  
  SegmentedColorGenerator::SegmentedColorGenerator(EventBase::EventGeneratorID_t gid, unsigned int sid, unsigned int mysid, unsigned int syc, unsigned int suc, unsigned int svc)
! 	: FilterBankGenerator("SegmentedColorGenerator",gid,sid,EventBase::visSegmentEGID,mysid), srcYChan(syc), srcUChan(suc), srcVChan(svc), tmaps(), tmapNames(), numColors(0), colorNames()
! { }
  
  SegmentedColorGenerator::~SegmentedColorGenerator() {
+ 	freeCaches();
+ 	destruct();
  	for(unsigned int i=0; i<tmaps.size(); i++)
  		delete [] tmaps[i];
! 
! 	//hashmap::iterator it=colorNames.begin(); //not the way i'd like to iterate, but there seems to be a bug in the current hashmap implementation we're using...
! 	//for(unsigned int i=0; i<colorNames.size(); it++,i++)
! 	//free(const_cast<char*>(it->first));
!   //colorNames.clear();
! 
!   colorNames.clear(); //we're leaking the memory of the names themselves...
  }
  
  void
  SegmentedColorGenerator::processEvent(const EventBase& event) {
! 	FilterBankGenerator::processEvent(event);
  	erouter->postEvent(new SegmentedColorFilterBankEvent(this,getGeneratorID(),getSourceID(),this,getNumColors(),getColors(),&colorNames));
  }
  
***************
*** 63,70 ****
  
  bool
  SegmentedColorGenerator::loadColorInfo(const std::string& col_file) {
! 	// todo - we're leaking the color names memory
!   colorNames.clear();
    numColors=CMVision::LoadColorInformation(colors,MAX_COLORS,col_file.c_str(),colorNames);
    if(numColors > 0){
      sout->printf("  Loaded %d colors.\n",numColors);
--- 58,70 ----
  
  bool
  SegmentedColorGenerator::loadColorInfo(const std::string& col_file) {
! 	//hashmap::iterator it=colorNames.begin(); //not the way i'd like to iterate, but there seems to be a bug in the current hashmap implementation we're using...
! 	//for(unsigned int i=0; i<colorNames.size(); it++,i++)
! 	//free(const_cast<char*>(it->first));
!   //colorNames.clear();
! 
!   colorNames.clear(); //we're leaking the memory of the names themselves...
! 
    numColors=CMVision::LoadColorInformation(colors,MAX_COLORS,col_file.c_str(),colorNames);
    if(numColors > 0){
      sout->printf("  Loaded %d colors.\n",numColors);
***************
*** 187,198 ****
  
  void
  SegmentedColorGenerator::setDimensions() {
! 	for(unsigned int i=0; i<numLayers; i++) {
! 		widths[i]=src->getWidth(i);
! 		heights[i]=src->getHeight(i);
! 		skips[i]=0;
  		strides[i]=widths[i];
- 	}	
  }
  
  void
--- 187,195 ----
  
  void
  SegmentedColorGenerator::setDimensions() {
! 	FilterBankGenerator::setDimensions();
! 	for(unsigned int i=0; i<numLayers; i++)
  		strides[i]=widths[i];
  }
  
  void
***************
*** 226,234 ****
   * @author ejt (reorganized)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
--- 223,231 ----
   * @author ejt (reorganized)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
Index: Tekkotsu/Vision/SegmentedColorGenerator.h
diff -c Tekkotsu/Vision/SegmentedColorGenerator.h:1.5 Tekkotsu/Vision/SegmentedColorGenerator.h:1.6
*** Tekkotsu/Vision/SegmentedColorGenerator.h:1.5	Thu Feb  5 18:33:48 2004
--- Tekkotsu/Vision/SegmentedColorGenerator.h	Wed Feb 18 16:13:32 2004
***************
*** 110,124 ****
  	
  	//! ignores @a nChannels - the number of channels is always the number of loaded threshold maps
  	virtual void setNumImages(unsigned int nLayers, unsigned int nChannels);
! 	virtual void setDimensions(); //!< sets width, height, skip, and stride parameters
  	virtual unsigned char * createImageCache(unsigned int layer, unsigned int chan) const;
  	virtual void calcImage(unsigned int layer, unsigned int chan) const;
  
- 	const FilterBankGenerator * src; //!< the generator of the last FilterBankEvent received
  	unsigned int srcYChan; //!< the channel of the source's Y channel
  	unsigned int srcUChan; //!< the channel of the source's U channel
  	unsigned int srcVChan; //!< the channel of the source's V channel
- 
  	
  	std::vector<cmap_t*> tmaps; //!< list of threshold maps so you can segment the same source different ways
  	std::vector<std::string> tmapNames; //!< filename of each tmap;
--- 110,122 ----
  	
  	//! ignores @a nChannels - the number of channels is always the number of loaded threshold maps
  	virtual void setNumImages(unsigned int nLayers, unsigned int nChannels);
! 	virtual void setDimensions(); //!< sets stride parameter to width (as set by FilterBankGenerator::setDimensions())
  	virtual unsigned char * createImageCache(unsigned int layer, unsigned int chan) const;
  	virtual void calcImage(unsigned int layer, unsigned int chan) const;
  
  	unsigned int srcYChan; //!< the channel of the source's Y channel
  	unsigned int srcUChan; //!< the channel of the source's U channel
  	unsigned int srcVChan; //!< the channel of the source's V channel
  	
  	std::vector<cmap_t*> tmaps; //!< list of threshold maps so you can segment the same source different ways
  	std::vector<std::string> tmapNames; //!< filename of each tmap;
***************
*** 138,147 ****
   * @author ejt (reorganized)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
--- 136,145 ----
   * @author ejt (reorganized)
   *
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #endif
Index: Tekkotsu/docs/doxygen.css
diff -c Tekkotsu/docs/doxygen.css:1.1.1.1 Tekkotsu/docs/doxygen.css:removed
*** Tekkotsu/docs/doxygen.css:1.1.1.1	Mon Sep 30 14:19:47 2002
--- Tekkotsu/docs/doxygen.css	Tue Mar 16 23:08:33 2004
***************
*** 1,51 ****
- H1 { text-align: center; }
- CAPTION { font-weight: bold }
- A:link { color: #000060 }
- A:visited { color: #603070 }
- A.qindex {}
- A.qindexRef {}
- A.el { text-decoration: none; font-weight: bold }
- A.elRef { font-weight: bold }
- A.code { text-decoration: none; font-weight: normal; color: #4444ee }
- A.codeRef { font-weight: normal; color: #4444ee }
- A:hover { text-decoration: none; background-color: #e2e2ff }
- DL.el { margin-left: -1cm }
- DIV.fragment { width: 100%; border: none; background-color: #eeeeee }
- DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px }
- TD.md { background-color: #e0e0f8; font-weight: bold; }
- TD.mdname1 { background-color: #e0e0f8; font-weight: bold; color: #902020; }
- TD.mdname { background-color: #e0e0f8; font-weight: bold; color: #902020; width: 600px; }
- DIV.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold }
- DIV.groupText { margin-left: 16px; font-style: italic; font-size: smaller }
- BODY { background: white }
- TD.indexkey { 
-    background-color: #eeeeff; 
-    font-weight: bold; 
-    padding-right  : 10px; 
-    padding-top    : 2px; 
-    padding-left   : 10px; 
-    padding-bottom : 2px; 
-    margin-left    : 0px; 
-    margin-right   : 0px; 
-    margin-top     : 2px; 
-    margin-bottom  : 2px  
- }
- TD.indexvalue { 
-    background-color: #eeeeff; 
-    font-style: italic; 
-    padding-right  : 10px; 
-    padding-top    : 2px; 
-    padding-left   : 10px; 
-    padding-bottom : 2px; 
-    margin-left    : 0px; 
-    margin-right   : 0px; 
-    margin-top     : 2px; 
-    margin-bottom  : 2px  
- }
- span.keyword       { color: #008000 }
- span.keywordtype   { color: #604020 }
- span.keywordflow   { color: #e08000 }
- span.comment       { color: #800000 }
- span.preprocessor  { color: #806020 }
- span.stringliteral { color: #002080 }
- span.charliteral   { color: #008080 }
--- 0 ----
Index: Tekkotsu/docs/doxygencfg
diff -c Tekkotsu/docs/doxygencfg:1.28 Tekkotsu/docs/doxygencfg:1.31
*** Tekkotsu/docs/doxygencfg:1.28	Wed Jan 21 15:18:59 2004
--- Tekkotsu/docs/doxygencfg	Tue Mar 16 22:00:07 2004
***************
*** 23,29 ****
  # This could be handy for archiving the generated documentation or 
  # if some version control system is used.
  
! PROJECT_NUMBER         = 2.0.1
  
  # 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         = 2.1
  
  # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
  # base path where the generated documentation will be put. 
***************
*** 544,550 ****
  # fine-tune the look of the HTML output. If the tag is left blank doxygen 
  # will generate a default style sheet
  
! HTML_STYLESHEET        = doxygen.css
  
  # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
  # files or namespaces will be aligned in HTML using tables. If set to 
--- 544,550 ----
  # fine-tune the look of the HTML output. If the tag is left blank doxygen 
  # will generate a default style sheet
  
! HTML_STYLESHEET        = html/doxygen.css
  
  # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
  # files or namespaces will be aligned in HTML using tables. If set to 
Index: Tekkotsu/docs/doxygenfoot.html
diff -c Tekkotsu/docs/doxygenfoot.html:1.2 Tekkotsu/docs/doxygenfoot.html:1.3
*** Tekkotsu/docs/doxygenfoot.html:1.2	Mon Apr 14 22:27:17 2003
--- Tekkotsu/docs/doxygenfoot.html	Mon Feb  9 20:47:08 2004
***************
*** 1,3 ****
--- 1,5 ----
+ </td></tr></tbody></table>
+ 
    <br>
  	<table cellpadding="2" cellspacing="2" border="0" style="text-align: left; width: 100%; color: rgb(0, 0, 0);">
  		<tbody>
Index: Tekkotsu/docs/doxygenhead.html
diff -c Tekkotsu/docs/doxygenhead.html:1.6 Tekkotsu/docs/doxygenhead.html:1.8
*** Tekkotsu/docs/doxygenhead.html:1.6	Tue Jan 20 23:51:23 2004
--- Tekkotsu/docs/doxygenhead.html	Mon Feb  9 20:47:08 2004
***************
*** 9,15 ****
  		<link rel="SHORTCUT ICON" href="favicon.ico">
  	</head>
  	<body>
! 		<img src="aibosmall.jpg" width=92 height=75 align=right>
  		<table cellpadding="1" cellspacing="6" border="0"
  					 style="text-align: left; margin-left: auto; margin-right: auto;">
  			<tbody>
--- 9,15 ----
  		<link rel="SHORTCUT ICON" href="favicon.ico">
  	</head>
  	<body>
! 		<!-- <img src="aibosmall.jpg" width=92 height=75 align=right> -->
  		<table cellpadding="1" cellspacing="6" border="0"
  					 style="text-align: left; margin-left: auto; margin-right: auto;">
  			<tbody>
***************
*** 30,32 ****
--- 30,36 ----
  				</tr>
  			</tbody>
  		</table>
+ <table style="text-align: left; margin-left: auto; margin-right: auto; width: 700px;" border="0" cellspacing="2" cellpadding="2">
+   <tbody>
+     <tr>
+       <td style="vertical-align: top;">
\ No newline at end of file
Index: Tekkotsu/docs/benchmarks/profilerun_ERS210A_2.1.txt
diff -c /dev/null Tekkotsu/docs/benchmarks/profilerun_ERS210A_2.1.txt:1.1
*** /dev/null	Tue Mar 16 23:08:33 2004
--- Tekkotsu/docs/benchmarks/profilerun_ERS210A_2.1.txt	Tue Mar 16 21:58:49 2004
***************
*** 0 ****
--- 1,110 ----
+ Setup:
+   Default build for ERS-2xx (TGT_ERS2xx)
+   Pink ball in view (8.5in from snout)
+   Press power button, start timer
+   Telnet to system console (port 59000)
+   Connect ControllerGUI
+   STARTUP script:
+     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: 18.672482 to 302.959106
+ ReadySendJoints():
+         2214 calls
+         1.292529 ms avg
+         1.329591 ms exp.avg
+         0.000939 ms avg child time (0.000000%)
+         128.206077 ms avg inter (7.799942 fps)
+         127.928062 ms exp.avg (7.816893 fps)
+         Exec: 0 1 449 1764 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 0
+         Inter: 0 1 1 0 0 0 0 0 0 0 2210 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+ GotSensorFrame():
+         8842 calls
+         0.332026 ms avg
+         0.329539 ms exp.avg
+         0.000000 ms avg child time (0.000000%)
+         32.084602 ms avg inter (31.167599 fps)
+         31.454290 ms exp.avg (31.792164 fps)
+         Exec: 0 0 8398 444 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 0
+         Inter: 0 0 0 0 0 3 1675 5398 1764 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+ GotImage():
+         7052 calls
+         10.114690 ms avg
+         10.314075 ms exp.avg
+         8.653587 ms avg child time (85.500000%)
+         40.220636 ms avg inter (24.862859 fps)
+         40.356495 ms exp.avg (24.779160 fps)
+         Exec: 0 0 5 16 0 6978 52 1 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 2 0 1 7047 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+ PowerEvent():
+         27 calls
+         36.724444 ms avg
+         14.618258 ms exp.avg
+         0.000000 ms avg child time (0.000000%)
+         9721.988926 ms avg inter (0.102860 fps)
+         8470.579102 ms exp.avg (0.118056 fps)
+         Exec: 0 0 26 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 0
+         Inter: 0 0 0 0 0 0 0 0 0 0 0 3 0 2 0 0 0 0 0 0 2 6 0 0 0 2 0 1 0 1 0 9
+ BallDetection::processEvent():
+         21123 calls
+         2.889035 ms avg
+         2.430843 ms exp.avg
+         2.781354 ms avg child time (96.200000%)
+         13.358826 ms avg inter (74.856880 fps)
+         11.905966 ms exp.avg (83.991508 fps)
+         Exec: 7000 6987 69 36 0 7027 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
+         Inter: 9 6908 89 45 0 7029 5 6925 112 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ RegionGenerator::calcImage(...):
+         7031 calls
+         8.355929 ms avg
+         8.288463 ms exp.avg
+         3.942998 ms avg child time (47.100000%)
+         40.109937 ms avg inter (24.931478 fps)
+         40.480179 ms exp.avg (24.703449 fps)
+         Exec: 0 0 0 0 0 7028 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
+         Inter: 0 0 0 0 0 0 0 1 7029 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ RLEGenerator::calcImage(...):
+         7031 calls
+         3.942998 ms avg
+         4.145589 ms exp.avg
+         2.529170 ms avg child time (64.100000%)
+         40.109973 ms avg inter (24.931455 fps)
+         40.480179 ms exp.avg (24.703449 fps)
+         Exec: 0 0 0 0 7021 10 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 0 1 7029 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ SegmentedColorGenerator::calcImage(...):
+         7031 calls
+         2.529170 ms avg
+         2.700440 ms exp.avg
+         0.018496 ms avg child time (0.700000%)
+         40.110032 ms avg inter (24.931419 fps)
+         40.480179 ms exp.avg (24.703449 fps)
+         Exec: 0 0 0 0 7030 1 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 0 1 7029 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ RawCameraGenerator::calcImage(...):
+         21093 calls
+         0.006165 ms avg
+         0.005677 ms exp.avg
+         0.000000 ms avg child time (0.000000%)
+         13.367994 ms avg inter (74.805538 fps)
+         11.580246 ms exp.avg (86.353958 fps)
+         Exec: 14057 7031 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 0 0
+         Inter: 6841 7217 4 0 0 0 0 2 7028 0 0 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,
+ ~~~ Motion: ~~~
+ Profiling information since: 18.674357 to 302.969298
+ ReadySendJoints():
+         8850 calls
+         1.535671 ms avg
+         1.504879 ms exp.avg
+         0.000000 ms avg child time (0.000000%)
+         32.039534 ms avg inter (31.211441 fps)
+         31.934410 ms exp.avg (31.314184 fps)
+         Exec: 0 0 10 8756 63 3 0 0 0 18 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 0 8830 1 18 0 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: Tekkotsu/docs/benchmarks/profilerun_ERS7_2.1.txt
diff -c /dev/null Tekkotsu/docs/benchmarks/profilerun_ERS7_2.1.txt:1.1
*** /dev/null	Tue Mar 16 23:08:33 2004
--- Tekkotsu/docs/benchmarks/profilerun_ERS7_2.1.txt	Tue Mar 16 21:58:49 2004
***************
*** 0 ****
--- 1,110 ----
+ Setup:
+   Default build for ERS-7 (TGT_ERS7)
+   Pink ball in view (8.5in from snout)
+   Press power button, start timer
+   Telnet to system console (port 59000)
+   Connect ControllerGUI
+   STARTUP script:
+     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: 15.566191 to 303.819087
+ ReadySendJoints():
+         1 calls
+         0.006000 ms avg
+         0.006000 ms exp.avg
+         0.000000 ms avg child time (0.000000%)
+         0.000000 ms avg inter (Inf fps)
+         0.000000 ms exp.avg (Inf fps)
+         Exec: 1 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 0 0 0 0
+         Inter: 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 0 0 0 0 0
+ GotSensorFrame():
+         8979 calls
+         0.369977 ms avg
+         0.263533 ms exp.avg
+         0.000000 ms avg child time (0.000000%)
+         32.039127 ms avg inter (31.211837 fps)
+         31.909868 ms exp.avg (31.338268 fps)
+         Exec: 0 2155 4583 2241 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 0
+         Inter: 0 0 0 0 1 0 0 8956 20 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ GotImage():
+         8611 calls
+         3.437430 ms avg
+         3.406528 ms exp.avg
+         2.816078 ms avg child time (81.900000%)
+         33.404760 ms avg inter (29.935854 fps)
+         33.086487 ms exp.avg (30.223820 fps)
+         Exec: 0 12 20 0 8574 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
+         Inter: 0 0 0 0 1 0 1 7135 1472 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ PowerEvent():
+         20 calls
+         24.939500 ms avg
+         22.766754 ms exp.avg
+         0.000000 ms avg child time (0.000000%)
+         14253.637900 ms avg inter (0.070158 fps)
+         13115.712891 ms exp.avg (0.076244 fps)
+         Exec: 0 12 6 1 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 0 0 0
+         Inter: 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 2 1 0 0 0 0 0 0 0 0 14
+ BallDetection::processEvent():
+         25776 calls
+         0.940769 ms avg
+         0.809764 ms exp.avg
+         0.874305 ms avg child time (92.900000%)
+         11.114810 ms avg inter (89.970050 fps)
+         9.329578 ms exp.avg (107.185974 fps)
+         Exec: 16953 245 0 0 8577 1 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: 6350 2256 0 0 8578 1 1 7541 1048 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ RegionGenerator::calcImage(...):
+         8578 calls
+         2.627196 ms avg
+         2.710576 ms exp.avg
+         2.095237 ms avg child time (79.700000%)
+         33.360246 ms avg inter (29.975798 fps)
+         33.078953 ms exp.avg (30.230701 fps)
+         Exec: 0 0 0 0 8578 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 0 0 7111 1466 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ RLEGenerator::calcImage(...):
+         8578 calls
+         2.095237 ms avg
+         2.118181 ms exp.avg
+         1.562293 ms avg child time (74.500000%)
+         33.359745 ms avg inter (29.976249 fps)
+         33.078869 ms exp.avg (30.230782 fps)
+         Exec: 0 0 0 8524 54 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 0 0 7111 1466 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ SegmentedColorGenerator::calcImage(...):
+         8578 calls
+         1.562293 ms avg
+         1.566725 ms exp.avg
+         0.014925 ms avg child time (0.900000%)
+         33.359934 ms avg inter (29.976078 fps)
+         33.077141 ms exp.avg (30.232361 fps)
+         Exec: 0 0 0 8568 10 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 0 0 7111 1466 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ RawCameraGenerator::calcImage(...):
+         25734 calls
+         0.004975 ms avg
+         0.004588 ms exp.avg
+         0.000000 ms avg child time (0.000000%)
+         11.118749 ms avg inter (89.938176 fps)
+         9.192039 ms exp.avg (108.789803 fps)
+         Exec: 23419 2313 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 0 0
+         Inter: 8420 8730 6 0 0 0 0 7111 1466 0 0 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,
+ ~~~ Motion: ~~~
+ Profiling information since: 15.566250 to 303.822684
+ ReadySendJoints():
+         8971 calls
+         0.852708 ms avg
+         0.667585 ms exp.avg
+         0.000000 ms avg child time (0.000000%)
+         32.056950 ms avg inter (31.194483 fps)
+         31.980471 ms exp.avg (31.269085 fps)
+         Exec: 0 0 6213 2741 1 0 0 0 0 14 2 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 0 8953 1 14 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: Tekkotsu/docs/html/doxygen.css
diff -c Tekkotsu/docs/html/doxygen.css:1.1 Tekkotsu/docs/html/doxygen.css:1.4
*** Tekkotsu/docs/html/doxygen.css:1.1	Wed Jan  8 21:03:01 2003
--- Tekkotsu/docs/html/doxygen.css	Mon Feb  9 20:47:12 2004
***************
*** 1,23 ****
! H1 { text-align: center; }
  CAPTION { font-weight: bold }
! A:link { color: #000060 }
! A:visited { color: #603070 }
! A.qindex {}
! A.qindexRef {}
! A.el { text-decoration: none; font-weight: bold }
  A.elRef { font-weight: bold }
  A.code { text-decoration: none; font-weight: normal; color: #4444ee }
  A.codeRef { font-weight: normal; color: #4444ee }
! A:hover { text-decoration: none; background-color: #e2e2ff }
  DL.el { margin-left: -1cm }
! DIV.fragment { width: 100%; border: none; background-color: #eeeeee }
  DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px }
! TD.md { background-color: #e0e0f8; font-weight: bold; }
! TD.mdname1 { background-color: #e0e0f8; font-weight: bold; color: #902020; }
! TD.mdname { background-color: #e0e0f8; font-weight: bold; color: #902020; width: 600px; }
  DIV.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold }
  DIV.groupText { margin-left: 16px; font-style: italic; font-size: smaller }
! BODY { background: white }
  TD.indexkey { 
     background-color: #eeeeff; 
     font-weight: bold; 
--- 1,55 ----
! H1 {
! 	text-align: center;
! 	font-family: Arial, Helvetica, sans-serif;
! }
! H2 {
! 	font-family: Geneva, Arial, Helvetica, sans-serif;
! }
  CAPTION { font-weight: bold }
! DIV.qindex { width: 100%;
!              background-color: #eeeeff;
!              border: 1px solid #B0B0B0;
!              text-align: center;
!              margin: 2px;
!              padding: 2px;
!              width: 620px;
!              align: center; margin-left: auto; margin-right: auto; 
! }
! A.qindex { text-decoration: none; font-weight: bold; color: #0000ee }
! A.qindex:visited { text-decoration: none; font-weight: bold; color: #0000ee }
! A.qindex:hover { text-decoration: none; background-color: #ddddff }
! A.qindexHL { text-decoration: none; font-weight: bold;
!              background-color: #6666cc;
!              color: #ffffff
!            }
! A.qindexHL:hover { text-decoration: none; background-color: #6666cc; color: #ffffff }
! A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff }
! A.el { text-decoration: none; font-weight: bold; color: #082090 }
! A.el:visited { text-decoration: none; font-weight: bold; color: #000058 }
  A.elRef { font-weight: bold }
  A.code { text-decoration: none; font-weight: normal; color: #4444ee }
  A.codeRef { font-weight: normal; color: #4444ee }
! A:hover { text-decoration: none; background-color: #f2f2ff }
  DL.el { margin-left: -1cm }
! DIV.fragment {
! 	width: 98%;
! 	border: 1px solid #CCCCCC;
! 	background-color: #f5f5f5;
! 	padding-left: 4px;
! 	margin: 4px;
! }
  DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px }
! TD.md { background-color: #f2f2ff; font-weight: bold; text-align: right; }
! TD.mdname1 { background-color: #f2f2ff; font-weight: bold; color: #602020; }
! TD.mdname { background-color: #f2f2ff; font-weight: bold; color: #602020; }
  DIV.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold }
  DIV.groupText { margin-left: 16px; font-style: italic; font-size: smaller }
! BODY {
! 	background: white;
! 	color: black;
! 	margin-right: 20px;
! 	margin-left: 20px;
! }
  TD.indexkey { 
     background-color: #eeeeff; 
     font-weight: bold; 
***************
*** 42,51 ****
     margin-top     : 2px; 
     margin-bottom  : 2px  
  }
! span.keyword       { color: #008000 }
! span.keywordtype   { color: #604020 }
! span.keywordflow   { color: #e08000 }
! span.comment       { color: #800000 }
! span.preprocessor  { color: #806020 }
! span.stringliteral { color: #002080 }
! span.charliteral   { color: #008080 }
--- 74,175 ----
     margin-top     : 2px; 
     margin-bottom  : 2px  
  }
! TR.memlist {
!    background-color: #f0f0f0; 
! }
! P.formulaDsp { text-align: center; }
! IMG.formulaDsp { }
! IMG.formulaInl { vertical-align: middle; }
! SPAN.keyword       { color: #008000 }
! SPAN.keywordtype   { color: #604020 }
! SPAN.keywordflow   { color: #e08000 }
! SPAN.comment       { color: #800000 }
! SPAN.preprocessor  { color: #806020 }
! SPAN.stringliteral { color: #002080 }
! SPAN.charliteral   { color: #008080 }
! .mdTable {
! 	border: 1px solid #808080;
! 	background-color: #f2f2ff;
! 	border-bottom-style: none;
! 	width: 100%
! }
! .mdRow {
! 	padding: 8px 20px;
! }
! .mdescLeft {
! 	font-size: smaller;
! 	font-family: Arial, Helvetica, sans-serif;
! 	background-color: #F4F4F4;
! 	padding-left: 8px;
! 	border-top: 1px none #E0E0E0;
! 	border-right: 1px solid #E0E0E0;
! 	border-bottom: 1px solid #D0D0D0;
! 	border-left: 1px none #B0B0B0;
! 	margin: 0px;
! }
! .mdescRight {
! 	font-size: smaller;
! 	font-family: Arial, Helvetica, sans-serif;
! 	font-style: italic;
! 	background-color: #F4F4F4;
! 	padding-left: 4px;
! 	border-top: 1px none #E0E0E0;
! 	border-right: 1px none #B0B0B0;
! 	border-bottom: 1px solid #D0D0D0;
! 	border-left: 1px none #E0E0E0;
! 	margin: 0px;
! 	padding-bottom: 0px;
! 	padding-right: 8px;
! }
! .memItemLeft {
! 	padding: 1px 0px 0px 8px;
! 	margin: 4px;
! 	border-top-width: 1px;
! 	border-right-width: 1px;
! 	border-bottom-width: 1px;
! 	border-left-width: 1px;
! 	border-top-style: solid;
! 	border-top-color: #D0D0D0;
! 	border-right-color: #E0E0E0;
! 	border-bottom-color: #E0E0E0;
! 	border-left-color: #B0B0B0;
! 	border-right-style: solid;
! 	border-bottom-style: none;
! 	border-left-style: none;
! 	background-color: #F4F4F4;
! 	font-family: Geneva, Arial, Helvetica, sans-serif;
! 	font-size: 12px;
! }
! .memItemRight {
! 	padding: 1px 0px 0px 8px;
! 	margin: 4px;
! 	border-top-width: 1px;
! 	border-right-width: 1px;
! 	border-bottom-width: 1px;
! 	border-left-width: 1px;
! 	border-top-style: solid;
! 	border-top-color: #D0D0D0;
! 	border-right-color: #B0B0B0;
! 	border-bottom-color: #E0E0E0;
! 	border-left-color: #E0E0E0;
! 	border-right-style: none;
! 	border-bottom-style: none;
! 	border-left-style: none;
! 	background-color: #F4F4F4;
! 	font-family: Geneva, Arial, Helvetica, sans-serif;
! 	font-size: 13px;
! }
! .search     { color: #000000;
!               font-weight: bold;
! }
! FORM.search {
!               margin-bottom: 0px;
!               margin-top: 0px;
! }
! INPUT.search { font-size: 75%;
!                color: #000080;
!                font-weight: normal;
!                background-color: #eeeeff;
! }
! TD.tiny      { font-size: 75%;
! }
Index: Tekkotsu/docs/html/index.html
diff -c Tekkotsu/docs/html/index.html:1.27 Tekkotsu/docs/html/index.html:1.30
*** Tekkotsu/docs/html/index.html:1.27	Thu Feb  5 22:33:08 2004
--- Tekkotsu/docs/html/index.html	Tue Mar 16 22:04:07 2004
***************
*** 52,59 ****
      </tr>
    </tbody>
  </table>
! <div style="text-align: center;"><a class="qindex" href="main.html">Main&nbsp;Page</a>
! | <a class="qindexHL" href="namespaces.html">Namespace List</a> | <a
   class="qindex" href="hierarchy.html">Class&nbsp;Hierarchy</a> | <a
   class="qindex" href="classes.html">Alphabetical&nbsp;List</a> | <a
   class="qindex" href="annotated.html">Class&nbsp;List</a> | <a
--- 52,59 ----
      </tr>
    </tbody>
  </table>
! <div class="qindex"><a class="qindexHL" href="main.html">Main&nbsp;Page</a>
! | <a class="qindex" href="namespaces.html">Namespace List</a> | <a
   class="qindex" href="hierarchy.html">Class&nbsp;Hierarchy</a> | <a
   class="qindex" href="classes.html">Alphabetical&nbsp;List</a> | <a
   class="qindex" href="annotated.html">Class&nbsp;List</a> | <a
***************
*** 121,128 ****
  static copies of the documentation, there are two formats:<br>
        </p>
        <ul style="margin-left: 40px;">
!         <li><a href="../media/Tekkotsu_doc_2.0.1.tar.gz">HTML</a> (v2.0.1,
! 3.8MB)</li>
        </ul>
        <div style="margin-left: 40px;">If you're using the most recent
  version from the <a href="http://cvs.tekkotsu.org/">CVS repository</a>,
--- 121,128 ----
  static copies of the documentation, there are two formats:<br>
        </p>
        <ul style="margin-left: 40px;">
!         <li><a href="../media/Tekkotsu_doc_2.1.tar.gz">HTML</a> (v2.1,
! 3.7MB)</li>
        </ul>
        <div style="margin-left: 40px;">If you're using the most recent
  version from the <a href="http://cvs.tekkotsu.org/">CVS repository</a>,
Index: Tekkotsu/project/Makefile
diff -c Tekkotsu/project/Makefile:1.59 Tekkotsu/project/Makefile:1.61
*** Tekkotsu/project/Makefile:1.59	Mon Feb  2 17:36:51 2004
--- Tekkotsu/project/Makefile	Tue Mar 16 22:40:55 2004
***************
*** 57,63 ****
  CXXFLAGS= \
  	-g -pipe -O2 -frename-registers -fomit-frame-pointer -ffast-math -fno-common \
  	-Wall -W -Wshadow -Wlarger-than-8192 -Wpointer-arith -Wcast-qual \
! 	-Woverloaded-virtual -Weffc++ -Winline -Wdeprecated -Wnon-virtual-dtor \
  	-I"`pwd`" -I$(TEKKOTSU_ROOT) \
  	-isystem $(TEKKOTSU_ROOT)/Shared/jpeg-6b \
  	-isystem $(OPENRSDK_ROOT)/OPEN_R/include/MCOOP \
--- 57,63 ----
  CXXFLAGS= \
  	-g -pipe -O2 -frename-registers -fomit-frame-pointer -ffast-math -fno-common \
  	-Wall -W -Wshadow -Wlarger-than-8192 -Wpointer-arith -Wcast-qual \
! 	-Woverloaded-virtual -Weffc++ -Wdeprecated -Wnon-virtual-dtor \
  	-I"`pwd`" -I$(TEKKOTSU_ROOT) \
  	-isystem $(TEKKOTSU_ROOT)/Shared/jpeg-6b \
  	-isystem $(OPENRSDK_ROOT)/OPEN_R/include/MCOOP \
***************
*** 191,196 ****
--- 191,199 ----
  # Hopefully, you shouldn't have to change anything down here,
  # except one or two little things ;)
  
+ # Location of Aperios (the Aibo's OS) binary executables
+ SYSTEM_BINARIES:=$(OPENRSDK_ROOT)/OPEN_R/MS_$(if $(findstring $(TEKKOTSU_TARGET_MODEL),TGT_ERS7),ERS7,ERS200)/WCONSOLE/nomemprot
+ 
  # List of all components for all processes, sorted to
  # remove duplicates.
  COMPONENTS:=$(sort $(foreach proc,$(PROCESS_OBJS),$($(proc)_COMP)))
***************
*** 231,252 ****
  
  compile: reportTarget cleanTemps updateTools $(USERLIBS) $(INSTALL_BINS)
  	@image="$(BUILDDIR)/$(notdir $(MEMSTICK_ROOT))" ; \
! 	if [ $(TEKKOTSU_ROOT)/TARGET_MODEL -nt $$image ] ; then \
  		echo "Deleting old cached OPEN-R binaries"; \
! 		rm -rf $$image ; \
  	fi; \
! 	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 ; \
! 		(cd $$image; $(CONVERTCASE) -r . ); \
! 		rm -f $$image/open-r/mw/conf/connect.cfg $$image/open-r/mw/conf/object.cfg $$image/open-r/system/conf/wlandflt.txt ; \
  		curt=`date +%Y%m%d%H%M`; \
! 		find $$image -exec touch -ft $$curt \{\} \; ; \
  	fi
  
  
--- 234,255 ----
  
  compile: reportTarget cleanTemps updateTools $(USERLIBS) $(INSTALL_BINS)
  	@image="$(BUILDDIR)/$(notdir $(MEMSTICK_ROOT))" ; \
! 	if [ "$(TEKKOTSU_ROOT)/TARGET_MODEL" -nt "$$image" ] ; then \
  		echo "Deleting old cached OPEN-R binaries"; \
! 		rm -rf "$$image" ; \
  	fi; \
! 	if [ \! -d "$$image" ] ; then \
! 		if [ \! -d "$(SYSTEM_BINARIES)" ] ; then \
  			echo "Could not find OPEN-R system binaries" ; \
  			exit 1 ; \
  		fi ; \
  		echo "Copying system files..." ; \
! 		cp -r "$(SYSTEM_BINARIES)" "$$image" ; \
! 		chmod -R u+w "$$image" ; \
! 		(cd "$$image" && $(CONVERTCASE) -r . ); \
! 		rm -f "$$image/open-r/mw/conf/connect.cfg" "$$image/open-r/mw/conf/object.cfg" "$$image/open-r/system/conf/wlandflt.txt" ; \
  		curt=`date +%Y%m%d%H%M`; \
! 		find "$$image" -exec touch -ft $$curt \{\} \; ; \
  	fi
  
  
***************
*** 455,461 ****
  newstick:
  	$(TEKKOTSU_ROOT)/tools/mntmem $(MEMSTICK_ROOT)
  	rm -rf $(MEMSTICK_ROOT)/*
! 	cp -r $(OPENRSDK_ROOT)/OPEN_R/MS/WCONSOLE/nomemprot/* $(MEMSTICK_ROOT)
  	$(TEKKOTSU_ROOT)/tools/umntmem $(MEMSTICK_ROOT)
  
  $(FILTERSYSWARN):
--- 458,464 ----
  newstick:
  	$(TEKKOTSU_ROOT)/tools/mntmem $(MEMSTICK_ROOT)
  	rm -rf $(MEMSTICK_ROOT)/*
! 	cp -r $(SYSTEM_BINARIES)/* $(MEMSTICK_ROOT)
  	$(TEKKOTSU_ROOT)/tools/umntmem $(MEMSTICK_ROOT)
  
  $(FILTERSYSWARN):
Index: Tekkotsu/project/StartupBehavior.cc
diff -c Tekkotsu/project/StartupBehavior.cc:1.55 Tekkotsu/project/StartupBehavior.cc:1.59
*** Tekkotsu/project/StartupBehavior.cc:1.55	Mon Jan 19 17:04:02 2004
--- Tekkotsu/project/StartupBehavior.cc	Wed Feb 18 16:13:48 2004
***************
*** 9,15 ****
  #include "Behaviors/Controls/ShutdownControl.h"
  
  #include "Motion/MotionCommand.h"
- #include "Motion/PostureMC.h"
  #include "Motion/EmergencyStopMC.h"
  #include "Motion/PIDMC.h"
  #include "Motion/MotionSequenceMC.h"
--- 9,14 ----
***************
*** 41,114 ****
  	//first in case later stuff wants to reference the vision stages)
  	initVision();
  
! 	//This will "fade" in the PIDs so the joints don't jerk to full power, also looks cooler
! 	pid_id=motman->addMotion(SharedObject<PIDMC>(0),MotionManager::kEmergencyPriority+1,false);
! 	//also, pause before we start fading in, PIDs take effect right away, before the emergencystop is picked up
  	erouter->addTimer(this,0,4*FrameTime*NumFrames,true);
  
! 	//This is the default emergency stop
  	const SharedObject<EmergencyStopMC> stop;
! 	stop->LoadFile("/ms/data/motion/liedown.pos"); //This *should* be replaced by the current position, but just in case, better than setting everything to 0's
! 	stop->setStopped(true,false); //if you want to start off paused
! 	//sndman->StopPlay(); //so it doesn't play the halt sound the first time (but the false in previous line does that now)
  	stop_id=motman->addMotion(stop,MotionManager::kEmergencyPriority);
  	
! 	//This displays the current battery conditions
  	BatteryCheckControl batchk;
  	batchk.activate(MotionManager::invalid_MC_ID,NULL);
! 	//	const SharedObject<LedMC> led; //! @todo LedMC's don't support autopruning yet, it should for uses like this, or could the one in Controller
  	//	batchk.activate(motman->addMotion(led,true));
  	batchk.deactivate();
  
! 	//This is for the menu system
  	Controller * controller=new Controller;
  	controller->DoStart();
  	controller->setEStopID(stop_id);
! 	controller->setRoot(SetupMenus());
  	wireless->setReceiver(sout, Controller::console_callback);
  	spawned.push_back(controller);
  	
  	sndman->PlayFile("roar.wav");
  
! 	//This will close the mouth so it doesn't look stupid
! 	//Now done by setting the emergency stop directly in processEvent, but left as demo code:
! 	/*	const SharedObject<PostureMC> closemouth;
! 			closemouth->setJointCmd(MouthOffset,outputRanges[MouthOffset][MaxRange],1);
! 			motman->addMotion(closemouth,MotionCommand::kEmergencyPriority+2,true);
! 	*/
  
! 	//if you didn't want to start off paused, you should throw an un-estop event:
! 	//erouter->postEvent(EventBase(EventBase::estopEGID,MotionManager::invalid_MC_ID,EventBase::deactivateETID,0));
  }
  
  void StartupBehavior::DoStop() {
! 	for(std::vector<BehaviorBase*>::iterator it=spawned.begin(); it!=spawned.end(); it++)
  		(*it)->DoStop();
  	motman->removeMotion(stop_id);
  	BehaviorBase::DoStop();
  }
  
  /*!Uses a few timer events at the beginning to fade in the PID values, and closes the mouth too*/
! void StartupBehavior::processEvent(const EventBase&) {
! 	static unsigned int start_time=-1U;
! 	const unsigned int tot_time=2000; 
! 	if(start_time==-1U) { //first time
! 		start_time=get_time();
! 		MMAccessor<EmergencyStopMC>(stop_id)->takeSnapshot(); //take new snapshot with hopefully valid data
! 	} else {
! 		float power=(get_time()-start_time)/(float)tot_time;
! 		if(power>1)
! 			power=1;
! 		{ MMAccessor<PIDMC>(pid_id)->setAllPowerLevel(power); }
  		if(state->robotDesign & WorldState::ERS210Mask)
! 			{ MMAccessor<EmergencyStopMC>(stop_id)->setOutputCmd(ERS210Info::MouthOffset,outputRanges[ERS210Info::MouthOffset][MaxRange]); }
  		if(state->robotDesign & WorldState::ERS7Mask)
! 			{ MMAccessor<EmergencyStopMC>(stop_id)->setOutputCmd(ERS7Info::MouthOffset,outputRanges[ERS7Info::MouthOffset][MaxRange]); }
! 	}
! 	if((get_time()-start_time)>=tot_time) {
! 		erouter->removeTimer(this);
! 		motman->removeMotion(pid_id);
! 		pid_id=MotionManager::invalid_MC_ID;
  	}
  }
  
--- 40,146 ----
  	//first in case later stuff wants to reference the vision stages)
  	initVision();
  
! 	//This will "fade" in the PIDs so the joints don't jerk to full
! 	//power, also looks cooler
! 	pid_id=motman->addMotion(SharedObject<PIDMC>(0),MotionManager::kEmergencyPriority+2,false);
! 	//also, pause before we start fading in, PIDs take effect right
! 	//away, before the emergencystop is picked up
  	erouter->addTimer(this,0,4*FrameTime*NumFrames,true);
  
! 	//This sets up the default emergency stop
  	const SharedObject<EmergencyStopMC> stop;
! 	//if you want to start off unpaused, either change 'true' to
! 	//'false', or just comment out the next line (estop's efault is off)
! 	//Note that if you don't want to start in estop, you should then
! 	//also uncomment the line at the end of this function
! 	stop->setStopped(true,false); 
  	stop_id=motman->addMotion(stop,MotionManager::kEmergencyPriority);
  	
! 	//This displays the current battery conditions on the console
  	BatteryCheckControl batchk;
  	batchk.activate(MotionManager::invalid_MC_ID,NULL);
! 	//	const SharedObject<LedMC> led; //! @todo LedMC's don't support autopruning yet, it should for uses like this
  	//	batchk.activate(motman->addMotion(led,true));
  	batchk.deactivate();
  
! 	//This is what runs the menu system
  	Controller * controller=new Controller;
  	controller->DoStart();
  	controller->setEStopID(stop_id);
! 	controller->setRoot(SetupMenus()); //this triggers the layout of the menus themselves
  	wireless->setReceiver(sout, Controller::console_callback);
  	spawned.push_back(controller);
  	
  	sndman->PlayFile("roar.wav");
  
! 	//This will close the mouth so it doesn't look stupid or get in the
! 	//way of head motions (ERS-210 or ERS-7 only)
! 	unsigned int mouthOffset=-1U;
! 	if(state->robotDesign & WorldState::ERS210Mask)
! 		mouthOffset=ERS210Info::MouthOffset;
! 	if(state->robotDesign & WorldState::ERS7Mask)
! 		mouthOffset=ERS7Info::MouthOffset;
! 	if(mouthOffset!=-1U) {
! 		SharedObject<MotionSequenceMC<MotionSequence::SizeTiny> > closeMouth;
! 		closeMouth->setPlayTime(3000); //take 3 seconds to close the mouth
! 		closeMouth->setOutputCmd(mouthOffset,outputRanges[mouthOffset][MaxRange]);
! 		closeMouth->setPlayTime(3500); //and hold it for another .5 seconds
! 		closeMouth->setOutputCmd(mouthOffset,outputRanges[mouthOffset][MaxRange]);
! 		motman->addMotion(closeMouth,MotionManager::kEmergencyPriority+1,true);
! 		erouter->addTimer(this,1,3250,false);
! 	}
  
! 	//if you didn't want to start off paused, you should throw an
! 	//un-estop event.  This will make it clear to any background
! 	//behaviors (namely WorldStateVelDaemon) that we're not in estop
! 	//erouter->postEvent(new EventBase(EventBase::estopEGID,MotionManager::invalid_MC_ID,EventBase::deactivateETID,0));
  }
  
  void StartupBehavior::DoStop() {
! 	for(std::vector<BehaviorBase*>::iterator it=spawned.begin(); it!=spawned.end(); it++) {
! 		cout << "StartupBehavior stopping spawned: " << (*it)->getName() << endl;
  		(*it)->DoStop();
+ 	}
  	motman->removeMotion(stop_id);
  	BehaviorBase::DoStop();
  }
  
  /*!Uses a few timer events at the beginning to fade in the PID values, and closes the mouth too*/
! void StartupBehavior::processEvent(const EventBase& event) {
! 	if(event.getGeneratorID()==EventBase::timerEGID && event.getSourceID()==0) {
! 		//this will do the work of fading in the PID values.  It helps the joints
! 		//to power up without twitching
! 		static unsigned int start_time=-1U;
! 		const unsigned int tot_time=2000; 
! 		if(start_time==-1U) { //first time
! 			start_time=get_time();
! 		} else {
! 			float power=(get_time()-start_time)/(float)tot_time;
! 			if(power>1)
! 				power=1;
! 			MMAccessor<PIDMC>(pid_id)->setAllPowerLevel(power*power);
! 		}
! 		if((get_time()-start_time)>=tot_time) {
! 			erouter->removeTimer(this,0);
! 			motman->removeMotion(pid_id);
! 			pid_id=MotionManager::invalid_MC_ID;
! 		}
! 	}
! 
! 	if(event.getGeneratorID()==EventBase::timerEGID && event.getSourceID()==1) {
! 		//we're done closing the mouth... set the mouth to closed in the estop too
! 		//otherwise it might twitch a little when the MotionSequence expires and the estop takes over
! 		// (little == +/-.1 radians, aka estop's threshold for resetting an "out of place" joint) (details, details)
! 		unsigned int mouthOffset=-1U;
  		if(state->robotDesign & WorldState::ERS210Mask)
! 			mouthOffset=ERS210Info::MouthOffset;
  		if(state->robotDesign & WorldState::ERS7Mask)
! 			mouthOffset=ERS7Info::MouthOffset;
! 		if(mouthOffset!=-1U) {
! 			MMAccessor<EmergencyStopMC> estop(stop_id);
! 			float weight=estop->getOutputCmd(mouthOffset).weight;
! 			estop->setOutputCmd(mouthOffset,OutputCmd(outputRanges[mouthOffset][MaxRange],weight));
! 		}
  	}
  }
  
Index: Tekkotsu/project/StartupBehavior.h
diff -c Tekkotsu/project/StartupBehavior.h:1.10 Tekkotsu/project/StartupBehavior.h:1.11
*** Tekkotsu/project/StartupBehavior.h:1.10	Tue Dec  9 18:56:58 2003
--- Tekkotsu/project/StartupBehavior.h	Mon Feb  9 17:45:29 2004
***************
*** 9,26 ****
  class Controller; // defined in Controller.h, don't actually need header file yet
  class ControlBase; // defined in ControlBase.h, don't actually need header file yet
  
! //! This Behavior is the only hardcoded behavior by the framework to start up once all the data structures and such are set up
  
  /*! This is done by assigning an instance of StartupBehavior to the
!  *  global ::startupBehavior variable.  Note that there's nothing
!  *  special about the type of this class, it's just another
!  *  BehaviorBase - ::startupBehavior could be any behavior.  If you
!  *  want some other behavior to run automatically at startup, simply
!  *  remove StartupBehavior from the project and assign an instance of
!  *  your own class to ::startupBehavior instead.
   *
!  *  By default, this behavior is similar in idea to the init process
!  *  in unix/linux. */
  class StartupBehavior : public BehaviorBase {
  public:
  	//! Constructor
--- 9,43 ----
  class Controller; // defined in Controller.h, don't actually need header file yet
  class ControlBase; // defined in ControlBase.h, don't actually need header file yet
  
! //! This is the default init behavior - it launches daemons, builds the Controller menu structure, does some nice things to fade the joints in to full power (reduces twitch)
  
  /*! This is done by assigning an instance of StartupBehavior to the
!  *  global ProjectInterface::startupBehavior variable.  Note that
!  *  there's nothing special about the type of this class, it's just
!  *  another BehaviorBase - ProjectInterface::startupBehavior could be
!  *  any behavior.
!  *  
!  *  If you want some other behavior to handle the root initialization,
!  *  simply remove the assignment of ::theStartup to startupBehavior at
!  *  the beginning of StartupBehavior.cc.  Then you can substitute your
!  *  own behavior instead.  Probably a good way to distribute project
!  *  code when you're all done with development and want to ship a
!  *  single-purpose memory stick (assuming your users won't want to get
!  *  access to things like the Controller anymore... up to you.)
   *
!  *  If all you want to do is get your behavior to launch at startup,
!  *  you don't need to replace this.  Just add a menu entry.  (in say,
!  *  the Mode Switch menu, which is separated out into
!  *  StartupBehavior_SetupModeSwitch.cc for reduced recompilation after
!  *  header files are modified) If you use a BehaviorSwitchControl, you
!  *  can call its BehaviorSwitchControl::start() method to start the
!  *  behavior it controls as you add it to the menu.  There are several
!  *  examples of this usage in the Background Behaviors menu
!  *  (StartupBehavior_SetupBackgroundBehaviors.cc)
!  *
!  *  This behavior is similar in idea to the init process in
!  *  unix/linux.
!  */
  class StartupBehavior : public BehaviorBase {
  public:
  	//! Constructor
***************
*** 51,60 ****
  	virtual void initVision(); //!< Sets up the vision pipelines (held in StartupBehavior_SetupVision.cc)
  
  	virtual void startSubMenu(); //!< future calls to addItem() will be placed under the most recently added item
! 	virtual void addItem(ControlBase * control); //!< inserts a control at the end of the menu
  	virtual ControlBase* endSubMenu();  //!< closes out a submenu so that future calls to addItem() will be added to the enclosing menu, returns the menu being closed out
  
! 	std::vector<BehaviorBase*> spawned; //!< Behaviors spawned from DoStart, so they can automatically be stopped on DoStop
  	std::stack<ControlBase*> setup;     //!< only used during setup - easier than passing it around all the functions
  	MotionManager::MC_ID stop_id; //!< the main EmergencyStopMC
  	MotionManager::MC_ID pid_id; //!< used to fade in the PIDs up to full strength (from initial zero) This is so the joints don't jerk on startup.
--- 68,77 ----
  	virtual void initVision(); //!< Sets up the vision pipelines (held in StartupBehavior_SetupVision.cc)
  
  	virtual void startSubMenu(); //!< future calls to addItem() will be placed under the most recently added item
! 	virtual void addItem(ControlBase * control); //!< inserts a control at the end of the current menu
  	virtual ControlBase* endSubMenu();  //!< closes out a submenu so that future calls to addItem() will be added to the enclosing menu, returns the menu being closed out
  
! 	std::vector<BehaviorBase*> spawned; //!< Holds pointers to all the behaviors spawned from DoStart, so they can automatically be stopped on DoStop (should only happen on shutdown, but ensures cleanliness)
  	std::stack<ControlBase*> setup;     //!< only used during setup - easier than passing it around all the functions
  	MotionManager::MC_ID stop_id; //!< the main EmergencyStopMC
  	MotionManager::MC_ID pid_id; //!< used to fade in the PIDs up to full strength (from initial zero) This is so the joints don't jerk on startup.
Index: Tekkotsu/project/StartupBehavior_SetupVision.cc
diff -c Tekkotsu/project/StartupBehavior_SetupVision.cc:1.12 Tekkotsu/project/StartupBehavior_SetupVision.cc:1.14
*** Tekkotsu/project/StartupBehavior_SetupVision.cc:1.12	Thu Feb  5 14:35:47 2004
--- Tekkotsu/project/StartupBehavior_SetupVision.cc	Mon Feb 23 11:17:15 2004
***************
*** 40,61 ****
  	unsigned int numSystemLayers=3;
  
  	defRawCameraGenerator = new RawCameraGenerator(numSystemLayers,numLayers,EventBase::visOFbkEGID,0,visRawCameraSID);
- 	defRawCameraGenerator->DoStart();
- 	spawned.push_back(defRawCameraGenerator);
  
  	defInterleavedYUVGenerator = new InterleavedYUVGenerator(EventBase::visRawCameraEGID,visRawCameraSID,visInterleaveSID,RawCameraGenerator::CHAN_Y,RawCameraGenerator::CHAN_U,RawCameraGenerator::CHAN_V);
- 	defInterleavedYUVGenerator->DoStart();
- 	spawned.push_back(defInterleavedYUVGenerator);
  
  	defColorJPEGGenerator = new JPEGGenerator(EventBase::visInterleaveEGID,visInterleaveSID,visColorJPEGSID,JPEGGenerator::SRC_AUTO);
- 	defColorJPEGGenerator->DoStart();
  	defColorJPEGGenerator->setName("ColorJPEGGenerator");
- 	spawned.push_back(defColorJPEGGenerator);
  
  	defGrayscaleJPEGGenerator = new JPEGGenerator(EventBase::visRawCameraEGID,visRawCameraSID,visGrayscaleJPEGSID,JPEGGenerator::SRC_AUTO);
- 	defGrayscaleJPEGGenerator->DoStart();
  	defGrayscaleJPEGGenerator->setName("GrayscaleJPEGGenerator");
- 	spawned.push_back(defGrayscaleJPEGGenerator);
  
  	// the hardware level CDT generator allows faster, but less flexible
  	// segmenting it still needs a little work though before it can be
--- 40,53 ----
***************
*** 66,83 ****
  	segcol->loadColorInfo(config->vision.colors);
  	for(unsigned int i=0; i<config->vision.thresh.size(); i++)
  		segcol->loadThresholdMap(config->vision.thresh[i]);
- 	if(config->vision.colors!="" && config->vision.thresh.size()>0) {
- 		defSegmentedColorGenerator->DoStart();
- 		spawned.push_back(defSegmentedColorGenerator);
- 	}
  
  	defRLEGenerator = new RLEGenerator(EventBase::visSegmentEGID,visSegmentSID,visRLESID);
- 	defRLEGenerator->DoStart();
- 	spawned.push_back(defRLEGenerator);
  	
  	defRegionGenerator = new RegionGenerator(EventBase::visRLEEGID,visRLESID,visRegionSID);
- 	defRegionGenerator->DoStart();
- 	spawned.push_back(defRegionGenerator);
  	
  	// for lack of a better idea, the object recognizers below will all
  	// use the config->vision.rlecam_channel for picking the threshold
--- 58,67 ----
***************
*** 100,121 ****
  	if(pinkIdx!=-1U) {
  		pball = new BallDetectionGenerator(EventBase::visRegionEGID,visRegionSID,visPinkBallSID,pinkIdx,threshChan,noiseFiltering,confidenceThreshold);
  		pball->setName("PinkBallDetectionGenerator");
- 		pball->DoStart();
- 		spawned.push_back(pball);
  	}
  	unsigned int blueIdx=segcol->getColorIndex("blue");
  	if(blueIdx!=-1U) {
  		bball = new BallDetectionGenerator(EventBase::visRegionEGID,visRegionSID,visBlueBallSID,blueIdx,threshChan,noiseFiltering,confidenceThreshold);
! 		pball->setName("BlueBallDetectionGenerator");
! 		bball->DoStart();
! 		spawned.push_back(bball);
  	}
  	unsigned int skinIdx=segcol->getColorIndex("brown");
  	if(skinIdx!=-1U) {
  		handball = new BallDetectionGenerator(EventBase::visRegionEGID,visRegionSID,visHandSID,skinIdx,threshChan,noiseFiltering,confidenceThreshold);
! 		pball->setName("HandBallDetectionGenerator");
! 		handball->DoStart();
! 		spawned.push_back(handball);
  	}
  }
  
--- 84,99 ----
  	if(pinkIdx!=-1U) {
  		pball = new BallDetectionGenerator(EventBase::visRegionEGID,visRegionSID,visPinkBallSID,pinkIdx,threshChan,noiseFiltering,confidenceThreshold);
  		pball->setName("PinkBallDetectionGenerator");
  	}
  	unsigned int blueIdx=segcol->getColorIndex("blue");
  	if(blueIdx!=-1U) {
  		bball = new BallDetectionGenerator(EventBase::visRegionEGID,visRegionSID,visBlueBallSID,blueIdx,threshChan,noiseFiltering,confidenceThreshold);
! 		bball->setName("BlueBallDetectionGenerator");
  	}
  	unsigned int skinIdx=segcol->getColorIndex("brown");
  	if(skinIdx!=-1U) {
  		handball = new BallDetectionGenerator(EventBase::visRegionEGID,visRegionSID,visHandSID,skinIdx,threshChan,noiseFiltering,confidenceThreshold);
! 		handball->setName("HandBallDetectionGenerator");
  	}
  }
  
***************
*** 124,139 ****
  	addItem(new ControlBase("Vision Pipeline","Start/Stop stages of the vision pipeline"));
  	startSubMenu();
  	{ 
! 		addItem(new BehaviorSwitchControlBase(defRawCameraGenerator));
! 		addItem(new BehaviorSwitchControlBase(defInterleavedYUVGenerator));
! 		addItem(new BehaviorSwitchControlBase(defColorJPEGGenerator));
! 		addItem(new BehaviorSwitchControlBase(defGrayscaleJPEGGenerator));
! 		addItem(new BehaviorSwitchControlBase(defSegmentedColorGenerator));
! 		addItem(new BehaviorSwitchControlBase(defRLEGenerator));
! 		addItem(new BehaviorSwitchControlBase(defRegionGenerator));
! 		addItem(new BehaviorSwitchControlBase(pball));
! 		addItem(new BehaviorSwitchControlBase(bball));
! 		addItem(new BehaviorSwitchControlBase(handball));
  	}
  	return endSubMenu();
  }
--- 102,120 ----
  	addItem(new ControlBase("Vision Pipeline","Start/Stop stages of the vision pipeline"));
  	startSubMenu();
  	{ 
! 		addItem((new BehaviorSwitchControlBase(defRawCameraGenerator))->start());
! 		addItem((new BehaviorSwitchControlBase(defInterleavedYUVGenerator))->start());
! 		addItem((new BehaviorSwitchControlBase(defColorJPEGGenerator))->start());
! 		addItem((new BehaviorSwitchControlBase(defGrayscaleJPEGGenerator))->start());
! 		if(config->vision.colors!="" && config->vision.thresh.size()>0)
! 			addItem((new BehaviorSwitchControlBase(defSegmentedColorGenerator))->start());
! 		else
! 			addItem(new BehaviorSwitchControlBase(defSegmentedColorGenerator));
! 		addItem((new BehaviorSwitchControlBase(defRLEGenerator))->start());
! 		addItem((new BehaviorSwitchControlBase(defRegionGenerator))->start());
! 		addItem((new BehaviorSwitchControlBase(pball))->start());
! 		addItem((new BehaviorSwitchControlBase(bball))->start());
! 		addItem((new BehaviorSwitchControlBase(handball))->start());
  	}
  	return endSubMenu();
  }
Index: Tekkotsu/project/StartupBehavior_SetupWalkEdit.cc
diff -c Tekkotsu/project/StartupBehavior_SetupWalkEdit.cc:1.6 Tekkotsu/project/StartupBehavior_SetupWalkEdit.cc:1.7
*** Tekkotsu/project/StartupBehavior_SetupWalkEdit.cc:1.6	Fri Jan 16 00:14:39 2004
--- Tekkotsu/project/StartupBehavior_SetupWalkEdit.cc	Wed Feb 25 20:03:00 2004
***************
*** 9,18 ****
   * @author PA Gov. School for the Sciences 2003 Team Project - Motion group: Haoqian Chen, Yantian Martin, Jon Stahlman (creators)
   * 
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #include "StartupBehavior.h"
--- 9,18 ----
   * @author PA Gov. School for the Sciences 2003 Team Project - Motion group: Haoqian Chen, Yantian Martin, Jon Stahlman (creators)
   * 
   * $Author: ejt $
!  * $Name: HEAD $
!  * $Revision: 1.1 $
   * $State: Exp $
!  * $Date: 2004/03/17 04:36:38 $
   */
  
  #include "StartupBehavior.h"
***************
*** 126,132 ****
  		startSubMenu();
  		{ 
  			addItem(new WalkCalibration());
! 			addItem(new LoadCalibration<3,11>(walker->getWalkMC()->getCP().f_calibration,walker->getWalkMC()->getCP().b_calibration));
  			addItem(new ValueEditControl<float>("forward max_accel",&walker->getWalkMC()->getCP().max_accel[WalkMC::CalibrationParam::forward]));
  			addItem(new ValueEditControl<float>("reverse max_accel",&walker->getWalkMC()->getCP().max_accel[WalkMC::CalibrationParam::reverse]));
  			addItem(new ValueEditControl<float>("strafe max_accel",&walker->getWalkMC()->getCP().max_accel[WalkMC::CalibrationParam::strafe]));
--- 126,132 ----
  		startSubMenu();
  		{ 
  			addItem(new WalkCalibration());
! 			addItem(new LoadCalibration(&walker->getWalkMC()->getCP()));
  			addItem(new ValueEditControl<float>("forward max_accel",&walker->getWalkMC()->getCP().max_accel[WalkMC::CalibrationParam::forward]));
  			addItem(new ValueEditControl<float>("reverse max_accel",&walker->getWalkMC()->getCP().max_accel[WalkMC::CalibrationParam::reverse]));
  			addItem(new ValueEditControl<float>("strafe max_accel",&walker->getWalkMC()->getCP().max_accel[WalkMC::CalibrationParam::strafe]));
Index: Tekkotsu/project/ms/config/ball.tm
Index: Tekkotsu/project/ms/config/ttt.col
diff -c /dev/null Tekkotsu/project/ms/config/ttt.col:1.1
*** /dev/null	Tue Mar 16 23:08:33 2004
--- Tekkotsu/project/ms/config/ttt.col	Wed Mar  3 18:14:44 2004
***************
*** 0 ****
--- 1,10 ----
+ 0 (128 128 128) "unclassified" 8 1.00
+ 1 (43 60 77) "blue" 8 0.75
+ 2 (75 128 45) "green" 8 0.75
+ 3 (142 95 33) "orange" 8 0.75
+ 4 (192 126 142) "pink" 8 0.75
+ 5 (234 21 56) "red" 8 0.75
+ 6 (249 249 9) "yellow" 8 0.75
+ 7 (9 244 225) "cyan" 8 0.75
+ 8 (200 14 204) "magenta" 8 0.75
+ 9 (76 254 247) "lime" 8 0.75
Index: Tekkotsu/project/ms/config/ttt.tm
Index: Tekkotsu/project/ms/config/ttt_old.tm
Index: Tekkotsu/project/ms/data/motion/README.txt
diff -c Tekkotsu/project/ms/data/motion/README.txt:1.2 Tekkotsu/project/ms/data/motion/README.txt:removed
*** Tekkotsu/project/ms/data/motion/README.txt:1.2	Sat Apr 26 17:17:05 2003
--- Tekkotsu/project/ms/data/motion/README.txt	Tue Mar 16 23:08:33 2004
***************
*** 1,43 ****
- .mot files are for use by the MotionSequence classes.
-      http://www.tekkotsu.org/dox/classMotionSequence.html
- .pos files are for use by the PositionEngine classes.
-      http://www.tekkotsu.org/dox/classPostureEngine.html
- 
- Both are text files and are human-editable.  See documentation for details.
- 
- The following motion files were converted from CMPack'02 files and fall under
- their license:
- *   Misc: dance.mot
- * Getups: gu_back.mot gu_front.mot gu_side.mot 
- *  Kicks: k_bump.mot k_diag.mot k_dive.mot k_fwd.mot k_grab.mot
-           k_head.mot k_heads.mot k_hold.mot k_punch.mot
- 
- See tools/convertmot for the conversion code and original motion files.
- 
-   LICENSE:
-   =========================================================================
-     CMPack'02 Source Code Release for OPEN-R SDK v1.0
-     Copyright (C) 2002 Multirobot Lab [Project Head: Manuela Veloso]
-     School of Computer Science, Carnegie Mellon University
-   -------------------------------------------------------------------------
-     This software is distributed under the GNU General Public License,
-     version 2.  If you do not have a copy of this licence, visit
-     www.gnu.org, or write: Free Software Foundation, 59 Temple Place,
-     Suite 330 Boston, MA 02111-1307 USA.  This program is distributed
-     in the hope that it will be useful, but WITHOUT ANY WARRANTY,
-     including MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-   -------------------------------------------------------------------------
-     Additionally licensed to Sony Corporation under the following terms:
- 
-     This software is provided by the copyright holders AS IS and any
-     express or implied warranties, including, but not limited to, the
-     implied warranties of merchantability and fitness for a particular
-     purpose are disclaimed.  In no event shall authors be liable for
-     any direct, indirect, incidental, special, exemplary, or consequential
-     damages (including, but not limited to, procurement of substitute
-     goods or services; loss of use, data, or profits; or business
-     interruption) however caused and on any theory of liability, whether
-     in contract, strict liability, or tort (including negligence or
-     otherwise) arising in any way out of the use of this software, even if
-     advised of the possibility of such damage.
-   =========================================================================
--- 0 ----
Index: Tekkotsu/project/ms/data/motion/clearcal.txt
diff -c Tekkotsu/project/ms/data/motion/clearcal.txt:1.1 Tekkotsu/project/ms/data/motion/clearcal.txt:1.2
*** Tekkotsu/project/ms/data/motion/clearcal.txt:1.1	Fri Jan 16 00:14:52 2004
--- Tekkotsu/project/ms/data/motion/clearcal.txt	Wed Feb 25 20:03:05 2004
***************
*** 1,3 ****
--- 1,4 ----
+ 180 180 140 1.8
  1 0 0 0 0 0 0 0 0 0 0
  0 1 0 0 0 0 0 0 0 0 0
  0 0 1 0 0 0 0 0 0 0 0
Index: Tekkotsu/project/ms/data/motion/readme.txt
diff -c /dev/null Tekkotsu/project/ms/data/motion/readme.txt:1.1
*** /dev/null	Tue Mar 16 23:08:33 2004
--- Tekkotsu/project/ms/data/motion/readme.txt	Wed Feb 18 16:14:14 2004
***************
*** 0 ****
--- 1,43 ----
+ .mot files are for use by the MotionSequence classes.
+      http://www.tekkotsu.org/dox/classMotionSequence.html
+ .pos files are for use by the PositionEngine classes.
+      http://www.tekkotsu.org/dox/classPostureEngine.html
+ 
+ Both are text files and are human-editable.  See documentation for details.
+ 
+ The following motion files were converted from CMPack'02 files and fall under
+ their license:
+ *   Misc: dance.mot
+ * Getups: gu_back.mot gu_front.mot gu_side.mot 
+ *  Kicks: k_bump.mot k_diag.mot k_dive.mot k_fwd.mot k_grab.mot
+           k_head.mot k_heads.mot k_hold.mot k_punch.mot
+ 
+ See tools/convertmot for the conversion code and original motion files.
+ 
+   LICENSE:
+   =========================================================================
+     CMPack'02 Source Code Release for OPEN-R SDK v1.0
+     Copyright (C) 2002 Multirobot Lab [Project Head: Manuela Veloso]
+     School of Computer Science, Carnegie Mellon University
+   -------------------------------------------------------------------------
+     This software is distributed under the GNU General Public License,
+     version 2.  If you do not have a copy of this licence, visit
+     www.gnu.org, or write: Free Software Foundation, 59 Temple Place,
+     Suite 330 Boston, MA 02111-1307 USA.  This program is distributed
+     in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+     including MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+   -------------------------------------------------------------------------
+     Additionally licensed to Sony Corporation under the following terms:
+ 
+     This software is provided by the copyright holders AS IS and any
+     express or implied warranties, including, but not limited to, the
+     implied warranties of merchantability and fitness for a particular
+     purpose are disclaimed.  In no event shall authors be liable for
+     any direct, indirect, incidental, special, exemplary, or consequential
+     damages (including, but not limited to, procurement of substitute
+     goods or services; loss of use, data, or profits; or business
+     interruption) however caused and on any theory of liability, whether
+     in contract, strict liability, or tort (including negligence or
+     otherwise) arising in any way out of the use of this software, even if
+     advised of the possibility of such damage.
+   =========================================================================
Index: Tekkotsu/project/ms/data/motion/walk.prm
Index: Tekkotsu/project/ms/data/motion/walkcal.txt
diff -c Tekkotsu/project/ms/data/motion/walkcal.txt:1.1 Tekkotsu/project/ms/data/motion/walkcal.txt:1.3
*** Tekkotsu/project/ms/data/motion/walkcal.txt:1.1	Fri Jan 16 00:14:53 2004
--- Tekkotsu/project/ms/data/motion/walkcal.txt	Fri Feb 27 20:58:55 2004
***************
*** 1,6 ****
!    1.1114950e+00   4.3793349e-02   3.6191516e+00  -2.8528403e-02  -1.0704690e+01  -1.6630287e+00  -1.0161892e-03  -1.9307957e-01  -1.0145463e-03   1.4387497e-01   2.5358894e+01
!   -1.5982849e-01   1.0121667e+00   8.4120978e+00  -1.3995280e-01  -5.7703782e+00   1.3642099e+01   1.1882969e-03  -1.1940036e-01   1.6860327e-03   2.2186785e-01   8.3247298e-01
!   -4.4086430e-04   3.6943915e-04   8.7219349e-01  -2.5621177e-04  -3.3549634e-02  -1.9053515e-03   2.5930239e-06  -7.8055622e-04   5.3484361e-06  -5.1855276e-05  -5.6217769e-03
!    1.4482688e+00  -2.8729604e-02   4.5315047e+00  -8.5684548e-02  -5.6070133e+00   1.6249840e+00   1.0114119e-03   2.0565857e-02   1.0163411e-03   2.9049390e-02   1.5138783e+01
!    1.8276090e-01   9.3280284e-01   8.4702686e+00  -2.6450978e-01  -8.3210648e+00   1.8642117e+01   1.8136075e-03  -1.1893791e-01  -6.1321027e-03   2.3487379e-01   6.6955859e+00
!   -3.4424686e-04   8.9065162e-04   8.7164554e-01   6.7355169e-04  -2.3861994e-02  -3.3616614e-02  -6.0636630e-06   3.8511214e-05   2.4927650e-05   9.4197067e-05  -2.2472680e-02
--- 1,7 ----
!    1.6000000e+02   1.5600000e+02   1.0300000e+02   2.0300000e+00
!    1.0479296e+00   2.0957160e-02   8.8388537e-01  -9.5867538e-02  -1.5343588e+01   9.1434057e-01  -7.2849794e-04  -1.9043844e-01  -9.4217255e-04   1.3391235e-01   3.0318738e+01
!   -1.2401241e-01   1.2913247e+00   8.8065656e+00  -1.2531225e-01  -1.9330677e+00  -9.6356296e+00   9.7583905e-04   1.2609761e-02   2.6829485e-04   1.8947370e-01  -2.9499687e-01
!   -7.4470449e-04   2.0721810e-04   8.5081328e-01  -3.9949940e-04  -3.6176833e-02   1.2013283e-01   4.4201870e-06  -2.2070940e-03   6.4104057e-06  -4.0661670e-04   2.2978403e-03
!    1.6386469e+00   4.4100098e-03   8.9295190e-01  -2.8468175e-01  -1.4036527e+01   3.1974737e+00   2.0310144e-03   2.8690882e-02   8.2136973e-04   6.5590462e-02   2.7178124e+01
!    1.1518999e-01   1.3083468e+00   8.6445766e+00  -2.2024709e-01  -4.5113527e+00  -9.3532091e+00   1.3076631e-03  -2.2767081e-01  -4.0793505e-03   2.2162944e-01   4.5452246e+00
!    2.0441291e-04   1.2304346e-04   8.5184341e-01   2.9945103e-04  -4.0769178e-02   1.1502130e-01  -3.1701517e-06   1.2370161e-03   1.9654829e-05  -3.6545940e-04   5.2478263e-03
Index: Tekkotsu/tools/buildRelease
diff -c Tekkotsu/tools/buildRelease:1.34 Tekkotsu/tools/buildRelease:1.37
*** Tekkotsu/tools/buildRelease:1.34	Thu Feb  5 22:33:21 2004
--- Tekkotsu/tools/buildRelease	Tue Mar 16 23:06:58 2004
***************
*** 44,51 ****
  	exit 1;
  fi;
  
! if [ `grep -c "$1" docs/html/index.html` -eq 0 ] ; then
! 	echo "Version mismatch with docs/doxygencfg - you forgot to update PROJECT_NUMBER";
  	exit 1;
  fi;
  
--- 44,56 ----
  	exit 1;
  fi;
  
! if [ `grep -c "Tekkotsu_doc_$1.tar.gz" docs/html/index.html` -eq 0 ] ; then
! 	echo "Version mismatch with docs/html/index.html - you forgot to update the documentation link URL";
! 	exit 1;
! fi;
! 
! if [ `grep -c "(v$1," docs/html/index.html` -eq 0 ] ; then
! 	echo "Version mismatch with docs/html/index.html - you forgot to update the documentation link's text";
  	exit 1;
  fi;
  
***************
*** 73,78 ****
--- 78,92 ----
  
  
  
+ #build patch files
+ 
+ echo "Building patch files..."
+ cd ${tmp}
+ cvs rdiff -r ${oldtag} -r ${newtag} Tekkotsu > Tekkotsu_patch_$2_to_$1.diff;
+ cvs rdiff -r ${oldtag} -r ${newtag} Tekkotsu/project > Tekkotsu_patch_project_$2_to_$1.diff;
+ 
+ 
+ 
  #build memstick image tarball
  
  cd ${tmp}/Tekkotsu_$1;
***************
*** 124,130 ****
  cd ${tmp}/Tekkotsu_$1;
  cd project;
  
- export OPENRSDK_ROOT=/usr0/OPEN_R_SDK_ERS7
  for x in TGT_ERS7; do
  	echo $x > ${TEKKOTSU_ROOT}/TARGET_MODEL;
  	printf "\n\nTesting $x build\n\n\n";
--- 138,143 ----
***************
*** 172,186 ****
  cd ${tmp};
  cp -r Tekkotsu_$1/tools/mon Tekkotsu_mon_$1;
  tar -cvzf Tekkotsu_mon_$1.tar.gz Tekkotsu_mon_$1;
- 
- 
- 
- #build patch file
- 
- echo "Building patch files..."
- cd ${tmp}
- cvs rdiff -r ${oldtag} -r ${newtag} Tekkotsu > Tekkotsu_patch_$2_to_$1.diff;
- cvs rdiff -r ${oldtag} -r ${newtag} Tekkotsu/project > Tekkotsu_patch_project_$2_to_$1.diff;
  
  
  
--- 185,190 ----
Index: Tekkotsu/tools/ftpinstall
diff -c Tekkotsu/tools/ftpinstall:1.1 Tekkotsu/tools/ftpinstall:1.2
*** Tekkotsu/tools/ftpinstall:1.1	Mon Jul 28 02:34:13 2003
--- Tekkotsu/tools/ftpinstall	Thu Feb 19 18:07:51 2004
***************
*** 7,14 ****
  $|=1;
  
  use Socket;
! $username = "lycra";
! $password = "lives";
  
  #----- set default options -----
  $message        = "\n ftpinstall - install MS tree using TinyFTP\n\n"
--- 7,14 ----
  $|=1;
  
  use Socket;
! $username = "ftpinst";
! $password = "ftpinst";
  
  #----- set default options -----
  $message        = "\n ftpinstall - install MS tree using TinyFTP\n\n"
Index: Tekkotsu/tools/ftpupdate
diff -c Tekkotsu/tools/ftpupdate:1.1 Tekkotsu/tools/ftpupdate:1.2
*** Tekkotsu/tools/ftpupdate:1.1	Mon Jul 28 02:34:13 2003
--- Tekkotsu/tools/ftpupdate	Thu Feb 19 18:07:51 2004
***************
*** 7,14 ****
  $|=1;
  
  use Socket;
! $username = "lycra";
! $password = "lives";
  
  #----- set default options -----
  $message        = "\n ftpupdate - install MS tree using TinyFTP\n\n"
--- 7,14 ----
  $|=1;
  
  use Socket;
! $username = "ftpinst";
! $password = "ftpinst";
  
  #----- set default options -----
  $message        = "\n ftpupdate - install MS tree using TinyFTP\n\n"
Index: Tekkotsu/tools/mon/ControllerGUI
diff -c Tekkotsu/tools/mon/ControllerGUI:1.3 Tekkotsu/tools/mon/ControllerGUI:1.4
*** Tekkotsu/tools/mon/ControllerGUI:1.3	Mon Nov 24 16:22:29 2003
--- Tekkotsu/tools/mon/ControllerGUI	Tue Mar 16 12:47:09 2004
***************
*** 1,2 ****
  #!/bin/sh
! java -Xmx256M org/tekkotsu/mon/ControllerGUI $*
\ No newline at end of file
--- 1,2 ----
  #!/bin/sh
! java -Xmx256M org.tekkotsu.mon.ControllerGUI $*
Index: Tekkotsu/tools/mon/lognow
diff -c Tekkotsu/tools/mon/lognow:1.1 Tekkotsu/tools/mon/lognow:1.2
*** Tekkotsu/tools/mon/lognow:1.1	Wed Jan 28 16:07:44 2004
--- Tekkotsu/tools/mon/lognow	Tue Mar 16 12:47:09 2004
***************
*** 1,2 ****
  #!/bin/sh
! java org/tekkotsu/mon/JointLogger $*
--- 1,2 ----
  #!/bin/sh
! java org.tekkotsu.mon.JointLogger $*
Index: Tekkotsu/tools/mon/plotlog.m
diff -c Tekkotsu/tools/mon/plotlog.m:1.2 Tekkotsu/tools/mon/plotlog.m:1.4
*** Tekkotsu/tools/mon/plotlog.m:1.2	Thu Feb  5 19:45:57 2004
--- Tekkotsu/tools/mon/plotlog.m	Tue Feb 24 16:27:27 2004
***************
*** 296,301 ****
--- 296,309 ----
    bodypos(step,1)=dl+dr+bodypos(step-1,1);
    bodypos(step,4)=rot+bodypos(step-1,4);
  end
+ 
+ step=1;
+ %while(step<samplecount){
+ steptimes=findStep(leg,step);
+ starting=steptimes(1); ending=steptimes(2);
+ plane=findStepPlane(3,starting,ending);
+ step=ending+1;
+ %end
    
    
  function centers=orbitCenter()
***************
*** 317,319 ****
--- 325,375 ----
  figure(pgraph);
  
  plot3(bodypos(:,1),bodypos(:,2),bodypos(:,3));
+ 
+ function steptimes=findStep(leg,from)
+ global logfile info jpl legpos aibopos samplecount pgraph;
+ buttons=getButton(leg);
+ hit=0; % 0 = waiting for hit, 1=while hit, 2=waiting for next hit
+ for i=from:samplecount
+   switch(hit)
+     case 0
+       if(buttons(i))
+ 	starting=i;
+ 	hit=1;
+       end
+     case 1
+       if(~buttons(i))
+ 	hit=2;
+       end
+     case 2
+       if(buttons(i))
+ 	ending=i-1;
+ 	hit=3;
+       end
+     otherwise
+       break;
+   end
+ end
+ steptimes=[starting,ending];
+ 
+ function stepplane=findStepPlane(leg,starting,ending)
+ global logfile info jpl legpos aibopos samplecount;
+ global points;
+ %we don't actually want z data
+ points=permute(legpos(leg,:,starting:ending),[3,2,1])
+ %least squares fitting:
+ %[m1 m2 b]*[x1 x2 x3 ~ ; y1 y2 y3 ~ ; 1 1 1 ~ ]=[z1 z2 z3 ~]
+ %A*B=C
+ %however A*B doesn't work 'cause different sizes, so multiply both sizes by A'??????????????
+ %B=[points(:,1:2),ones(size(points,1),1)]'
+ %C=points(:,3)'
+ %B=B*B'
+ %C=C*C'
+ %A=C\B
+ %consult mathworld! http://mathworld.wolfram.com/LeastSquaresFitting.html
+ %this should work, but there's an error somewhere else in the code.....????
+ x=points(:,1);
+ y=points(:,2);
+ b=cov(x,y)/var(x)^2;
+ a=mean(y)-b*mean(x);
+ stepplane=[a,b]
Index: Tekkotsu/tools/mon/org/tekkotsu/mon/JointRelay.java
diff -c Tekkotsu/tools/mon/org/tekkotsu/mon/JointRelay.java:1.1 Tekkotsu/tools/mon/org/tekkotsu/mon/JointRelay.java:1.2
*** Tekkotsu/tools/mon/org/tekkotsu/mon/JointRelay.java:1.1	Wed Jan 28 16:08:46 2004
--- Tekkotsu/tools/mon/org/tekkotsu/mon/JointRelay.java	Tue Feb 24 16:13:27 2004
***************
*** 17,29 ****
        InputStream in=socket.getInputStream();
        while (true) {
          _data.timestamp=readInt(in);
!         for (int i=0; i<18; i++)
            _data.positions[i]=readFloat(in);
!         for (int i=0; i<6; i++)
            _data.sensors[i]=readFloat(in);
!         for (int i=0; i<8; i++)
            _data.buttons[i]=readFloat(in);
!         for (int i=0; i<18; i++)
            _data.duties[i]=readFloat(in);
  
          synchronized(_outd) {
--- 17,38 ----
        InputStream in=socket.getInputStream();
        while (true) {
          _data.timestamp=readInt(in);
! 	int count;
! 	count=readInt(in);
! 	_data.positions=new float[count];
!         for (int i=0; i<count; i++)
            _data.positions[i]=readFloat(in);
! 	count=readInt(in);
! 	_data.sensors=new float[count];
!         for (int i=0; i<count; i++)
            _data.sensors[i]=readFloat(in);
! 	count=readInt(in);
! 	_data.buttons=new float[count];
!         for (int i=0; i<count; i++)
            _data.buttons[i]=readFloat(in);
! 	count=readInt(in);
! 	_data.duties=new float[count];
!         for (int i=0; i<count; i++)
            _data.duties[i]=readFloat(in);
  
          synchronized(_outd) {
Index: Tekkotsu/tools/mon/org/tekkotsu/mon/JointWriter.java
diff -c Tekkotsu/tools/mon/org/tekkotsu/mon/JointWriter.java:1.1 Tekkotsu/tools/mon/org/tekkotsu/mon/JointWriter.java:1.2
*** Tekkotsu/tools/mon/org/tekkotsu/mon/JointWriter.java:1.1	Wed Jan 28 16:08:46 2004
--- Tekkotsu/tools/mon/org/tekkotsu/mon/JointWriter.java	Tue Feb 24 16:13:27 2004
***************
*** 1,5 ****
--- 1,6 ----
  package org.tekkotsu.mon;
  
+ 
  import java.io.*;
  
  public class JointWriter implements JointRequestor{
***************
*** 59,67 ****
      protected void launch(String s[]){
  	String ip="172.16.1.1",filename="aibo";
  	for(int i=0;i<s.length;i++){
  	    if(s[i].startsWith("-i"))
  		ip=s[i].substring(2);
! 	    else if(s[i].startsWith("-f"))
  		filename=s[i].substring(2);
  	}
  	File outfile=findNextLog(filename);
--- 60,74 ----
      protected void launch(String s[]){
  	String ip="172.16.1.1",filename="aibo";
  	for(int i=0;i<s.length;i++){
+ 	    if(s[i].equals("-?") || s[i].equals("-h") || s[i].startsWith("--h")){
+ 		System.out.println("valid flags:\n"+
+ 				   "-i<ip address/name of dog>"+
+ 				   "-f<log filename prefix>");
+ 		System.exit(0);
+ 	    }
  	    if(s[i].startsWith("-i"))
  		ip=s[i].substring(2);
! 	    else if(s[i].startsWith("-f") || s[i].startsWith("-l"))
  		filename=s[i].substring(2);
  	}
  	File outfile=findNextLog(filename);
Index: Tekkotsu/tools/mon/org/tekkotsu/mon/Joints.java
diff -c Tekkotsu/tools/mon/org/tekkotsu/mon/Joints.java:1.1 Tekkotsu/tools/mon/org/tekkotsu/mon/Joints.java:1.2
*** Tekkotsu/tools/mon/org/tekkotsu/mon/Joints.java:1.1	Fri Sep 26 00:36:19 2003
--- Tekkotsu/tools/mon/org/tekkotsu/mon/Joints.java	Tue Feb 24 16:13:27 2004
***************
*** 8,13 ****
--- 8,14 ----
    int timestamp;
  
    Joints() {
+       //note: this is old and for the ers2xx, but, eh. doesn't hurt to leave like this
      positions=new float[18];
      duties=new float[18];
      sensors=new float[6];
***************
*** 20,44 ****
  
    public String positionsString() {
      String ret="";
!     for (int i=0; i<18; i++) ret+=positions[i]+" ";
      return ret+"\n";
    }
  
    public String dutiesString() {
      String ret="";
!     for (int i=0; i<18; i++) ret+=duties[i]+" ";
      return ret+"\n";
    }
  
    public String sensorsString() {
      String ret="";
!     for (int i=0; i<6; i++) ret+=sensors[i]+" ";
      return ret+"\n";
    }
  
    public String buttonsString() {
      String ret="";
!     for (int i=0; i<8; i++) ret+=buttons[i]+" ";
      return ret+"\n";
    }
  
--- 21,45 ----
  
    public String positionsString() {
      String ret="";
!     for (int i=0; i<positions.length; i++) ret+=positions[i]+" ";
      return ret+"\n";
    }
  
    public String dutiesString() {
      String ret="";
!     for (int i=0; i<duties.length; i++) ret+=duties[i]+" ";
      return ret+"\n";
    }
  
    public String sensorsString() {
      String ret="";
!     for (int i=0; i<sensors.length; i++) ret+=sensors[i]+" ";
      return ret+"\n";
    }
  
    public String buttonsString() {
      String ret="";
!     for (int i=0; i<buttons.length; i++) ret+=buttons[i]+" ";
      return ret+"\n";
    }
  
Index: Tekkotsu/tools/mon/org/tekkotsu/mon/SketchGUI.java
diff -c Tekkotsu/tools/mon/org/tekkotsu/mon/SketchGUI.java:1.1 Tekkotsu/tools/mon/org/tekkotsu/mon/SketchGUI.java:1.2
*** Tekkotsu/tools/mon/org/tekkotsu/mon/SketchGUI.java:1.1	Thu Jan 29 21:13:10 2004
--- Tekkotsu/tools/mon/org/tekkotsu/mon/SketchGUI.java	Tue Mar  2 09:43:21 2004
***************
*** 109,122 ****
  			String inputLine;
  			System.out.println(inputLine = netin.readLine());
  			while((inputLine=netin.readLine()).compareTo("list end") != 0) {
- 				// parse name
- 				StringTokenizer st = new StringTokenizer(inputLine,": ");
- 				st.nextToken();
- 				String name = st.nextToken();
- 
  				// parse id
! 				inputLine = netin.readLine();
! 				st = new StringTokenizer(inputLine,": ");
  				st.nextToken();
  				int id = Integer.parseInt(st.nextToken());
  				
--- 109,116 ----
  			String inputLine;
  			System.out.println(inputLine = netin.readLine());
  			while((inputLine=netin.readLine()).compareTo("list end") != 0) {
  				// parse id
! 				StringTokenizer st = new StringTokenizer(inputLine,": ");
  				st.nextToken();
  				int id = Integer.parseInt(st.nextToken());
  				
***************
*** 126,141 ****
  				st.nextToken();
  				int parentId = Integer.parseInt(st.nextToken());
  			
! 				// add node
  				System.out.println("id:"+id+"parentId:"+parentId+"name:"+name);
  				DefaultMutableTreeNode newnode = new DefaultMutableTreeNode(new SketchInfo(id, parentId, name));
  				root.add(newnode);
  			}
  			System.out.println(inputLine);
  			//sketchTree = new JTree(root); // is this right?
  			//JScrollPane treeView = new JScrollPane(sketchTree);
  //			sketchTree.removeAll();
  //			sketchTree.add(root);
  			sketchTree.updateUI();
  		} catch(IOException ioe) {
  			System.err.println("Transfer error");
--- 120,168 ----
  				st.nextToken();
  				int parentId = Integer.parseInt(st.nextToken());
  			
! 				// parse name
! 				inputLine = netin.readLine();
! 				st = new StringTokenizer(inputLine,":\r\n");
! 				st.nextToken();
! 				String name = st.nextToken();
! 
! 
! 				// create node
  				System.out.println("id:"+id+"parentId:"+parentId+"name:"+name);
  				DefaultMutableTreeNode newnode = new DefaultMutableTreeNode(new SketchInfo(id, parentId, name));
  				root.add(newnode);
+ 
+ 				// pair up nodes with parents, quite inefficiently (?)
+ //				Enumeration nodes = root.preorderEnumeration();
+ //				while(nodes.hasMoreElements()) {
+ //					SketchInfo cur = (SketchInfo)(nodes.nextElement());
+ //					while(nodes.hasMoreElements()) {
+ //						
+ //					}
+ //				}
+ 			
+ 				
+ 				DefaultMutableTreeNode curNode = root;
+ 				while((curNode = curNode.getNextNode()) != null) {
+ 					DefaultMutableTreeNode potentialParent = root;
+ 					while((potentialParent = potentialParent.getNextNode()) != null) {
+ 						if(((SketchInfo)(curNode.getUserObject())).parentId == ((SketchInfo)(potentialParent.getUserObject())).id && !potentialParent.isNodeAncestor(curNode)) {
+ 							potentialParent.add(curNode);
+ 						}
+ 					}
+ 
+ 				}
  			}
  			System.out.println(inputLine);
  			//sketchTree = new JTree(root); // is this right?
  			//JScrollPane treeView = new JScrollPane(sketchTree);
  //			sketchTree.removeAll();
  //			sketchTree.add(root);
+ 			// expand all the rows
+ 			for (int i = 0; i < sketchTree.getRowCount(); i++) {
+ 				sketchTree.expandRow(i);
+ 			sketchTree.updateUI();
+ 			}
  			sketchTree.updateUI();
  		} catch(IOException ioe) {
  			System.err.println("Transfer error");
***************
*** 298,310 ****
  
  	// gets called when a Sketch selection is clicked
  	public void valueChanged(TreeSelectionEvent e) {
! 		DefaultMutableTreeNode node = (DefaultMutableTreeNode)
! 			sketchTree.getLastSelectedPathComponent();
  
  		if (node == null) return;
  
  		Object nodeInfo = node.getUserObject();
! 		if (node.isLeaf()) {
  			SketchInfo sinfo = (SketchInfo)nodeInfo;
  			System.out.println("id clicked:"+sinfo.id);
  			netout.println("get "+sinfo.id);
--- 325,339 ----
  
  	// gets called when a Sketch selection is clicked
  	public void valueChanged(TreeSelectionEvent e) {
! 		DefaultMutableTreeNode node 
! 			= (DefaultMutableTreeNode)sketchTree.getLastSelectedPathComponent();
  
  		if (node == null) return;
  
+ //		sketchTree.expandPath(sketchTree.getLeadSelectionPath());
+ 
  		Object nodeInfo = node.getUserObject();
! 		if (!node.isRoot()) {
  			SketchInfo sinfo = (SketchInfo)nodeInfo;
  			System.out.println("id clicked:"+sinfo.id);
  			netout.println("get "+sinfo.id);
Index: Tekkotsu/tools/seg/ImageShow.java
diff -c Tekkotsu/tools/seg/ImageShow.java:1.3 Tekkotsu/tools/seg/ImageShow.java:1.4
*** Tekkotsu/tools/seg/ImageShow.java:1.3	Tue Jan 20 22:32:26 2004
--- Tekkotsu/tools/seg/ImageShow.java	Wed Feb 18 00:10:13 2004
***************
*** 96,104 ****
        curimg--;
        if (curimg<0) curimg+=imglist.length;
  			if(isRGB)
! 				imageData.loadRGBFileAsYUV(imglist[curimg]);
  			else
! 				imageData.loadYUVFileAsYUV(imglist[curimg]);
        int[] data=imageData.getPixels();
        showImage(data, tmap, imageData.image_width, imageData.image_height);
      } else if (e.getKeyCode()==KeyEvent.VK_RIGHT ||
--- 96,104 ----
        curimg--;
        if (curimg<0) curimg+=imglist.length;
  			if(isRGB)
! 				imageData.loadRGBFileAsRGB(imglist[curimg]);
  			else
! 				imageData.loadYUVFileAsRGB(imglist[curimg]);
        int[] data=imageData.getPixels();
        showImage(data, tmap, imageData.image_width, imageData.image_height);
      } else if (e.getKeyCode()==KeyEvent.VK_RIGHT ||
***************
*** 109,117 ****
        curimg++;
        if (curimg>=imglist.length) curimg-=imglist.length;
  			if(isRGB)
! 				imageData.loadRGBFileAsYUV(imglist[curimg]);
  			else
! 				imageData.loadYUVFileAsYUV(imglist[curimg]);
        int[] data=imageData.getPixels();
        showImage(data, tmap, imageData.image_width, imageData.image_height);
      }
--- 109,117 ----
        curimg++;
        if (curimg>=imglist.length) curimg-=imglist.length;
  			if(isRGB)
! 				imageData.loadRGBFileAsRGB(imglist[curimg]);
  			else
! 				imageData.loadYUVFileAsRGB(imglist[curimg]);
        int[] data=imageData.getPixels();
        showImage(data, tmap, imageData.image_width, imageData.image_height);
      }
Index: Tekkotsu/tools/seg/VisionTrain.java
diff -c Tekkotsu/tools/seg/VisionTrain.java:1.6 Tekkotsu/tools/seg/VisionTrain.java:1.7
*** Tekkotsu/tools/seg/VisionTrain.java:1.6	Mon Feb  2 13:31:25 2004
--- Tekkotsu/tools/seg/VisionTrain.java	Tue Feb 24 17:17:38 2004
***************
*** 50,56 ****
  
  	public static void usageAndExit() {
  		System.out.println("usage: java VisionTrain (-isRGB|-isYUV) filename [filename ..]");
! 		System.out.println("       Using RGB images will minimize color space conversions.");
  		System.out.println("       A mode must be specified.");
  		System.exit(1);
  	}
--- 50,56 ----
  
  	public static void usageAndExit() {
  		System.out.println("usage: java VisionTrain (-isRGB|-isYUV) filename [filename ..]");
! 		System.out.println("       Using YUV images is recommended.");
  		System.out.println("       A mode must be specified.");
  		System.exit(1);
  	}
Index: Tekkotsu/tools/walk_calibration/WalkCalibration.m
diff -c Tekkotsu/tools/walk_calibration/WalkCalibration.m:1.1 Tekkotsu/tools/walk_calibration/WalkCalibration.m:1.3
*** Tekkotsu/tools/walk_calibration/WalkCalibration.m:1.1	Fri Jan 16 00:15:18 2004
--- Tekkotsu/tools/walk_calibration/WalkCalibration.m	Fri Feb 27 20:58:59 2004
***************
*** 25,30 ****
--- 25,35 ----
  % forward, strafe, and rotation.  Columns 4-6 are the commanded
  % values.
  
+ DEF_MAX_FORWARD=180;
+ DEF_MAX_BACKWARD=180;
+ DEF_MAX_STRAFE=140;
+ DEF_MAX_ROTATE=1.8;
+ 
  dat{1}=load(strcat(base_file_name,'fs.txt'));
  dat{2}=load(strcat(base_file_name,'fr.txt'));
  dat{3}=load(strcat(base_file_name,'sr.txt'));
***************
*** 41,64 ****
  data=mungeRawData(intend,cmd);
  m{1}=doLLS(data);
  
! disp('Errors:');
  calcmd=m{1}*data(1:3:size(data,1),1:(size(data,2)-1)/3)';
  err=(cmd-calcmd');
! err=[intend err (sum((cmd'-calcmd).^2)')];
! %disp(sortrows(err,7));
  disp(sprintf('Total Error=%g;    N=%g;    Avg. Err=%g',sum(err(:,7)),size(intend,1),sum(err(:,7))/size(intend,1)));
  
  disp('Backward Matrix:');
  intend=backward(:,1:3);
  cmd=backward(:,4:6);
  data=mungeRawData(intend,cmd);
  m{2}=doLLS(data);
  
! disp('Errors:');
  calcmd=m{2}*data(1:3:size(data,1),1:(size(data,2)-1)/3)';
  err=(cmd-calcmd');
! err=[intend err (sum((cmd'-calcmd).^2)')];
! %disp(sortrows(err,7));
  disp(sprintf('Total Error=%g;    N=%g;    Avg. Err=%g',sum(err(:,7)),size(intend,1),sum(err(:,7))/size(intend,1)));
  
  disp(' ');
--- 46,77 ----
  data=mungeRawData(intend,cmd);
  m{1}=doLLS(data);
  
! disp('10 Largest Errors:');
! disp('First 3 cols are intended, next 3 are % error in command, last is total SSE');
  calcmd=m{1}*data(1:3:size(data,1),1:(size(data,2)-1)/3)';
  err=(cmd-calcmd');
! scerr=err./[ones(size(err,1),1)*DEF_MAX_FORWARD ones(size(err,1),1)*DEF_MAX_STRAFE ones(size(err,1),1)*DEF_MAX_ROTATE/2];
! err=[intend scerr (sum(scerr'.^2)')];
! tmp=sortrows(err,7);
! disp(tmp(end-10:end,:));
  disp(sprintf('Total Error=%g;    N=%g;    Avg. Err=%g',sum(err(:,7)),size(intend,1),sum(err(:,7))/size(intend,1)));
  
+ disp(' ');
+ 
  disp('Backward Matrix:');
  intend=backward(:,1:3);
  cmd=backward(:,4:6);
  data=mungeRawData(intend,cmd);
  m{2}=doLLS(data);
  
! disp('10 Largest Errors:');
! disp('First 3 cols are intended, next 3 are % error in command, last is total SSE');
  calcmd=m{2}*data(1:3:size(data,1),1:(size(data,2)-1)/3)';
  err=(cmd-calcmd');
! scerr=err./[ones(size(err,1),1)*DEF_MAX_BACKWARD ones(size(err,1),1)*DEF_MAX_STRAFE ones(size(err,1),1)*DEF_MAX_ROTATE/2];
! err=[intend scerr (sum(scerr'.^2)')];
! tmp=sortrows(err,7);
! disp(tmp(end-10:end,:));
  disp(sprintf('Total Error=%g;    N=%g;    Avg. Err=%g',sum(err(:,7)),size(intend,1),sum(err(:,7))/size(intend,1)));
  
  disp(' ');
***************
*** 67,89 ****
  disp('Final Backward Matrix:');
  disp(m{2});
  
  if nargin>1
  	disp(sprintf('Saving to %s',outname));
  	forwC=m{1};
  	backC=m{2};
! 	save(outname,'forwC','backC','-ASCII');
  end
  
! 
! function data = mungeRawData(itd,cmd)
  abs_sr=abs(itd(:,2:3));
  cross_mult=itd.*circshift(itd,[0 1]);
  %ang=atan2(itd(:,2),itd(:,1));
  ang=atan2(itd(:,2),abs(itd(:,1)));
  spd=itd(:,1).^2+itd(:,2).^2;
  
! row=[itd abs_sr ang spd cross_mult ones(size(itd,1),1) ];
  
  data=zeros(3*size(row,1),size(row,2));
  data(1:3:size(data,1),:)=row;
  data=[ data circshift(data,1) circshift(data,2) reshape(cmd',size(data,1),1) ];
--- 80,189 ----
  disp('Final Backward Matrix:');
  disp(m{2});
  
+ %intend=forward(:,1:3);
+ %cmd=forward(:,4:6);
+ %disp([intend (m{1}*mungeRows(intend)')' ((m{1}*mungeRows(intend)')'-cmd)]);
+ 
+ %for visualization
+ % see basis function fits
+ %visFunc(m{1},mungeRows(dat{1}(:,1:3)),dat{1}(:,4:6),mungeRows(dat{2}(:,1:3)),dat{2}(:,4:6),mungeRows(dat{3}(:,1:3)),dat{3}(:,4:6),mungeRows(dat{6}(:,1:3)),dat{6}(:,4:6));
+ % see basis function errors
+ %visFuncError(m{1},mungeRows(dat{1}(:,1:3)),dat{1}(:,4:6),mungeRows(dat{2}(:,1:3)),dat{2}(:,4:6),mungeRows(dat{3}(:,1:3)),dat{3}(:,4:6),mungeRows(dat{6}(:,1:3)),dat{6}(:,4:6));
+ % see predictions
+ %visPredict(m{1},mungeRows(dat{1}(:,1:3)),dat{1}(:,4:6),mungeRows(dat{2}(:,1:3)),dat{2}(:,4:6),mungeRows(dat{3}(:,1:3)),dat{3}(:,4:6),mungeRows(dat{6}(:,1:3)),dat{6}(:,4:6));
+ % see errors
+ %visError(m{1},mungeRows(dat{1}(:,1:3)),dat{1}(:,4:6),mungeRows(dat{2}(:,1:3)),dat{2}(:,4:6),mungeRows(dat{3}(:,1:3)),dat{3}(:,4:6),mungeRows(dat{6}(:,1:3)),dat{6}(:,4:6));
+ 
+ disp('Max speeds are now:');
+ f=mungeRows([(0:DEF_MAX_FORWARD)' zeros(DEF_MAX_FORWARD+1,2)])*m{1}';
+ b=mungeRows([(-DEF_MAX_BACKWARD:0)' zeros(DEF_MAX_BACKWARD+1,2)])*m{2}';
+ fs=mungeRows([zeros(DEF_MAX_STRAFE*2+1,1) (-DEF_MAX_STRAFE:DEF_MAX_STRAFE)' zeros(DEF_MAX_STRAFE*2+1,1)])*m{1}';
+ bs=mungeRows([zeros(DEF_MAX_STRAFE*2+1,1) (-DEF_MAX_STRAFE:DEF_MAX_STRAFE)' zeros(DEF_MAX_STRAFE*2+1,1)])*m{2}';
+ fr=mungeRows([zeros(DEF_MAX_ROTATE*2/.01+1,2) (-DEF_MAX_ROTATE:.01:DEF_MAX_ROTATE)'])*m{1}';
+ br=mungeRows([zeros(DEF_MAX_ROTATE*2/.01+1,2) (-DEF_MAX_ROTATE:.01:DEF_MAX_ROTATE)'])*m{2}';
+ 
+ figure;
+ subplot(231);
+ plot(0:DEF_MAX_FORWARD,f(:,1));
+ title('Forward Velocity curve');xlabel('Actual');ylabel('Command')
+ subplot(232);
+ plot(-DEF_MAX_STRAFE:DEF_MAX_STRAFE,fs(:,2));
+ title('Forward Strafing Velocity curve');xlabel('Actual');ylabel('Command')
+ subplot(233);
+ plot(-DEF_MAX_ROTATE:.01:DEF_MAX_ROTATE,fr(:,3));
+ title('Forward Rotating Velocity curve');xlabel('Actual');ylabel('Command')
+ subplot(234);
+ plot(-DEF_MAX_BACKWARD:0,b(:,1));
+ title('Backward Velocity curve');xlabel('Actual');ylabel('Command')
+ subplot(235);
+ plot(-DEF_MAX_STRAFE:DEF_MAX_STRAFE,bs(:,2));
+ title('Backward Strafing Velocity curve');xlabel('Actual');ylabel('Command')
+ subplot(236);
+ plot(-DEF_MAX_ROTATE:.01:DEF_MAX_ROTATE,br(:,3));
+ title('Backward Rotating Velocity curve');xlabel('Actual');ylabel('Command')
+ 
+ %use bigger ranges in case calibration increases top speed value
+ fin=(0:DEF_MAX_FORWARD*2);
+ bin=(-DEF_MAX_BACKWARD*2:0);
+ stin=(-DEF_MAX_STRAFE*2:DEF_MAX_STRAFE*2);
+ rotin=(-DEF_MAX_ROTATE*2:.01:DEF_MAX_ROTATE*2);
+ f=mungeRows([fin' zeros(DEF_MAX_FORWARD*2+1,2)])*m{1}';
+ b=mungeRows([bin' zeros(DEF_MAX_BACKWARD*2+1,2)])*m{2}';
+ fs=mungeRows([zeros(DEF_MAX_STRAFE*4+1,1) stin' zeros(DEF_MAX_STRAFE*4+1,1)])*m{1}';
+ bs=mungeRows([zeros(DEF_MAX_STRAFE*4+1,1) stin' zeros(DEF_MAX_STRAFE*4+1,1)])*m{2}';
+ fr=mungeRows([zeros(DEF_MAX_ROTATE*4/.01+1,2) rotin'])*m{1}';
+ br=mungeRows([zeros(DEF_MAX_ROTATE*4/.01+1,2) rotin'])*m{2}';
+ bestf=find(f(:,1)<=DEF_MAX_FORWARD);
+ bestf=fin(bestf(end));
+ bestb=find(b(:,1)>=-DEF_MAX_BACKWARD);
+ bestb=bin(bestb(1));
+ bestfs1=find(fs(:,2)<=DEF_MAX_STRAFE);
+ bestfs2=find(fs(:,2)>=-DEF_MAX_STRAFE);
+ bestfs=min(abs([stin(bestfs1(end)) stin(bestfs2(1))]));
+ bestfr1=find(fr(:,3)<=DEF_MAX_ROTATE);
+ bestfr2=find(fr(:,3)>=-DEF_MAX_ROTATE);
+ bestfr=min(abs([rotin(bestfr1(end)) rotin(bestfr2(1))]));
+ bestbs1=find(bs(:,2)<=DEF_MAX_STRAFE);
+ bestbs2=find(bs(:,2)>=-DEF_MAX_STRAFE);
+ bestbs=min(abs([stin(bestbs1(end)) stin(bestbs2(1))]));
+ bestbr1=find(br(:,3)<=DEF_MAX_ROTATE);
+ bestbr2=find(br(:,3)>=-DEF_MAX_ROTATE);
+ bestbr=min(abs([rotin(bestbr1(end)) rotin(bestbr2(1))]));
+ 
+ disp(sprintf('         \t\tstrafe\trotate'));
+ disp(sprintf(' Forward:\t%.5g\t%.5g\t%.5g',bestf,bestfs,bestfr));
+ disp(sprintf('Backward:\t%.5g\t%.5g\t%.5g',bestb,bestbs,bestbr));
+ disp('These are only recommended values, based on default parameters');
+ 
  if nargin>1
  	disp(sprintf('Saving to %s',outname));
+ 	maxspd=[ bestf abs(bestb) min([bestfs ; bestbs]) min([bestfr ; bestbr]) ];
  	forwC=m{1};
  	backC=m{2};
! 	save(outname,'maxspd','forwC','backC','-ASCII');
  end
  
! function row = mungeRows(itd)
  abs_sr=abs(itd(:,2:3));
+ 
  cross_mult=itd.*circshift(itd,[0 1]);
+ 
  %ang=atan2(itd(:,2),itd(:,1));
  ang=atan2(itd(:,2),abs(itd(:,1)));
+ 
  spd=itd(:,1).^2+itd(:,2).^2;
  
! invrot=itd(:,3).^(-1);
! invrot(find(isinf(invrot)))=0;
! invrot=invrot-itd(:,3);
! 
! gab=exp(-.5*itd(:,3).^2).*sin(itd(:,3)*2.5);
! 
! row=[itd abs_sr gab spd cross_mult(:,1:3) ones(size(itd,1),1) ];
  
+ 
+ function data = mungeRawData(itd,cmd)
+ row=mungeRows(itd);
  data=zeros(3*size(row,1),size(row,2));
  data(1:3:size(data,1),:)=row;
  data=[ data circshift(data,1) circshift(data,2) reshape(cmd',size(data,1),1) ];
***************
*** 138,183 ****
  ans=reshape(data(:,end),3,size(data,1)/3);
  
  
! function visPredict(t1,t2,ans)
! visPredicts(t1,t2,ans,[1 2 3]);
! visPredicts(t1,t2,ans,4:7)
! visPredicts(t1,t2,ans,8:size(t1,2))
! 
! function visError(t1,t2,ans)
! visErrors(t1,t2,ans,[1 2 3]);
! visErrors(t1,t2,ans,4:7);
! visErrors(t1,t2,ans,8:size(t1,2));
  
! function visPredicts(t1,t2,ans,jrange)
  figure;
  for j=jrange
  	for i=1:3,
  		subplot(3,size(jrange,2),(j-min(jrange)+1)+(i-1)*size(jrange,2));
- 		mn=min(t1(:,j));
- 		mx=max(t1(:,j));
  		if(mn==mx)
  			x=[mn-1 mx+1];
! 			y=[ ans(i,j) ans(i,j) ];
  		else
! 			x=[mn mx];
! 			y=x*ans(i,j);
  		end
- 		plot(t1(:,j),t2(:,i)-(ans(i,:)*t1')'+t1(:,j)*ans(i,j),'b.',x,y,'g-');
  	end
  end
  
! function visErrors(t1,t2,ans,jrange)
  figure;
! for j=jrange,
  	for i=1:3,
  		subplot(3,size(jrange,2),(j-min(jrange)+1)+(i-1)*size(jrange,2));
- 		mn=min(t1(:,j));
- 		mx=max(t1(:,j));
  		if(mn==mx)
  			x=[mn-1 mx+1];
  		else
  			x=[mn mx];
  		end
- 		plot(t1(:,j),t2(:,i)-(ans(i,:)*t1')','r.',x,[0 0],'g-');
  	end
  end
--- 238,409 ----
  ans=reshape(data(:,end),3,size(data,1)/3);
  
  
! function visFunc(m,varargin)
! srcs=[1 2 3 2 3 3 1 1 2 3 0];
! visFuncs(m,[1 2 3],srcs,varargin{:});
! last=4;
! if(size(m,2)>=7)
! 	visFuncs(m,4:7,srcs,varargin{:})
! 	last=8;
! end
! visFuncs(m,last:size(m,2),srcs,varargin{:})
! 
! function visFuncError(m,varargin)
! srcs=[1 2 3 2 3 3 1 1 2 3 0];
! visFuncErrors(m,[1 2 3],srcs,varargin{:});
! last=4;
! if(size(m,2)>=7)
! 	visFuncErrors(m,4:7,srcs,varargin{:})
! 	last=8;
! end
! visFuncErrors(m,last:size(m,2),srcs,varargin{:})
! 
! function visPredict(m,varargin)
! visPredicts(m,[1 2 3],varargin{:});
! last=4;
! if(size(m,2)>=7)
! 	visPredicts(m,4:7,varargin{:})
! 	last=8;
! end
! visPredicts(m,last:size(m,2),varargin{:})
  
! function visError(m,varargin)
! visErrors(m,[1 2 3],varargin{:});
! last=4;
! if(size(m,2)>=7)
! 	visErrors(m,4:7,varargin{:})
! 	last=8;
! end
! visErrors(m,last:size(m,2),varargin{:})
! 
! function visFuncs(m,jrange,xrange,varargin)
  figure;
+ colors={ 'b.' 'r.' 'g.' 'm.' };
  for j=jrange
+ 	intend=[];
+ 	for n=1:2:size(varargin,2),
+ 		intend=[intend ; varargin{n}];
+ 	end
+ 	if(xrange(j)==0)
+ 		mn=0;
+ 		mx=0;
+ 	else
+ 		mn=min(intend(:,xrange(j)));
+ 		mx=max(intend(:,xrange(j)));
+ 	end
  	for i=1:3,
  		subplot(3,size(jrange,2),(j-min(jrange)+1)+(i-1)*size(jrange,2));
  		if(mn==mx)
  			x=[mn-1 mx+1];
! 			y=[ m(i,j) m(i,j) ];
  		else
! 			x=mn:(mx-mn)/100:mx;
! 			dat=circshift([ x ; zeros(size(x)) ; zeros(size(x)) ],xrange(j)-1)';
! 			mdat=mungeRows(dat);
! 			y=mdat(:,j)*m(i,j);
! 		end
! 		plot(x,y,'k-');
! 		hold on;
! 		for n=1:2:size(varargin,2),
! 			t1=varargin{n};
! 			t2=varargin{n+1};
! 			if(xrange(j)==0)
! 				plot(zeros(size(t1,1)),t2(:,i)-(m(i,:)*t1')'+t1(:,j)*m(i,j),colors{(n+1)/2});
! 			else
! 				plot(t1(:,xrange(j)),t2(:,i)-(m(i,:)*t1')'+t1(:,j)*m(i,j),colors{(n+1)/2});
! 			end
  		end
  	end
  end
  
! function visFuncErrors(m,jrange,xrange,varargin)
  figure;
! colors={ 'b.' 'r.' 'g.' 'm.' };
! for j=jrange
! 	intend=[];
! 	for n=1:2:size(varargin,2),
! 		intend=[intend ; varargin{n}];
! 	end
! 	if(xrange(j)==0)
! 		mn=0;
! 		mx=0;
! 	else
! 		mn=min(intend(:,xrange(j)));
! 		mx=max(intend(:,xrange(j)));
! 	end
! 	if(mn==mx)
! 		x=[mn-1 mx+1];
! 	else
! 		x=[mn mx];
! 	end
! 	for i=1:3,
! 		subplot(3,size(jrange,2),(j-min(jrange)+1)+(i-1)*size(jrange,2));
! 		plot(x,[0 0],'k-');
! 		hold on;
! 		for n=1:2:size(varargin,2),
! 			t1=varargin{n};
! 			t2=varargin{n+1};
! 			if(xrange(j)==0)
! 				plot(zeros(size(t1,1)),t2(:,i)-(m(i,:)*t1')',colors{(n+1)/2});
! 			else
! 				plot(t1(:,xrange(j)),t2(:,i)-(m(i,:)*t1')',colors{(n+1)/2});
! 			end
! 		end
! 	end
! end
! 
! function visPredicts(m,jrange,varargin)
! figure;
! colors={ 'b.' 'r.' 'g.' 'm.' };
! for j=jrange
! 	intend=[];
! 	for n=1:2:size(varargin,2),
! 		intend=[intend ; varargin{n}];
! 	end
! 	mn=min(intend(:,j));
! 	mx=max(intend(:,j));
  	for i=1:3,
  		subplot(3,size(jrange,2),(j-min(jrange)+1)+(i-1)*size(jrange,2));
  		if(mn==mx)
  			x=[mn-1 mx+1];
+ 			y=[ m(i,j) m(i,j) ];
  		else
  			x=[mn mx];
+ 			y=x*m(i,j);
+ 		end
+ 		plot(x,y,'k-');
+ 		hold on;
+ 		for n=1:2:size(varargin,2),
+ 			t1=varargin{n};
+ 			t2=varargin{n+1};
+ 			plot(t1(:,j),t2(:,i)-(m(i,:)*t1')'+t1(:,j)*m(i,j),colors{(n+1)/2});
+ 		end
+ 	end
+ end
+ 
+ function visErrors(m,jrange,varargin)
+ figure;
+ colors={ 'b.' 'r.' 'g.' 'm.' };
+ for j=jrange
+ 	intend=[];
+ 	for n=1:2:size(varargin,2),
+ 		intend=[intend ; varargin{n}];
+ 	end
+ 	mn=min(intend(:,j));
+ 	mx=max(intend(:,j));
+ 	if(mn==mx)
+ 		x=[mn-1 mx+1];
+ 	else
+ 		x=[mn mx];
+ 	end
+ 	for i=1:3,
+ 		subplot(3,size(jrange,2),(j-min(jrange)+1)+(i-1)*size(jrange,2));
+ 		plot(x,[0 0],'k-');
+ 		hold on;
+ 		for n=1:2:size(varargin,2),
+ 			t1=varargin{n};
+ 			t2=varargin{n+1};
+ 			plot(t1(:,j),t2(:,i)-(m(i,:)*t1')',colors{(n+1)/2});
  		end
  	end
  end
Index: Tekkotsu/tools/walk_calibration/final3outliers.txt
diff -c Tekkotsu/tools/walk_calibration/final3outliers.txt:1.1 Tekkotsu/tools/walk_calibration/final3outliers.txt:1.2
*** Tekkotsu/tools/walk_calibration/final3outliers.txt:1.1	Fri Jan 16 00:15:18 2004
--- Tekkotsu/tools/walk_calibration/final3outliers.txt	Wed Feb 25 20:03:19 2004
***************
*** 1,8 ****
  sr:
  0 -47.0713 0.55378 19.998 -122.71 0.632115 
! 0 79.4963 -0.240669 13.338 126.168 -0.280987 
! 0 65.062 -0.542184 7.74 121.94 -0.562667 
  0 75.7781 -0.673583 13.338 126.168 -0.713513 
  
  fs:
  108.119 113.317 0 135.936 105.728 0.0532512
--- 1,8 ----
  sr:
  0 -47.0713 0.55378 19.998 -122.71 0.632115 
! 0 -119.645 -0.882887 13.338 -122.71 -0.829874 
  0 75.7781 -0.673583 13.338 126.168 -0.713513 
+ 0 65.062 -0.542184 7.74 121.94 -0.562667 
  
  fs:
  108.119 113.317 0 135.936 105.728 0.0532512
Index: Tekkotsu/tools/walk_calibration/final3rr.txt
diff -c Tekkotsu/tools/walk_calibration/final3rr.txt:1.1 Tekkotsu/tools/walk_calibration/final3rr.txt:1.2
*** Tekkotsu/tools/walk_calibration/final3rr.txt:1.1	Fri Jan 16 00:15:18 2004
--- Tekkotsu/tools/walk_calibration/final3rr.txt	Wed Feb 25 20:03:19 2004
***************
*** 7,9 ****
--- 7,21 ----
  0 0 1.02745 15.48 1.512 0.852515
  0 0 1.60253 15.48 7.532 1.26615
  0 0 2.00487 15.48 22.582 1.61153
+ 0 0 -0.184963 46.458 -3.01 -0.300517
+ 0 0 -0.423129 15.48 3.01 -0.520225
+ 0 0 -0.854019 15.588 -6.02 -0.80008
+ 0 0 -1.15727 15.588 -0 -1.0198
+ 0 0 -1.45433 15.588 6.02 -1.26615
+ 0 0 0.156205 38.718 -0 0.240594
+ 0 0 0.200401 34.83 -6.02 0.332975
+ 0 0 0.498389 23.22 6.02 0.520225
+ 0 0 0.776421 11.61 9.03 0.700203
+ 0 0 1.13991 3.87 9.03 0.962376
+ 0 0 1.39937 0 12.04 1.13965
+ 0 0 1.82148 0 12.04 1.46839
Index: Tekkotsu/tools/walk_calibration/final3sr.txt
diff -c Tekkotsu/tools/walk_calibration/final3sr.txt:1.1 Tekkotsu/tools/walk_calibration/final3sr.txt:1.2
*** Tekkotsu/tools/walk_calibration/final3sr.txt:1.1	Fri Jan 16 00:15:19 2004
--- Tekkotsu/tools/walk_calibration/final3sr.txt	Wed Feb 25 20:03:19 2004
***************
*** 18,25 ****
  0 -57.6954 0.19876 11.61 -85.806 0.16319
  0 -62.2876 0.0905847 11.61 -85.806 0.0532512
  0 -97.2001 -0.427253 13.338 -122.71 -0.438909 
- 0 -119.645 -0.882887 13.338 -122.71 -0.829874 
  0 -75.499 0.208273 13.338 -122.71 0.215115 
  0 102.075 0.749646 8.892 126.168 0.685907 
  0 100.37 0.295207 19.998 126.168 0.298755 
  0 -71.1758 0.365004 7.74 -124.95 0.402883 
--- 18,25 ----
  0 -57.6954 0.19876 11.61 -85.806 0.16319
  0 -62.2876 0.0905847 11.61 -85.806 0.0532512
  0 -97.2001 -0.427253 13.338 -122.71 -0.438909 
  0 -75.499 0.208273 13.338 -122.71 0.215115 
  0 102.075 0.749646 8.892 126.168 0.685907 
  0 100.37 0.295207 19.998 126.168 0.298755 
+ 0 79.4963 -0.240669 13.338 126.168 -0.280987 
  0 -71.1758 0.365004 7.74 -124.95 0.402883 
