Skip to content
Snippets Groups Projects
task-dyn-inequality.cpp 5.96 KiB
Newer Older
Nicolas Mansard's avatar
Nicolas Mansard committed
/*
 * Copyright 2011, Nicolas Mansard, LAAS-CNRS
 *
 * This file is part of sot-dyninv.
 * sot-dyninv is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation, either version 3 of
 * the License, or (at your option) any later version.
 * sot-dyninv 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 Lesser General Public License for more details.  You should
 * have received a copy of the GNU Lesser General Public License along
 * with sot-dyninv.  If not, see <http://www.gnu.org/licenses/>.
 */


/* --------------------------------------------------------------------- */
/* --- INCLUDE --------------------------------------------------------- */
/* --------------------------------------------------------------------- */

//#define VP_DEBUG
//#define VP_DEBUG_MODE 15
#include <sot/core/debug.hh>

#include <dynamic-graph/factory.h>
#include <sot-dyninv/task-dyn-inequality.h>


/* --------------------------------------------------------------------- */
/* --- CLASS ----------------------------------------------------------- */
/* --------------------------------------------------------------------- */

namespace dynamicgraph
{
  namespace sot
  {
    namespace dyninv
    {

      namespace dg = ::dynamicgraph;

      /* --- DG FACTORY ------------------------------------------------------- */
      DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(TaskDynInequality,"TaskDynInequality");

      /* ---------------------------------------------------------------------- */
      /* --- CONSTRUCTION ----------------------------------------------------- */
      /* ---------------------------------------------------------------------- */

      TaskDynInequality::
      TaskDynInequality( const std::string & name )
	: TaskDynPD(name)

	,CONSTRUCT_SIGNAL_IN(referenceInf,dg::Vector)
	,CONSTRUCT_SIGNAL_IN(referenceSup,dg::Vector)
Nicolas Mansard's avatar
Nicolas Mansard committed
	,CONSTRUCT_SIGNAL_IN(selec,Flags)

	  //,CONSTRUCT_SIGNAL_OUT(size,int,
	  //			      errorSOUT<<selecSIN)
	,sizeSOUT( boost::bind(&  TaskDynInequality::sizeSOUT_function,this,_1,_2),
		   errorSOUT<<selecSIN,getClassName()+"("+getName()+")::output(int)::size" )

      {
	taskSOUT.setFunction( boost::bind(&TaskDynInequality::computeTaskDyn,this,_1,_2) );
	taskSOUT.addDependency( selecSIN );
	taskSOUT.addDependency( referenceSupSIN );
	taskSOUT.addDependency( referenceInfSIN );
	taskSOUT.addDependency( sizeSOUT );

	jacobianSOUT.setFunction( boost::bind(&TaskDynInequality::computeJacobian,this,_1,_2) );
	jacobianSOUT.addDependency( selecSIN );
	jacobianSOUT.addDependency( sizeSOUT );

	controlGainSIN = 1.0;
	selecSIN = true;
	signalRegistration( referenceSupSIN << referenceInfSIN
			    << selecSIN << sizeSOUT );
      }

      /* ---------------------------------------------------------------------- */
      /* --- COMPUTATION ------------------------------------------------------ */
      /* ---------------------------------------------------------------------- */
      int& TaskDynInequality::
      sizeSOUT_function(int& res, int time)
      {
	const Flags & selec = selecSIN(time);
	const int size = errorSOUT(time).size();
	res=0;
	for( int i=0;i<size;++i )
	  {
	    if(selec(i)) res++;
	  }
	return res;
      }

      dg::sot::VectorMultiBound& TaskDynInequality::
      computeTaskDyn( dg::sot::VectorMultiBound& res,int iter )
      {
	dg::Vector dummy;
Nicolas Mansard's avatar
Nicolas Mansard committed
	const bool withInf = referenceInfSIN, withSup = referenceSupSIN;
	MultiBound::SupInfType bound = withInf ? MultiBound::BOUND_INF : MultiBound::BOUND_SUP;

	const dg::Vector & error = errorSOUT(iter);
	const dg::Vector & errorDot = errorDotSOUT(iter);
	const dg::Vector & refInf = withInf ? referenceInfSIN(iter) : dummy;
	const dg::Vector & refSup = withSup ? referenceSupSIN(iter) : dummy;
Nicolas Mansard's avatar
Nicolas Mansard committed
	const Flags & selec = selecSIN(iter);
	const int insize = error.size(), outsize=sizeSOUT(iter);
	const double dt = dtSIN(iter)*controlGainSIN(iter), dt2 = 2/(dt*dt);
	assert( !withInf || insize==(int)refInf.size() );
	assert( !withSup || insize==(int)refSup.size() );

	// using std::cout; using std::endl;
Nicolas Mansard's avatar
Nicolas Mansard committed
	// int iterShow = 76;
	// if(iter==iterShow)
	//   {
	//     cout << "e = " << error << endl;
	//     cout << "edot = " << errorDot << endl;
	//     cout << "l = " << refInf << endl;
	//     cout << "u = " << refSup << endl;
	//   }
	res.resize(outsize); int idx=0;
	for( int i=0;i<insize;++i )
	  {
	    if( selec(i) )
	      {
		const double & e = error(i), & u = refSup(i),
		  & l = refInf(i), & ed = errorDot(idx);
		const double de = ed*dt;

		//const double EPS = 1e-4;
		//assert( e<=u+EPS && e>=l-EPS );

		double inf,sup;
		if(! withSup )                    { sup = 0; }
		else /*if( e+de/2<=u || e>u)*/	  { sup = (u-e-de)*dt2; }
		//else 		                  { sup = ed*ed/(2*(e-u)); }

		if(! withInf )	      	          { inf = 0; }
		else /*if(e<l || e+de/2>=l )*/	  { inf = (l-e-de)*dt2; }
		//else 		                  { inf = ed*ed/(2*(e-l)); }

		// if(i==0)
		//   {
		//     std::cout << inf << " " << sup;
		//     if( e+de/2>=l ) std::cout << " B";
		//     if( e<l ) std::cout << " C";
		//     std::cout << endl;
		//   }

		if( withInf && withSup )
		  res[idx++] = dg::sot::MultiBound( inf,sup );
		else
		  res[idx++] = dg::sot::MultiBound( inf+sup,bound );
	      }
	  }

	sotDEBUG(15) << "taskU = "<< res << std::endl;
	return res;
      }

      dg::Matrix& TaskDynInequality::
      computeJacobian( dg::Matrix& res,int iter )
Nicolas Mansard's avatar
Nicolas Mansard committed
      {
	const Flags & selec = selecSIN(iter);
	dg::Matrix Jin;  TaskDynPD::computeJacobian(Jin,iter);
	const int insize = Jin.rows(), outsize=sizeSOUT(iter), nbc=Jin.cols();
Nicolas Mansard's avatar
Nicolas Mansard committed
	assert( insize>=outsize );

	res.resize(outsize,nbc); int idx=0;
	for( int i=0;i<insize;++i )
	  {
	    if( selec(i) )
	      {
		for( int j=0;j<nbc;++j )
		  res(idx,j) = Jin(i,j);
		idx++;
	      }
	  }

	return res;
      }

    } // namespace dyninv
  } // namespace sot
} // namespace dynamicgraph