00001 #include <kdl/constraints.hpp>
00002 #include <kdl/jacobianframe.hpp>
00003 #include <fstream>
00004 #include <iomanip>
00005
00006 using namespace KDL;
00007
00012 ConstraintMatrix::ConstraintMatrix(int _maxrows,int _maxcols) :
00013 maxrows(_maxrows),
00014 maxcols(_maxcols),
00015 cmat(new double[_maxrows*_maxcols]),
00016 cmatstride(_maxcols),
00017 desval(new double[_maxrows]),
00018 weight(new double[_maxrows]),
00019 jsweight(new double[_maxcols]),
00020 pinvtmps( _maxrows>_maxcols?_maxrows:_maxcols),
00021
00022
00023
00024
00025
00026 cmati(new double[_maxrows*_maxcols]),
00027 cmatistride(_maxrows),
00028 nrOfConstraints(0),
00029 eps(0.05),
00030 nrofits(100)
00031 {}
00032
00033 void ConstraintMatrix::dump(std::ostream& os) {
00034 int p = os.precision(7);
00035 int w = 16;
00036 std::ios_base::fmtflags fl = os.setf(std::ios::scientific);
00037 int i,j;
00038 os << "Constraint Matrix and desired velocity(last column)" << std::endl;
00039 for (i=0;i<nrOfConstraints;++i) {
00040 for (j=0;j<nrofjoints;++j) {
00041 os << std::setw(w) << cmat[i*cmatstride+j] << "\t";
00042 }
00043 os << desval[i];
00044 os << std::endl;
00045 }
00046 os.flags(fl);
00047 os.precision(p);
00048 }
00049
00050 void ConstraintMatrix::dumpsvd(std::ostream& os) {
00051 int p = os.precision(7);
00052 int w = 16;
00053 std::ios_base::fmtflags fl = os.setf(std::ios::scientific);
00054 int i;
00055 for (i=0;i<nrofjoints;++i) {
00056 os << std::setw(w) << pinvtmps.S[pinvtmps.ndx[i]] << " ";
00057 }
00058 os << std::endl;
00059 os.flags(fl);
00060 os.precision(p);
00061 }
00062
00063 void ConstraintMatrix::resetConstraints(int _nrofjoints) {
00064 int i;
00065 nrofjoints = _nrofjoints;
00066 nrOfConstraints=0;
00067 for (i=0;i<nrofjoints;++i) {
00068 jsweight[i]=1.0;
00069 }
00070 }
00071 void ConstraintMatrix::addConstraint(const Jacobian<double>& c,double K,double _desval,double _desvald,double _weight) {
00072 int i;
00073 assert((0<=nrOfConstraints)&&(nrOfConstraints<maxrows));
00074 assert((!c.hasDerivs())||(c.nrOfDeriv()==nrofjoints));
00075 desval[nrOfConstraints] = K*(_desval - c.value()) + _desvald;
00076 weight[nrOfConstraints] = ::sqrt(_weight);
00077 if (c.hasDerivs()) {
00078 for (i=0;i<nrofjoints;++i) {
00079 if (c.hasDeriv(i)) {
00080 cmat[cmatstride*nrOfConstraints+i] = c.deriv(i);
00081 } else {
00082 cmat[cmatstride*nrOfConstraints+i] = 0.0;
00083 }
00084 }
00085 } else {
00086 for (i=0;i<nrofjoints;++i) {
00087 cmat[cmatstride*nrOfConstraints+i] = 0.0;
00088 }
00089 }
00090 nrOfConstraints++;
00091 }
00092
00093 void ConstraintMatrix::addConstraintJoint(int jointnr,double value,double K,double _desval,double _desvald,double _weight) {
00094 int i;
00095 assert((0<=nrOfConstraints)&&(nrOfConstraints<maxrows));
00096 desval[nrOfConstraints] = K*(_desval - value) + _desvald;
00097 weight[nrOfConstraints] = ::sqrt(_weight);
00098 for (i=0;i<nrofjoints;++i) {
00099 cmat[cmatstride*nrOfConstraints+i] = (i==jointnr)?1.0:0.0;
00100 }
00101 nrOfConstraints++;
00102 }
00103
00104
00105 void ConstraintMatrix::addConstraint(
00106 const Jacobian<Vector>& c,
00107 double K,
00108 const Vector& _desval,
00109 const Vector& _desvald,
00110 double _weight
00111 ) {
00112 assert((0<=nrOfConstraints)&&(nrOfConstraints+2<maxrows));
00113 assert((!c.hasDerivs())||(c.nrOfDeriv()==nrofjoints));
00114 int r,i;
00115 Vector d = K*(_desval- c.value()) + _desvald;
00116 _weight = ::sqrt(_weight);
00117 for (r=0;r<3;r++) {
00118 desval[nrOfConstraints] = d(r);
00119 weight[nrOfConstraints] = _weight;
00120 if (c.hasDerivs()) {
00121 for (i=0;i<nrofjoints;++i) {
00122 if (c.hasDeriv(i)) {
00123 cmat[cmatstride*nrOfConstraints+i] = c.deriv(i)(r);
00124 } else {
00125 cmat[cmatstride*nrOfConstraints+i] = 0.0;
00126 }
00127 }
00128 } else {
00129 for (i=0;i<nrofjoints;++i) {
00130 cmat[cmatstride*nrOfConstraints+i] = 0.0;
00131 }
00132 }
00133 nrOfConstraints++;
00134 }
00135 }
00139 void ConstraintMatrix::addConstraint(
00140 const Jacobian<Frame>& c,
00141 const std::vector<double>& K,
00142 const Frame& _desval,
00143 const Twist& _desvald,
00144 const std::vector<double>& _weight
00145 ) {
00146 assert((0<=nrOfConstraints)&&(nrOfConstraints+5<maxrows));
00147 assert((!c.hasDerivs())||(c.nrOfDeriv()==nrofjoints));
00148 int r,i;
00149 Twist d = diff(c.value(),_desval,1.0);
00150 for (r=0;r<6;r++) {
00151 desval[nrOfConstraints] = K[r]*d(r)+_desvald(r);
00152 weight[nrOfConstraints] = ::sqrt(_weight[r]);
00153 if (c.hasDerivs()) {
00154 for (i=0;i<nrofjoints;++i) {
00155 if (c.hasDeriv(i)) {
00156 cmat[cmatstride*nrOfConstraints+i] = c.deriv(i)(r);
00157 } else {
00158 cmat[cmatstride*nrOfConstraints+i] = 0.0;
00159 }
00160 }
00161 } else {
00162 for (i=0;i<nrofjoints;++i) {
00163 cmat[cmatstride*nrOfConstraints+i] = 0.0;
00164 }
00165 }
00166 nrOfConstraints++;
00167 }
00168 }
00169
00173 void ConstraintMatrix::addConstraintWithoutControl(
00174 const Jacobian<Frame>& c,
00175 const Twist& desired,
00176 const std::vector<double>& _weight
00177 ) {
00178 assert((0<=nrOfConstraints)&&(nrOfConstraints+5<maxrows));
00179 assert((!c.hasDerivs())||(c.nrOfDeriv()==nrofjoints));
00180 int r,i;
00181 for (r=0;r<6;r++) {
00182 desval[nrOfConstraints] = desired(r);
00183 weight[nrOfConstraints] = ::sqrt(_weight[r]);
00184 if (c.hasDerivs()) {
00185 for (i=0;i<nrofjoints;++i) {
00186 if (c.hasDeriv(i)) {
00187 cmat[cmatstride*nrOfConstraints+i] = c.deriv(i)(r);
00188 } else {
00189 cmat[cmatstride*nrOfConstraints+i] = 0.0;
00190 }
00191 }
00192 } else {
00193 for (i=0;i<nrofjoints;++i) {
00194 cmat[cmatstride*nrOfConstraints+i] = 0.0;
00195 }
00196 }
00197 nrOfConstraints++;
00198 }
00199 }
00200
00201
00202
00203 void ConstraintMatrix::addConstraint(
00204 const Jacobian<Frame>& c,
00205 double Kpos,
00206 double Krot,
00207 const Frame& _desval,
00208 const Twist& _desvald,
00209 double _weightpos,
00210 double _weightrot
00211 ) {
00212 assert((0<=nrOfConstraints)&&(nrOfConstraints+5<maxrows));
00213 assert((!c.hasDerivs())||(c.nrOfDeriv()==nrofjoints));
00214 int r,i;
00215 Twist d = diff(c.value(),_desval,1.0);
00216 _weightpos = ::sqrt(_weightpos);
00217 _weightrot = ::sqrt(_weightrot);
00218 for (r=0;r<6;r++) {
00219 if (r<3) {
00220 desval[nrOfConstraints] = Kpos*d(r)+_desvald(r);
00221 weight[nrOfConstraints] = _weightpos;
00222 } else {
00223 desval[nrOfConstraints] = Krot*d(r)+_desvald(r);
00224 weight[nrOfConstraints] = _weightrot;
00225 }
00226 if (c.hasDerivs()) {
00227 for (i=0;i<nrofjoints;++i) {
00228 if (c.hasDeriv(i)) {
00229 cmat[cmatstride*nrOfConstraints+i] = c.deriv(i)(r);
00230 } else {
00231 cmat[cmatstride*nrOfConstraints+i] = 0.0;
00232 }
00233 }
00234 } else {
00235 for (i=0;i<nrofjoints;++i) {
00236 cmat[cmatstride*nrOfConstraints+i] = 0.0;
00237 }
00238 }
00239 nrOfConstraints++;
00240 }
00241 }
00242
00243
00244
00245 void ConstraintMatrix::addConstraint(
00246 const Jacobian<Twist>& c,
00247 double Kpos,
00248 double Krot,
00249 const Twist& _desval,
00250 const Twist& _desvald,
00251 double _weightpos,
00252 double _weightrot
00253 ) {
00254 assert((0<=nrOfConstraints)&&(nrOfConstraints+5<maxrows));
00255 assert((!c.hasDerivs())||(c.nrOfDeriv()==nrofjoints));
00256 int r,i;
00257 Twist d = _desval - c.value();
00258 _weightpos = ::sqrt(_weightpos);
00259 _weightrot = ::sqrt(_weightrot);
00260 for (r=0;r<6;r++) {
00261 if (r<3) {
00262 desval[nrOfConstraints] = Kpos*d(r)+_desvald(r);
00263 weight[nrOfConstraints] = _weightpos;
00264 } else {
00265 desval[nrOfConstraints] = Krot*d(r)+_desvald(r);
00266 weight[nrOfConstraints] = _weightrot;
00267 }
00268 if (c.hasDerivs()) {
00269 for (i=0;i<nrofjoints;++i) {
00270 if (c.hasDeriv(i)) {
00271 cmat[cmatstride*nrOfConstraints+i] = c.deriv(i)(r);
00272 } else {
00273 cmat[cmatstride*nrOfConstraints+i] = 0.0;
00274 }
00275 }
00276 } else {
00277 for (i=0;i<nrofjoints;++i) {
00278 cmat[cmatstride*nrOfConstraints+i] = 0.0;
00279 }
00280 }
00281 nrOfConstraints++;
00282 }
00283 }
00284
00285
00286
00287
00288 void ConstraintMatrix::addConstraint(
00289 const Jacobian<Wrench>& c,
00290 double Kpos,
00291 double Krot,
00292 const Wrench& _desval,
00293 const Wrench& _desvald,
00294 double _weightpos,
00295 double _weightrot
00296 ) {
00297
00298 assert((0<=nrOfConstraints)&&(nrOfConstraints+5<maxrows));
00299 assert((!c.hasDerivs())||(c.nrOfDeriv()==nrofjoints));
00300 int r,i;
00301 _weightpos = ::sqrt(_weightpos);
00302 _weightrot = ::sqrt(_weightrot);
00303 Wrench d = diff(c.value(),_desval,1.0);
00304 for (r=0;r<6;r++) {
00305 if (r<3) {
00306 desval[nrOfConstraints] = Kpos*d(r)+_desvald(r);
00307 weight[nrOfConstraints] = _weightpos;
00308 } else {
00309 desval[nrOfConstraints] = Krot*d(r)+_desvald(r);
00310 weight[nrOfConstraints] = _weightrot;
00311 }
00312 if (c.hasDerivs()) {
00313 for (i=0;i<nrofjoints;++i) {
00314 if (c.hasDeriv(i)) {
00315 cmat[cmatstride*nrOfConstraints+i] = c.deriv(i)(r);
00316 } else {
00317 cmat[cmatstride*nrOfConstraints+i] = 0.0;
00318 }
00319 }
00320 } else {
00321 for (i=0;i<nrofjoints;++i) {
00322 cmat[cmatstride*nrOfConstraints+i] = 0.0;
00323 }
00324 }
00325 nrOfConstraints++;
00326 }
00327 }
00334 void ConstraintMatrix::calculateOutput(std::vector<double>& output) {
00335 int i;
00336 if (nrOfConstraints==0) {
00337 for (i=0;i<nrofjoints;++i) output[i]=0.0;
00338 return;
00339 }
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371 pinvtmps.prepare(cmat,cmatstride,nrOfConstraints,nrofjoints,weight,jsweight,nrofits);
00372
00373 pinvtmps.inverse(desval,&output[0],eps);
00374 }
00375
00376 ConstraintMatrix::~ConstraintMatrix() {
00377 delete [] cmat;
00378 delete [] desval;
00379 delete [] weight;
00380 delete [] jsweight;
00381 delete [] cmati;
00382 }
00383
00384 void ConstraintMatrix::setJointSpaceWeights(const std::vector<double>& jsw) {
00385 int i;
00386 for (i=0;i<nrofjoints;++i) {
00387 jsweight[i]=::sqrt(jsw[i]);
00388 }
00389 }
00394 void ConstraintMatrix::calculateOutput(std::vector<double>& output,const std::vector<double>& nullspace) {
00395 int i;
00396 if (nrOfConstraints==0) {
00397 for (i=0;i<nrofjoints;++i) output[i]=nullspace[i];
00398 return;
00399 }
00400
00401
00402
00403
00404
00405
00406
00407 pinvtmps.prepare(cmat,cmatstride,nrOfConstraints,nrofjoints,weight,jsweight,nrofits);
00408 pinvtmps.inverseWithNullSpace(desval,&output[0],&nullspace[0],eps);
00409
00410 }
00411
00412
00413 void ConstraintMatrix::reduce(const std::vector<bool>& list,const std::vector<double> value) {
00414 int newcol =0;
00415 for (int col=0;col<nrofjoints;++col) {
00416
00417 int row;
00418 if (!list[col]) {
00419
00420
00421 for (row=0;row<nrOfConstraints;++row)
00422 cmat[cmatstride*row+newcol] = cmat[cmatstride*row+col];
00423
00424 jsweight[newcol]=jsweight[col];
00425
00426 newcol++;
00427 } else {
00428 for (row=0;row<nrOfConstraints;++row) {
00429 desval[row] -= cmat[cmatstride*row+col]*value[row];
00430 }
00431 }
00432
00433 }
00434
00435 nrofjoints= newcol;
00436 }
00437
00438 void ConstraintMatrix::reducejv(const std::vector<bool>& list,std::vector<double>& vec)
00439 {
00440 int newcol =0;
00441 for (int col=0;col<nrofjoints;++col) {
00442 if (!list[col]) {
00443 vec[newcol] = vec[col];
00444 newcol++;
00445 }
00446 }
00447 }
00448
00449 void ConstraintMatrix::expandjv(int nrofalljoints,const std::vector<bool>& list,const std::vector<double>& values,std::vector<double>& vec)
00450 {
00451 int oldcol =nrofjoints-1;
00452 for (int col=nrofalljoints-1;col>=0;--col) {
00453
00454 if (!list[col]) {
00455 vec[col] = vec[oldcol];
00456 oldcol--;
00457 } else {
00458 vec[col] = values[col];
00459 }
00460
00461 }
00462 }
00463
00464
00465
00466 void ConstraintMatrix::calculateOutput(const std::vector<bool>& list, const std::vector<double>& value, std::vector<double>& output) {
00467 int nrofalljoints = nrofjoints;
00468 reduce(list,value);
00469 calculateOutput(output);
00470 expandjv(nrofalljoints,list,value,output);
00471 }
00472
00473
00474 void ConstraintMatrix::calculateOutput(
00475 const std::vector<bool>& list,
00476 const std::vector<double>& values,
00477 std::vector<double>& output,
00478 std::vector<double>& nullspace)
00479 {
00480 int nrofalljoints = nrofjoints;
00481 reduce(list,values);
00482 reducejv(list,nullspace);
00483 calculateOutput(output,nullspace);
00484 expandjv(nrofalljoints,list,values,output);
00485 }
00486
00487