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/AnalyticLagrangianNullSpaceBetaOptimizer>
00026 #include <robot/control/kinematics/ReferenceOpVectorFormObjective>
00027 #include <robot/control/kinematics/solution_error>
00028
00029 using base::transpose;
00030 using robot::control::kinematics::AnalyticLagrangianNullSpaceBetaOptimizer;
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 AnalyticLagrangianNullSpaceBetaOptimizer::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) );
00098 Assert(t.size() == span);
00099
00100
00101 Vector dq( gs.size1() );
00102 dq = zeroVector( gs.size1() );
00103 for(Int i=0; i<span; i++)
00104 dq += t[i]*matrixColumn(gs,i);
00105
00106 return dq;
00107 }
00108
00109
00110
00111 base::Vector AnalyticLagrangianNullSpaceBetaOptimizer::calct(const Matrix& Ginv, const Vector& H, ref<const BetaFormConstraints> betaConstraints) const
00112 {
00113
00114
00115
00116
00117
00118
00119
00120
00121 const Int span = Ginv.size1();
00122 Vector t(span);
00123
00124
00125 if (betaConstraints->numBetaConstraints() == 0) {
00126
00127
00128
00129 t = zeroVector(span);
00130
00131 }
00132 else {
00133
00134
00135
00136
00137
00138
00139
00140 Matrix betas(betaConstraints->getBetas());
00141 Int r = betas.size2();
00142
00143
00144 Vector d(r);
00145 Vector GinvH( Ginv * H );
00146 for(Int i=0; i<r; i++)
00147 d[i] = -(1.0 + inner_prod( matrixColumn(betas, i), GinvH ));
00148
00149
00150 if (!betaConstraints->isAlphaConstraint()) {
00151
00152
00153 Matrix A(r,r);
00154 for(Int j=0; j<r; j++) {
00155 Vector Ginvbetaj( Ginv * Vector(matrixColumn(betas,j)) );
00156 for(Int i=0; i<r; i++)
00157 A(i,j) = inner_prod( matrixColumn(betas,i), Ginvbetaj );
00158 }
00159 Matrix Ainv( Math::inverse(A) );
00160
00161
00162
00163 Vector nu( Ainv*d );
00164
00165 Vector Bnu( betas*nu );
00166 t = -Ginv*(Bnu + H);
00167
00168 }
00169 else {
00170
00171 throw solution_error(Exception("Null-space solution with non-holonomic constraint not implemented."));
00172
00173 }
00174
00175
00176 }
00177
00178 return t;
00179
00180 }
00181
00182