00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "KNI_InvKin/ikBase.h"
00023 #include "libKinematics.h"
00024
00025 CikBase::~CikBase() {
00026 if(mKinematics != 0) {
00027
00028
00029 if(_kinematicsIsInitialized) {
00030 kin_clean();
00031 }
00032 }
00033 }
00034
00035 void CikBase::_initKinematics() {
00036
00037 if(mKinematics == 0) {
00038
00039 if( std::string(base->GetGNL()->modelName) == "Katana6M90A_G") {
00040 _kinematicsImpl.reset(new KNI::KatanaKinematics6M90G);
00041 } else if(std::string(base->GetGNL()->modelName) == "Katana6M90A_F") {
00042 _kinematicsImpl.reset(new KNI::KatanaKinematics6M90T);
00043 } else if( std::string(base->GetGNL()->modelName) == "Katana6M90B_G") {
00044 _kinematicsImpl.reset(new KNI::KatanaKinematics6M90G);
00045 } else if(std::string(base->GetGNL()->modelName) == "Katana6M90B_F") {
00046 _kinematicsImpl.reset(new KNI::KatanaKinematics6M90T);
00047 } else if( std::string(base->GetGNL()->modelName) == "Katana6M90G") {
00048 _kinematicsImpl.reset(new KNI::KatanaKinematics6M90G);
00049 } else if(std::string(base->GetGNL()->modelName) == "Katana6M90T") {
00050 _kinematicsImpl.reset(new KNI::KatanaKinematics6M90T);
00051 } else if(std::string(base->GetGNL()->modelName) == "Katana6M180") {
00052 _kinematicsImpl.reset(new KNI::KatanaKinematics6M180);
00053 } else if(std::string(base->GetGNL()->modelName) == "Katana5M180") {
00054 _kinematicsImpl.reset(new KNI::KatanaKinematics5M180);
00055 } else {
00056 return;
00057 }
00058
00059 const TKatEFF* eff = base->GetEFF();
00060 const TKatMOT* mot = base->GetMOT();
00061
00062 KNI::KatanaKinematics::metrics length;
00063 for(int i = 0; i < getNumberOfMotors()-2; ++i) {
00064 length.push_back( eff->arr_segment[i] );
00065 }
00066
00067 KNI::KinematicParameters joint;
00068 KNI::KatanaKinematics::parameter_container parameters;
00069 for(int i = 0; i < getNumberOfMotors(); ++i) {
00070 joint.epc = mot->arr[i].GetInitialParameters()->encodersPerCycle;
00071 joint.encOffset = mot->arr[i].GetInitialParameters()->encoderOffset;
00072 joint.angleOffset = mot->arr[i].GetInitialParameters()->angleOffset;
00073 joint.angleStop = mot->arr[i].GetInitialParameters()->angleStop;
00074 joint.rotDir = mot->arr[i].GetInitialParameters()->rotationDirection;
00075 parameters.push_back(joint);
00076 }
00077
00078 _kinematicsImpl->init(length, parameters);
00079 } else {
00080
00081
00082 int type = -1;
00083 if( std::string(base->GetGNL()->modelName) == "Katana6M90A_G") {
00084 type = 1;
00085 } else if(std::string(base->GetGNL()->modelName) == "Katana6M90A_F") {
00086 type = 0;
00087 } else if(std::string(base->GetGNL()->modelName) == "Katana6M90B_G") {
00088 type = 4;
00089 } else if(std::string(base->GetGNL()->modelName) == "Katana6M90B_F") {
00090 type = 3;
00091 } else if(std::string(base->GetGNL()->modelName) == "Katana6M90G") {
00092 type = 1;
00093 } else if(std::string(base->GetGNL()->modelName) == "Katana6M90T") {
00094 type = 0;
00095 } else if(std::string(base->GetGNL()->modelName) == "Katana6M180") {
00096 type = 2;
00097 } else {
00098 return;
00099 }
00100
00101
00102 kin_setType(type);
00103 int dom = kin_getDOM();
00104
00105 FloatVector links;
00106 links.data[0] = (float) (base->GetEFF()->arr_segment[0] / 1000.0);
00107 links.data[1] = (float) (base->GetEFF()->arr_segment[1] / 1000.0);
00108 links.data[2] = (float) (base->GetEFF()->arr_segment[2] / 1000.0);
00109 links.data[3] = (float) (base->GetEFF()->arr_segment[3] / 1000.0);
00110 links.length = 4;
00111 kin_setLinkLen(&links);
00112
00113 IntVector epc;
00114 for (int i = 0; i < dom; ++i) {
00115 epc.data[i] = base->GetMOT()->arr[i].GetInitialParameters()->encodersPerCycle;
00116 }
00117 epc.length = dom;
00118 kin_setEPC(&epc);
00119
00120 IntVector encOffset;
00121 for (int i = 0; i < dom; ++i) {
00122 encOffset.data[i] = base->GetMOT()->arr[i].GetInitialParameters()->encoderOffset;
00123 }
00124 encOffset.length = dom;
00125 kin_setEncOff(&encOffset);
00126
00127 IntVector rotDir;
00128 for (int i = 0; i < dom; ++i) {
00129 if (i < 3) {
00130
00131 rotDir.data[i] = -base->GetMOT()->arr[i].GetInitialParameters()->rotationDirection;
00132 } else {
00133 rotDir.data[i] = base->GetMOT()->arr[i].GetInitialParameters()->rotationDirection;
00134 }
00135 }
00136 rotDir.length = dom;
00137 kin_setRotDir(&rotDir);
00138
00139 FloatVector angleOffset;
00140 for (int i = 0; i < dom; ++i) {
00141 angleOffset.data[i] = (float) (base->GetMOT()->arr[i].GetInitialParameters()->angleOffset);
00142 }
00143 angleOffset.length = dom;
00144 FloatVector angleOffset2;
00145 kin_K4D2mDHAng(&angleOffset, &angleOffset2);
00146 kin_setAngOff(&angleOffset2);
00147
00148 FloatVector angleRange;
00149 for (int i = 0; i < dom; ++i) {
00150 angleRange.data[i] = (float) fabs(base->GetMOT()->arr[i].GetInitialParameters()->angleRange);
00151 }
00152 angleRange.length = dom;
00153 kin_setAngRan(&angleRange);
00154
00155 kin_init();
00156 }
00157
00158 _kinematicsIsInitialized = true;
00159 }
00160
00161 void CikBase::getKinematicsVersion(std::vector<int>& version) {
00162 if(mKinematics == 0) {
00163
00164 version.clear();
00165 version.push_back(0);
00166 version.push_back(1);
00167 version.push_back(0);
00168 } else {
00169
00170
00171 IntVector v;
00172 kin_getVersion(&v);
00173 version.clear();
00174 for (int i = 0; i < v.length; ++i) {
00175 version.push_back(v.data[i]);
00176 }
00177 }
00178 }
00179
00180 void CikBase::setTcpOffset(double xoff, double yoff, double zoff, double psioff) {
00181
00182 if(mKinematics != 0) {
00183
00184
00185 FloatVector tcpOff;
00186 tcpOff.data[0] = (float) xoff;
00187 tcpOff.data[1] = (float) yoff;
00188 tcpOff.data[2] = (float) zoff;
00189 tcpOff.data[3] = (float) psioff;
00190 tcpOff.length = 4;
00191 kin_setTcpOff(&tcpOff);
00192 }
00193
00194 }
00195
00196 void CikBase::DKApos(double* position) {
00197 getCoordinates(position[0], position[1], position[2], position[3], position[4], position[5]);
00198 }
00199
00200 void CikBase::IKCalculate(double X, double Y, double Z, double phi, double theta, double psi, std::vector<int>::iterator solution_iter) {
00201
00202 if(!_kinematicsIsInitialized)
00203 _initKinematics();
00204
00205 if(mKinematics == 0) {
00206
00207 std::vector<double> pose(6);
00208 pose[0] = X;
00209 pose[1] = Y;
00210 pose[2] = Z;
00211 pose[3] = phi;
00212 pose[4] = theta;
00213 pose[5] = psi;
00214
00215 std::vector<int> actualPosition;
00216 base->recvMPS();
00217 for(int c = 0; c < getNumberOfMotors(); ++c) {
00218 actualPosition.push_back(getMotorEncoders(c, false));
00219 }
00220
00221 _kinematicsImpl->IK(solution_iter, pose, actualPosition);
00222 } else {
00223
00224
00225 int maxBisection = 3;
00226 int nOfMot = getNumberOfMotors();
00227
00228 FloatVector pose;
00229 pose.data[0] = (float) (X / 1000);
00230 pose.data[1] = (float) (Y / 1000);
00231 pose.data[2] = (float) (Z / 1000);
00232 pose.data[3] = (float) phi;
00233 pose.data[4] = (float) theta;
00234 pose.data[5] = (float) psi;
00235 pose.length = 6;
00236
00237 IntVector actualPosition;
00238 base->recvMPS();
00239 for(int i = 0; i < nOfMot; ++i) {
00240 actualPosition.data[i] = getMotorEncoders(i, false);
00241 }
00242 actualPosition.length = nOfMot;
00243 FloatVector prev;
00244 kin_enc2rad(&actualPosition, &prev);
00245
00246 FloatVector ikangle;
00247 kin_IK(&pose, &prev, &ikangle, maxBisection);
00248
00249 IntVector ikenc;
00250 kin_rad2enc(&ikangle, &ikenc);
00251
00252
00253 if (ikenc.length == actualPosition.length - 1) {
00254 ikenc.data[ikenc.length] = actualPosition.data[ikenc.length];
00255 ikenc.length = actualPosition.length;
00256 }
00257
00258 for(int i = 0; i < nOfMot; ++i) {
00259 *solution_iter = ikenc.data[i];
00260 solution_iter++;
00261 }
00262 }
00263
00264 }
00265
00266 void CikBase::IKCalculate(double X, double Y, double Z, double phi, double theta, double psi, std::vector<int>::iterator solution_iter, const std::vector<int>& actualPosition) {
00267
00268 if(!_kinematicsIsInitialized)
00269 _initKinematics();
00270
00271 if(mKinematics == 0) {
00272
00273 std::vector<double> pose(6);
00274 pose[0] = X;
00275 pose[1] = Y;
00276 pose[2] = Z;
00277 pose[3] = phi;
00278 pose[4] = theta;
00279 pose[5] = psi;
00280
00281 _kinematicsImpl->IK(solution_iter, pose, actualPosition);
00282 } else {
00283
00284
00285 int maxBisection = 3;
00286 int nOfMot = getNumberOfMotors();
00287
00288 FloatVector pose;
00289 pose.data[0] = (float) (X / 1000);
00290 pose.data[1] = (float) (Y / 1000);
00291 pose.data[2] = (float) (Z / 1000);
00292 pose.data[3] = (float) phi;
00293 pose.data[4] = (float) theta;
00294 pose.data[5] = (float) psi;
00295 pose.length = 6;
00296
00297 IntVector actPos;
00298 for(int i = 0; i < nOfMot; ++i) {
00299 actPos.data[i] = actualPosition.at(i);
00300 }
00301 actPos.length = nOfMot;
00302 FloatVector prev;
00303 kin_enc2rad(&actPos, &prev);
00304
00305 FloatVector ikangle;
00306 int error = kin_IK(&pose, &prev, &ikangle, maxBisection);
00307 if (error)
00308 throw KNI::NoSolutionException();
00309
00310 IntVector ikenc;
00311 kin_rad2enc(&ikangle, &ikenc);
00312
00313
00314 if (ikenc.length == actPos.length - 1) {
00315 ikenc.data[ikenc.length] = actPos.data[ikenc.length];
00316 ikenc.length = actPos.length;
00317 }
00318
00319 for(int i = 0; i < nOfMot; ++i) {
00320 *solution_iter = ikenc.data[i];
00321 solution_iter++;
00322 }
00323 }
00324
00325 }
00326
00327 void CikBase::IKGoto(double X, double Y, double Z, double Al, double Be, double Ga, bool wait, int tolerance, long timeout) {
00328
00329 if(!_kinematicsIsInitialized)
00330 _initKinematics();
00331
00332 const TKatMOT* mot = base->GetMOT();
00333
00334 std::vector<int> solution(getNumberOfMotors());
00335
00336 std::vector<int> act_pos(getNumberOfMotors());
00337 std::vector<int> distance(getNumberOfMotors());
00338
00339 base->recvMPS();
00340 for (int idx=0; idx<getNumberOfMotors(); ++idx) {
00341 act_pos[idx] = mot->arr[idx].GetPVP()->pos;
00342 }
00343
00344 IKCalculate( X, Y, Z, Al, Be, Ga, solution.begin(), act_pos );
00345 moveRobotToEnc( solution.begin(), solution.end(), wait, tolerance, timeout);
00346
00347 }
00348
00349 void CikBase::getCoordinates(double& x, double& y, double& z, double& phi, double& theta, double& psi, bool refreshEncoders) {
00350
00351 if(!_kinematicsIsInitialized)
00352 _initKinematics();
00353
00354 if(refreshEncoders)
00355 base->recvMPS();
00356
00357 if(mKinematics == 0) {
00358
00359 std::vector<int> current_encoders(getNumberOfMotors());
00360 for (int i=0; i<getNumberOfMotors(); i++) {
00361 current_encoders[i] = base->GetMOT()->arr[i].GetPVP()->pos;
00362 }
00363
00364 std::vector<double> pose(6);
00365
00366 _kinematicsImpl->DK(pose, current_encoders);
00367
00368 x = pose[0];
00369 y = pose[1];
00370 z = pose[2];
00371 phi = pose[3];
00372 theta = pose[4];
00373 psi = pose[5];
00374 } else {
00375
00376
00377 int nOfMot = getNumberOfMotors();
00378
00379 IntVector actPos;
00380 for(int i = 0; i < nOfMot; ++i) {
00381 actPos.data[i] = base->GetMOT()->arr[i].GetPVP()->pos;
00382 }
00383 actPos.length = nOfMot;
00384 FloatVector angle;
00385 kin_enc2rad(&actPos, &angle);
00386
00387 FloatVector pose;
00388 kin_DK(&angle, &pose);
00389
00390 x = pose.data[0] * 1000;
00391 y = pose.data[1] * 1000;
00392 z = pose.data[2] * 1000;
00393 phi = pose.data[3];
00394 theta = pose.data[4];
00395 psi = pose.data[5];
00396 }
00397 }
00398
00399 void CikBase::getCoordinatesFromEncoders(std::vector<double>& pos, const std::vector<int>& encs){
00400
00401 if(!_kinematicsIsInitialized)
00402 _initKinematics();
00403
00404 if(mKinematics == 0) {
00405
00406 _kinematicsImpl->DK(pos, encs);
00407 } else {
00408
00409 int nOfMot = getNumberOfMotors();
00410 IntVector actPos;
00411 for(int i = 0; i < nOfMot; ++i) {
00412 actPos.data[i] = encs.at(i);
00413 }
00414 actPos.length = nOfMot;
00415 FloatVector angle;
00416 kin_enc2rad(&actPos, &angle);
00417 FloatVector pose;
00418 kin_DK(&angle, &pose);
00419 pos.clear();
00420 pos.push_back(pose.data[0] * 1000);
00421 pos.push_back(pose.data[1] * 1000);
00422 pos.push_back(pose.data[2] * 1000);
00423 pos.push_back(pose.data[3]);
00424 pos.push_back(pose.data[4]);
00425 pos.push_back(pose.data[5]);
00426 }
00427 }
00428
00429 void CikBase::moveRobotTo(double x, double y, double z, double phi, double theta, double psi, const bool waitUntilReached, const int waitTimeout) {
00430 IKGoto(x, y, z, phi, theta, psi, waitUntilReached, 100, waitTimeout);
00431 }
00432
00433 void CikBase::moveRobotTo(std::vector<double> coordinates, const bool waitUntilReached, const int waitTimeout) {
00434 IKGoto(coordinates.at(0), coordinates.at(1), coordinates.at(2), coordinates.at(3), coordinates.at(4), coordinates.at(5), waitUntilReached, 100, waitTimeout);
00435 }