00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <robot/control/kinematics/AnalyticLagrangianFSBetaOptimizer>
00026 #include <robot/control/kinematics/ReferenceOpVectorFormObjective>
00027 #include <robot/control/kinematics/solution_error>
00028
00029 using base::transpose;
00030 using robot::control::kinematics::AnalyticLagrangianFSBetaOptimizer;
00031
00032 using robot::control::kinematics::ReferenceOpVectorFormObjective;
00033 using robot::control::kinematics::BetaFormConstraints;
00034 using robot::control::kinematics::solution_error;
00035
00036
00037
00038 base::Vector AnalyticLagrangianFSBetaOptimizer::optimize(ref<const Objective> objective,
00039 ref<const Constraints> constraints) const
00040 {
00041 if (!instanceof(*objective, const ReferenceOpVectorFormObjective))
00042 throw std::invalid_argument(Exception("objective is not in the required form (ReferenceOpVectorFormObjective)"));
00043 ref<const ReferenceOpVectorFormObjective> rovfObjective(narrow_ref<const ReferenceOpVectorFormObjective>(objective));
00044
00045 if (!instanceof(*constraints, const BetaFormConstraints))
00046 throw std::invalid_argument(Exception("constraints are not of the required form (BetaFormConstraints)"));
00047 ref<const BetaFormConstraints> betaConstraints(narrow_ref<const BetaFormConstraints>(constraints));
00048
00049 if (!gs)
00050 throw std::runtime_error(Exception("no Gs supplied via setGs()"));
00051 const Matrix& gs(*(this->gs));
00052
00053 const Int span = gs.size2();
00054
00055
00056
00057 Matrix B( rovfObjective->getB() );
00058 Vector dZr( rovfObjective->getdZr() );
00059
00060 Matrix G(span,span);
00061 Matrix BtB( transpose(B) * B );
00062 for(Int j=0; j<span; j++) {
00063 Vector gj( matrixColumn(gs,j) );
00064 Vector BtBgj( BtB*gj );
00065 for(Int i=0; i<span; i++) {
00066 Vector gi( matrixColumn(gs,i) );
00067 G(i,j) = dot( gi, BtBgj );
00068 }
00069 }
00070
00071 Matrix Ginv;
00072 try {
00073 Ginv = Math::inverse(G);
00074 } catch (std::exception& e) {
00075 throw solution_error(Exception("unable to invert Grammian G:"+String(e.what())));
00076 }
00077
00078
00079 Vector H(span);
00080 if (equals(dZr,zeroVector(dZr.size()))) {
00081 H = zeroVector(span);
00082 }
00083 else {
00084 Vector dZrtB( dZr*B );
00085 for(Int k=0; k<span; k++)
00086 H[k] = dot( dZrtB, matrixColumn(gs,k) );
00087 }
00088
00089
00090
00091
00092
00093 o.reset(zeroVector(span));
00094 e.resize(span);
00095 for(Int i=0; i<span; i++) e[i]=1;
00096
00097 Vector t( calct(Ginv, H, betaConstraints, nullSpace) );
00098 Assert(t.size() == span);
00099
00100
00101 Real s=0;
00102 for(Int i=0; i<t.size(); i++) s+=t[i];
00103 if (!Math::equals(s,nullSpace?0:1,0.00001))
00104 throw solution_error(Exception("failed to find a solution meeting the criteria and constraints (sum of tis="
00105 + base::realToString(s) +"), but should be "+base::realToString(nullSpace?0:1)));
00106
00107
00108 Vector dq( gs.size1() );
00109 dq = zeroVector( gs.size1() );
00110 for(Int i=0; i<span; i++)
00111 dq += t[i]*matrixColumn(gs,i);
00112
00113 return dq;
00114 }
00115
00116
00117
00118 base::Vector AnalyticLagrangianFSBetaOptimizer::calct(const Matrix& Ginv, const Vector& H, ref<const BetaFormConstraints> betaConstraints, bool nullSpace) const
00119 {
00120
00121
00122
00123
00124
00125
00126
00127
00128 const Int span = Ginv.size1();
00129 Vector t(span);
00130
00131
00132 if (betaConstraints->numBetaConstraints() == 0) {
00133
00134
00135
00136
00137 Real a = dot( e, Ginv*e );
00138 Vector GinvH( Ginv * H );
00139
00140
00141 if (!betaConstraints->isAlphaConstraint()) {
00142
00143 if (Math::equals(a,0))
00144 throw solution_error(Exception("optimization failed: a=0"));
00145
00146 Real etGinvH = dot(e, GinvH);
00147
00148 Real b = -( (nullSpace?0:1) + etGinvH)/a;
00149
00150 t = -Ginv*(b*e + H);
00151
00152 }
00153 else {
00154
00155 Vector alpha( betaConstraints->getAlpha() );
00156 if (equals(alpha,e))
00157 throw solution_error(Exception("optimization failed: alpha=e=(1,1,..,1) - undeterminable"));
00158
00159
00160 Real f = dot(e, GinvH);
00161
00162
00163 Real ft = nullSpace?0:1 + f;
00164
00165
00166 Real k = dot(alpha, GinvH);
00167
00168
00169 Vector etGinv( e * Ginv );
00170 Real l = dot(etGinv, alpha);
00171
00172
00173 Real s = dot(alpha, Ginv*alpha);
00174
00175
00176 Real l2msa = Math::sqr(l) - s*a;
00177 Real eta = (a*k - l*ft) / l2msa;
00178 Real mu = -(ft + eta*l) / a;
00179
00180 t = -Ginv*(H + mu*e + eta*alpha);
00181
00182
00183 Assert(alpha.size()==t.size());
00184 Real sum=0;
00185 for(Int i=0; i<alpha.size(); i++)
00186 sum+= alpha[i]*t[i];
00187 if (!Math::equals(sum,0,1e-9)) {
00188 throw solution_error(Exception("Solution generated violates NonHolonomic constraint (Sum alphai.ti != 0)"));
00189 }
00190
00191 }
00192
00193
00194 }
00195 else {
00196
00197
00198
00199
00200
00201
00202
00203 Matrix betas(betaConstraints->getBetas());
00204 Int r = betas.size2();
00205
00206
00207 Real a = inner_prod( e, Ginv*e );
00208
00209 if (Math::equals(a,0))
00210 throw solution_error(Exception("optimization failed: a=0"));
00211
00212
00213 Vector b(r);
00214 Vector etGinv( e * Ginv );
00215 for(Int i=0; i<r; i++)
00216 b[i] = inner_prod( etGinv, matrixColumn(betas,i) );
00217
00218
00219
00220 Vector d(r);
00221 Vector GinvH( Ginv * H );
00222 for(Int i=0; i<r; i++)
00223 d[i] = 1.0 + inner_prod( matrixColumn(betas, i), GinvH );
00224
00225
00226 Real f = inner_prod(e, GinvH);
00227
00228
00229 Real ft = nullSpace?0:1 + f;
00230
00231
00232 if (!betaConstraints->isAlphaConstraint()) {
00233
00234
00235 Matrix A(r,r);
00236 for(Int j=0; j<r; j++) {
00237 Vector Ginvbetaj( Ginv * Vector(matrixColumn(betas,j)) );
00238 for(Int i=0; i<r; i++)
00239 A(i,j) = b[i]*b[j] - a*inner_prod( matrixColumn(betas,i), Ginvbetaj );
00240 }
00241 Matrix Ainv( Math::inverse(A) );
00242
00243
00244
00245 Vector nu( Ainv*(a*d - b*ft) );
00246 Real mu = -( inner_prod(nu,b) + ft)/a;
00247
00248 Vector Bnu( betas*nu );
00249 t = -Ginv*(mu*e + Bnu + H);
00250
00251 }
00252 else {
00253
00254 Vector alpha( betaConstraints->getAlpha() );
00255 if (equals(alpha,e))
00256 throw solution_error(Exception("optimization failed: alpha=e=(1,1,..,1) - undeterminable"));
00257
00258
00259 Real k = inner_prod(alpha, GinvH);
00260
00261
00262 Real l = inner_prod(etGinv, alpha);
00263
00264
00265 Real s = inner_prod(alpha, Ginv*alpha);
00266
00267
00268 Vector c(r);
00269 Vector Ginvalpha( Ginv*alpha );
00270 for(Int i=0; i<r; i++)
00271 c[i] = inner_prod( matrixColumn(betas,i), Ginvalpha );
00272
00273 Real l2msa = Math::sqr(l) - s*a;
00274
00275 if (Math::equals(l2msa,0))
00276 throw solution_error(Exception("optimization failed: l^2-s.a=0"));
00277
00278
00279 Matrix A(r,r);
00280 for(Int j=0; j<r; j++) {
00281 Real sbjmlcj = s*b[j] - l*c[j];
00282 Real acjmlbj = a*c[j] - l*b[j];
00283 Vector Ginvbetaj( Ginv * Vector(matrixColumn(betas,j)) );
00284 for(Int i=0; i<r; i++)
00285 A(i,j) = b[i]*sbjmlcj + c[i]*acjmlbj + l2msa*inner_prod( matrixColumn(betas,i), Ginvbetaj );
00286 }
00287
00288 Matrix Ainv( Math::inverse(A) );
00289
00290
00291 Vector nu( Ainv*((l*k - s*ft)*b - (a*k - l*ft)*c - l2msa*d) );
00292 Real eta = (a*k - l*ft - inner_prod(nu,l*b-a*c)) / l2msa;
00293 Real mu = -(ft + inner_prod(nu,b) + eta*l) / a;
00294
00295
00296 Vector Bnu( betas*nu );
00297 t = -Ginv*(H + mu*e + Bnu + eta*alpha);
00298
00299 }
00300
00301
00302 }
00303
00304 return t;
00305
00306 }
00307
00308