[ return ]

net.c




/*
 * file : net.c
 *
 * [DEFINE DESCRIPTION = Top-level R/S network]
 * 
 *  Name                Date        Description
 *  --------------      --------    -------------------------------------
 *  Andrew H. Fagg      09/05/94    Original
 *
 *
 *
 */

/*
*
*     Copyright (C) 1995 Andrew H. Fagg (af0a@robotics.usc.edu)
*     
*     This program is free software; you can redistribute it and/or
*     modify it under the terms of the GNU General Public License
*     as published by the Free Software Foundation; either version 2
*     of the License, or any later version.
*     
*     This program is distributed in the hope that it will be useful,
*     but WITHOUT ANY WARRANTY; without even the implied warranty of
*     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*     GNU General Public License for more details.
*     
*     You should have received a copy of the GNU General Public License
*     along with this program; if not, write to the Free Software
*     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/

#include "nsl_include.h"
#include "alib.h"
#include "layer.h"
#include "sensor.h"
#include "gen.h"
#include "connection.h"
#include "hand.h"
#include "strings.h"


extern void user_closetrack();


/* #define DEBUG*/

extern layer_class* translate_string_to_layer(char*);
extern connector_class* translate_string_to_connector(char*);

NETWORK(RS);


/************************************************************************/
				/* Network Layers */

layer_class* F5;
layer_class* AIP;
layer_class* Mcx;
layer_class* SI;
layer_class* SII;
layer_class* BG_PHASE;
layer_class* BG_GRASP;
layer_class* BG_F5_RECURRENT;
layer_class* BG_AIP_RECURRENT;
layer_class* F2;


				/* Area 46 Working memory */
sensor_class* A46;
VECTOR(A46_accum, F5_SIZE);

				/* Task-specific grasp bias */
sensor_class* F6;
VECTOR(F6_INPUT, F6_SIZE);
VECTOR(F6_STORE, F6_SIZE);

				/* Network sensors */
sensor_class *PIP;
sensor_class *SMA;
sensor_class *SMA_task;
sensor_class *TRIGGER;
sensor_class *F5_NORMALIZE;
sensor_class *AIP_NORMALIZE;
sensor_class *TH_PAD_FORCES;	/* Thalamic pad forces. */
sensor_class *TH_FINGER_POS;	/* Thalamic representation of finger */
				/*   position (distributed rep)*/
sensor_class *CONSTANT;
sensor_class *ABSTRACT;		/* Abstract inputs (IS).   */


				/* Other sensors that are just used */
				/*  to facilitate tracking. */

sensor_class *INPUT_FINGER_DESIRED;
sensor_class *FINGER_POSITIONS;

/************************************************************************/
				/* Outputs collected from Mcx */
connector_class* finger_outputs[HAND_JOINTS];
connector_class* finger_degree[HAND_JOINTS];
nsl_vector* finger_output_weights[HAND_JOINTS];
nsl_vector* finger_degree_weights[HAND_JOINTS];

				/* PET connectors */
connector_class* pet_pos[NUM_REGIONS];
connector_class* pet_neg[NUM_REGIONS];

VECTOR(PET_pos, NUM_REGIONS);
VECTOR(PET_neg, NUM_REGIONS);
				/* Other pet parms */
DATA(pet_flag);
int pet_init_flag = 0;

/************************************************************************/
/*
 *  Connectors for extracting a symbolic description of what the
 * network is doing.  These connectors will connect to the units in F5.
 * <grasp_measure> connectors will measure the number of cells that 
 * are active for a particular grasp type.  The one with the highest
 * amount of activity is interpretted as the one that the network
 * has selected.
 *  <grasp_aperture_measure> will accept connection from all aperture-
 * specifying F5 cells.  We will compute a weighted average of these
 * votes to approximate the aperture that the network is supposed to be
 * generating.
 *  Note that these measures are not used to generate movement, but only
 * to obtain a view of what the network 'thinks' it is doing.
 *  
 *
 */


connector_class* grasp_measure[NUM_GRASPS];
connector_class* grasp_aperture_measure;
				/* Number of votes for each grasp type */
VECTOR(grasp_measure_levels, NUM_GRASPS);
				/* Current winning grasp type */
DATA(grasp_win);
				/* Estimate of the networks grasp aperture */
DATA(grasp_aperture_estimate);
				/* sensor for tracking. */
sensor_class *GRASP_APERTURE_ESTIMATE;



/************************************************************************/
				/* Display vectors */

VECTOR(AIP_output_display, AIP_SIZE);
VECTOR(F5_output_display, F5_SIZE);
VECTOR(F2_output_display, F2_SIZE);
VECTOR(SI_output_display, SI_SIZE);
VECTOR(SII_output_display, SII_SIZE);
VECTOR(Mcx_output_display, MCX_SIZE);
VECTOR(BG_PHASE_output_display, BG_PHASE_SIZE);
VECTOR(BG_GRASP_output_display, BG_GRASP_SIZE);
VECTOR(BG_F5_RECURRENT_output_display, BG_F5_RECURRENT_SIZE);
VECTOR(BG_AIP_RECURRENT_output_display, BG_AIP_RECURRENT_SIZE);


VECTOR(AIP_output_mem_display, AIP_SIZE);
VECTOR(F5_output_mem_display, F5_SIZE);
VECTOR(F2_output_mem_display, F2_SIZE);
VECTOR(SI_output_mem_display, SI_SIZE);
VECTOR(SII_output_mem_display, SII_SIZE);
VECTOR(Mcx_output_mem_display, MCX_SIZE);
VECTOR(BG_PHASE_output_mem_display, BG_PHASE_SIZE);
VECTOR(BG_GRASP_output_mem_display, BG_GRASP_SIZE);
VECTOR(BG_F5_RECURRENT_output_mem_display, BG_F5_RECURRENT_SIZE);
VECTOR(BG_AIP_RECURRENT_output_mem_display, BG_AIP_RECURRENT_SIZE);


/************************************************************************/
				/* Input vectors */

VECTOR(PIP_INPUT, PIP_SIZE);
VECTOR(SMA_INPUT, SMA_SIZE);
VECTOR(ABSTRACT_INPUT, ABSTRACT_SIZE);
VECTOR(ABSTRACT_STORE, ABSTRACT_SIZE);



/************************************************************************/
				/* Random Variables */
int init_flag = 0;
int counter = 0;
int release_time;		/* Time at which system transitioned */
				/*  to the release phase. */
DATA(dump_skip);
DATA(F5_NORM_kx0);
DATA(F5_NORM_kx1);
DATA(F5_NORM_ky0);
DATA(F5_NORM_ky1);
DATA(AIP_NORM_kx0);
DATA(AIP_NORM_kx1);
DATA(AIP_NORM_ky0);
DATA(AIP_NORM_ky1);

VECTOR(F5_NORM_MEM, 1);
VECTOR(F5_NORM, 1);
DATA(F5_NORM_tau);

VECTOR(AIP_NORM_MEM, 1);
VECTOR(AIP_NORM, 1);
DATA(AIP_NORM_tau);

int current_phase = 0;


/************************************************************************/
				/* Column class parameters */

class column_parms_class column_parms;

DATA(column_collector_kx1);
DATA(column_collector_kx2);
DATA(column_collector_ky1);
DATA(column_collector_ky2);
DATA(column_collector_ky3);

DATA(column_sensory_kx1);
DATA(column_sensory_kx2);
DATA(column_sensory_ky1);
DATA(column_sensory_ky2);

DATA(column_output_kx1);
DATA(column_output_kx2);
DATA(column_output_ky1);
DATA(column_output_ky2);
DATA(column_minimum_output_mem);

DATA(column_tau);

				/* Special parms for SI */
class column_parms_class SI_column_parms;
DATA(SI_column_collector_kx1);
DATA(SI_column_collector_kx2);
DATA(SI_column_collector_ky1);
DATA(SI_column_collector_ky2);
DATA(SI_column_collector_ky3);

DATA(SI_column_sensory_kx1);
DATA(SI_column_sensory_kx2);
DATA(SI_column_sensory_ky1);
DATA(SI_column_sensory_ky2);

DATA(SI_column_output_kx1);
DATA(SI_column_output_kx2);
DATA(SI_column_output_ky1);
DATA(SI_column_output_ky2);
DATA(SI_column_minimum_output_mem);
DATA(SI_column_tau);


				/* Special parms for SII */
class column_parms_class SII_column_parms;
DATA(SII_column_collector_kx1);
DATA(SII_column_collector_kx2);
DATA(SII_column_collector_ky1);
DATA(SII_column_collector_ky2);
DATA(SII_column_collector_ky3);

DATA(SII_column_sensory_kx1);
DATA(SII_column_sensory_kx2);
DATA(SII_column_sensory_ky1);
DATA(SII_column_sensory_ky2);

DATA(SII_column_output_kx1);
DATA(SII_column_output_kx2);
DATA(SII_column_output_ky1);
DATA(SII_column_output_ky2);

				/* Parms for F5 */
class column_parms_class F5_column_parms;

DATA(F5_column_tau);

				/* Special parms for AIP */
class column_parms_class AIP_column_parms;

DATA(AIP_column_collector_kx1);
DATA(AIP_column_collector_kx2);
DATA(AIP_column_collector_ky1);
DATA(AIP_column_collector_ky2);
DATA(AIP_column_collector_ky3);

DATA(AIP_column_sensory_kx1);
DATA(AIP_column_sensory_kx2);
DATA(AIP_column_sensory_ky1);
DATA(AIP_column_sensory_ky2);

DATA(AIP_column_output_kx1);
DATA(AIP_column_output_kx2);
DATA(AIP_column_output_ky1);
DATA(AIP_column_output_ky2);
DATA(AIP_column_minimum_output_mem);

DATA(AIP_column_tau);

class column_parms_class mcx_column_parms;
				/* Special parms for Mcx */
DATA(mcx_column_collector_kx1);
DATA(mcx_column_collector_kx2);
DATA(mcx_column_collector_ky1);
DATA(mcx_column_collector_ky2);
DATA(mcx_column_collector_ky3);

DATA(mcx_column_sensory_kx1);
DATA(mcx_column_sensory_kx2);
DATA(mcx_column_sensory_ky1);
DATA(mcx_column_sensory_ky2);

DATA(mcx_column_output_kx1);
DATA(mcx_column_output_kx2);
DATA(mcx_column_output_ky1);
DATA(mcx_column_output_ky2);
DATA(mcx_column_minimum_output_mem);


class column_parms_class BG_PHASE_column_parms;

DATA(BG_PHASE_column_collector_kx1);
DATA(BG_PHASE_column_collector_kx2);
DATA(BG_PHASE_column_collector_ky1);
DATA(BG_PHASE_column_collector_ky2);
DATA(BG_PHASE_column_collector_ky3);

DATA(BG_PHASE_column_sensory_kx1);
DATA(BG_PHASE_column_sensory_kx2);
DATA(BG_PHASE_column_sensory_ky1);
DATA(BG_PHASE_column_sensory_ky2);

DATA(BG_PHASE_column_output_kx1);
DATA(BG_PHASE_column_output_kx2);
DATA(BG_PHASE_column_output_ky1);
DATA(BG_PHASE_column_output_ky2);
DATA(BG_PHASE_column_minimum_output_mem);


class column_parms_class BG_GRASP_column_parms;

DATA(BG_GRASP_column_collector_kx1);
DATA(BG_GRASP_column_collector_kx2);
DATA(BG_GRASP_column_collector_ky1);
DATA(BG_GRASP_column_collector_ky2);
DATA(BG_GRASP_column_collector_ky3);

DATA(BG_GRASP_column_sensory_kx1);
DATA(BG_GRASP_column_sensory_kx2);
DATA(BG_GRASP_column_sensory_ky1);
DATA(BG_GRASP_column_sensory_ky2);

DATA(BG_GRASP_column_output_kx1);
DATA(BG_GRASP_column_output_kx2);
DATA(BG_GRASP_column_output_ky1);
DATA(BG_GRASP_column_output_ky2);
DATA(BG_GRASP_column_minimum_output_mem);

class column_parms_class BG_F5_RECURRENT_column_parms;

DATA(BG_F5_RECURRENT_column_collector_kx1);
DATA(BG_F5_RECURRENT_column_collector_kx2);
DATA(BG_F5_RECURRENT_column_collector_ky1);
DATA(BG_F5_RECURRENT_column_collector_ky2);
DATA(BG_F5_RECURRENT_column_collector_ky3);

DATA(BG_F5_RECURRENT_column_sensory_kx1);
DATA(BG_F5_RECURRENT_column_sensory_kx2);
DATA(BG_F5_RECURRENT_column_sensory_ky1);
DATA(BG_F5_RECURRENT_column_sensory_ky2);

DATA(BG_F5_RECURRENT_column_output_kx1);
DATA(BG_F5_RECURRENT_column_output_kx2);
DATA(BG_F5_RECURRENT_column_output_ky1);
DATA(BG_F5_RECURRENT_column_output_ky2);
DATA(BG_F5_RECURRENT_column_minimum_output_mem);
DATA(BG_F5_RECURRENT_column_tau);

class column_parms_class BG_AIP_RECURRENT_column_parms;

DATA(BG_AIP_RECURRENT_column_collector_kx1);
DATA(BG_AIP_RECURRENT_column_collector_kx2);
DATA(BG_AIP_RECURRENT_column_collector_ky1);
DATA(BG_AIP_RECURRENT_column_collector_ky2);
DATA(BG_AIP_RECURRENT_column_collector_ky3);

DATA(BG_AIP_RECURRENT_column_sensory_kx1);
DATA(BG_AIP_RECURRENT_column_sensory_kx2);
DATA(BG_AIP_RECURRENT_column_sensory_ky1);
DATA(BG_AIP_RECURRENT_column_sensory_ky2);

DATA(BG_AIP_RECURRENT_column_output_kx1);
DATA(BG_AIP_RECURRENT_column_output_kx2);
DATA(BG_AIP_RECURRENT_column_output_ky1);
DATA(BG_AIP_RECURRENT_column_output_ky2);
DATA(BG_AIP_RECURRENT_column_minimum_output_mem);
DATA(BG_AIP_RECURRENT_column_tau);


class column_parms_class F2_column_parms;

DATA(F2_column_collector_kx1);
DATA(F2_column_collector_kx2);
DATA(F2_column_collector_ky1);
DATA(F2_column_collector_ky2);
DATA(F2_column_collector_ky3);

DATA(F2_column_sensory_kx1);
DATA(F2_column_sensory_kx2);
DATA(F2_column_sensory_ky1);
DATA(F2_column_sensory_ky2);

DATA(F2_column_output_kx1);
DATA(F2_column_output_kx2);
DATA(F2_column_output_ky1);
DATA(F2_column_output_ky2);
DATA(F2_column_minimum_output_mem);




/************************************************************************/
				/* Gate class parameters */
class gate_parms_class gate_parms;

DATA(gate_pr_kx1);
DATA(gate_pr_kx2);
DATA(gate_pr_ky1);
DATA(gate_pr_ky2);

DATA(gate_support_kx1);
DATA(gate_support_kx2);
DATA(gate_support_ky1);
DATA(gate_support_ky2);

				/* F5 Gate parameters */
class gate_parms_class F5_gate_parms;

DATA(F5_gate_pr_kx1);
DATA(F5_gate_pr_kx2);
DATA(F5_gate_pr_ky1);
DATA(F5_gate_pr_ky2);

DATA(F5_gate_support_kx1);
DATA(F5_gate_support_kx2);
DATA(F5_gate_support_ky1);
DATA(F5_gate_support_ky2);

				/* Special MCX gate parameters */
class gate_parms_class mcx_gate_parms;
DATA(mcx_gate_support_kx1);
DATA(mcx_gate_support_kx2);
DATA(mcx_gate_support_ky1);
DATA(mcx_gate_support_ky2);

				/* Special SII gate parameters */
class gate_parms_class SII_gate_parms;
DATA(SII_gate_pr_kx1);
DATA(SII_gate_pr_kx2);
DATA(SII_gate_pr_ky1);
DATA(SII_gate_pr_ky2);

DATA(SII_gate_support_kx1);
DATA(SII_gate_support_kx2);
DATA(SII_gate_support_ky1);
DATA(SII_gate_support_ky2);

				/* Special AIP gate parms */
class gate_parms_class AIP_gate_parms;

DATA(AIP_gate_pr_kx1);
DATA(AIP_gate_pr_kx2);
DATA(AIP_gate_pr_ky1);
DATA(AIP_gate_pr_ky2);

DATA(AIP_gate_support_kx1);
DATA(AIP_gate_support_kx2);
DATA(AIP_gate_support_ky1);
DATA(AIP_gate_support_ky2);

class gate_parms_class BG_PHASE_gate_parms;

DATA(BG_PHASE_gate_pr_kx1);
DATA(BG_PHASE_gate_pr_kx2);
DATA(BG_PHASE_gate_pr_ky1);
DATA(BG_PHASE_gate_pr_ky2);

DATA(BG_PHASE_gate_support_kx1);
DATA(BG_PHASE_gate_support_kx2);
DATA(BG_PHASE_gate_support_ky1);
DATA(BG_PHASE_gate_support_ky2);

class gate_parms_class BG_GRASP_gate_parms;

DATA(BG_GRASP_gate_pr_kx1);
DATA(BG_GRASP_gate_pr_kx2);
DATA(BG_GRASP_gate_pr_ky1);
DATA(BG_GRASP_gate_pr_ky2);

DATA(BG_GRASP_gate_support_kx1);
DATA(BG_GRASP_gate_support_kx2);
DATA(BG_GRASP_gate_support_ky1);
DATA(BG_GRASP_gate_support_ky2);

class gate_parms_class BG_F5_RECURRENT_gate_parms;

DATA(BG_F5_RECURRENT_gate_pr_kx1);
DATA(BG_F5_RECURRENT_gate_pr_kx2);
DATA(BG_F5_RECURRENT_gate_pr_ky1);
DATA(BG_F5_RECURRENT_gate_pr_ky2);

DATA(BG_F5_RECURRENT_gate_support_kx1);
DATA(BG_F5_RECURRENT_gate_support_kx2);
DATA(BG_F5_RECURRENT_gate_support_ky1);
DATA(BG_F5_RECURRENT_gate_support_ky2);

class gate_parms_class BG_AIP_RECURRENT_gate_parms;

DATA(BG_AIP_RECURRENT_gate_pr_kx1);
DATA(BG_AIP_RECURRENT_gate_pr_kx2);
DATA(BG_AIP_RECURRENT_gate_pr_ky1);
DATA(BG_AIP_RECURRENT_gate_pr_ky2);

DATA(BG_AIP_RECURRENT_gate_support_kx1);
DATA(BG_AIP_RECURRENT_gate_support_kx2);
DATA(BG_AIP_RECURRENT_gate_support_ky1);
DATA(BG_AIP_RECURRENT_gate_support_ky2);


				/* F2 Gate class parameters */
class gate_parms_class F2_gate_parms;

DATA(F2_gate_pr_kx1);
DATA(F2_gate_pr_kx2);
DATA(F2_gate_pr_ky1);
DATA(F2_gate_pr_ky2);

DATA(F2_gate_support_kx1);
DATA(F2_gate_support_kx2);
DATA(F2_gate_support_ky1);
DATA(F2_gate_support_ky2);

/************************************************************************/
				/* Area 46 */
DATA(A46_accum_flag);
DATA(A46_scale);


/************************************************************************/
				/* Protocol parameters */
DATA(TRIGGER0_ON_TIME);
DATA(TRIGGER0_OFF_TIME);
DATA(TRIGGER_ON_TIME);
DATA(TRIGGER_OFF_TIME);
DATA(TRIGGER2_ON_TIME);
DATA(TRIGGER2_OFF_TIME);

DATA(TRIGGER3_ON_TIME);		/* Indicates when abstract stimulus is */
DATA(TRIGGER3_OFF_TIME);	/*  presented. */

DATA(TRIGGER4_ON_TIME);		/* Indicates when f6 IS is */
DATA(TRIGGER4_OFF_TIME);	/*  presented generated. */

DATA(ENCLOSE_TIME);
DATA(ATTENTION_OFF_TIME);

				/* Used for tracking when major */
				/*  events happen */
VECTOR(EVENTS, NUM_EVENTS);

				/* Denotes when to engage 46 input to */
				/*  F5.  */
DATA(TRIGGER_46_ON_TIME);
DATA(TRIGGER_46_OFF_TIME);


/************************************************************************/
				/* Hand-related variables. */

				/* Joint angles */
VECTOR(finger_positions, HAND_JOINTS);
VECTOR(finger_vel, HAND_JOINTS);

VECTOR(input_finger_forces, HAND_JOINTS);

				/* Finger outputs from Mcx */
VECTOR(input_finger_desired, HAND_JOINTS);
				/* Degree of support for position */
VECTOR(input_finger_degree, HAND_JOINTS);
				/* Debugging device */
VECTOR(input_finger_flag, HAND_JOINTS);


				/* Quick hack to simulate collision with */
				/*  an object. */
				/* Maintain max and min joint values for */
				/*  each type of grasp */
VECTOR(max_flexion, HAND_JOINTS);
VECTOR(max_flexion_hold_precision, HAND_JOINTS);
VECTOR(max_flexion_hold_finger, HAND_JOINTS);
VECTOR(max_flexion_hold_palm, HAND_JOINTS);
VECTOR(max_flexion_hold_side, HAND_JOINTS);

VECTOR(min_flexion, HAND_JOINTS);
VECTOR(min_flexion_hold_precision, HAND_JOINTS);
VECTOR(min_flexion_hold_finger, HAND_JOINTS);
VECTOR(min_flexion_hold_palm, HAND_JOINTS);
VECTOR(min_flexion_hold_side, HAND_JOINTS);

				/* Default values for both */
				/* (parmeters of the hand) */
VECTOR(default_finger_desired, HAND_JOINTS);
VECTOR(default_finger_degree, HAND_JOINTS);
DATA(default_finger_threshold);

VECTOR(finger_stiffness, HAND_JOINTS);
DATA(degree2stiffness);
DATA(finger_vel_gain);
DATA(degree2vel_gain);


//VECTOR(object_forces, HAND_JOINTS);
DATA(finger_gain);
//DATA(finger_position_gain);
DATA(finger_force_gain);
DATA(force_gain);
//VECTOR(object_parms, OBJECT_PARMS_SIZE);
//DATA(grasp_type);
VECTOR(pad_forces, PAD_FORCES_SIZE);
DATA(max_pad_forces);
//DATA(force_i_gain);
//DATA(corner_offset);
//DATA(corner_gain);
//DATA(width_gain);
DATA(position_gain);
//DATA(corner_force_const);

int hand_enclosed_flag;

MATRIX(hand_display, HAND_DISPLAY_X, HAND_DISPLAY_Y);


DATA(gauss_position_min);	/* Coding of hand parameters in the */
DATA(gauss_position_max);	/*  distributed coding scheme */
DATA(gauss_position_pad);
DATA(gauss_position_std);




/************************************************************************/
/*  Random parameters.  */
DATA(free_parm);
DATA(free2_parm);
DATA(free3_parm);
DATA(delta);



/************************************************************************/
				/* Create Network */

void create_network()
{
  int i;

#ifdef DEBUG
  cout << "*** create_network ***" nl;
#endif

  if(init_flag)			/* If we already have a net, then */
    {				/*   want to delete it first.     */
      delete F5;
      delete F2;
      delete AIP;
      delete Mcx;
      delete SI;
      delete SII;
      delete BG_PHASE;
      delete BG_GRASP;
      delete BG_F5_RECURRENT;
      delete BG_AIP_RECURRENT;

				/* Delete sensors also. */
      delete A46;
      delete F6;
      delete PIP;
      delete SMA;
      delete SMA_task;
      delete TRIGGER;
      delete F5_NORMALIZE;
      delete AIP_NORMALIZE;
      delete TH_PAD_FORCES;
      delete TH_FINGER_POS;
      delete CONSTANT;

      delete INPUT_FINGER_DESIRED;
      delete FINGER_POSITIONS;
      delete ABSTRACT;

      user_closetrack();	/* Clear current track structures if */
				/*  they exist. */
      for(i = 0; i <HAND_JOINTS; ++i)
	{
	  delete finger_outputs[i];
	  delete finger_degree[i];
	};
				/* If the PET structures exist, then */
				/*   delete them. */
      if(pet_init_flag)
	{
	  for(i = 0; i < NUM_REGIONS; ++i)
	    {
	      delete pet_pos[i];
	      delete pet_neg[i];
	    };
	  pet_init_flag = 0;
	};
				/* Grasp measures */
      for(i = 0; i < NUM_GRASPS; ++i)
	{
	  delete grasp_measure[i];
	};
      
    }
  init_flag = 1;		/* Delete network next time through. */

				/* Create layers. */

  F5 = new layer_class("F5", F5_SIZE, WEIGHT_FLAGS, &F5_column_parms,
		       NUM_GATES, WEIGHT_FLAGS, &F5_gate_parms);

  F2 = new layer_class("F2", F2_SIZE, WEIGHT_FLAGS, &F2_column_parms,
		       NUM_GATES, WEIGHT_FLAGS, &F2_gate_parms);

  AIP = new layer_class("AIP", AIP_SIZE, WEIGHT_FLAGS,
			  &AIP_column_parms,
		       NUM_GATES, WEIGHT_FLAGS, &AIP_gate_parms);

  Mcx = new layer_class("Mcx", MCX_SIZE, WEIGHT_FLAGS, &mcx_column_parms,
			NUM_GATES, WEIGHT_FLAGS, &mcx_gate_parms);

  SI = new layer_class("SI", SI_SIZE, WEIGHT_FLAGS, &SI_column_parms,
			NUM_GATES, WEIGHT_FLAGS, &gate_parms);

  SII = new layer_class("SII", SII_SIZE, WEIGHT_FLAGS, &SII_column_parms,
			SII_NUM_GATES, WEIGHT_FLAGS, &SII_gate_parms);



  BG_PHASE = new layer_class("BG_PHASE", BG_PHASE_SIZE,
			     WEIGHT_FLAGS, &BG_PHASE_column_parms,
			     1, WEIGHT_FLAGS, &BG_PHASE_gate_parms);

  BG_GRASP = new layer_class("BG_GRASP", BG_GRASP_SIZE,
			     WEIGHT_FLAGS, &BG_GRASP_column_parms,
			     1, WEIGHT_FLAGS, &BG_GRASP_gate_parms);

  BG_F5_RECURRENT = new layer_class("BG_F5_RECURRENT",  BG_F5_RECURRENT_SIZE,
				    WEIGHT_FLAGS,
				    &BG_F5_RECURRENT_column_parms,
				    1, WEIGHT_FLAGS,
				    &BG_F5_RECURRENT_gate_parms);

  BG_AIP_RECURRENT = new layer_class("BG_AIP_RECURRENT", BG_AIP_RECURRENT_SIZE,
				     WEIGHT_FLAGS,
				     &BG_AIP_RECURRENT_column_parms,
				     1, WEIGHT_FLAGS,
				     &BG_AIP_RECURRENT_gate_parms);


				/* Area 46 treated as just a sensor */
  A46 = new sensor_class(F5_SIZE, "A46");
  A46_accum = 0;

				/* Area F6 also treated as just a sensor */
  F6 = new sensor_class(F6_SIZE, "F6");

				/* Create sensory inputs. */
  PIP = new sensor_class(PIP_SIZE, "PIP");

  SMA = new sensor_class(SMA_SIZE, "SMA");
  SMA_task = new sensor_class(SMA_TASK_SIZE, "SMA_task");

  TRIGGER = new sensor_class(TRIGGER_SIZE, "TRIGGER");

  F5_NORMALIZE = new sensor_class(1, "F5_NORMALIZE");

  AIP_NORMALIZE = new sensor_class(1, "AIP_NORMALIZE");

  TH_PAD_FORCES = new sensor_class(TH_PAD_FORCES_SIZE, "TH_PAD_FORCES");

  TH_FINGER_POS = new sensor_class(FINGER_POS_SIZE, "TH_FINGER_POS");

  CONSTANT = new sensor_class(1, "CONSTANT");


				/* Sensors for tracking */
  INPUT_FINGER_DESIRED = new sensor_class(HAND_JOINTS, "INPUT_FINGER_DESIRED");
  FINGER_POSITIONS = new sensor_class(HAND_JOINTS, "FINGER_POSITIONS");

  ABSTRACT = new sensor_class(ABSTRACT_SIZE, "ABSTRACT");

  GRASP_APERTURE_ESTIMATE = new sensor_class(1, "GRASP_APERTURE_ESTIMATE");

				/* Create connectors that collect */
				/*   output from Mcx.             */
  for(i = 0; i <HAND_JOINTS; ++i)
    {
      finger_outputs[i] = new connector_class(WEIGHT_FLAGS);
      finger_degree[i] = new connector_class(WEIGHT_FLAGS);
    };
				/* Create connectors for PET computations */
  if(pet_flag.elem() == 1.0)
    {
      for(i = 0; i < NUM_REGIONS; ++i)
	{
	  pet_pos[i] = new connector_class(0);
	  pet_neg[i] = new connector_class(0);
	};
      pet_init_flag = 1;
    };
				/* Grasp measures */
  for(i = 0; i < NUM_GRASPS; ++i)
    {
      grasp_measure[i] = new connector_class(0);
    };
  grasp_aperture_measure = new connector_class(WEIGHT_FLAGS);

};


/************************************************************************/
				/* User Routines */


/*
  * void user_clear()
  *
  *  Clear out all structures in order to prepare for the next trial.
  *
  */

void user_clear()
{
				/* Clear network state. */
  AIP->clear_activities();        //OVERLOAD CALL: clear_activities: column.c(column_class), gate.c(gate_class), layer.c(layer_class)
  F5->clear_activities();        //OVERLOAD CALL: clear_activities: column.c(column_class), gate.c(gate_class), layer.c(layer_class)
  F2->clear_activities();        //OVERLOAD CALL: clear_activities: column.c(column_class), gate.c(gate_class), layer.c(layer_class)
  Mcx->clear_activities();        //OVERLOAD CALL: clear_activities: column.c(column_class), gate.c(gate_class), layer.c(layer_class)
  SI->clear_activities();        //OVERLOAD CALL: clear_activities: column.c(column_class), gate.c(gate_class), layer.c(layer_class)
  SII->clear_activities();        //OVERLOAD CALL: clear_activities: column.c(column_class), gate.c(gate_class), layer.c(layer_class)
  BG_PHASE->clear_activities();        //OVERLOAD CALL: clear_activities: column.c(column_class), gate.c(gate_class), layer.c(layer_class)
  BG_GRASP->clear_activities();        //OVERLOAD CALL: clear_activities: column.c(column_class), gate.c(gate_class), layer.c(layer_class)
  BG_F5_RECURRENT->clear_activities();        //OVERLOAD CALL: clear_activities: column.c(column_class), gate.c(gate_class), layer.c(layer_class)
  BG_AIP_RECURRENT->clear_activities();        //OVERLOAD CALL: clear_activities: column.c(column_class), gate.c(gate_class), layer.c(layer_class)

				/* Area 46 */
  nsl_vector a46_tmp(F5_SIZE);
  a46_tmp = 0;
  A46->set_values(a46_tmp);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)

				/* Reset sensor values */
  PIP->set_values(PIP_INPUT);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)
  SMA->set_values(SMA_INPUT);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)

  pad_forces = 0;		/* Finger pads */
  hand_enclosed_flag = 0;

  counter = 0;			/* Start of new trial. */
  release_time = -1;			/* Start of new trial. */
  F5_NORM_MEM = 0;
  AIP_NORM_MEM = 0;

  finger_positions = default_finger_desired;
  finger_vel = 0;
				/* Always on */
  nsl_vector tmp(1);
  tmp.elem(0) = 1.0;
  CONSTANT->set_values(tmp);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)
  current_phase = 0;
  max_flexion = 100;
  min_flexion = -10;

				/* Clear out PET measures */
  PET_pos = 0;
  PET_neg = 0;

				/* Clear abstract inputs */
  ABSTRACT_INPUT = 0;
  ABSTRACT->set_values(ABSTRACT_INPUT);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)
  F6_INPUT = 0;
  F6->set_values(F6_INPUT);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)
				/* Clear out log of all events */
  EVENTS = -1;

				/* Set F6 initial state */
  F6->set_values(F6_INPUT);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)

				/* Tracks the maximum sum of pad forces */
  max_pad_forces = 0;
}

/*
  * void user_column()
  *
  *  Prompt for a layer name and a column index; report the
  * status of the specified column
  *
  */

void user_column()
{
  char layer[20];
  int i;

  cout << "layer -> ";
  cin >> layer;
  cout << "index -> ";
  cin >> i;

  switch(layer[0])
    {
    case 'f' :
    case 'F' :
      F5->report_column(i, TRUE, TRUE);        //OVERLOAD CALL: report_column: column.c(column_class), layer.c(layer_class)
      break;
    case 'd' :
    case 'D' :
      F2->report_column(i, TRUE, TRUE);        //OVERLOAD CALL: report_column: column.c(column_class), layer.c(layer_class)
      break;
    case 'm' :
    case 'M' :
      Mcx->report_column(i, TRUE, TRUE);        //OVERLOAD CALL: report_column: column.c(column_class), layer.c(layer_class)
      break;
    case 's' :
    case 'S' :
    case 'a' :
    case 'A' :
      AIP->report_column(i, TRUE, TRUE);        //OVERLOAD CALL: report_column: column.c(column_class), layer.c(layer_class)
      break;
    case '1' :
      SI->report_column(i, TRUE, TRUE);        //OVERLOAD CALL: report_column: column.c(column_class), layer.c(layer_class)
      break;
    case '2' :
      SII->report_column(i, TRUE, TRUE);        //OVERLOAD CALL: report_column: column.c(column_class), layer.c(layer_class)
      break;
    case 'p' :
    case 'P' :
      BG_PHASE->report_column(i, TRUE, TRUE);        //OVERLOAD CALL: report_column: column.c(column_class), layer.c(layer_class)
      break;
    case 'g' :
    case 'G' :
      BG_GRASP->report_column(i, TRUE, TRUE);        //OVERLOAD CALL: report_column: column.c(column_class), layer.c(layer_class)
      break;
    case 'r' :
      BG_F5_RECURRENT->report_column(i, TRUE, TRUE);        //OVERLOAD CALL: report_column: column.c(column_class), layer.c(layer_class)
      break;
    case 'R' :
      BG_AIP_RECURRENT->report_column(i, TRUE, TRUE);        //OVERLOAD CALL: report_column: column.c(column_class), layer.c(layer_class)
      break;
    case '?' :
    case 'h' :
    case 'H' :
      cout nl << "Available Layers" nl;
      cout << "a\tAIP" nl;
      cout << "d\tF2 (dorsal premotor)" nl;
      cout << "f\tF5" nl;
      cout << "g\tbg Grasp" nl;
      cout << "m\tMcx" nl;
      cout << "p\tbg Phase" nl;
      cout << "r\tf5 Recurrent" nl;
      cout << "R\taip Recurrent" nl;
      cout << "1\tSI" nl;
      cout << "2\tSII" nl;
      cout nl;
      break;
    }
}

/*
  * void user_sensor()
  *
  *  Prompt for a sensor name; report the
  * status of the specified sensor.
  *
  */

void user_sensor()
{
  char layer[20];

  cout << "sensor -> ";
  cin >> layer;

  switch(layer[0])
    {
    case 'c' :
    case 'C' :
      cout << "SMA: " << SMA->get_values() nl;        //OVERLOAD CALL: get_values: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class)
      break;
    case 'f' :
    case 'F' :
      cout << "TH_PAD_FORCES: " << TH_PAD_FORCES->get_values() nl;        //OVERLOAD CALL: get_values: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class)
      break;
    case 'o' :
    case 'O' :
      cout << "PIP: " << PIP->get_values() nl;        //OVERLOAD CALL: get_values: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class)
      break;
    case 'n' :
    case 'N' :
      cout << "NORMALIZE F5: " << F5_NORMALIZE->get_values() nl;        //OVERLOAD CALL: get_values: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class)
      break;
    case 'p' :
    case 'P' :
      cout << "TH_FINGER_POS: " << TH_FINGER_POS->get_values() nl;        //OVERLOAD CALL: get_values: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class)
      break;
    case 't' :
    case 'T' :
      cout << "TRIGGER: " << TRIGGER->get_values() nl;        //OVERLOAD CALL: get_values: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class)
      break;
    case '4' :
      cout << "A46: " << A46->get_values() nl;        //OVERLOAD CALL: get_values: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class)
      break;
    case '6' :
      cout << "F6: " << F6->get_values() nl;        //OVERLOAD CALL: get_values: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class)
      break;
    case '?' :
    case 'h' :
    case 'H' :
      cout nl << "Available Sensors" nl;
      cout << "c\tSMA/Cingulate" nl;
      cout << "f\tTH_PAD_FORCES" nl;
      cout << "n\tNORMALIZE F5" nl;
      cout << "o\tPIP" nl;
      cout << "p\tTH_FINGER_POS" nl;
      cout << "t\tTRIGGER" nl;
      cout << "4\t46" nl;
      cout << "6\tF6" nl;
      cout nl;
      break;
    }
}

/*
  * void user_connector()
  *
  *  Prompt for a connector name; report the
  * status of the specified sensor.
  *
  */

void user_connector()
{
  char layer[20];
  int index;

  cout << "connector -> ";
  cin >> layer;
  cout << "index -> ";
  cin >> index;
  switch(layer[0])
    {
    case 'j' :
    case 'J' :
      {
	if(index < 0 || index >= HAND_JOINTS)
	  {
	    cout << "Error: expecting and index between 0 and " << HAND_JOINTS-1 nl;
	    return;
	  }
	cout << "Joint Output (j" << index << ")" nl;
	nsl_vector tmp = finger_outputs[index]->get_values();        //OVERLOAD CALL: get_values: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class)
	finger_outputs[index]->report_state(&tmp,        //OVERLOAD CALL: report_state: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class)
					    finger_output_weights[index],
					    finger_degree_weights[index],
					    NULL);
      };
      break;
    case '?' :
    case 'h' :
    case 'H' :
      cout nl << "Available Connectors" nl;
      cout << "j\tJoints" nl;
      cout nl;
      break;
    default:
      cout << "Error: unrecognized connector name: " << layer[0] nl;
    }
}

ofstream dump_file;
int dump_flag = 0;

/*
  * void user_file()
  *
  *  Open the dump output file (storage of activity state for the
  * most important regions).
  *
  */

void user_file()
{
  char dump_file_name[20];
  cout << "Dump file name -> ";
  cin >> dump_file_name;

  dump_file.open(dump_file_name);
  if(!dump_file)
    {
      cerr << "Error opening dump file." nl;
    }
  else
    {
      dump_flag = 1;
      cout << "Dump file opened." nl;
    }
}


/*
  * int stuff_network(ifstream& netfile)
  *
  *  Read the open network file (<netfile>) and set up the 
  * connectivity matrix.
  *
  */

int stuff_network(ifstream& netfile)
{
  char tmp[STRSIZE];
  char tmp2[STRSIZE];
  layer_class *layer;
  connector_class *connector;

				/* Check the header. */
  netfile >> tmp;
  if(strncmp(tmp, "rsnet", STRSIZE))
    {
      cout << "stuff_network(): Bad header on rsnet file." nl;
      return 0;
    }
				/* Loop for each layer in the file. */
  while(!netfile.eof())
    {
      netfile >> tmp;
      if(!strncmp(tmp, "layer", STRSIZE))
	{			/* This is a layer */
	  netfile >> tmp;
				/* Layer AIP */
	  if(!(layer = translate_string_to_layer(tmp)))
	    {
	      cout << "stuff_network(): layer " << tmp << " not recognized.";
	      return 0;
	    }
	  if(!(layer->stuff(netfile)))        //OVERLOAD CALL: stuff: gate.c(gate_class), layer.c(layer_class), column.c(column_class), connector.c(connector_class)
	    return 1;
	}
      else if(!strncmp(tmp, "connector", STRSIZE))
	{			/* This is a connector */
	  netfile >> tmp;
				/* Layer AIP */
	  if(!(connector = translate_string_to_connector(tmp)))
	    {
	      cout << "stuff_network(): connector " << tmp << " not recognized.";
	      return 0;
	    }
	  if(!(connector->stuff(netfile)))        //OVERLOAD CALL: stuff: gate.c(gate_class), layer.c(layer_class), column.c(column_class), connector.c(connector_class)
	    return 1;
	}
      else
	{
	  if(netfile.eof())
	    return 1;
	  cout << "stuff_network(): Error parsing top-level object line." nl;
	  cout << tmp nl;
	  return 0;
	};
      
    };
  return 0;
};


void connect_pet()
{
  if(pet_flag.elem() == 1.0 && pet_init_flag)
    {
      AIP->stuff_pet_connector(pet_pos[PET_AIP], PET_POS);
      AIP->stuff_pet_connector(pet_neg[PET_AIP], PET_NEG);
      F5->stuff_pet_connector(pet_pos[PET_F5], PET_POS);
      F5->stuff_pet_connector(pet_neg[PET_F5], PET_NEG);
      F2->stuff_pet_connector(pet_pos[PET_F2], PET_POS);
      F2->stuff_pet_connector(pet_neg[PET_F2], PET_NEG);
      BG_PHASE->stuff_pet_connector(pet_pos[PET_BG_PHASE], PET_POS);
      BG_PHASE->stuff_pet_connector(pet_neg[PET_BG_PHASE], PET_NEG);
      BG_GRASP->stuff_pet_connector(pet_pos[PET_BG_GRASP], PET_POS);
      BG_GRASP->stuff_pet_connector(pet_neg[PET_BG_GRASP], PET_NEG);
      BG_F5_RECURRENT->stuff_pet_connector(pet_pos[PET_BG_F5_RECURRENT], PET_POS);
      BG_F5_RECURRENT->stuff_pet_connector(pet_neg[PET_BG_F5_RECURRENT], PET_NEG);
      BG_AIP_RECURRENT->stuff_pet_connector(pet_pos[PET_BG_AIP_RECURRENT], PET_POS);
      BG_AIP_RECURRENT->stuff_pet_connector(pet_neg[PET_BG_AIP_RECURRENT], PET_NEG);
      Mcx->stuff_pet_connector(pet_pos[PET_Mcx], PET_POS);
      Mcx->stuff_pet_connector(pet_neg[PET_Mcx], PET_NEG);
      SI->stuff_pet_connector(pet_pos[PET_SI], PET_POS);
      SI->stuff_pet_connector(pet_neg[PET_SI], PET_NEG);
      SII->stuff_pet_connector(pet_pos[PET_SII], PET_POS);
      SII->stuff_pet_connector(pet_neg[PET_SII], PET_NEG);
    };
};



/*
  * void user_load()
  *
  *  Read a network file.
  *
  */

void user_load()
{
  char fname[20];
  ifstream netfile;

  cout << "Network file -> ";
  cin >> fname;

  netfile.open(fname);		/* Open the file */
  if(!netfile)			/* ok? */
    {
      cerr << "Error opening network file." nl;
    }
  else				/* Yes - create net and stuff it. */
    {
      create_network();
      if(stuff_network(netfile))
	{
				/* Loaded ok - initialize all weights */
	  Mcx->init_weights();        //OVERLOAD CALL: init_weights: column.c(column_class), gate.c(gate_class), layer.c(layer_class)
	  SI->init_weights();        //OVERLOAD CALL: init_weights: column.c(column_class), gate.c(gate_class), layer.c(layer_class)
	  SII->init_weights();        //OVERLOAD CALL: init_weights: column.c(column_class), gate.c(gate_class), layer.c(layer_class)
	  AIP->init_weights();        //OVERLOAD CALL: init_weights: column.c(column_class), gate.c(gate_class), layer.c(layer_class)
	  F5->init_weights();        //OVERLOAD CALL: init_weights: column.c(column_class), gate.c(gate_class), layer.c(layer_class)
	  F2->init_weights();        //OVERLOAD CALL: init_weights: column.c(column_class), gate.c(gate_class), layer.c(layer_class)
	  BG_PHASE->init_weights();        //OVERLOAD CALL: init_weights: column.c(column_class), gate.c(gate_class), layer.c(layer_class)
	  BG_GRASP->init_weights();        //OVERLOAD CALL: init_weights: column.c(column_class), gate.c(gate_class), layer.c(layer_class)
	  BG_F5_RECURRENT->init_weights();        //OVERLOAD CALL: init_weights: column.c(column_class), gate.c(gate_class), layer.c(layer_class)
	  BG_AIP_RECURRENT->init_weights();        //OVERLOAD CALL: init_weights: column.c(column_class), gate.c(gate_class), layer.c(layer_class)

	  connect_pet();
	}
      netfile.close();
    }
};


/*
  * layer_class* translate_string_to_layer(char* str)
  *
  *  Given a string, return the corresponding layer pointer.
  *
  */

layer_class* translate_string_to_layer(char* str)
{
  if(!strcmp(str, "AIP"))
    {
      return AIP;
    }
  else if(!strcmp(str, "F5"))
    {
      return F5;
    }
  else if(!strcmp(str, "F2"))
    {
      return F2;
    }
  else if(!strcmp(str, "Mcx"))
    {
      return Mcx;
    }
  else if(!strcmp(str, "SI"))
    {
      return SI;
    }
  else if(!strcmp(str, "SII"))
    {
      return SII;
    }
  else if(!strcmp(str, "BG_PHASE"))
    {
      return BG_PHASE;
    }
  else if(!strcmp(str, "BG_GRASP"))
    {
      return BG_GRASP;
    }
  else if(!strcmp(str, "BG_F5_RECURRENT"))
    {
      return BG_F5_RECURRENT;
    }
  else if(!strcmp(str, "BG_AIP_RECURRENT"))
    {
      return BG_AIP_RECURRENT;
    }
  return NULL;
};

connector_class* translate_string_to_connector(char* str)
{
  if(!strcmp(str, "J_T0_pref"))
    {
      return finger_outputs[J_T0];
    }
  else if(!strcmp(str, "J_T1_pref"))
    {
      return finger_outputs[J_T1];
    }
  else if(!strcmp(str, "J_T2_pref"))
    {
      return finger_outputs[J_T2];
    }
  else if(!strcmp(str, "J_I0_pref"))
    {
      return finger_outputs[J_I0];
    }
  else if(!strcmp(str, "J_I1_pref"))
    {
      return finger_outputs[J_I1];
    }
  else if(!strcmp(str, "J_I2_pref"))
    {
      return finger_outputs[J_I2];
    }
  else if(!strcmp(str, "J_M0_pref"))
    {
      return finger_outputs[J_M0];
    }
  else if(!strcmp(str, "J_M1_pref"))
    {
      return finger_outputs[J_M1];
    }
  else if(!strcmp(str, "J_M2_pref"))
    {
      return finger_outputs[J_M2];
    }
  else if(!strcmp(str, "J_R0_pref"))
    {
      return finger_outputs[J_R0];
    }
  else if(!strcmp(str, "J_R1_pref"))
    {
      return finger_outputs[J_R1];
    }
  else if(!strcmp(str, "J_R2_pref"))
    {
      return finger_outputs[J_R2];
    }
  else if(!strcmp(str, "J_L0_pref"))
    {
      return finger_outputs[J_L0];
    }
  else if(!strcmp(str, "J_L1_pref"))
    {
      return finger_outputs[J_L1];
    }
  else if(!strcmp(str, "J_L2_pref"))
    {
      return finger_outputs[J_L2];
    }


  if(!strcmp(str, "J_T0_deg"))
    {
      return finger_degree[J_T0];
    }
  else if(!strcmp(str, "J_T1_deg"))
    {
      return finger_degree[J_T1];
    }
  else if(!strcmp(str, "J_T2_deg"))
    {
      return finger_degree[J_T2];
    }
  else if(!strcmp(str, "J_I0_deg"))
    {
      return finger_degree[J_I0];
    }
  else if(!strcmp(str, "J_I1_deg"))
    {
      return finger_degree[J_I1];
    }
  else if(!strcmp(str, "J_I2_deg"))
    {
      return finger_degree[J_I2];
    }
  else if(!strcmp(str, "J_M0_deg"))
    {
      return finger_degree[J_M0];
    }
  else if(!strcmp(str, "J_M1_deg"))
    {
      return finger_degree[J_M1];
    }
  else if(!strcmp(str, "J_M2_deg"))
    {
      return finger_degree[J_M2];
    }
  else if(!strcmp(str, "J_R0_deg"))
    {
      return finger_degree[J_R0];
    }
  else if(!strcmp(str, "J_R1_deg"))
    {
      return finger_degree[J_R1];
    }
  else if(!strcmp(str, "J_R2_deg"))
    {
      return finger_degree[J_R2];
    }
  else if(!strcmp(str, "J_L0_deg"))
    {
      return finger_degree[J_L0];
    }
  else if(!strcmp(str, "J_L1_deg"))
    {
      return finger_degree[J_L1];
    }
  else if(!strcmp(str, "J_L2_deg"))
    {
      return finger_degree[J_L2];
    }
  else if(!strcmp(str, "precision"))
    {
      return grasp_measure[GRASP_PRECISION];
    }
  else if(!strcmp(str, "finger"))
    {
      return grasp_measure[GRASP_FINGER];
    }
  else if(!strcmp(str, "palm"))
    {
      return grasp_measure[GRASP_PALM];
    }
  else if(!strcmp(str, "side"))
    {
      return grasp_measure[GRASP_SIDE];
    }

  else if(!strcmp(str, "GRASP_APERTURE"))
    {
      return grasp_aperture_measure;
    }

  return NULL;
};


/*
 * nsl_data* translate_string_to_pointer_name(char* str, name_class** name)
 *
 *  Translate a reference string (typically from a file) into a pointer
 * to the output unit of the corresponding column or sensor.
 *
 * Input = string of the form <name>.<index>
 * Output:
 *  Return = the pointer to the nsl_data object
 *  name* points to the name of the column or sensor element.
 *
 */

nsl_data* translate_string_to_pointer_name(char* str, name_class** name)
{
  char tmp[STRSIZE];
  int index;
  char* ptr;

				/* Replace the '.' with a space so */
				/*  we can parse it. */
  if((ptr = strchr(str, '.')))
    {
/*
      cout << "translate_string_to_pointer(): error parsing object name: " << str nl;
      return NULL;
*/
      *ptr = ' ';
    }
				/* Pull out name and index. */
  if(sscanf(str, "%s %d", tmp, &index) != 2)
    {
      cout << "translate_string_to_pointer(): error parsing object name: " << str nl;
      return NULL;
    }

  if(!strcmp(tmp, "AIP"))
    {
      *name = AIP->get_column_name(index);
      return AIP->get_column_output(index);
    }
  else if(!strcmp(tmp, "F5"))
    {
      *name = F5->get_column_name(index);
      return F5->get_column_output(index);
    }
  else if(!strcmp(tmp, "F2"))
    {
      *name = F2->get_column_name(index);
      return F2->get_column_output(index);
    }
  else if(!strcmp(tmp, "Mcx"))
    {
      *name = Mcx->get_column_name(index);
      return Mcx->get_column_output(index);
    }
  else if(!strcmp(tmp, "SI"))
    {
      *name = SI->get_column_name(index);
      return SI->get_column_output(index);
    }
  else if(!strcmp(tmp, "SII"))
    {
      *name = SII->get_column_name(index);
      return SII->get_column_output(index);
    }

  else if(!strcmp(tmp, "BG_PHASE"))
    {
      *name = BG_PHASE->get_column_name(index);
      return BG_PHASE->get_column_output(index);
    }

  else if(!strcmp(tmp, "BG_GRASP"))
    {
      *name = BG_GRASP->get_column_name(index);
      return BG_GRASP->get_column_output(index);
    }

  else if(!strcmp(tmp, "BG_F5_RECURRENT"))
    {
      *name = BG_F5_RECURRENT->get_column_name(index);
      return BG_F5_RECURRENT->get_column_output(index);
    }

  else if(!strcmp(tmp, "BG_AIP_RECURRENT"))
    {
      *name = BG_AIP_RECURRENT->get_column_name(index);
      return BG_AIP_RECURRENT->get_column_output(index);
    }

  else if(!strcmp(tmp, "A46"))
    {
      *name = A46->get_name(index);        //OVERLOAD CALL: get_name: column.c(column_class), connector.c(connector_class), gate.c(gate_class), layer.c(layer_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class)
      return A46->get_element(index);
    }

  else if(!strcmp(tmp, "F6"))
    {
      *name = F6->get_name(index);        //OVERLOAD CALL: get_name: column.c(column_class), connector.c(connector_class), gate.c(gate_class), layer.c(layer_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class)
      return F6->get_element(index);
    }

  else if(!strcmp(tmp, "PIP"))
    {
      *name = PIP->get_name(index);        //OVERLOAD CALL: get_name: column.c(column_class), connector.c(connector_class), gate.c(gate_class), layer.c(layer_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class)
      return PIP->get_element(index);
    }

  else if(!strcmp(tmp, "SMA"))
    {
      *name = SMA->get_name(index);        //OVERLOAD CALL: get_name: column.c(column_class), connector.c(connector_class), gate.c(gate_class), layer.c(layer_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class)
      return SMA->get_element(index);
    }

  else if(!strcmp(tmp, "SMA_task"))
    {
      *name = SMA_task->get_name(index);        //OVERLOAD CALL: get_name: column.c(column_class), connector.c(connector_class), gate.c(gate_class), layer.c(layer_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class)
      return SMA_task->get_element(index);
    }

  else if(!strcmp(tmp, "TRIGGER"))
    {
      *name = TRIGGER->get_name(index);        //OVERLOAD CALL: get_name: column.c(column_class), connector.c(connector_class), gate.c(gate_class), layer.c(layer_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class)
      return TRIGGER->get_element(index);
    }

  else if(!strcmp(tmp, "F5_NORMALIZE"))
    {
      *name = F5_NORMALIZE->get_name(index);        //OVERLOAD CALL: get_name: column.c(column_class), connector.c(connector_class), gate.c(gate_class), layer.c(layer_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class)
      return F5_NORMALIZE->get_element(index);
    }

  else if(!strcmp(tmp, "AIP_NORMALIZE"))
    {
      *name = AIP_NORMALIZE->get_name(index);        //OVERLOAD CALL: get_name: column.c(column_class), connector.c(connector_class), gate.c(gate_class), layer.c(layer_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class)
      return AIP_NORMALIZE->get_element(index);
    }

  else if(!strcmp(tmp, "TH_PAD_FORCES"))
    {
      *name = TH_PAD_FORCES->get_name(index);        //OVERLOAD CALL: get_name: column.c(column_class), connector.c(connector_class), gate.c(gate_class), layer.c(layer_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class)
      return TH_PAD_FORCES->get_element(index);
    }

  else if(!strcmp(tmp, "TH_FINGER_POS"))
    {
      *name = TH_FINGER_POS->get_name(index);        //OVERLOAD CALL: get_name: column.c(column_class), connector.c(connector_class), gate.c(gate_class), layer.c(layer_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class)
      return TH_FINGER_POS->get_element(index);
    }
  else if(!strcmp(tmp, "CONSTANT"))
    {
      *name = CONSTANT->get_name(index);        //OVERLOAD CALL: get_name: column.c(column_class), connector.c(connector_class), gate.c(gate_class), layer.c(layer_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class)
      return CONSTANT->get_element(index);
    }
  else if(!strcmp(tmp, "INPUT_FINGER_DESIRED"))
    {
      *name = INPUT_FINGER_DESIRED->get_name(index);        //OVERLOAD CALL: get_name: column.c(column_class), connector.c(connector_class), gate.c(gate_class), layer.c(layer_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class)
      return INPUT_FINGER_DESIRED->get_element(index);
    }
  else if(!strcmp(tmp, "FINGER_POSITIONS"))
    {
      *name = FINGER_POSITIONS->get_name(index);        //OVERLOAD CALL: get_name: column.c(column_class), connector.c(connector_class), gate.c(gate_class), layer.c(layer_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class)
      return FINGER_POSITIONS->get_element(index);
    }
  else if(!strcmp(tmp, "ABSTRACT"))
    {
      *name = ABSTRACT->get_name(index);        //OVERLOAD CALL: get_name: column.c(column_class), connector.c(connector_class), gate.c(gate_class), layer.c(layer_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class)
      return ABSTRACT->get_element(index);
    }

  else if(!strcmp(tmp, "GRASP_APERTURE_ESTIMATE"))
    {
      *name = GRASP_APERTURE_ESTIMATE->get_name(index);        //OVERLOAD CALL: get_name: column.c(column_class), connector.c(connector_class), gate.c(gate_class), layer.c(layer_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class)
      return GRASP_APERTURE_ESTIMATE->get_element(index);
    }

  return NULL;
};


/*
  * void user_clear_46()
  *
  *  Zero out all info stored in Area 46
  *
  */

void user_clear_46()
{
  A46_accum = 0;
  A46->set_values(A46_accum);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)
  cout << "Area 46 memory cleared." nl;
};

/************************************************************************/
ofstream track_file;
int track_flag = 0;
int track_skip = 0;
connector_class *track_connector;



/*
  * void parse_track_file(ifstream& trkfile, int prompt_flag)
  *
  *  Parse a track file and set up the track_connector.  The track
  * file specifies a list of column outputs to report to a file.
  * These elements are placed into a connector structure for
  * efficient reference later.
  *
  *  File format:

trk
<fname>
<track_skip>
<layer name>.<column index>.<sub-object>
:
:
<layer name>.<column index>.<sub-object>


  *  If <prompt_flag> is TRUE, then <fname> is ignored and
  * a file name is prompted for.
  *
  */

int parse_track_file(ifstream& trkfile, int prompt_flag)
{
  char tmp[STRSIZE];
  char tmp2[STRSIZE];
  char *ptr;
  char obj[STRSIZE];
  int index;
  layer_class *layer;
  nsl_data* elem;
  name_class* nm;

				/* Read in the header and check it. */
  trkfile >> tmp;
  if(!trkfile)
    {
      cout << "Error getting header" nl;
      return 0;
    };
  if(strncmp(tmp, "trk", STRSIZE))
    {
      cout << "Track file: unexpected header (wanted 'trk'):\n" << tmp nl;
      return 0;
    };

				/* Get the output file name */
  trkfile >> tmp;
  if(!trkfile)
    {
      cerr << "Error getting output track file name." nl;
      return 0;
    }

				/* If in prompt mode, then dump */
				/*  the name that is in the file */
				/*  and prompt the user for one. */
  if(prompt_flag)
    {
      cout << "Output file name -> " nl;
      cin >> tmp;
    };
    
				/* Open the output file. */
  track_file.open(tmp);
  if(!track_file)
    {
      cout << "Error opening output file " << tmp nl;
      return 0;
    }
				/* Get the skip value. */
  trkfile >> track_skip;
  if(!trkfile)
    {
      cout << "Error reading skip." nl;
    };

  while(!trkfile.eof())
    {
      trkfile >> tmp;		/* Get the object name */
      if(!trkfile)
	{
	  if(!trkfile.eof())
	    {
	      cout << "Error reading next element name." nl;
	    };
	}
      else
	{
				/* Expecting a . to separate object name */
				/*  from the index */
	  if(!(ptr = strchr(tmp, '.')))
	    {
	      cout << "parse_track_file(): error parsing object " << tmp nl;
	      return 0;
	    };
	  *ptr = ' ';
				/* Parse out the object name */
	  if(sscanf(tmp, "%s %s", obj, tmp2) != 2)
	    {
	      cout << "parse_track_file(): error parsing object " << tmp nl;
	      return 0;
	    };
	  if((layer = translate_string_to_layer(obj)))
	    {			/* The object is a layer */
				/* Parse out index and sub-object */
	      if(sscanf(tmp2, "%d.%s", &index, tmp) != 2)
		{
		  cout << "parse_track_file(): error parsing index and sub object: " << tmp2 nl;
		  return 0;
		};
	                        /* Right now, only support exporting  */
				/*   the output, but check for this. */
	      if(!strncmp(tmp, "output", STRSIZE))
		{
				/* Add the element to the connector */
		  track_connector->add_connection(layer->get_column_output(index),        //OVERLOAD CALL: add_connection: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class)
						  layer->get_column_name(index),
						  0);
		}
	      else
		{
		  cout << "parse_track_file(): don't recognize sub-object " << tmp nl;
		  return 0;
		};
	    }
	  else
	    {

				/* Parse out the object name */
	      if((elem = translate_string_to_pointer_name(tmp, &nm)))
		{			/* The object is a sensor  */

				/* Add the element to the connector */
		  track_connector->add_connection(elem, nm, 0);        //OVERLOAD CALL: add_connection: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class)
		}
	      else
		{
		  cout << "parse_track_file(): error parsing object: " << tmp nl;
		  return 0;
		};
	    };
	};
    }
  cout << track_connector->get_num_connections() << " elements found." nl;        //OVERLOAD CALL: get_num_connections: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class)
  return 1;
};

/*
  * void user_closetrack()
  *
  *  Turn off track mode and clear out the structures.
  *
  */

void user_closetrack()
{
  if(track_flag)
    {
      track_flag = 0;
      delete track_connector;
      track_file.close();
      cout << "Tracking cleared." nl;
    }
};

/*
  * void user_track()
  *
  *   Turn on track mode, open the track file and parse it.
  *  Track mode is like dumping, except only specified elements
  *  are dumped to the file (specified in the track file).
  *
  */

void user_track(int prompt_flag)
{
  ifstream trkfile;
  char track_file_name[20];

				/* We expect that a network has */
				/*  already been loaded at this point. */
				/*  Otherwise - there will not be any */
				/*  objects to link to. */
  if(!init_flag)
    {
      cout << "Must load a network first.\n";
      return;
    }

				/* Track file is already open, then  */
				/*  clear existing setup first. */
  if(track_flag)
    {
      user_closetrack();
    };

  track_flag = 1;
  track_connector = new connector_class(0);

				/* Track file to parse */
  cout << "Input track file name -> ";
  cin >> track_file_name;
				/* Open the file */
  trkfile.open(track_file_name);
  if(!trkfile)
    {
      cerr << "Error opening trackfile file." nl;
    }
  else
    {
				/* Parse the file. */
      track_flag = 1;
      if(!parse_track_file(trkfile, prompt_flag))
	{			/* An error occurred - clean up. */
	  delete track_connector;
	  track_flag = 0;
	  trkfile.close();
	};
      trkfile.close();
    }
}

/*
  * user_set_output()
  *
  *  Prompts the user for a layer and a column for which the output
  * value is to be set.
  *
  */

void user_set_output()
{
  char tmp[STRSIZE];

  layer_class *layer;
  int index;
  float val;

				/* Get the layer name */
  cout << "layer -> ";
  cin >> tmp;
  if(!(layer = translate_string_to_layer(tmp)))
    {
      cout << "set_output(): do not understand layer " << tmp nl;
      return;
    };
				/* Get the column index */
  cout << "column index -> ";
  cin >> index;
  if(index < 0 || index >= layer->get_num_columns())
    {
      cout << "Column index must fall between 0 and "
	<< layer->get_num_columns()-1 << "(" << index << ")" nl;
      return;
    }
				/* Get the value and set it. */
  cout << "value -> ";
  cin >> val;
  ((layer->get_column(index))->get_output())->elem() = val;        //OVERLOAD CALL: get_output: layer.c(layer_class), column.c(column_class)
};



/*
  * void user_devents()
  *
  *  Write out the event vector to a user-supplied file.
  *
  */

void user_devents()
{
  ofstream efile;
  char file_name[20];

  cout << "File name -> ";
  cin >> file_name;

  efile.open(file_name);
  if(!efile)
    {
      cerr << "Error opening event file." nl;
    }
  else
    {
      efile << EVENTS;
      efile << (delta * EVENTS);
    }
  efile.close();
};

/*
  * void user_dpet()
  *
  *  Write out the PET vector to a user-supplied file.
  *
  */

void user_dpet()
{
  ofstream efile;
  char file_name[20];

				/* Make sure pet is turned on and */
				/*  the network was loaded with the */
				/*  flag on. */
  if(pet_flag.elem() != 1)
    {
      cout << "Error: pet_flag not set." nl;
      return;
    };
  if(pet_init_flag != 1)
    {
      cout << "Error: network not loaded with pet_flag set." nl;
      return;
    };

  cout << "File name -> ";
  cin >> file_name;

  efile.open(file_name);
  if(!efile)
    {
      cerr << "Error opening PET output file." nl;
    }
  else				/* Everything ok - write out the measures. */
    {
      efile << (PET_pos + PET_neg);
      efile << PET_pos;
      efile << PET_neg;
    }
  efile.close();
};


/************************************************************************/
				/* Support routines */

int near(float x, float y)
{
  return(fabs(x-y) < SMALL_VALUE);
};

char* translate_index_to_grasp_string(int grasp)
{
  switch(grasp)
    {
    case GRASP_PRECISION:
      return "PRECISION";
    case GRASP_FINGER:
      return "FINGER";
    case GRASP_PALM:
      return "PALM";
    case GRASP_SIDE:
      return "SIDE";
    default:
      cout << "translate_index_to_grasp_string(): bad grasp index specified ("
	<< grasp << ")" nl;
      exit(1);
    };
  return NULL;
};


/**********************************************************************/

				/* Init column parameters */

void init_column_parameters()
{
#ifdef DEBUG
  cout << "*** init_column_parameters() ***" nl;
#endif
  column_parms.collector_kx1 = &column_collector_kx1;
  column_parms.collector_kx2 = &column_collector_kx2;
  column_parms.collector_ky1 = &column_collector_ky1;
  column_parms.collector_ky2 = &column_collector_ky2;
  column_parms.collector_ky3 = &column_collector_ky3;

  column_parms.sensory_kx1 = &column_sensory_kx1;
  column_parms.sensory_kx2 = &column_sensory_kx2;
  column_parms.sensory_ky1 = &column_sensory_ky1;
  column_parms.sensory_ky2 = &column_sensory_ky2;

  column_parms.output_kx1 = &column_output_kx1;
  column_parms.output_kx2 = &column_output_kx2;
  column_parms.output_ky1 = &column_output_ky1;
  column_parms.output_ky2 = &column_output_ky2;
  column_parms.minimum_output_mem = &column_minimum_output_mem;

  column_parms.tau = &column_tau;
  column_parms.pet_flag = &pet_flag;
}

void init_F5_column_parameters()
{
#ifdef DEBUG
  cout << "*** init_F5_column_parameters() ***" nl;
#endif
  F5_column_parms.collector_kx1 = &column_collector_kx1;
  F5_column_parms.collector_kx2 = &column_collector_kx2;
  F5_column_parms.collector_ky1 = &column_collector_ky1;
  F5_column_parms.collector_ky2 = &column_collector_ky2;
  F5_column_parms.collector_ky3 = &column_collector_ky3;

  F5_column_parms.sensory_kx1 = &column_sensory_kx1;
  F5_column_parms.sensory_kx2 = &column_sensory_kx2;
  F5_column_parms.sensory_ky1 = &column_sensory_ky1;
  F5_column_parms.sensory_ky2 = &column_sensory_ky2;

  F5_column_parms.output_kx1 = &column_output_kx1;
  F5_column_parms.output_kx2 = &column_output_kx2;
  F5_column_parms.output_ky1 = &column_output_ky1;
  F5_column_parms.output_ky2 = &column_output_ky2;
  F5_column_parms.minimum_output_mem = &column_minimum_output_mem;

  F5_column_parms.tau = &F5_column_tau;
  F5_column_parms.pet_flag = &pet_flag;
}

void init_mcx_column_parameters()
{
#ifdef DEBUG
  cout << "*** init_mcx_column_parameters() ***" nl;
#endif
  mcx_column_parms.collector_kx1 = &mcx_column_collector_kx1;
  mcx_column_parms.collector_kx2 = &mcx_column_collector_kx2;
  mcx_column_parms.collector_ky1 = &mcx_column_collector_ky1;
  mcx_column_parms.collector_ky2 = &mcx_column_collector_ky2;
  mcx_column_parms.collector_ky3 = &mcx_column_collector_ky3;

  mcx_column_parms.sensory_kx1 = &mcx_column_sensory_kx1;
  mcx_column_parms.sensory_kx2 = &mcx_column_sensory_kx2;
  mcx_column_parms.sensory_ky1 = &mcx_column_sensory_ky1;
  mcx_column_parms.sensory_ky2 = &mcx_column_sensory_ky2;

  mcx_column_parms.output_kx1 = &mcx_column_output_kx1;
  mcx_column_parms.output_kx2 = &mcx_column_output_kx2;
  mcx_column_parms.output_ky1 = &mcx_column_output_ky1;
  mcx_column_parms.output_ky2 = &mcx_column_output_ky2;
  mcx_column_parms.minimum_output_mem = &mcx_column_minimum_output_mem;

  mcx_column_parms.tau = &column_tau;
  mcx_column_parms.pet_flag = &pet_flag;
}

void SI_init_column_parameters()
{
#ifdef DEBUG
  cout << "*** SI_init_column_parameters() ***" nl;
#endif
  SI_column_parms.collector_kx1 = &SI_column_collector_kx1;
  SI_column_parms.collector_kx2 = &SI_column_collector_kx2;
  SI_column_parms.collector_ky1 = &SI_column_collector_ky1;
  SI_column_parms.collector_ky2 = &SI_column_collector_ky2;
  SI_column_parms.collector_ky3 = &SI_column_collector_ky3;

  SI_column_parms.sensory_kx1 = &SI_column_sensory_kx1;
  SI_column_parms.sensory_kx2 = &SI_column_sensory_kx2;
  SI_column_parms.sensory_ky1 = &SI_column_sensory_ky1;
  SI_column_parms.sensory_ky2 = &SI_column_sensory_ky2;

  SI_column_parms.output_kx1 = &SI_column_output_kx1;
  SI_column_parms.output_kx2 = &SI_column_output_kx2;
  SI_column_parms.output_ky1 = &SI_column_output_ky1;
  SI_column_parms.output_ky2 = &SI_column_output_ky2;
  SI_column_parms.minimum_output_mem = &SI_column_minimum_output_mem;

  SI_column_parms.tau = &SI_column_tau;
  SI_column_parms.pet_flag = &pet_flag;
}


void SII_init_column_parameters()
{
#ifdef DEBUG
  cout << "*** SII_init_column_parameters() ***" nl;
#endif
  SII_column_parms.collector_kx1 = &SII_column_collector_kx1;
  SII_column_parms.collector_kx2 = &SII_column_collector_kx2;
  SII_column_parms.collector_ky1 = &SII_column_collector_ky1;
  SII_column_parms.collector_ky2 = &SII_column_collector_ky2;
  SII_column_parms.collector_ky3 = &SII_column_collector_ky3;

  SII_column_parms.sensory_kx1 = &SII_column_sensory_kx1;
  SII_column_parms.sensory_kx2 = &SII_column_sensory_kx2;
  SII_column_parms.sensory_ky1 = &SII_column_sensory_ky1;
  SII_column_parms.sensory_ky2 = &SII_column_sensory_ky2;

  SII_column_parms.output_kx1 = &SII_column_output_kx1;
  SII_column_parms.output_kx2 = &SII_column_output_kx2;
  SII_column_parms.output_ky1 = &SII_column_output_ky1;
  SII_column_parms.output_ky2 = &SII_column_output_ky2;
  SII_column_parms.minimum_output_mem = &column_minimum_output_mem;

  SII_column_parms.tau = &column_tau;
  SII_column_parms.pet_flag = &pet_flag;
}

void AIP_init_column_parameters()
{
#ifdef DEBUG
  cout << "*** AIP_init_column_parameters() ***" nl;
#endif
  AIP_column_parms.collector_kx1 = &AIP_column_collector_kx1;
  AIP_column_parms.collector_kx2 = &AIP_column_collector_kx2;
  AIP_column_parms.collector_ky1 = &AIP_column_collector_ky1;
  AIP_column_parms.collector_ky2 = &AIP_column_collector_ky2;
  AIP_column_parms.collector_ky3 = &AIP_column_collector_ky3;

  AIP_column_parms.sensory_kx1 = &AIP_column_sensory_kx1;
  AIP_column_parms.sensory_kx2 = &AIP_column_sensory_kx2;
  AIP_column_parms.sensory_ky1 = &AIP_column_sensory_ky1;
  AIP_column_parms.sensory_ky2 = &AIP_column_sensory_ky2;

  AIP_column_parms.output_kx1 = &AIP_column_output_kx1;
  AIP_column_parms.output_kx2 = &AIP_column_output_kx2;
  AIP_column_parms.output_ky1 = &AIP_column_output_ky1;
  AIP_column_parms.output_ky2 = &AIP_column_output_ky2;
  AIP_column_parms.minimum_output_mem = &AIP_column_minimum_output_mem;

  AIP_column_parms.tau = &AIP_column_tau;
  AIP_column_parms.pet_flag = &pet_flag;
}


void init_BG_PHASE_column_parameters()
{
#ifdef DEBUG
  cout << "*** init_BG_PHASE_column_parameters() ***" nl;
#endif
  BG_PHASE_column_parms.collector_kx1 = &BG_PHASE_column_collector_kx1;
  BG_PHASE_column_parms.collector_kx2 = &BG_PHASE_column_collector_kx2;
  BG_PHASE_column_parms.collector_ky1 = &BG_PHASE_column_collector_ky1;
  BG_PHASE_column_parms.collector_ky2 = &BG_PHASE_column_collector_ky2;
  BG_PHASE_column_parms.collector_ky3 = &BG_PHASE_column_collector_ky3;

  BG_PHASE_column_parms.sensory_kx1 = &BG_PHASE_column_sensory_kx1;
  BG_PHASE_column_parms.sensory_kx2 = &BG_PHASE_column_sensory_kx2;
  BG_PHASE_column_parms.sensory_ky1 = &BG_PHASE_column_sensory_ky1;
  BG_PHASE_column_parms.sensory_ky2 = &BG_PHASE_column_sensory_ky2;

  BG_PHASE_column_parms.output_kx1 = &BG_PHASE_column_output_kx1;
  BG_PHASE_column_parms.output_kx2 = &BG_PHASE_column_output_kx2;
  BG_PHASE_column_parms.output_ky1 = &BG_PHASE_column_output_ky1;
  BG_PHASE_column_parms.output_ky2 = &BG_PHASE_column_output_ky2;
  BG_PHASE_column_parms.minimum_output_mem = &BG_PHASE_column_minimum_output_mem;

  BG_PHASE_column_parms.tau = &column_tau;
  BG_PHASE_column_parms.pet_flag = &pet_flag;
}


void init_BG_GRASP_column_parameters()
{
#ifdef DEBUG
  cout << "*** init_BG_GRASP_column_parameters() ***" nl;
#endif
  BG_GRASP_column_parms.collector_kx1 = &BG_GRASP_column_collector_kx1;
  BG_GRASP_column_parms.collector_kx2 = &BG_GRASP_column_collector_kx2;
  BG_GRASP_column_parms.collector_ky1 = &BG_GRASP_column_collector_ky1;
  BG_GRASP_column_parms.collector_ky2 = &BG_GRASP_column_collector_ky2;
  BG_GRASP_column_parms.collector_ky3 = &BG_GRASP_column_collector_ky3;

  BG_GRASP_column_parms.sensory_kx1 = &BG_GRASP_column_sensory_kx1;
  BG_GRASP_column_parms.sensory_kx2 = &BG_GRASP_column_sensory_kx2;
  BG_GRASP_column_parms.sensory_ky1 = &BG_GRASP_column_sensory_ky1;
  BG_GRASP_column_parms.sensory_ky2 = &BG_GRASP_column_sensory_ky2;

  BG_GRASP_column_parms.output_kx1 = &BG_GRASP_column_output_kx1;
  BG_GRASP_column_parms.output_kx2 = &BG_GRASP_column_output_kx2;
  BG_GRASP_column_parms.output_ky1 = &BG_GRASP_column_output_ky1;
  BG_GRASP_column_parms.output_ky2 = &BG_GRASP_column_output_ky2;
  BG_GRASP_column_parms.minimum_output_mem = &BG_GRASP_column_minimum_output_mem;

  BG_GRASP_column_parms.tau = &column_tau;
  BG_GRASP_column_parms.pet_flag = &pet_flag;
}

void init_BG_F5_RECURRENT_column_parameters()
{
#ifdef DEBUG
  cout << "*** init_BG_F5_RECURRENT_column_parameters() ***" nl;
#endif
  BG_F5_RECURRENT_column_parms.collector_kx1 = &BG_F5_RECURRENT_column_collector_kx1;
  BG_F5_RECURRENT_column_parms.collector_kx2 = &BG_F5_RECURRENT_column_collector_kx2;
  BG_F5_RECURRENT_column_parms.collector_ky1 = &BG_F5_RECURRENT_column_collector_ky1;
  BG_F5_RECURRENT_column_parms.collector_ky2 = &BG_F5_RECURRENT_column_collector_ky2;
  BG_F5_RECURRENT_column_parms.collector_ky3 = &BG_F5_RECURRENT_column_collector_ky3;

  BG_F5_RECURRENT_column_parms.sensory_kx1 = &BG_F5_RECURRENT_column_sensory_kx1;
  BG_F5_RECURRENT_column_parms.sensory_kx2 = &BG_F5_RECURRENT_column_sensory_kx2;
  BG_F5_RECURRENT_column_parms.sensory_ky1 = &BG_F5_RECURRENT_column_sensory_ky1;
  BG_F5_RECURRENT_column_parms.sensory_ky2 = &BG_F5_RECURRENT_column_sensory_ky2;

  BG_F5_RECURRENT_column_parms.output_kx1 = &BG_F5_RECURRENT_column_output_kx1;
  BG_F5_RECURRENT_column_parms.output_kx2 = &BG_F5_RECURRENT_column_output_kx2;
  BG_F5_RECURRENT_column_parms.output_ky1 = &BG_F5_RECURRENT_column_output_ky1;
  BG_F5_RECURRENT_column_parms.output_ky2 = &BG_F5_RECURRENT_column_output_ky2;
  BG_F5_RECURRENT_column_parms.minimum_output_mem = &BG_F5_RECURRENT_column_minimum_output_mem;

  BG_F5_RECURRENT_column_parms.tau = &BG_F5_RECURRENT_column_tau;
  BG_F5_RECURRENT_column_parms.pet_flag = &pet_flag;
}

void init_BG_AIP_RECURRENT_column_parameters()
{
#ifdef DEBUG
  cout << "*** init_BG_AIP_RECURRENT_column_parameters() ***" nl;
#endif
  BG_AIP_RECURRENT_column_parms.collector_kx1 = &BG_AIP_RECURRENT_column_collector_kx1;
  BG_AIP_RECURRENT_column_parms.collector_kx2 = &BG_AIP_RECURRENT_column_collector_kx2;
  BG_AIP_RECURRENT_column_parms.collector_ky1 = &BG_AIP_RECURRENT_column_collector_ky1;
  BG_AIP_RECURRENT_column_parms.collector_ky2 = &BG_AIP_RECURRENT_column_collector_ky2;
  BG_AIP_RECURRENT_column_parms.collector_ky3 = &BG_AIP_RECURRENT_column_collector_ky3;

  BG_AIP_RECURRENT_column_parms.sensory_kx1 = &BG_AIP_RECURRENT_column_sensory_kx1;
  BG_AIP_RECURRENT_column_parms.sensory_kx2 = &BG_AIP_RECURRENT_column_sensory_kx2;
  BG_AIP_RECURRENT_column_parms.sensory_ky1 = &BG_AIP_RECURRENT_column_sensory_ky1;
  BG_AIP_RECURRENT_column_parms.sensory_ky2 = &BG_AIP_RECURRENT_column_sensory_ky2;

  BG_AIP_RECURRENT_column_parms.output_kx1 = &BG_AIP_RECURRENT_column_output_kx1;
  BG_AIP_RECURRENT_column_parms.output_kx2 = &BG_AIP_RECURRENT_column_output_kx2;
  BG_AIP_RECURRENT_column_parms.output_ky1 = &BG_AIP_RECURRENT_column_output_ky1;
  BG_AIP_RECURRENT_column_parms.output_ky2 = &BG_AIP_RECURRENT_column_output_ky2;
  BG_AIP_RECURRENT_column_parms.minimum_output_mem = &BG_AIP_RECURRENT_column_minimum_output_mem;

  BG_AIP_RECURRENT_column_parms.tau = &BG_AIP_RECURRENT_column_tau;
  BG_AIP_RECURRENT_column_parms.pet_flag = &pet_flag;
}

void init_F2_column_parameters()
{
#ifdef DEBUG
  cout << "*** init_F2_column_parameters() ***" nl;
#endif
  F2_column_parms.collector_kx1 = &F2_column_collector_kx1;
  F2_column_parms.collector_kx2 = &F2_column_collector_kx2;
  F2_column_parms.collector_ky1 = &F2_column_collector_ky1;
  F2_column_parms.collector_ky2 = &F2_column_collector_ky2;
  F2_column_parms.collector_ky3 = &F2_column_collector_ky3;

  F2_column_parms.sensory_kx1 = &F2_column_sensory_kx1;
  F2_column_parms.sensory_kx2 = &F2_column_sensory_kx2;
  F2_column_parms.sensory_ky1 = &F2_column_sensory_ky1;
  F2_column_parms.sensory_ky2 = &F2_column_sensory_ky2;

  F2_column_parms.output_kx1 = &F2_column_output_kx1;
  F2_column_parms.output_kx2 = &F2_column_output_kx2;
  F2_column_parms.output_ky1 = &F2_column_output_ky1;
  F2_column_parms.output_ky2 = &F2_column_output_ky2;
  F2_column_parms.minimum_output_mem = &F2_column_minimum_output_mem;

  F2_column_parms.tau = &column_tau;
  F2_column_parms.pet_flag = &pet_flag;
}



/************************************************************************/
				/* Init gate parameters */

void init_gate_parameters()
{
#ifdef DEBUG
  cout << "*** init_gate_parameters() ***" nl;
#endif

  gate_parms.pr_kx1 = &gate_pr_kx1;
  gate_parms.pr_kx2 = &gate_pr_kx2;
  gate_parms.pr_ky1 = &gate_pr_ky1;
  gate_parms.pr_ky2 = &gate_pr_ky2;

  gate_parms.support_kx1 = &gate_support_kx1;
  gate_parms.support_kx2 = &gate_support_kx2;
  gate_parms.support_ky1 = &gate_support_ky1;
  gate_parms.support_ky2 = &gate_support_ky2;
  gate_parms.pet_flag = &pet_flag;

}

void init_F5_gate_parameters()
{
#ifdef DEBUG
  cout << "*** init_F5_gate_parameters() ***" nl;
#endif

  F5_gate_parms.pr_kx1 = &F5_gate_pr_kx1;
  F5_gate_parms.pr_kx2 = &F5_gate_pr_kx2;
  F5_gate_parms.pr_ky1 = &F5_gate_pr_ky1;
  F5_gate_parms.pr_ky2 = &F5_gate_pr_ky2;

  F5_gate_parms.support_kx1 = &F5_gate_support_kx1;
  F5_gate_parms.support_kx2 = &F5_gate_support_kx2;
  F5_gate_parms.support_ky1 = &F5_gate_support_ky1;
  F5_gate_parms.support_ky2 = &F5_gate_support_ky2;
  F5_gate_parms.pet_flag = &pet_flag;

}

void mcx_init_gate_parameters()
{
#ifdef DEBUG
  cout << "*** mcx_init_gate_parameters() ***" nl;
#endif

  mcx_gate_parms.pr_kx1 = &gate_pr_kx1;
  mcx_gate_parms.pr_kx2 = &gate_pr_kx2;
  mcx_gate_parms.pr_ky1 = &gate_pr_ky1;
  mcx_gate_parms.pr_ky2 = &gate_pr_ky2;

  mcx_gate_parms.support_kx1 = &mcx_gate_support_kx1;
  mcx_gate_parms.support_kx2 = &mcx_gate_support_kx2;
  mcx_gate_parms.support_ky1 = &mcx_gate_support_ky1;
  mcx_gate_parms.support_ky2 = &mcx_gate_support_ky2;
  mcx_gate_parms.pet_flag = &pet_flag;

}


void SII_init_gate_parameters()
{
#ifdef DEBUG
  cout << "*** SII_init_gate_parameters() ***" nl;
#endif

  SII_gate_parms.pr_kx1 = &SII_gate_pr_kx1;
  SII_gate_parms.pr_kx2 = &SII_gate_pr_kx2;
  SII_gate_parms.pr_ky1 = &SII_gate_pr_ky1;
  SII_gate_parms.pr_ky2 = &SII_gate_pr_ky2;

  SII_gate_parms.support_kx1 = &SII_gate_support_kx1;
  SII_gate_parms.support_kx2 = &SII_gate_support_kx2;
  SII_gate_parms.support_ky1 = &SII_gate_support_ky1;
  SII_gate_parms.support_ky2 = &SII_gate_support_ky2;
  SII_gate_parms.pet_flag = &pet_flag;

}

void BG_PHASE_init_gate_parameters()
{
#ifdef DEBUG
  cout << "*** BG_PHASE_init_gate_parameters() ***" nl;
#endif

  BG_PHASE_gate_parms.pr_kx1 = &BG_PHASE_gate_pr_kx1;
  BG_PHASE_gate_parms.pr_kx2 = &BG_PHASE_gate_pr_kx2;
  BG_PHASE_gate_parms.pr_ky1 = &BG_PHASE_gate_pr_ky1;
  BG_PHASE_gate_parms.pr_ky2 = &BG_PHASE_gate_pr_ky2;

  BG_PHASE_gate_parms.support_kx1 = &BG_PHASE_gate_support_kx1;
  BG_PHASE_gate_parms.support_kx2 = &BG_PHASE_gate_support_kx2;
  BG_PHASE_gate_parms.support_ky1 = &BG_PHASE_gate_support_ky1;
  BG_PHASE_gate_parms.support_ky2 = &BG_PHASE_gate_support_ky2;
  BG_PHASE_gate_parms.pet_flag = &pet_flag;

}
void BG_GRASP_init_gate_parameters()
{
#ifdef DEBUG
  cout << "*** BG_GRASP_init_gate_parameters() ***" nl;
#endif

  BG_GRASP_gate_parms.pr_kx1 = &BG_GRASP_gate_pr_kx1;
  BG_GRASP_gate_parms.pr_kx2 = &BG_GRASP_gate_pr_kx2;
  BG_GRASP_gate_parms.pr_ky1 = &BG_GRASP_gate_pr_ky1;
  BG_GRASP_gate_parms.pr_ky2 = &BG_GRASP_gate_pr_ky2;

  BG_GRASP_gate_parms.support_kx1 = &BG_GRASP_gate_support_kx1;
  BG_GRASP_gate_parms.support_kx2 = &BG_GRASP_gate_support_kx2;
  BG_GRASP_gate_parms.support_ky1 = &BG_GRASP_gate_support_ky1;
  BG_GRASP_gate_parms.support_ky2 = &BG_GRASP_gate_support_ky2;
  BG_GRASP_gate_parms.pet_flag = &pet_flag;

}
void BG_F5_RECURRENT_init_gate_parameters()
{
#ifdef DEBUG
  cout << "*** BG_F5_RECURRENT_init_gate_parameters() ***" nl;
#endif

  BG_F5_RECURRENT_gate_parms.pr_kx1 = &BG_F5_RECURRENT_gate_pr_kx1;
  BG_F5_RECURRENT_gate_parms.pr_kx2 = &BG_F5_RECURRENT_gate_pr_kx2;
  BG_F5_RECURRENT_gate_parms.pr_ky1 = &BG_F5_RECURRENT_gate_pr_ky1;
  BG_F5_RECURRENT_gate_parms.pr_ky2 = &BG_F5_RECURRENT_gate_pr_ky2;

  BG_F5_RECURRENT_gate_parms.support_kx1 = &BG_F5_RECURRENT_gate_support_kx1;
  BG_F5_RECURRENT_gate_parms.support_kx2 = &BG_F5_RECURRENT_gate_support_kx2;
  BG_F5_RECURRENT_gate_parms.support_ky1 = &BG_F5_RECURRENT_gate_support_ky1;
  BG_F5_RECURRENT_gate_parms.support_ky2 = &BG_F5_RECURRENT_gate_support_ky2;
  BG_F5_RECURRENT_gate_parms.pet_flag = &pet_flag;

}

void BG_AIP_RECURRENT_init_gate_parameters()
{
#ifdef DEBUG
  cout << "*** BG_AIP_RECURRENT_init_gate_parameters() ***" nl;
#endif

  BG_AIP_RECURRENT_gate_parms.pr_kx1 = &BG_AIP_RECURRENT_gate_pr_kx1;
  BG_AIP_RECURRENT_gate_parms.pr_kx2 = &BG_AIP_RECURRENT_gate_pr_kx2;
  BG_AIP_RECURRENT_gate_parms.pr_ky1 = &BG_AIP_RECURRENT_gate_pr_ky1;
  BG_AIP_RECURRENT_gate_parms.pr_ky2 = &BG_AIP_RECURRENT_gate_pr_ky2;

  BG_AIP_RECURRENT_gate_parms.support_kx1 = &BG_AIP_RECURRENT_gate_support_kx1;
  BG_AIP_RECURRENT_gate_parms.support_kx2 = &BG_AIP_RECURRENT_gate_support_kx2;
  BG_AIP_RECURRENT_gate_parms.support_ky1 = &BG_AIP_RECURRENT_gate_support_ky1;
  BG_AIP_RECURRENT_gate_parms.support_ky2 = &BG_AIP_RECURRENT_gate_support_ky2;
  BG_AIP_RECURRENT_gate_parms.pet_flag = &pet_flag;

}


void AIP_init_gate_parameters()
{
#ifdef DEBUG
  cout << "*** AIP_init_gate_parameters() ***" nl;
#endif

  AIP_gate_parms.pr_kx1 = &AIP_gate_pr_kx1;
  AIP_gate_parms.pr_kx2 = &AIP_gate_pr_kx2;
  AIP_gate_parms.pr_ky1 = &AIP_gate_pr_ky1;
  AIP_gate_parms.pr_ky2 = &AIP_gate_pr_ky2;

  AIP_gate_parms.support_kx1 = &AIP_gate_support_kx1;
  AIP_gate_parms.support_kx2 = &AIP_gate_support_kx2;
  AIP_gate_parms.support_ky1 = &AIP_gate_support_ky1;
  AIP_gate_parms.support_ky2 = &AIP_gate_support_ky2;
  AIP_gate_parms.pet_flag = &pet_flag;

}

				/* F2 Init gate parameters */

void F2_init_gate_parameters()
{
#ifdef DEBUG
  cout << "*** F2_init_gate_parameters() ***" nl;
#endif

  F2_gate_parms.pr_kx1 = &F2_gate_pr_kx1;
  F2_gate_parms.pr_kx2 = &F2_gate_pr_kx2;
  F2_gate_parms.pr_ky1 = &F2_gate_pr_ky1;
  F2_gate_parms.pr_ky2 = &F2_gate_pr_ky2;

  F2_gate_parms.support_kx1 = &F2_gate_support_kx1;
  F2_gate_parms.support_kx2 = &F2_gate_support_kx2;
  F2_gate_parms.support_ky1 = &F2_gate_support_ky1;
  F2_gate_parms.support_ky2 = &F2_gate_support_ky2;
  F2_gate_parms.pet_flag = &pet_flag;

}



void user_reset_parms()
{
  init_column_parameters();
  init_mcx_column_parameters();
  SI_init_column_parameters();
  SII_init_column_parameters();
  AIP_init_column_parameters();
  init_BG_PHASE_column_parameters();
  init_BG_GRASP_column_parameters();
  init_BG_F5_RECURRENT_column_parameters();
  init_BG_AIP_RECURRENT_column_parameters();
  init_F5_column_parameters();
  init_F2_column_parameters();

  init_gate_parameters();
  init_F5_gate_parameters();
  mcx_init_gate_parameters();
  SII_init_gate_parameters();
  BG_PHASE_init_gate_parameters();
  BG_GRASP_init_gate_parameters();
  BG_F5_RECURRENT_init_gate_parameters();
  BG_AIP_RECURRENT_init_gate_parameters();
  AIP_init_gate_parameters();
  F2_init_gate_parameters();
};


/**********************************************************************/
INIT_MODULE(init_check)
{
  if(!init_flag)
    {
      cout << "Must load a network first.\n";
      exit(1);
    }
};



/************************************************************************/
INIT_MODULE(setup_parms)
{
  user_reset_parms();
};




/************************************************************************/
INIT_MODULE(initialize_weight_matrices)
{
  int i;

#ifdef DEBUG
  cout << "*** initialize_weight_matrices ***" nl;
#endif

				/* Outputs from Mcx. */
				/* Create weight matrices and fill */
				/*  them in */

  for(i = 0; i < HAND_JOINTS; ++i)
    {
      finger_output_weights[i] =
	new nsl_vector(finger_outputs[i]->get_num_connections());        //OVERLOAD CALL: get_num_connections: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class)
      *finger_output_weights[i] =
	finger_outputs[i]->get_initial_weights(0, 0, 0);

      finger_degree_weights[i] =
	new nsl_vector(finger_degree[i]->get_num_connections());        //OVERLOAD CALL: get_num_connections: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class)
      *finger_degree_weights[i] =
	finger_degree[i]->get_initial_weights(0, 0, 0);
    }

}


INIT_MODULE(initialize_sensors)
{
#ifdef DEBUG
  cout << "*** initialize_sensors ***" nl;
#endif
  user_clear();
}




/************************************************************************/

RUN_MODULE(check)
{
  if(!init_flag)
    {
      cout << "Must load a network first.\n";
      exit(1);
    }
};

RUN_MODULE(random_stuff)
{
  PIP->set_values(PIP_INPUT);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)
  F6->set_values(F6_INPUT);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)
};


/*
  * RUN_MODULE(protocol)
  *
  *  Handle timing of external inputs to the model.
  *
  */

RUN_MODULE(protocol)
{
  nsl_vector tmp(1);
 
  if((counter * delta.elem()) == 0)
    {
      tmp = 0;
      TRIGGER->set_values(tmp, 0);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)
      TRIGGER->set_values(tmp, 1);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)
      TRIGGER->set_values(tmp, 2);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)
      TRIGGER->set_values(tmp, 3);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)
//      tmp = 1;
//      TRIGGER->set_values(tmp, 2); /* Trigger 2 is the initial context */        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)
//      cout << "Event: Initial context\n";
      SMA_INPUT = 1;
      SMA->set_values(SMA_INPUT);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)
      EVENTS.elem(EVENT_VISION) = counter;
    }

//  cout << counter * delta.elem() sp << TRIGGER_ON_TIME.elem() sp
//    << ((((float)counter) * delta.elem()) ==  TRIGGER_ON_TIME.elem()) nl;

  if(near(counter * delta.elem(), TRIGGER0_ON_TIME.elem()))
    {
      tmp = 1;			/* Now turn on main trigger stimulus. */
      TRIGGER->set_values(tmp, 2);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)
      EVENTS.elem(EVENT_CONTEXT) = counter;
      cout << "Event: Context on\n";
    }
  if(near(counter * delta.elem(), TRIGGER0_OFF_TIME.elem()))
    {
      tmp = 0;
      cout << "Event: Context off\n";
      TRIGGER->set_values(tmp, 2);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)
    }
  if(near(counter * delta.elem(), TRIGGER_ON_TIME.elem()))
    {
      tmp = 1;			/* Now turn on main trigger stimulus. */
      TRIGGER->set_values(tmp, 0);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)
      EVENTS.elem(EVENT_GO) = counter;
      cout << "Event: Trigger on\n";
    }
  if(near(counter * delta.elem(), TRIGGER_OFF_TIME.elem()))
    {
      tmp = 0;
      cout << "Event: Trigger off\n";
      TRIGGER->set_values(tmp, 0);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)
    }

  if(near(counter * delta.elem(), TRIGGER2_ON_TIME.elem()))
    {
      tmp = 1;
      cout << "Event: Trigger 2 on\n";
      TRIGGER->set_values(tmp, 1);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)
      EVENTS.elem(EVENT_GO_2) = counter;
    }
  if(near(counter * delta.elem(), TRIGGER2_OFF_TIME.elem()))
    {
      tmp = 0;
      cout << "Event: Trigger 2 off\n";
      TRIGGER->set_values(tmp, 1);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)
    }

//  if(near(counter * delta.elem(), ENCLOSE_TIME.elem()))
//    {
//      cout << "Event: Hand Enclose\n";
//      hand_enclosed_flag = 1;
//    };      

//  if(near(counter * delta.elem(), ATTENTION_OFF_TIME.elem()))
//    {
//      cout << "Event: Attention off\n";
//      SMA_INPUT = 0;
//      SMA->set_values(SMA_INPUT);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)
//    }

				/* Abstract input on */
  if(near(counter * delta.elem(), TRIGGER3_ON_TIME.elem()))
    {
      cout << "Event: IS on" nl;
      tmp = 1;
      TRIGGER->set_values(tmp, TRIGGER_IS); /* Used just for tracking */        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)

      ABSTRACT_INPUT = ABSTRACT_STORE;
      ABSTRACT->set_values(ABSTRACT_INPUT);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)
      EVENTS.elem(EVENT_ABSTRACT) = counter;
    };

				/* Abstract input off */
  if(near(counter * delta.elem(), TRIGGER3_OFF_TIME.elem()))
    {
      cout << "Event: IS off" nl;
      tmp = 0;
      TRIGGER->set_values(tmp, TRIGGER_IS); /* Used just for tracking */        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)

      ABSTRACT_INPUT = 0;
      ABSTRACT->set_values(ABSTRACT_INPUT);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)
    };

				/* F6 IS input on */
  if(near(counter * delta.elem(), TRIGGER4_ON_TIME.elem()))
    {
      cout << "Event: F6 IS on" nl;
      tmp = 1;
      TRIGGER->set_values(tmp, TRIGGER_F6); /* Used just for tracking */        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)

      F6_INPUT = F6_STORE;
      F6->set_values(F6_INPUT);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)
      EVENTS.elem(EVENT_F6) = counter;
    };

				/* F6 IS input off */
  if(near(counter * delta.elem(), TRIGGER4_OFF_TIME.elem()))
    {
      cout << "Event: F6 IS off" nl;
      tmp = 0;
      TRIGGER->set_values(tmp, TRIGGER_F6); /* Used just for tracking */        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)

      F6_INPUT = 0;
      F6->set_values(F6_INPUT);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)
    };

				/* A46 engage */
  if(near(counter * delta.elem(), TRIGGER_46_ON_TIME.elem()))
    {
      cout << "Event: A46 engage" nl;
      A46->set_values(A46_scale * A46_accum);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)
      EVENTS.elem(EVENT_46_ENGAGE) = counter;
    };

				/* A46 disengage */
  if(near(counter * delta.elem(), TRIGGER_46_OFF_TIME.elem()))
    {
      cout << "Event: A46 disengage" nl;
      nsl_vector a46_tmp(F5_SIZE);
      a46_tmp = 0;
      A46->set_values(a46_tmp);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)
      EVENTS.elem(EVENT_46_DISENGAGE) = counter;
    };

  ++counter;
}

/*
  * RUN_MODULE(compute_th_finger_position)
  *
  *  Take the current finger positions, compute the
  * distributed representation for these positions
  * and insert them into the TH_FINGER_POS vector.
  *
  */

RUN_MODULE(compute_th_finger_position)
{
#ifdef DEBUG
  cout << "*** compute_th_finger_position()  ***" nl;
#endif

  int i;
  nsl_vector tmp(INDIVIDUAL_FINGER_POS_SIZE);

  for(i = 0; i < HAND_JOINTS; ++i)
    {
      tmp = value_to_gauss(finger_positions.elem(i),
			   gauss_position_min.elem(),
			   gauss_position_max.elem(),
			   (int) gauss_position_pad.elem(),
			   gauss_position_std.elem(),
			   tmp);
      TH_FINGER_POS->set_values(tmp, i * INDIVIDUAL_FINGER_POS_SIZE);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)
    }

				/* Set values for tracking purposes */
  INPUT_FINGER_DESIRED->set_values(input_finger_desired);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)
  FINGER_POSITIONS->set_values(finger_positions);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)
}

RUN_MODULE(compute_th_finger_force)
{
#ifdef DEBUG
  cout << "*** compute_th_finger_force() ***" nl;
#endif

				/* First half proportional to force */
  TH_PAD_FORCES->set_values(force_gain.elem() * pad_forces, 0);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)

				/* Second half reverse of force. */
  TH_PAD_FORCES->set_values(force_gain.elem() * (1-pad_forces), PAD_FORCES_SIZE);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)
}

RUN_MODULE(F5_normalization_terms)
{
#ifdef DEBUG
  cout << "*** normalization_terms() ***" nl;
#endif
/*
  DIFF.eq(F5_NORM_MEM, F5_NORM_tau) = -F5_NORM_MEM +
    (F5->get_output()).sum();        //OVERLOAD CALL: get_output: layer.c(layer_class), column.c(column_class)
  
  F5_NORM = F5_NORM_kx1.elem() * NSLramp(F5_NORM_MEM, F5_NORM_kx0.elem(),
					 F5_NORM_ky0.elem(),
					 F5_NORM_ky1.elem());
  F5_NORMALIZE->set_values(F5_NORM);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)

  DIFF.eq(AIP_NORM_MEM, F5_NORM_tau) = -AIP_NORM_MEM +
    (AIP->get_output()).sum();        //OVERLOAD CALL: get_output: layer.c(layer_class), column.c(column_class)

  AIP_NORM = AIP_NORM_kx1.elem() * NSLramp(AIP_NORM_MEM, AIP_NORM_kx0.elem(),
				      AIP_NORM_ky0.elem(),
				      AIP_NORM_ky1.elem());
  AIP_NORMALIZE->set_values(AIP_NORM);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)
*/
}

RUN_MODULE(membrane_potentials_main_net)
{
#ifdef DEBUG
  cout << "*** membrane_potentials ***" nl;
#endif
  SI->forward_mem();        //OVERLOAD CALL: forward_mem: column.c(column_class), layer.c(layer_class)
  SII->forward_mem();        //OVERLOAD CALL: forward_mem: column.c(column_class), layer.c(layer_class)
  Mcx->forward_mem();        //OVERLOAD CALL: forward_mem: column.c(column_class), layer.c(layer_class)
  AIP->forward_mem();        //OVERLOAD CALL: forward_mem: column.c(column_class), layer.c(layer_class)
  F5->forward_mem();        //OVERLOAD CALL: forward_mem: column.c(column_class), layer.c(layer_class)
  F2->forward_mem();        //OVERLOAD CALL: forward_mem: column.c(column_class), layer.c(layer_class)
  BG_PHASE->forward_mem();        //OVERLOAD CALL: forward_mem: column.c(column_class), layer.c(layer_class)
  BG_GRASP->forward_mem();        //OVERLOAD CALL: forward_mem: column.c(column_class), layer.c(layer_class)
  BG_F5_RECURRENT->forward_mem();        //OVERLOAD CALL: forward_mem: column.c(column_class), layer.c(layer_class)
  BG_AIP_RECURRENT->forward_mem();        //OVERLOAD CALL: forward_mem: column.c(column_class), layer.c(layer_class)
}


RUN_MODULE(activity_levels)
{
#ifdef DEBUG
  cout << "*** activity levels ***" nl;
#endif
  SI->forward_act();        //OVERLOAD CALL: forward_act: column.c(column_class), layer.c(layer_class)
  SII->forward_act();        //OVERLOAD CALL: forward_act: column.c(column_class), layer.c(layer_class)
  Mcx->forward_act();        //OVERLOAD CALL: forward_act: column.c(column_class), layer.c(layer_class)
  AIP->forward_act();        //OVERLOAD CALL: forward_act: column.c(column_class), layer.c(layer_class)
  F5->forward_act();        //OVERLOAD CALL: forward_act: column.c(column_class), layer.c(layer_class)
  F2->forward_act();        //OVERLOAD CALL: forward_act: column.c(column_class), layer.c(layer_class)
  BG_PHASE->forward_act();        //OVERLOAD CALL: forward_act: column.c(column_class), layer.c(layer_class)
  BG_GRASP->forward_act();        //OVERLOAD CALL: forward_act: column.c(column_class), layer.c(layer_class)
  BG_F5_RECURRENT->forward_act();        //OVERLOAD CALL: forward_act: column.c(column_class), layer.c(layer_class)
  BG_AIP_RECURRENT->forward_act();        //OVERLOAD CALL: forward_act: column.c(column_class), layer.c(layer_class)
}

RUN_MODULE(compute_finger_forces)
{
  int i;

#ifdef DEBUG
  cout << "*** compute_finger_forces() ***" nl;
#endif
  input_finger_flag = 0;
				/* Collect outputs from Mcx. */

  for(i = 0; i < HAND_JOINTS; ++i)
    {
				/* weighted desired value */
      input_finger_desired.elem(i) =
	(*finger_output_weights[i]
	 ^ (finger_outputs[i]->get_values())).sum();        //OVERLOAD CALL: get_values: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class)
				/* weighting */
      input_finger_degree.elem(i) =
	(*finger_degree_weights[i]
	 ^ (finger_degree[i]->get_values())).sum();        //OVERLOAD CALL: get_values: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class)
/*
      if(i == 4)
	{
	  printf("%f %f\n", input_finger_desired.elem(i),
		input_finger_degree.elem(i));
	};
*/
				/* If there is really no input */
				/*  from mcx, then install a */
				/*  default. */
      if(input_finger_degree.elem(i) < default_finger_threshold.elem())
	{
	  input_finger_degree.elem(i) +=
	    default_finger_degree.elem(i);

	  input_finger_desired.elem(i) +=
	    default_finger_desired.elem(i)
	      * default_finger_degree.elem(i);
/*
	  if(i == 4)
	    {
	      printf("R = %f %f\n", input_finger_desired.elem(i),
		    input_finger_degree.elem(i));
	      
	    };
*/
				/* Indicate that not above threshold */
	  input_finger_flag.elem(i) = 1;
	};

				/* Now remove weighting */
      input_finger_desired.elem(i) /= input_finger_degree.elem(i);
    };
};


RUN_MODULE(increment_hand_state)
{
#ifdef DEBUG
  cout << "*** increment_hand_state()  ***" nl;
#endif
  hand_dynamics(finger_positions,        //OVERLOAD CALL: hand_dynamics: hand.c(?), hand.orig.c(?)
		input_finger_desired, input_finger_degree,
		finger_stiffness,
		position_gain,
		degree2stiffness,
		max_flexion,
		min_flexion,
		pad_forces,
		finger_vel,
		finger_vel_gain,
		degree2vel_gain,
		delta,
		input_finger_forces);
};

/*
  * RUN_MODULE(PET)
  *
  *  For each layer of interest, sum over all units.
  *
  */

RUN_MODULE(PET)
{
  int i;

#ifdef DEBUG
  cout << "*** PET()  ***" nl;
#endif
  if(pet_flag.elem() && pet_init_flag)
    {
      for(i = 0; i < NUM_REGIONS; ++i)
	{
	  PET_pos.elem(i) += (pet_pos[i]->get_values()).sum();        //OVERLOAD CALL: get_values: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class)
	  PET_neg.elem(i) += (pet_neg[i]->get_values()).sum();        //OVERLOAD CALL: get_values: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class)
	};
    };
};


RUN_MODULE(get_display_vectors)
{
#ifdef DEBUG
  cout << "*** display_vectors ***" nl;
#endif
  AIP_output_display = AIP->get_output();        //OVERLOAD CALL: get_output: layer.c(layer_class), column.c(column_class)
  F5_output_display = F5->get_output();        //OVERLOAD CALL: get_output: layer.c(layer_class), column.c(column_class)
  F2_output_display = F2->get_output();        //OVERLOAD CALL: get_output: layer.c(layer_class), column.c(column_class)
  SI_output_display = SI->get_output();        //OVERLOAD CALL: get_output: layer.c(layer_class), column.c(column_class)
  SII_output_display = SII->get_output();        //OVERLOAD CALL: get_output: layer.c(layer_class), column.c(column_class)
  Mcx_output_display = Mcx->get_output();        //OVERLOAD CALL: get_output: layer.c(layer_class), column.c(column_class)
  BG_PHASE_output_display = BG_PHASE->get_output();        //OVERLOAD CALL: get_output: layer.c(layer_class), column.c(column_class)
  BG_GRASP_output_display = BG_GRASP->get_output();        //OVERLOAD CALL: get_output: layer.c(layer_class), column.c(column_class)
  BG_F5_RECURRENT_output_display = BG_F5_RECURRENT->get_output();        //OVERLOAD CALL: get_output: layer.c(layer_class), column.c(column_class)
  BG_AIP_RECURRENT_output_display = BG_AIP_RECURRENT->get_output();        //OVERLOAD CALL: get_output: layer.c(layer_class), column.c(column_class)

  AIP_output_mem_display = AIP->get_output_mem();        //OVERLOAD CALL: get_output_mem: column.c(column_class), layer.c(layer_class)
  F5_output_mem_display = F5->get_output_mem();        //OVERLOAD CALL: get_output_mem: column.c(column_class), layer.c(layer_class)
  F2_output_mem_display = F2->get_output_mem();        //OVERLOAD CALL: get_output_mem: column.c(column_class), layer.c(layer_class)
  SI_output_mem_display = SI->get_output_mem();        //OVERLOAD CALL: get_output_mem: column.c(column_class), layer.c(layer_class)
  SII_output_mem_display = SII->get_output_mem();        //OVERLOAD CALL: get_output_mem: column.c(column_class), layer.c(layer_class)
  Mcx_output_mem_display = Mcx->get_output_mem();        //OVERLOAD CALL: get_output_mem: column.c(column_class), layer.c(layer_class)
  BG_PHASE_output_mem_display = BG_PHASE->get_output_mem();        //OVERLOAD CALL: get_output_mem: column.c(column_class), layer.c(layer_class)
  BG_GRASP_output_mem_display = BG_GRASP->get_output_mem();        //OVERLOAD CALL: get_output_mem: column.c(column_class), layer.c(layer_class)
  BG_F5_RECURRENT_output_mem_display = BG_F5_RECURRENT->get_output_mem();        //OVERLOAD CALL: get_output_mem: column.c(column_class), layer.c(layer_class)
  BG_AIP_RECURRENT_output_mem_display = BG_AIP_RECURRENT->get_output_mem();        //OVERLOAD CALL: get_output_mem: column.c(column_class), layer.c(layer_class)
}

/*
  * RUN_MODULE(A46_memory)
  *
  *   If the accum_flag is turned on, then remember the maximum value
  * achieved by each F5 unit.
  *
  */

RUN_MODULE(A46_memory)
{
  int i;

  if(A46_accum_flag.elem() == 1.0)
    {
      for(i = 0; i < F5_SIZE; ++i)
	{
	  if(F5_output_display.elem(i) > A46_accum.elem(i))
	    A46_accum.elem(i) = F5_output_display.elem(i);
	};
    };
};



RUN_MODULE(dump)
{
  if(dump_flag && (counter % ((int) dump_skip.elem())) == 0)
    {
      dump_file << counter sp << (counter * delta.elem()) nl;
      dump_file << finger_positions;
      dump_file << TRIGGER->get_values();        //OVERLOAD CALL: get_values: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class)
      dump_file << AIP_output_display;
      dump_file << F5_output_display;
      dump_file << F2_output_display;
      dump_file << SII_output_mem_display;
      dump_file << BG_PHASE_output_display;
      dump_file << BG_GRASP_output_display;
      dump_file << BG_F5_RECURRENT_output_display;
      dump_file << BG_AIP_RECURRENT_output_display;

    }
				/* Note that track_skip is in time steps */
				/*   and not in ms.  */

  if(track_flag && (counter % track_skip) == 0)
    {
      track_file << (counter * delta.elem()) sp
	<< track_connector->get_values();        //OVERLOAD CALL: get_values: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class)
    }
}


/*
  * RUN_MODULE(compute_measures)
  *
  *  Snoops on the network state to see what grasp type and aperture
  * have been selected.
  *
  */

RUN_MODULE(compute_measures)
{
#ifdef DEBUG
  cout << "*** compute measures ***" nl;
#endif

  int i, max_i;
  float max;

				/* Compute the total votes for each grasp */
				/*  type and figure out which one wins. */
  max = -1;
  max_i = -1;
  for(i = 0; i < NUM_GRASPS; ++i)
    {
				/* Retrieve the votes and sum. */

				/* Are there any votes for this grasp? */
      if(grasp_measure[i]->get_num_connections() > 0)        //OVERLOAD CALL: get_num_connections: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class)
	{
	  grasp_measure_levels.elem(i) = (grasp_measure[i]->get_values()).sum();        //OVERLOAD CALL: get_values: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class)

				/* Check to see if this is the largest  */
				/*  thus far. */

	  if(grasp_measure_levels.elem(i) > max)
	    {
	      max = grasp_measure_levels.elem(i);
	      max_i = i;
	    };
	}
      else			/* No F5 units voting for this grasp.*/
	{
	  grasp_measure_levels.elem(i) = 0;
	};
    };
  grasp_win = max_i;
				/* Estimate aperture */

				/* Vote levels */
  nsl_vector ap = grasp_aperture_measure->get_values();        //OVERLOAD CALL: get_values: connector.c(connector_class), reverse_connector.c(reverse_connector_input_class), reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class)
  float total = ap.sum();

				/* Weighted average of aperture votes       */
				/*   Weights (get_initial_weights) are the  */
				/*   individual apertures                   */
				/*   for which F5 cells are voting.         */
  if(total > 0.1)
    {
      nsl_vector gae_tmp(1);

      grasp_aperture_estimate.elem() =
	(ap ^ grasp_aperture_measure->get_initial_weights(0,0,0)).sum() / total;

				/* Put value into sensor for tracking*/
      gae_tmp.elem(0) = grasp_aperture_estimate.elem();
      GRASP_APERTURE_ESTIMATE->set_values(gae_tmp);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)
    }
  else
    grasp_aperture_estimate = 0;
};

/*
  * RUN_MODULE(monitor_phase)
  *
  *   Detect which phase F5 thinks we are in.  Right now this is just
  * a quick hack (not that we do not handle the initial boundary
  * condition in a clean way - but it will work).
  *
  */

// int bogus_flag = 0;

RUN_MODULE(monitor_phase)
{
  int vel_flag;
				/* Detects when all index joints begin*/
				/*  to flex. */
  vel_flag = (finger_vel.elem(J_I0) > 0)
    && (finger_vel.elem(J_I1) > 0)
      && (finger_vel.elem(J_I2) > 0);


  if(current_phase < F5_PHASE_RELEASE)        //OVERLOAD CALL: F5_PHASE_RELEASE: net.h(?), wire.h(?)
    {
				/* Should there be a phase transition? */
				/* First: does BG say there is a phase change*/
      if((BG_PHASE_output_display.elem(F5_PHASES+current_phase-1) <
	 BG_PHASE_output_display.elem(F5_PHASES+current_phase))
				/* Second: Peak aperture reached */
	 || ((current_phase == F5_PHASE_EXTENSION)        //OVERLOAD CALL: F5_PHASE_EXTENSION: net.h(?), wire.h(?)
	     && vel_flag))
	{
	  ++current_phase;
	  cout << "Transition to phase ";
	  switch (current_phase)
	    {
	    case F5_PHASE_EXTENSION:        //OVERLOAD CALL: F5_PHASE_EXTENSION: net.h(?), wire.h(?)
	      cout << "Extension" nl;
	      break;
	    case F5_PHASE_FLEXION:        //OVERLOAD CALL: F5_PHASE_FLEXION: net.h(?), wire.h(?)
	      cout << "Flexion" nl;

				/* Report which grasp this is */
	      cout << "Grasp is "
		<< translate_index_to_grasp_string((int) grasp_win.elem())
		  << ", aperture = "
		    << grasp_aperture_estimate;

				/* Install max and min joint values  */
				/*  to simulate contact with object. */
				/* These values are a function of the */
				/*  type of grasp that has been chosen. */

	      EVENTS.elem(EVENT_PEAK_APERTURE) = counter;
	      
	      switch((int) grasp_win.elem())
		{
		case GRASP_PRECISION:
		  max_flexion = max_flexion_hold_precision;
		  min_flexion = min_flexion_hold_precision;
		  break;
		case GRASP_FINGER:
		  max_flexion = max_flexion_hold_finger;
		  min_flexion = min_flexion_hold_finger;
		  break;
		case GRASP_PALM:
		  max_flexion = max_flexion_hold_palm;
		  min_flexion = min_flexion_hold_palm;
		  break;
		case GRASP_SIDE:
		  max_flexion = max_flexion_hold_side;
		  min_flexion = min_flexion_hold_side;
		  break;
		};
	      break;
	    case F5_PHASE_HOLD:        //OVERLOAD CALL: F5_PHASE_HOLD: net.h(?), wire.h(?)
	      cout << "Hold" nl;
	      EVENTS.elem(EVENT_HOLD) = counter;
	      break;
	    case F5_PHASE_RELEASE:        //OVERLOAD CALL: F5_PHASE_RELEASE: net.h(?), wire.h(?)
	      cout << "Release" nl;
	      release_time = counter;
	      break;
	    };
	}
    };

				/* Detection of task completion */
  if(current_phase == F5_PHASE_RELEASE &&        //OVERLOAD CALL: F5_PHASE_RELEASE: net.h(?), wire.h(?)
     (counter-release_time) * delta.elem() >= ATTENTION_OFF_TIME.elem())
    {
      cout << "Shutting down SMA" nl;
      SMA_INPUT = 0;
      SMA->set_values(SMA_INPUT);        //OVERLOAD CALL: set_values: reverse_connector.c(reverse_connector_output_class), sensor.c(sensor_class), sensor.c(sensor_class)
      current_phase = F5_PHASE_DONE;
				/* Remove object model */
      max_flexion = 100; 
      min_flexion = -10;
      EVENTS.elem(EVENT_SHUTDOWN) = counter;
    };
				/* Detection of movement initiation */
  if((current_phase == F5_PHASE_SET || current_phase == F5_PHASE_EXTENSION) &&        //OVERLOAD CALL: F5_PHASE_SET: net.h(?), wire.h(?); F5_PHASE_EXTENSION: net.h(?), wire.h(?)
     (finger_vel.elem(J_I0) < 0)
     && (finger_vel.elem(J_I1) < 0)
     && (finger_vel.elem(J_I2) < 0)
     && (EVENTS.elem(EVENT_MOVEMENT_INIT) == -1.0))
    {
      EVENTS.elem(EVENT_MOVEMENT_INIT) = counter;
    };

				/* Detection of contact  */
  if((current_phase == F5_PHASE_FLEXION || current_phase == F5_PHASE_HOLD)        //OVERLOAD CALL: F5_PHASE_FLEXION: net.h(?), wire.h(?); F5_PHASE_HOLD: net.h(?), wire.h(?)
     && (pad_forces.sum() > 0.4)
     && (EVENTS.elem(EVENT_CONTACT) == -1.0))
    {
      EVENTS.elem(EVENT_CONTACT) = counter;
    };
				/* Detection of release */

				/* What is the total pad forces detected? */
  if(pad_forces.sum() > max_pad_forces.elem())
    {
      max_pad_forces.elem() = pad_forces.sum();
    }

				/* Now check for release */
  if((current_phase == F5_PHASE_HOLD || current_phase == F5_PHASE_RELEASE)        //OVERLOAD CALL: F5_PHASE_HOLD: net.h(?), wire.h(?); F5_PHASE_RELEASE: net.h(?), wire.h(?)
     && (pad_forces.sum() < max_pad_forces.elem())
     && (counter * delta.elem() > TRIGGER2_ON_TIME.elem())
     && (EVENTS.elem(EVENT_RELEASE) == -1.0))
    {
      EVENTS.elem(EVENT_RELEASE) = counter;
//      bogus_flag = 0;
    };
//  if((current_phase == F5_PHASE_HOLD || current_phase == F5_PHASE_RELEASE)        //OVERLOAD CALL: F5_PHASE_HOLD: net.h(?), wire.h(?); F5_PHASE_RELEASE: net.h(?), wire.h(?)
//     && (pad_forces.sum() == 0)
//     && (EVENTS.elem(EVENT_RELEASE) == -1.0))
//    {
//      cout << "CONDITIONS are TRUE" nl;
//      cout << counter nl;
//      bogus_flag = 1;
//    };
//  if(bogus_flag)
//    {
//      cout << current_phase sp << (pad_forces.sum()) sp << counter sp << EVENTS.elem(EVENT_RELEASE) nl;
//    };

};


[ return ]