Skip to content
Snippets Groups Projects
force-compensation.cpp 17.3 KiB
Newer Older
Thomas Moulard's avatar
Thomas Moulard committed
/*
 * Copyright 2010,
 * François Bleibel,
 * Olivier Stasse,
Thomas Moulard's avatar
Thomas Moulard committed
 * CNRS/AIST
Thomas Moulard's avatar
Thomas Moulard committed
 */
#include <sot-dynamic-pinocchio/force-compensation.h>
#include <dynamic-graph/factory.h>
using namespace dynamicgraph::sot;
using namespace dynamicgraph;
DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(ForceCompensationPlugin,"ForceCompensation");

/* --- PLUGIN --------------------------------------------------------------- */
/* --- PLUGIN --------------------------------------------------------------- */
/* --- PLUGIN --------------------------------------------------------------- */
ForceCompensation::
ForceCompensation(void)
  :usingPrecompensation(false)
{}


ForceCompensationPlugin::
Nicolas Mansard's avatar
Nicolas Mansard committed
ForceCompensationPlugin( const std::string & name )
  :Entity(name)
  ,calibrationStarted(false)
Nicolas Mansard's avatar
Nicolas Mansard committed

  ,torsorSIN(NULL,"sotForceCompensation("+name+")::input(vector6)::torsorIN")
  ,worldRhandSIN(NULL,"sotForceCompensation("+name+")::input(MatrixRotation)::worldRhand")
Nicolas Mansard's avatar
Nicolas Mansard committed

  ,handRsensorSIN(NULL,"sotForceCompensation("+name+")::input(MatrixRotation)::handRsensor")
  ,translationSensorComSIN(NULL,"sotForceCompensation("+name+")::input(vector3)::sensorCom")
  ,gravitySIN(NULL,"sotForceCompensation("+name+")::input(vector6)::gravity")
  ,precompensationSIN(NULL,"sotForceCompensation("+name+")::input(vector6)::precompensation")
  ,gainSensorSIN(NULL,"sotForceCompensation("+name+")::input(matrix6)::gain")
  ,deadZoneLimitSIN(NULL,"sotForceCompensation("+name+")::input(vector6)::deadZoneLimit")
Nicolas Mansard's avatar
Nicolas Mansard committed
  ,transSensorJointSIN(NULL,"sotForceCompensation("+name+")::input(vector6)::sensorJoint")  ,inertiaJointSIN(NULL,"sotForceCompensation("+name+")::input(matrix6)::inertiaJoint")
  ,velocitySIN(NULL,"sotForceCompensation("+name+")::input(vector6)::velocity")
  ,accelerationSIN(NULL,"sotForceCompensation("+name+")::input(vector6)::acceleration")

  ,handXworldSOUT( SOT_INIT_SIGNAL_2( ForceCompensation::computeHandXworld,
				      worldRhandSIN,MatrixRotation,
				      translationSensorComSIN,dynamicgraph::Vector ),
		   "sotForceCompensation("+name+")::output(MatrixForce)::handXworld" )
   ,handVsensorSOUT( SOT_INIT_SIGNAL_1( ForceCompensation::computeHandVsensor,
					handRsensorSIN,MatrixRotation),
		     "sotForceCompensation("+name+")::output(MatrixForce)::handVsensor" )
   ,torsorDeadZoneSIN(NULL,"sotForceCompensation("+name+")::input(vector6)::torsorNullifiedIN")
Nicolas Mansard's avatar
Nicolas Mansard committed

  ,sensorXhandSOUT( SOT_INIT_SIGNAL_2( ForceCompensation::computeSensorXhand,
				       handRsensorSIN,MatrixRotation,
				       transSensorJointSIN,dynamicgraph::Vector ),
		   "sotForceCompensation("+name+")::output(MatrixForce)::sensorXhand" )
//   ,inertiaSensorSOUT( SOT_INIT_SIGNAL_2( ForceCompensation::computeInertiaSensor,
// 					  inertiaJointSIN,dynamicgraph::Matrix,
// 					  sensorXhandSOUT,MatrixForce ),
// 		       "ForceCompensation("+name+")::output(MatrixForce)::inertiaSensor" )
   ,momentumSOUT( SOT_INIT_SIGNAL_4(ForceCompensation::computeMomentum,
				    velocitySIN,dynamicgraph::Vector,
				    accelerationSIN,dynamicgraph::Vector,
				    sensorXhandSOUT,MatrixForce,
				    inertiaJointSIN,dynamicgraph::Matrix),
Nicolas Mansard's avatar
Nicolas Mansard committed
		  "sotForceCompensation("+name+")::output(Vector6)::momentum" )
  ,momentumSIN(NULL,"sotForceCompensation("+name+")::input(vector6)::momentumIN")

  ,torsorCompensatedSOUT( SOT_INIT_SIGNAL_7(ForceCompensation::computeTorsorCompensated,
					    torsorSIN,dynamicgraph::Vector,
					    precompensationSIN,dynamicgraph::Vector,
					    gravitySIN,dynamicgraph::Vector,
					    handXworldSOUT,MatrixForce,
					    handVsensorSOUT,MatrixForce,
					    gainSensorSIN,dynamicgraph::Matrix,
					    momentumSIN,dynamicgraph::Vector),
Nicolas Mansard's avatar
Nicolas Mansard committed
			  "sotForceCompensation("+name+")::output(Vector6)::torsor" )
  ,torsorDeadZoneSOUT( SOT_INIT_SIGNAL_2(ForceCompensation::computeDeadZone,
					 torsorDeadZoneSIN,dynamicgraph::Vector,
					 deadZoneLimitSIN,dynamicgraph::Vector),
Nicolas Mansard's avatar
Nicolas Mansard committed
		       "sotForceCompensation("+name+")::output(Vector6)::torsorNullified" )
   ,calibrationTrigerSOUT( boost::bind(&ForceCompensationPlugin::calibrationTriger,
				       this,_1,_2),
			   torsorSIN << worldRhandSIN,
			   "sotForceCompensation("+name+")::output(Dummy)::calibrationTriger")
{
  sotDEBUGIN(5);
Nicolas Mansard's avatar
Nicolas Mansard committed

  signalRegistration(torsorSIN);
  signalRegistration(worldRhandSIN);
  signalRegistration(handRsensorSIN);
  signalRegistration(translationSensorComSIN);
  signalRegistration(gravitySIN);
  signalRegistration(precompensationSIN);
  signalRegistration(gainSensorSIN);
  signalRegistration(deadZoneLimitSIN);
  signalRegistration(transSensorJointSIN);
  signalRegistration(inertiaJointSIN);
  signalRegistration(velocitySIN );
  signalRegistration(accelerationSIN);
  signalRegistration(handXworldSOUT);
  signalRegistration(handVsensorSOUT);
  signalRegistration(torsorDeadZoneSIN);
  signalRegistration(sensorXhandSOUT);
  signalRegistration(momentumSOUT);
  signalRegistration(momentumSIN);
  signalRegistration(torsorCompensatedSOUT);
  signalRegistration(torsorDeadZoneSOUT);
  signalRegistration(calibrationTrigerSOUT);
  torsorDeadZoneSIN.plug(&torsorCompensatedSOUT);
Nicolas Mansard's avatar
Nicolas Mansard committed

  // By default, I choose: momentum is not compensated.
  //  momentumSIN.plug( &momentumSOUT );
  dynamicgraph::Vector v(6); v.fill(0); momentumSIN = v;

  sotDEBUGOUT(5);
}


ForceCompensationPlugin::
~ForceCompensationPlugin( void )
{
  return;
}

/* --- CALIB --------------------------------------------------------------- */
/* --- CALIB --------------------------------------------------------------- */
/* --- CALIB --------------------------------------------------------------- */

MatrixRotation ForceCompensation::I3;

void ForceCompensation::
clearCalibration( void )
{
  torsorList.clear();
  rotationList.clear();
}


void ForceCompensation::
addCalibrationValue( const dynamicgraph::Vector& /*torsor*/,
Nicolas Mansard's avatar
Nicolas Mansard committed
		     const MatrixRotation & /*worldRhand*/ )
{
  sotDEBUGIN(45);

  //   sotDEBUG(25) << "Add torsor: t"<<torsorList.size() <<" = " << torsor;
  //   sotDEBUG(25) << "Add Rotation: wRh"<<torsorList.size() <<" = " << worldRhand;

  //   torsorList.push_back(torsor);
  //   rotationList.push_back(worldRhand);

  sotDEBUGOUT(45);
}
Nicolas Mansard's avatar
Nicolas Mansard committed

dynamicgraph::Vector ForceCompensation::
calibrateTransSensorCom( const dynamicgraph::Vector& gravity,
Nicolas Mansard's avatar
Nicolas Mansard committed
			 const MatrixRotation& /*handRsensor*/ )
{
  //   sotDEBUGIN(25);

  //   dynamicgraph::Vector grav3(3);
  //   dynamicgraph::Vector Rgrav3(3),tau(3),Rtau(3);
  //   for( unsigned int j=0;j<3;++j ) { grav3(j)=gravity(j); }

  //   std::list< dynamicgraph::Vector >::iterator iterTorsor = torsorList.begin();
Nicolas Mansard's avatar
Nicolas Mansard committed
  //   std::list< MatrixRotation >::const_iterator iterRotation
  //     = rotationList.begin();


  //   const unsigned int NVAL = torsorList.size();
Nicolas Mansard's avatar
Nicolas Mansard committed
  //   if( 0==NVAL )
  //       dynamicgraph::Vector zero(3); zero.fill(0);
  //       return zero;
  //     }

Nicolas Mansard's avatar
Nicolas Mansard committed
  //   if(NVAL!=rotationList.size() )
  //     {
  // 	  // TODO: ERROR THROW
  //     }
  //   dynamicgraph::Matrix torsors( 3,NVAL );
  //   dynamicgraph::Matrix gravitys( 3,NVAL );

  //   for( unsigned int i=0;i<NVAL;++i )
  //     {
  //       if( (torsorList.end()==iterTorsor)||(rotationList.end()==iterRotation) )
  // 	{
  // 	  // TODO: ERROR THROW
  // 	  break;
  // 	}
  //       const dynamicgraph::Vector & torsor = *iterTorsor;
  //       const MatrixRotation & worldRhand = *iterRotation;

  //       for( unsigned int j=0;j<3;++j ) { tau(j)=torsor(j+3); }
  //       handRsensor.multiply(tau,Rtau);
  //       worldRhand.transpose().multiply( grav3,Rgrav3 );
  //       for( unsigned int j=0;j<3;++j )
  // 	{
  // 	  torsors( j,i ) = -Rtau(j);
  // 	  gravitys( j,i ) = Rgrav3(j);
  // 	}
  //       sotDEBUG(35) << "R" << i << " = " << worldRhand;
  //       sotDEBUG(35) << "Rtau" << i << " = " << Rtau;
  //       sotDEBUG(35) << "Rg" << i << " = " << Rgrav3;

  //       iterTorsor++; iterRotation++;
  //     }

  //   sotDEBUG(35) << "Rgs = " << gravitys;
  //   sotDEBUG(35) << "Rtaus = " << torsors;

  //   dynamicgraph::Matrix gravsInv( gravitys.nbCols(),gravitys.nbRows() );
  //   sotDEBUG(25) << "Compute the pinv..." << std::endl;
  //   gravitys.pseudoInverse(gravsInv);
  //   sotDEBUG(25) << "Compute the pinv... [DONE]" << std::endl;
  //   sotDEBUG(25) << "gravsInv = " << gravsInv << std::endl;

  //   dynamicgraph::Matrix Skew(3,3);
  //   torsors.multiply( gravsInv,Skew );
  //   sotDEBUG(25) << "Skew = " << Skew << std::endl;
Nicolas Mansard's avatar
Nicolas Mansard committed

  //   sc(0)=(Skew(2,1)-Skew(1,2))*.5 ;
  //   sc(1)=(Skew(0,2)-Skew(2,0))*.5 ;
  //   sc(2)=(Skew(1,0)-Skew(0,1))*.5 ;
Nicolas Mansard's avatar
Nicolas Mansard committed
  //   sotDEBUG(15) << "SC = " << sc << std::endl;
  //   /* TAKE the antisym constraint into account inside the minimization pbm. */

  //   sotDEBUGOUT(25);
  //   return sc;
  return gravity;
}

dynamicgraph::Vector ForceCompensation::
Nicolas Mansard's avatar
Nicolas Mansard committed
calibrateGravity( const MatrixRotation& /*handRsensor*/,
		  bool /*precompensationCalibration*/,
		  const MatrixRotation& /*hand0RsensorArg*/ )
{
  sotDEBUGIN(25);

  //   MatrixRotation hand0Rsensor;
  //   if( &hand0Rsensor==&I3 ) hand0Rsensor.setIdentity();
  //   else hand0Rsensor=hand0RsensorArg;

  //   std::list< dynamicgraph::Vector >::const_iterator iterTorsor = torsorList.begin();
Nicolas Mansard's avatar
Nicolas Mansard committed
  //   std::list< MatrixRotation >::const_iterator iterRotation
  //     = rotationList.begin();

  //   const unsigned int NVAL = torsorList.size();
Nicolas Mansard's avatar
Nicolas Mansard committed
  //   if(NVAL!=rotationList.size() )
  //     {
  // 	  // TODO: ERROR THROW
  //     }
Nicolas Mansard's avatar
Nicolas Mansard committed
  //   if( 0==NVAL )
  //       dynamicgraph::Vector zero(6); zero.fill(0);
  //       return zero;
  //     }
Nicolas Mansard's avatar
Nicolas Mansard committed

  //   dynamicgraph::Vector force(3),forceHand(3),forceWorld(3);
  //   dynamicgraph::Vector sumForce(3); sumForce.fill(0);

  //   for( unsigned int i=0;i<NVAL;++i )
  //     {
  //       if( (torsorList.end()==iterTorsor)||(rotationList.end()==iterRotation) )
  // 	{
  // 	  // TODO: ERROR THROW
  // 	  break;
  // 	}
  //       const dynamicgraph::Vector & torsor = *iterTorsor;
  //       const MatrixRotation & R = *iterRotation;

  //       /* The sensor read [-] the value, and the grav is [-] the sensor force.
  //        * [-]*[-] = [+] -> force = + torsor(1:3). */
  //       for( unsigned int j=0;j<3;++j ) { force(j)=-torsor(j); }
  //       handRsensor.multiply(force,forceHand);
  //       if( usingPrecompensation )
  // 	{
  // 	  dynamicgraph::Matrix R_I(3,3); R_I = R.transpose();
  // 	  R_I -= hand0Rsensor;
  // 	  R_I.pseudoInverse(.01).multiply( forceHand,forceWorld );
  // 	}
Nicolas Mansard's avatar
Nicolas Mansard committed
  //       else
  // 	{ R.multiply( forceHand,forceWorld ); }
Nicolas Mansard's avatar
Nicolas Mansard committed

  //       sotDEBUG(35) << "R(" << i << "*3+1:" << i << "*3+3,:)  = " << R << "';";
  //       sotDEBUG(35) << "rhFs(" << i << "*3+1:" << i << "*3+3) = " << forceHand;
  //       sotDEBUG(45) << "fworld(" << i << "*3+1:" << i << "*3+3) = " << forceWorld;

  //       sumForce+= forceWorld;

  //       iterTorsor++; iterRotation++;
  //     }

  //   sumForce*= (1./NVAL);
  //   sotDEBUG(35) << "Fmean = " << sumForce;
  //   sumForce.resize(6,false);
  //   sumForce(3)=sumForce(4)=sumForce(5)=0.;

  //   sotDEBUG(25)<<"mg = " << sumForce<<std::endl;

  sotDEBUGOUT(25);
  dynamicgraph::Vector sumForce(3); sumForce.fill(0);
  return sumForce;
}


/* --- SIGNALS -------------------------------------------------------------- */
/* --- SIGNALS -------------------------------------------------------------- */
/* --- SIGNALS -------------------------------------------------------------- */
MatrixForce& ForceCompensation::
computeHandXworld( const MatrixRotation & worldRhand,
		   const dynamicgraph::Vector & transSensorCom,
		   MatrixForce& res )
{
  sotDEBUGIN(35);

  sotDEBUG(25) << "wRrh = " << worldRhand <<std::endl;
  sotDEBUG(25) << "SC = " << transSensorCom <<std::endl;

Guilhem Saurel's avatar
Guilhem Saurel committed
  MatrixHomogeneous scRw;
  scRw.linear()=worldRhand.transpose();  scRw.translation()=transSensorCom;
  sotDEBUG(25) << "scMw = " << scRw <<std::endl;
Nicolas Mansard's avatar
Nicolas Mansard committed

  /////////////////////////////
  // res.buildFrom( scRw );
  Eigen::Vector3d _t = scRw.translation();
  MatrixRotation R(scRw.linear());
  Eigen::Matrix3d Tx;
  Tx << 0, -_t(2), _t(1),
    _t(2), 0, -_t(0),
    -_t(1), _t(0), 0;
  Eigen::Matrix3d sk; sk = Tx*R;
Guilhem Saurel's avatar
Guilhem Saurel committed

  res.block<3,3>(0,0) = R;
  res.block<3,3>(0,3).setZero();
  res.block<3,3>(3,0) = sk;
  res.block<3,3>(3,3) = R;
  ////////////////////////////


  sotDEBUG(15) << "scXw = " << res <<std::endl;
Nicolas Mansard's avatar
Nicolas Mansard committed

  sotDEBUGOUT(35);
  return res;
}

MatrixForce& ForceCompensation::
computeHandVsensor( const MatrixRotation & handRsensor,
		    MatrixForce& res )
{
  sotDEBUGIN(35);

  for( unsigned int i=0;i<3;++i )
    for( unsigned int j=0;j<3;++j )
      {
	res(i,j)=handRsensor(i,j);
	res(i+3,j+3)=handRsensor(i,j);
	res(i+3,j)=0.;
	res(i,j+3)=0.;
      }

  sotDEBUG(25) << "hVs" << res << std::endl;

  sotDEBUGOUT(35);
  return res;
}

MatrixForce& ForceCompensation::
Nicolas Mansard's avatar
Nicolas Mansard committed
computeSensorXhand( const MatrixRotation & /*handRsensor*/,
		    const dynamicgraph::Vector & transJointSensor,
		    MatrixForce& res )
{
  sotDEBUGIN(35);
Nicolas Mansard's avatar
Nicolas Mansard committed

  /* Force Matrix to pass from the joint frame (ie frame located
   * at the position of the motor, in which the acc is computed by Spong)
   * to the frame SensorHand where all the forces are expressed (ie
   * frame located at the sensor position bu oriented like the hand). */

  Eigen::Matrix3d Tx;
  Tx << 0, -transJointSensor(2), transJointSensor(1),
    transJointSensor(2), 0, -transJointSensor(0),
    -transJointSensor(1), transJointSensor(0), 0;
Guilhem Saurel's avatar
Guilhem Saurel committed

  res.block<3,3>(0,0).setIdentity();
  res.block<3,3>(0,3).setZero();
  res.block<3,3>(3,0) = Tx;
  res.block<3,3>(3,3).setIdentity();

  sotDEBUG(25) << "shXJ" << res << std::endl;

  sotDEBUGOUT(35);
  return res;
}

// dynamicgraph::Matrix& ForceCompensation::
// computeInertiaSensor( const dynamicgraph::Matrix& inertiaJoint,
// 		      const MatrixForce& sensorXhand,
// {
//   sotDEBUGIN(35);
Nicolas Mansard's avatar
Nicolas Mansard committed

//   /* Inertia felt at the sensor position, expressed in the orientation
//    * of the hand. */

//   res.resize(6,6);
//   sensorXhand.multiply( inertiaJoint,res );

//   sotDEBUGOUT(35);
//   return res;
// }


dynamicgraph::Vector& ForceCompensation::
computeTorsorCompensated( const dynamicgraph::Vector& torqueInput,
			  const dynamicgraph::Vector& torquePrecompensation,
			  const dynamicgraph::Vector& gravity,
			  const MatrixForce& handXworld,
			  const MatrixForce& handVsensor,
			  const dynamicgraph::Matrix& gainSensor,
			  const dynamicgraph::Vector& momentum,
			  dynamicgraph::Vector& res )

{
  sotDEBUGIN(35);
  /* Torsor in the sensor frame: K*(-torsred-gamma)+sVh*hXw*mg  */
  /* Torsor in the hand frame: hVs*K*(-torsred-gamma)+hXw*mg  */
  /* With gamma expressed in the sensor frame  (gamma_s = sVh*gamma_h) */

  sotDEBUG(25) << "t_nc = " << torqueInput;
  dynamicgraph::Vector torquePrecompensated(6);
  //if( usingPrecompensation )
Guilhem Saurel's avatar
Guilhem Saurel committed
  torquePrecompensated = torqueInput+torquePrecompensation;
  //else { torquePrecompensated = torqueInput; }
  sotDEBUG(25) << "t_pre = " << torquePrecompensated;

  dynamicgraph::Vector torqueS(6), torqueRH(6);
  torqueS = gainSensor*torquePrecompensated;
  res = handVsensor*torqueS;
  sotDEBUG(25) << "t_rh = " << res;

  dynamicgraph::Vector grh(6);
  grh = handXworld*gravity;
  grh *= -1;
  sotDEBUG(25) << "g_rh = " << grh;
Nicolas Mansard's avatar
Nicolas Mansard committed

  res+=grh;
  sotDEBUG(25) << "fcomp = " << res;
Nicolas Mansard's avatar
Nicolas Mansard committed

  res+=momentum;
  sotDEBUG(25) << "facc = " << res;
  /* TODO res += m xddot */

  sotDEBUGOUT(35);
  return res;
}

dynamicgraph::Vector& ForceCompensation::
crossProduct_V_F( const dynamicgraph::Vector& velocity,
		  const dynamicgraph::Vector& force,
		  dynamicgraph::Vector& res )
{
  /* [ v;w] x [ f;tau ] = [ w x f; v x f + w x tau ] */
  for( unsigned int i=0;i<3;++i )
    {
      v(i)=velocity(i); w(i) = velocity(i+3);
      f(i) = force(i); tau(i) = force(i+3);
    }
  Eigen::Vector3d res1(3),res2a(3),res2b(3);
  res1 = w.cross(f);
  res2a = v.cross(f);
  res2b = w.cross(tau);
  res2a += res2b;
Nicolas Mansard's avatar
Nicolas Mansard committed

  res.resize(6);
  for( unsigned int i=0;i<3;++i )
    {
      res(i)=res1(i); res(i+3)=res2a(i);
    }
  return res;
}
Guilhem Saurel's avatar
Guilhem Saurel committed

dynamicgraph::Vector& ForceCompensation::
computeMomentum( const dynamicgraph::Vector& velocity,
		 const dynamicgraph::Vector& acceleration,
		 const MatrixForce& sensorXhand,
		 const dynamicgraph::Matrix& inertiaJoint,
		 dynamicgraph::Vector& res )
{
  sotDEBUGIN(35);

  /* Fs + Fext = I acc + V x Iv */
  dynamicgraph::Vector Iacc(6); Iacc = inertiaJoint* acceleration;
  res.resize(6); res = sensorXhand*Iacc;
Nicolas Mansard's avatar
Nicolas Mansard committed

  dynamicgraph::Vector Iv(6); Iv = inertiaJoint*velocity;
  dynamicgraph::Vector vIv(6); crossProduct_V_F( velocity,Iv,vIv );
  dynamicgraph::Vector XvIv(6); XvIv = sensorXhand*vIv;
  res+= XvIv;

  sotDEBUGOUT(35);
  return res;
}

dynamicgraph::Vector& ForceCompensation::
computeDeadZone( const dynamicgraph::Vector& torqueInput,
		 const dynamicgraph::Vector& deadZone,
		 dynamicgraph::Vector& res )
{
  sotDEBUGIN(35);
Nicolas Mansard's avatar
Nicolas Mansard committed

  if( torqueInput.size()>deadZone.size() ) return res;
  res.resize(torqueInput.size());
  for( int i=0;i<torqueInput.size();++i )
Nicolas Mansard's avatar
Nicolas Mansard committed
      const double th = fabs(deadZone(i));
      if( (torqueInput(i)<th)&&(torqueInput(i)>-th) )
	{ res(i)=0; }
      else if(torqueInput(i)<0) res(i)=torqueInput(i)+th;
      else res(i)=torqueInput(i)-th;
    }

  sotDEBUGOUT(35);
  return res;
}


ForceCompensationPlugin::sotDummyType& ForceCompensationPlugin::
Nicolas Mansard's avatar
Nicolas Mansard committed
calibrationTriger( ForceCompensationPlugin::sotDummyType& dummy,int /*time*/ )
{
  //   sotDEBUGIN(45);
Nicolas Mansard's avatar
Nicolas Mansard committed
  //   if(! calibrationStarted ) { sotDEBUGOUT(45); return dummy=0; }

  //   addCalibrationValue( torsorSIN(time),worldRhandSIN(time) );
  //   sotDEBUGOUT(45);
  return dummy=1;
}