1 #include <iCub/grasp/forceClosure.h> 9 static double cross2D(
const Vector &v1,
const Vector &v2)
11 return (v1[0]*v2[1])-(v1[1]*v2[0]);
14 static bool included(
double cosine,
double angle)
16 double alpha1=(M_PI/2)+angle;
17 double alpha2=(M_PI/2)-angle;
19 double cosMin=cos(alpha1);
20 double cosMax=cos(alpha2);
22 return (cosine>cosMin)&&(cosine<cosMax);
25 static bool computeIntersectionPoint(
const yarp::sig::Vector &line1,
const yarp::sig::Vector &line2, yarp::sig::Vector &point)
28 if (line2[0]-line1[0]==0)
30 point[0]=(line1[1]-line2[1])/(line2[0]-line1[0]);
31 point[1]=(line1[0]*point[0])+line1[1];
35 static yarp::sig::Vector projectVectorOnThePlane(
const yarp::sig::Vector &v,
const yarp::sig::Vector &plane)
37 yarp::sig::Vector projection=v-(dot(v,plane)*plane);
38 projection/=norm(projection);
42 static void computeLineParameters(
const Vector &x1,
const Vector &x2, Vector &line)
47 if ((x2[0]-x1[0])!=0.0)
48 line[0]=(x2[1]-x1[1])/(x2[0]-x1[0]);
50 line[1]=x1[1]-(line[0]*x1[0]);
53 static bool pointInCone(
const vector<Vector> &a1,
const vector<Vector> &a2,
const vector<Vector> &a3,
const yarp::sig::Vector &c)
55 Vector intersectionPoint(2);
56 for (
unsigned int i=0; i<a1.size(); i++)
58 for (
unsigned int j=0; j<a2.size(); j++)
60 if (computeIntersectionPoint(a1[i],a2[j],intersectionPoint))
62 if (sign(cross2D(intersectionPoint-c,a3.at(0)))*sign(cross2D(intersectionPoint-c,a3.at(1)))<0)
70 static yarp::sig::Vector transformVector(
const yarp::sig::Vector &v,
const yarp::sig::Matrix &orientation)
72 return orientation.submatrix(0,2,0,2).transposed()*v;
75 static yarp::sig::Vector transformPoint(
const yarp::sig::Vector &p,
const yarp::sig::Matrix &orientation)
77 Vector pHom(4); pHom[3]=1.0;
78 pHom.setSubvector(0,p);
79 return (SE3inv(orientation)*pHom).subVector(0,2);
82 static bool verifySameHalfPlane(
const Vector &normal1,
const Vector &normal2,
const Vector &normal3)
88 Vector tmp(2); tmp=0.0;
90 computeLineParameters(normal1,tmp,line1);
91 computeLineParameters(normal2,tmp,line2);
92 computeLineParameters(normal3,tmp,line3);
95 double signv2=sign(normal2[1]-(line1[0]*normal2[0])-line1[1]);
96 double signv3=sign(normal3[1]-(line1[0]*normal3[0])-line1[1]);
98 if ((signv2==signv3)||(signv2==0)||(signv3==0))
102 double signv1=sign(normal1[1]-(line2[0]*normal1[0])-line2[1]);
103 signv3=sign(normal3[1]-(line2[0]*normal3[0])-line2[1]);
105 if ((signv1==signv3)||(signv1==0)||(signv3==0))
109 signv1=sign(normal1[1]-(line3[0]*normal1[0])-line3[1]);
110 signv2=sign(normal2[1]-(line3[0]*normal2[0])-line3[1]);
112 if ((signv1==signv2)||(signv1==0)||(signv2==0))
118 static bool verifyConesIntersection(
const yarp::sig::Vector &c1,
const yarp::sig::Vector &c2,
const yarp::sig::Vector &c3,
const std::vector<iCub::grasp::ConeBounds> &conesBounds2D)
120 Vector line11, line12, line21, line22, line31, line32;
122 computeLineParameters(c1+conesBounds2D.at(0).n1,c1,line11);
123 computeLineParameters(c1+conesBounds2D.at(0).n2,c1,line12);
125 vector<Vector> a1; a1.push_back(line11); a1.push_back(line12);
126 computeLineParameters(c2+conesBounds2D.at(1).n1,c2,line21);
127 computeLineParameters(c2+conesBounds2D.at(1).n2,c2,line22);
129 vector<Vector> a2; a2.push_back(line21);a2.push_back(line22);
130 computeLineParameters(c3+conesBounds2D.at(2).n1,c3,line31);
131 computeLineParameters(c3+conesBounds2D.at(2).n2,c3,line32);
133 vector<Vector> a3; a3.push_back(line31); a3.push_back(line32);
135 if (pointInCone(a1,a2,a3,c3))
137 if (pointInCone(a1,a3,a2,c2))
139 if (pointInCone(a2,a3,a1,c1))
147 Vector projection1=projectVectorOnThePlane(contactPoints.n1,plane);
148 Vector c=(contactPoints.c1+contactPoints.c2+contactPoints.c3)/3;
151 Vector x=projection1;
152 Vector y=cross(plane,x); y/=norm(y);
154 Matrix orientation=eye(4,4);
155 orientation(0,0)=x[0]; orientation(1,0)=x[1]; orientation(2,0)=x[2];
156 orientation(0,1)=y[0]; orientation(1,1)=y[1]; orientation(2,1)=y[2];
157 orientation(0,2)=z[0]; orientation(1,2)=z[1]; orientation(2,2)=z[2];
158 orientation(0,3)=c[0]; orientation(1,3)=c[1]; orientation(2,3)=c[2];
163 static yarp::sig::Vector solveForT(
const double &a,
const double &b,
const double &c)
165 yarp::sig::Vector t(2);
166 double normFact=sqrt((a*a)+(b*b));
167 double alpha=acos(a/normFact);
169 if (abs(sin(alpha)-(b/normFact))>0.0001)
172 double x0=asin(c/normFact);
173 double x1=M_PI-asin(c/normFact);
181 static iCub::grasp::ConeBounds findConeBounds(
const yarp::sig::Vector &c,
const yarp::sig::Vector &n,
const yarp::sig::Vector &plane,
double alpha)
183 iCub::grasp::ConeBounds coneBounds;
185 yarp::sig::Vector c0=c+n;
187 yarp::sig::Vector tmp(3); tmp[0]=1.0; tmp[1]=0.0; tmp[2]=0.0;
189 yarp::sig::Vector x=projectVectorOnThePlane(tmp,n); x/=norm(x);
190 yarp::sig::Vector y=cross(n,x); y/=norm(y);
197 double A=r*dot(x,plane);
198 double B=r*dot(y,plane);
199 double C=(dot(c,plane))-(dot(c0,plane));
202 yarp::sig::Vector t=solveForT(A,B,C);
205 yarp::sig::Vector P1=c0+(r*sin(t[0])*x)+(r*cos(t[0])*y);
206 yarp::sig::Vector P2=c0+(r*sin(t[1])*x)+(r*cos(t[1])*y);
209 coneBounds.n1=(P1-c)/norm(P1-c);
210 coneBounds.n2=(P2-c)/norm(P2-c);
215 static bool verifyCondition2D(
const iCub::grasp::ContactPoints &contactPoints,
const Vector &plane,
const std::vector<iCub::grasp::ConeBounds> &conesBounds)
217 Matrix orientation=findOrientationForPlane(contactPoints,plane);
219 Vector projection1=projectVectorOnThePlane(contactPoints.n1,plane);
220 Vector projection2=projectVectorOnThePlane(contactPoints.n2,plane);
221 Vector projection3=projectVectorOnThePlane(contactPoints.n3,plane);
223 Vector n1=transformVector(projection1,orientation);
224 Vector n2=transformVector(projection2,orientation);
225 Vector n3=transformVector(projection3,orientation);
227 Vector c1=(transformPoint(contactPoints.c1,orientation)).subVector(0,1);
228 Vector c2=(transformPoint(contactPoints.c2,orientation)).subVector(0,1);
229 Vector c3=(transformPoint(contactPoints.c3,orientation)).subVector(0,1);
231 std::vector<iCub::grasp::ConeBounds> conesBounds2D;
232 for (
unsigned int i=0; i<conesBounds.size(); i++)
234 iCub::grasp::ConeBounds tmp;
235 tmp.n1=(transformVector(conesBounds[i].n1,orientation)).subVector(0,1);
236 tmp.n2=(transformVector(conesBounds[i].n2,orientation)).subVector(0,1);
237 conesBounds2D.push_back(tmp);
240 return verifySameHalfPlane(n1,n2,n3)&&verifyConesIntersection(c1,c2,c3,conesBounds2D);
245 Vector diff1=contactPoints.c1-contactPoints.c2;
246 Vector diff2=contactPoints.c1-contactPoints.c3;
249 Vector plane=cross(diff2,diff1); plane/=norm(plane);
251 double cos1=(dot(plane,contactPoints.n1));
252 double cos2=(dot(plane,contactPoints.n2));
253 double cos3=(dot(plane,contactPoints.n3));
256 if (!included(cos1,contactPoints.alpha1) || !included(cos2,contactPoints.alpha2) || !included(cos3,contactPoints.alpha3))
259 ConeBounds bounds1=findConeBounds(contactPoints.c1,contactPoints.n1,plane,contactPoints.alpha1);
260 ConeBounds bounds2=findConeBounds(contactPoints.c2,contactPoints.n2,plane,contactPoints.alpha2);
261 ConeBounds bounds3=findConeBounds(contactPoints.c3,contactPoints.n3,plane,contactPoints.alpha3);
263 std::vector<ConeBounds> conesBounds;
264 conesBounds.push_back(bounds1);
265 conesBounds.push_back(bounds2);
266 conesBounds.push_back(bounds3);
268 return verifyCondition2D(contactPoints,plane,conesBounds);