Forked from
Stack Of Tasks / jrl-walkgen
169 commits behind the upstream repository.
relative-feet-inequalities.cpp 10.40 KiB
/*
* Copyright 2010,
*
* Mehdi Benallegue
* Andrei Herdt
* Olivier Stasse
*
*
* JRL, CNRS/AIST
*
* This file is part of walkGenJrl.
* walkGenJrl 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.
*
* walkGenJrl 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 Lesser Public License for more details.
* You should have received a copy of the GNU Lesser General Public License
* along with walkGenJrl. If not, see <http://www.gnu.org/licenses/>.
*
* Research carried out within the scope of the
* Joint Japanese-French Robotics Laboratory (JRL)
*/
/** \file FootConstraintAsLinearSystemForVelRef.cpp
\brief This object builds linear constraints relative to the current and the previewed feet positions.
*/
#include <iostream>
#include <fstream>
#include <Mathematics/relative-feet-inequalities.hh>
using namespace std;
using namespace PatternGeneratorJRL;
#include <Debug.hh>
RelativeFeetInequalities::RelativeFeetInequalities( SimplePluginManager *aSPM,
PinocchioRobot *aPR ) :
SimplePlugin(aSPM)
{
DSFeetDistance_ = 0.2;
SecurityMarginX_ = 0.04;
SecurityMarginY_ = 0.04;
double DefaultFPosEdgesX[5] = {-0.28, -0.2, 0.0, 0.2, 0.28};
double DefaultFPosEdgesY[5] = {-0.2, -0.3, -0.4, -0.3, -0.2};
for(int i=0;i<5;i++)
{
LeftFPosEdgesX_[i] = DefaultFPosEdgesX[i];
LeftFPosEdgesY_[i] = DefaultFPosEdgesY[i];
RightFPosEdgesX_[i] = DefaultFPosEdgesX[i];
RightFPosEdgesY_[i] = -DefaultFPosEdgesY[i];
}
set_feet_dimensions( aPR );
init_convex_hulls();
// Register method to handle
string aMethodName[] =
{":setfeetconstraint",
":setDSFeetDistance",
":setFPosEdges"};
for(int i=0;i<1;i++)
{
if (!RegisterMethod(aMethodName[i]))
{
std::cerr << "Unable to register " << aMethodName << std::endl;
}
}
}
RelativeFeetInequalities::~RelativeFeetInequalities()
{ }
int
RelativeFeetInequalities::init_convex_hulls()
{
const unsigned nbVertCoP = 4;
const unsigned nbVertFeet = 5;
const unsigned nbIneqCoM = 10;
// Feet polygonal hulls:
// ---------------------
FootPosEdges_.LeftDS.resize( nbVertFeet );
FootPosEdges_.LeftSS.resize( nbVertFeet );
FootPosEdges_.RightDS.resize( nbVertFeet );
FootPosEdges_.RightSS.resize( nbVertFeet );
FootPosEdges_.LeftDS.set_vertices ( LeftFPosEdgesX_, LeftFPosEdgesY_ );
FootPosEdges_.LeftSS.set_vertices ( LeftFPosEdgesX_, LeftFPosEdgesY_ );
FootPosEdges_.RightDS.set_vertices( RightFPosEdgesX_, RightFPosEdgesY_ );
FootPosEdges_.RightSS.set_vertices( RightFPosEdgesX_, RightFPosEdgesY_ );
// ZMP polygonal hulls:
// --------------------
double lxcoefsRight[nbVertCoP] = { 1.0, 1.0, -1.0, -1.0};
double lycoefsRight[nbVertCoP] = {-1.0, 1.0, 1.0, -1.0};
double lxcoefsLeft[nbVertCoP] = { 1.0, 1.0, -1.0, -1.0};
double lycoefsLeft[nbVertCoP] = { 1.0, -1.0, -1.0, 1.0};
ZMPPosEdges_.LeftDS.resize(nbVertCoP);
ZMPPosEdges_.LeftSS.resize(nbVertCoP);
ZMPPosEdges_.RightDS.resize(nbVertCoP);
ZMPPosEdges_.RightSS.resize(nbVertCoP);
for( unsigned j = 0; j < nbVertCoP; j++ )
{
//Left single support phase
ZMPPosEdges_.LeftSS.X_vec[j] = lxcoefsLeft[j]*LeftFootSize_.getHalfWidth();
ZMPPosEdges_.LeftSS.Y_vec[j] = lycoefsLeft[j]*LeftFootSize_.getHalfHeight();
//Right single support phase
ZMPPosEdges_.RightSS.X_vec[j] = lxcoefsRight[j]*RightFootSize_.getHalfWidth();
ZMPPosEdges_.RightSS.Y_vec[j] = lycoefsRight[j]*RightFootSize_.getHalfHeight();
//Left DS phase
ZMPPosEdges_.LeftDS.X_vec[j] = lxcoefsLeft[j]*LeftFootSize_.getHalfWidth();
ZMPPosEdges_.LeftDS.Y_vec[j] = lycoefsLeft[j]*LeftFootSize_.getHalfHeightDS()-DSFeetDistance_/2.0;
//Right DS phase
ZMPPosEdges_.RightDS.X_vec[j] = lxcoefsRight[j]*RightFootSize_.getHalfWidth();
ZMPPosEdges_.RightDS.Y_vec[j] = lycoefsRight[j]*RightFootSize_.getHalfHeightDS()+DSFeetDistance_/2.0;
}
// CoM polyhedric hull:
// --------------------
double IneqCoMA_a[nbIneqCoM] = { -0.6, -0.6, -0.6, -0.6, -0.6, -0.3, -0.3, -0.3, -0.3, -0.3};
double IneqCoMB_a[nbIneqCoM] = {-0.3, -0.175, -0.05, 0.075, 0.2, -0.3, -0.175, -0.05, 0.075, 0.2};
double IneqCoMC_a[nbIneqCoM] = {-0.8544, -0.818917, -0.801561, -0.803508, -0.824621, -1, -0.969858, -0.955249, -0.956883, -0.974679};
double IneqCoMD_a[nbIneqCoM] = {-0.862318, -0.836995, -0.818542, -0.807405, -0.803531, -0.9175, -0.894201, -0.876789, -0.865534, -0.860404};
CoMHull_.resize(0, nbIneqCoM);
CoMHull_.set_inequalities( IneqCoMA_a, IneqCoMB_a, IneqCoMC_a, IneqCoMD_a );
return 0;
}
int
RelativeFeetInequalities::set_feet_dimensions( PinocchioRobot *aPR )
{
// Read feet specificities.
double HeightHalf,WidthHalf;
PRFoot * RightFoot = aPR->rightFoot();
if (RightFoot->associatedAnkle==0)
{
cerr << "Problem with the reading of the right foot"<< endl;
return 0;
}
WidthHalf = RightFoot->soleWidth ;
HeightHalf = RightFoot->soleHeight ;
PRFoot * LeftFoot = aPR->leftFoot();
if (RightFoot->associatedAnkle==0)
{
cerr << "Problem while reading of the left foot"<< endl;
return 0;
}
WidthHalf = LeftFoot->soleWidth ;
HeightHalf = LeftFoot->soleHeight ;
assert(WidthHalf > 0);
LeftFootSize_.setHalfSizeInit( WidthHalf, HeightHalf, DSFeetDistance_ );
LeftFootSize_.setConstraints( SecurityMarginX_, SecurityMarginY_, DSFeetDistance_ );
RightFootSize_.setHalfSizeInit( WidthHalf, HeightHalf, DSFeetDistance_ );
RightFootSize_.setConstraints( SecurityMarginX_, SecurityMarginY_, DSFeetDistance_ );
return 0;
}
void
RelativeFeetInequalities::set_vertices( convex_hull_t & ConvexHull,
const support_state_t & Support, ineq_e type)
{
edges_s * ConvexHull_p = 0;
switch(type)
{
case INEQ_COP:
ConvexHull_p = & ZMPPosEdges_;
break;
case INEQ_FEET:
ConvexHull_p = & FootPosEdges_;
break;
case INEQ_COM:
break;
}
//Choose edges
if( Support.Foot == LEFT )
{
if( Support.Phase == DS )
{
ConvexHull.X_vec = ConvexHull_p->LeftDS.X_vec;
ConvexHull.Y_vec = ConvexHull_p->LeftDS.Y_vec;
}
else
{
ConvexHull.X_vec = ConvexHull_p->LeftSS.X_vec;
ConvexHull.Y_vec = ConvexHull_p->LeftSS.Y_vec;
}
}
else
{
if( Support.Phase == DS )
{
ConvexHull.X_vec = ConvexHull_p->RightDS.X_vec;
ConvexHull.Y_vec = ConvexHull_p->RightDS.Y_vec;
}
else
{
ConvexHull.X_vec = ConvexHull_p->RightSS.X_vec;
ConvexHull.Y_vec = ConvexHull_p->RightSS.Y_vec;
}
}
ConvexHull.rotate( YAW, Support.Yaw);
}
void
RelativeFeetInequalities::set_inequalities( convex_hull_t & ConvexHull,
const support_state_t &, ineq_e type)
{
convex_hull_t * ConvexHull_p = 0;
switch(type)
{
case INEQ_COP:
break;
case INEQ_FEET:
break;
case INEQ_COM:
ConvexHull_p = & CoMHull_;
break;
}
ConvexHull.A_vec = ConvexHull_p->A_vec;
ConvexHull.B_vec = ConvexHull_p->B_vec;
ConvexHull.C_vec = ConvexHull_p->C_vec;
ConvexHull.D_vec = ConvexHull_p->D_vec;
}
void
RelativeFeetInequalities::compute_linear_system ( convex_hull_t & ConvexHull,
const support_state_t & PrwSupport ) const
{
double dx,dy,dc,x1,y1,x2,y2;
unsigned nbRows = ConvexHull.X_vec.size();
double sign;
if( PrwSupport.Foot == LEFT )
sign = 1.0;
else
sign = -1.0;
for( unsigned i=0; i<nbRows-1;i++ )//first n-1 inequalities
{
y1 = ConvexHull.Y_vec[i];
y2 = ConvexHull.Y_vec[i+1];
x1 = ConvexHull.X_vec[i];
x2 = ConvexHull.X_vec[i+1];
dx = y1-y2;
dy = x2-x1;
dc = dx*x1+dy*y1;
//symmetrical constraints
dx = sign*dx;
dy = sign*dy;
dc = sign*dc;
ConvexHull.A_vec[i] = dx; ConvexHull.B_vec[i]= dy;
ConvexHull.D_vec[i] = dc;
}
{
//Last inequality
unsigned i = nbRows-1;
y1 = ConvexHull.Y_vec[i];
y2 = ConvexHull.Y_vec[0];
x1 = ConvexHull.X_vec[i];
x2 = ConvexHull.X_vec[0];
dx = y1-y2;
dy = x2-x1;
dc = dx*x1+dy*y1;
//for symmetrical constraints
dx = sign*dx;
dy = sign*dy;
dc = sign*dc;
ConvexHull.A_vec[i] = dx; ConvexHull.B_vec[i]= dy;
ConvexHull.D_vec[i] = dc;
}
}
void
RelativeFeetInequalities::CallMethod( std::string &Method, std::istringstream &Args )
{
if ( Method==":setfeetconstraint" )
{
string lCmd;
Args >> lCmd;
if (lCmd=="XY")
{
Args >> SecurityMarginX_;
Args >> SecurityMarginY_;
RightFootSize_.setConstraints( SecurityMarginX_, SecurityMarginY_ , DSFeetDistance_ );
LeftFootSize_.setConstraints( SecurityMarginX_, SecurityMarginY_, DSFeetDistance_ );
init_convex_hulls();
// cout << "Security margin On X: " << SecurityMarginX_
// << " Security margin On Y: " << SecurityMarginY_ << endl;
}
}
else if( Method == ":setDSFeetDistance" )
{
Args >> DSFeetDistance_;
init_convex_hulls();
//cout << "DSFeetDistance = " << DSFeetDistance_ << endl;
}
else if( Method == ":setFPosEdges" )
{
string lCmd;
Args >> lCmd;
if (lCmd == "X")
{
//cout << "LeftFeftFPosEdgesX = ";
for(int i=0;i<5;i++)
{
Args >> LeftFPosEdgesX_[i];
RightFPosEdgesX_[i] = LeftFPosEdgesX_[i];
//cout << LeftFPosEdgesX_[i] << " ";
}
//cout << endl;
init_convex_hulls();
}
else if (lCmd == "Y")
{
//cout << "LeftFeftFPosEdgesY = ";
for(int i=0;i<5;i++)
{
Args >> LeftFPosEdgesY_[i];
RightFPosEdgesY_[i] = -LeftFPosEdgesY_[i];
//cout << LeftFPosEdgesY_[i] << " ";
}
//cout << endl;
init_convex_hulls();
}
}
}
void
RelativeFeetInequalities::getFeetSize(FootHalfSize & leftFootSize, FootHalfSize & rightFootSize)
{
leftFootSize = LeftFootSize_ ;
rightFootSize = RightFootSize_ ;
}