Go to the documentation of this file.00001 
00060 #include <schunk_powercube_chain/PowerCubeSim.h>
00061 #include <string>
00062 #include <sstream>
00063 #ifdef PYTHON_THREAD
00064 #include <Python.h>
00065 #endif
00066 
00067 
00068 #define DEG 57.295779524
00069 #define MANUAL_AXES0_OFFSET  1.8
00070 #define MANUAL_AXES6_OFFSET 1.5
00071 
00072 
00073 #define SIM_CLOCK_FREQUENCY 10.0 //ms
00074 using namespace std;
00075 
00076 #ifndef PCTRL_CHECK_INITIALIZED()
00077 #define PCTRL_CHECK_INITIALIZED() \
00078 if ( isInitialized()==false )                                                                                                   \
00079 {                                                                                                                                               \
00080     m_ErrorMessage.assign("Manipulator not initialized.");              \
00081         return false;                                                                                                           \
00082 }
00083 #endif
00084 
00085 
00086 PowerCubeSim::PowerCubeSim()
00087 {
00088         m_Dev=0;
00089         m_NumOfModules = 0;
00090         m_SimThreadArgs = NULL;
00091         m_SimThreadID = NULL;
00092 
00093         
00094         
00095         
00096 }
00097 
00098 
00103 bool PowerCubeSim::Init(PowerCubeCtrlParams * params)
00104 {
00105         
00106         m_DOF=params->GetNumberOfDOF();
00107 
00108         m_Dev=0;
00109         m_NumOfModules = m_DOF;
00110         
00111         m_maxVel = params->GetMaxVel();
00112         m_maxAcc = params->GetMaxAcc();
00113 
00114         
00115         m_IdModules.clear();
00116                         
00117 
00118         m_CurrentAngles.resize(m_DOF);
00119         m_CurrentAngularMaxAccel.resize(m_DOF);
00120         m_CurrentAngularMaxVel.resize(m_DOF);
00121         m_CurrentAngularVel.resize(m_DOF);
00122 
00123         
00124 
00125         for(int i=0; i<m_DOF; i++)
00126         {
00127                 std::ostringstream os;
00128                 os << "ID_Module_Number" << i+1;
00129                 
00130                 
00131                 
00132                 
00133                 m_CurrentAngles[i] = 0.0;
00134                 m_CurrentAngularVel[i] =0.0;
00135                 m_CurrentAngularMaxVel[i] = m_maxVel[i];
00136                 m_CurrentAngularMaxAccel[i] =m_maxAcc[i];
00137                 
00138                 
00139         }
00140         
00141         
00142         
00143         
00144 
00145         
00146         
00147         pthread_mutex_init(&m_Movement_Mutex,NULL);
00148         pthread_mutex_init(&m_Angles_Mutex,NULL);
00149         pthread_mutex_init(&m_AngularVel_Mutex,NULL);
00150 
00151         m_SimThreadID = (pthread_t*)malloc(m_DOF * sizeof(pthread_t));
00152         m_MovementInProgress.resize(m_DOF);
00153         m_SimThreadArgs = (SimThreadArgs**)malloc(m_DOF * sizeof(SimThreadArgs*));
00154         for (int i = 0; i < m_DOF; i++)
00155         {
00156                 m_MovementInProgress[i] = false;
00157                 m_SimThreadArgs[i] = new SimThreadArgs();
00158                 m_SimThreadArgs[i]->cubeSimPtr = this;
00159                 m_SimThreadArgs[i]->cubeID = i;
00160         }
00161         setMaxVelocity(MAX_VEL);
00162         setMaxAcceleration(MAX_ACC);
00163 
00164 
00165         
00166         m_Initialized = true;
00167         return true;
00168 }
00169 
00170 
00173 PowerCubeSim::~PowerCubeSim()
00174 { 
00175         free(m_SimThreadID);
00176         for (int i = 0; i < m_DOF; i++)
00177         {
00178                 delete m_SimThreadArgs[i];
00179         }
00180         free(m_SimThreadArgs);
00181 
00182 }
00183 
00185 bool PowerCubeSim::getConfig(std::vector<double>& result)
00186 {
00187         PCTRL_CHECK_INITIALIZED();
00188         
00189         
00190         
00191         pthread_mutex_lock(&m_Angles_Mutex);
00192         
00193         result.resize(m_DOF);
00194         for(int i; i < m_DOF; i++)
00195                 result[i] = m_CurrentAngles[i]*DEG;
00196         
00197         
00198         
00199         pthread_mutex_unlock(&m_Angles_Mutex);
00200         
00201         
00202         return true;
00203 }
00204 
00205 
00206 
00208 bool PowerCubeSim::getJointVelocities(std::vector<double>& result)
00209 {
00210         PCTRL_CHECK_INITIALIZED();
00211         
00212         
00213         
00214         pthread_mutex_lock(&m_AngularVel_Mutex);
00215         
00216         result.resize(m_DOF);
00217         result = m_CurrentAngularVel;
00218         
00219         
00220         
00221         pthread_mutex_unlock(&m_AngularVel_Mutex);
00222         
00223 
00224         return true;
00225 }
00226 void PowerCubeSim::setCurrentAngles(std::vector<double> Angles)
00227 {
00228 
00229         
00230         pthread_mutex_lock(&m_Angles_Mutex);
00231         
00232         
00233         m_CurrentAngles = Angles;
00234         
00235         
00236         
00237         pthread_mutex_unlock(&m_Angles_Mutex);
00238         
00239         
00240 
00241 }
00242 
00243 void PowerCubeSim::setCurrentJointVelocities( std::vector<double> AngularVel)
00244 {
00245 
00246         
00247         
00248         pthread_mutex_lock(&m_AngularVel_Mutex);
00249         
00250         
00251         m_CurrentAngularVel = AngularVel;
00252         
00253         
00254         
00255         pthread_mutex_unlock(&m_AngularVel_Mutex);
00256         
00257 
00258 }
00259         
00260 
00261 
00263 bool PowerCubeSim::MoveJointSpaceSync(const std::vector<double>& target)
00264 {
00265         PCTRL_CHECK_INITIALIZED();
00266         std::cout << "Starting MoveJointSpaceSync(Jointd Angle) ... "<<endl;
00267         std::vector<double> targetRAD;
00268         targetRAD.resize(m_DOF);
00269         for(int i = 0; i<m_DOF; i++)
00270                 targetRAD[i] = target[i]/DEG;
00271 
00272         
00273         std::vector<double> acc(m_DOF);
00274         std::vector<double> vel(m_DOF);
00275         
00276         double TG = 0;
00277         
00278         try
00279         {
00280                 
00281                 
00282                 int DOF = m_DOF;
00283 
00284                 std::vector<double> posnow;
00285                 if ( getConfig(posnow) == false )
00286                     return false;
00287 
00288 
00289                 std::vector<double> velnow;
00290                 if ( getJointVelocities(velnow) == false )
00291                     return false;
00292 
00293                 std::vector<double> times(DOF);
00294 
00295                 for (int i=0; i < DOF; i++)
00296                 {
00297                         RampCommand rm(posnow[i], velnow[i], targetRAD[i], m_maxAcc[i], m_maxVel[i]);
00298                         times[i] = rm.getTotalTime();
00299                 }
00300                 
00301                 
00302                 int furthest = 0;
00303 
00304                 double max = times[0];
00305 
00306             for (int i=1; i<m_DOF; i++)
00307             {
00308                     if (times[i] > max)
00309                     {
00310                             max = times[i];
00311                             furthest = i;
00312                     }
00313             }
00314 
00315                 RampCommand rm_furthest(posnow[furthest], velnow[furthest], targetRAD[furthest], m_maxAcc[furthest], m_maxVel[furthest]);
00316 
00317                 double T1 = rm_furthest.T1();
00318                 double T2 = rm_furthest.T2();
00319                 double T3 = rm_furthest.T3();
00320 
00321                 
00322                 TG = T1 + T2 + T3;
00323                 
00324                 
00325                 acc[furthest] = m_maxAcc[furthest];
00326                 vel[furthest] = m_maxVel[furthest];
00327                 
00328                 for (int i = 0; i < DOF; i++)
00329                 {
00330                         if (i != furthest)
00331                         {
00332                                 double a; double v;
00333                                 
00334                                 RampCommand::calculateAV(
00335                                         posnow[i],
00336                                         velnow[i],
00337                                         targetRAD[i],
00338                                         TG, T3,
00339                                         m_maxAcc[i],
00340                                         m_maxVel[i],
00341                                         a,
00342                                         v);
00343 
00344                                 acc[i] = a;
00345                                 vel[i] = v;
00346                         }
00347                 }
00348         }
00349         catch(...)
00350         {
00351                 return false;
00352         }
00353 
00354         startSimulatedMovement(targetRAD);
00355         
00356         
00357         return true;
00358                 
00359 }
00360 
00361 
00362                 
00363 
00365 double PowerCubeSim::timeRampMove(double dtheta, double vnow, double v, double a)
00366 {
00367         
00368         
00369         
00370         
00371         
00372         
00373         
00374         
00375         
00376         double vm = (dtheta<0)?-v:v;
00377         double am = (dtheta<0)?-a:a;
00378         
00379         
00380         
00381         
00382         double T1 = (vm - vnow) / am;
00383         
00384         double dtheta1 = vnow * T1 + 0.5 * am * T1 * T1;
00385         
00386         
00387         
00388         
00389         double T3 = vm / am;
00390         
00391         double dtheta3 = 0.5 * vm * T3;
00392         
00393         
00394         double dtheta2 = dtheta - dtheta1 - dtheta3;
00395         
00396         double T2 = dtheta2 / vm;
00397         
00398         
00399         
00400         
00401 
00402         
00403         
00404         return T1 + T2 + T3;
00405 }
00406 
00407                 
00409 bool PowerCubeSim::MoveVel(const std::vector<double>& vel)
00410 {
00411         PCTRL_CHECK_INITIALIZED();
00412         
00413 
00414 
00415 
00416 
00417 
00418 
00419 
00420 
00421 
00422 
00423 
00424 }
00425                 
00426                                 
00428 bool PowerCubeSim::Stop()
00429 {
00430         for (int i=0; i < m_DOF; i++)
00431                 setStatusMoving(i, false);
00432         return true;
00433 }
00434 
00437 bool PowerCubeSim::setMaxVelocity(double radpersec)
00438 { 
00439         for (int i=0; i<m_DOF; i++)
00440         {
00441                 m_CurrentAngularMaxVel[i] = radpersec;
00442         }
00443         return true;
00444 }
00445 
00446 bool PowerCubeSim::setMaxVelocity(const std::vector<double>& radpersec)
00447 {
00448         for (int i=0; i<m_DOF; i++)
00449         {
00450                 m_CurrentAngularMaxVel[i] = radpersec[i];
00451         }
00452         return true;
00453 }
00454 
00455 
00458 bool PowerCubeSim::setMaxAcceleration(double radPerSecSquared)
00459 {
00460     PCTRL_CHECK_INITIALIZED();
00461 
00462         for (int i=0; i<m_DOF; i++)
00463         {
00464                 m_CurrentAngularMaxAccel[i] = radPerSecSquared;
00465         }
00466 
00467     return true;
00468 }
00469 bool PowerCubeSim::setMaxAcceleration(const std::vector<double>& radPerSecSquared)
00470 {
00471     PCTRL_CHECK_INITIALIZED();
00472 
00473         for (int i=0; i<m_DOF; i++)
00474         {
00475                 m_CurrentAngularMaxAccel[i] = radPerSecSquared[i];
00476         }
00477 
00478     return true;
00479 }
00480 
00481 
00482 
00484 bool PowerCubeSim::statusMoving()
00485 {
00486         PCTRL_CHECK_INITIALIZED();
00487         bool isMoving = false;
00488 
00489         
00490         pthread_mutex_lock(&m_Movement_Mutex);
00491         
00492         for (int i = 0; i < m_DOF; i++)
00493         {
00494                 if (m_MovementInProgress[i])
00495                 {
00496                         isMoving = true;
00497                         break;
00498                 }
00499         }
00500 
00501         
00502         
00503         pthread_mutex_unlock(&m_Movement_Mutex);
00504         
00505 
00506         return isMoving;
00507 }
00508 
00509 bool PowerCubeSim::statusMoving(int cubeNo)
00510 {
00511         PCTRL_CHECK_INITIALIZED();
00512         bool isMoving = false;
00513 
00514         
00515         pthread_mutex_lock(&m_Movement_Mutex);
00516         
00517         if (m_MovementInProgress[cubeNo])
00518         {
00519                 isMoving = true;
00520         }
00521 
00522         
00523         
00524         pthread_mutex_unlock(&m_Movement_Mutex);
00525         
00526 
00527         return isMoving;
00528 }
00529                 
00530 void PowerCubeSim::setStatusMoving (int cubeNo, bool moving)
00531 {
00532         
00533         pthread_mutex_lock(&m_Movement_Mutex);
00534         
00535 
00536         m_MovementInProgress[cubeNo] = moving;
00537 
00538         
00539         pthread_mutex_unlock(&m_Movement_Mutex);
00540         
00541 
00542 }
00543 
00545 bool PowerCubeSim::statusDec()
00546 {
00547         PCTRL_CHECK_INITIALIZED();
00548         
00549 
00550 
00551 
00552 
00553 
00554 
00555 
00556 
00557         return false;
00558 }
00559 
00560 
00562 bool PowerCubeSim::statusAcc()
00563 {
00564         PCTRL_CHECK_INITIALIZED();
00565         
00566 
00567 
00568 
00569 
00570 
00571 
00572 
00573 
00574 
00575         return false;
00576 }
00577 
00578 void  * SimThreadRoutine(void* threadArgs)
00579 {
00580         
00581         SimThreadArgs * args =  (SimThreadArgs*)threadArgs;
00582         PowerCubeSim* cubeSimPtr = args->cubeSimPtr;
00583         int cubeNo = args->cubeID;
00584         double targetAngle = args->targetAngle;
00585 
00586         
00587         
00588         
00589         float t1,t2,t,tges; 
00590         double deltaT = SIM_CLOCK_FREQUENCY/1000; 
00591         t1=t2=t=tges=0;
00592         float maxVel = (cubeSimPtr->getCurrentAngularMaxVel())[cubeNo];
00593         float maxAccel = (cubeSimPtr->getCurrentAngularMaxAccel())[cubeNo];
00594         std::vector<double> currAngles;
00595         cubeSimPtr->getConfig(currAngles);
00596         std::vector<double> currVels;
00597         cubeSimPtr->getJointVelocities(currVels);
00598 
00599         double deltaAngle = targetAngle - currAngles[cubeNo];
00600         
00601         
00602         t1 = maxVel/maxAccel;
00603 
00604         
00605         t2 = abs(deltaAngle)/maxVel - t1;
00606 
00607         
00608         
00609         
00610         if (abs(deltaAngle) > maxVel*maxVel/maxAccel)
00611         {
00612                 tges=2*t1+t2;
00613         }
00614         else
00615         {
00616 
00617                 
00618                 t = sqrt(abs(deltaAngle)/(maxAccel));
00619                 
00620                 
00621                 tges = 2*t;
00622         }
00623 
00624         
00625         if (deltaAngle<0)
00626         {
00627                 maxAccel = -maxAccel;
00628                 maxVel = -maxVel;
00629         }
00630         std::cout << "maxVel: "<<maxVel<<"; maxAccel: "<<maxAccel<< "; t1 [ms]: "<<t1<<"; t2 [ms]: "<<t2 <<"; deltaAngle[rad]" <<deltaAngle<<endl;
00631 
00632         
00633         
00634         double simulatedTime = 0.0; 
00635         int n = 0;  
00636         float currDeltaAngle = deltaAngle;
00637 
00638         if (abs(deltaAngle) > 0.001)
00639         {
00640                 while ((simulatedTime <= tges) && cubeSimPtr->getStatusMoving(cubeNo) )
00641                 
00642                 {
00643                         
00644                         cubeSimPtr->millisleep((int)SIM_CLOCK_FREQUENCY);
00645                         simulatedTime += SIM_CLOCK_FREQUENCY/1000; 
00646                         n++;
00647                         cubeSimPtr->getJointVelocities(currVels);
00648                         
00649                         double deltaPhi = 0.0;
00650 
00651                         
00652                         if (abs(deltaAngle) > maxVel*maxVel/abs(maxAccel))
00653                         {
00654                                 if (simulatedTime < t1)
00655                                 {
00656                                         deltaPhi = 0.5*maxAccel*(n*deltaT*n*deltaT - (n-1)*deltaT*(n-1)*deltaT);
00657                                         currVels[cubeNo] = maxAccel * n*deltaT;
00658                                         std::cout << "Phase 1, maxVel ->";
00659 
00660                                 }
00661                                 else if ((t1 < simulatedTime) && (simulatedTime < t1+t2))
00662                                 {
00663                                         deltaPhi = maxVel * deltaT;
00664                                         currVels[cubeNo] = maxVel;
00665                                         std::cout << "Phase 2, maxVel ->";
00666                                 }
00667                                 else if ((simulatedTime > t1+t2) && (simulatedTime < 2*t1+t2))
00668                                 {
00669                                         
00670                                         deltaPhi = maxVel*deltaT - 0.5*maxAccel*((n*deltaT-(t1+t2))*(n*deltaT-(t1+t2))-((n-1)*deltaT-(t1+t2))*((n-1)*deltaT-(t1+t2)));
00671                                         currVels[cubeNo] = maxVel - maxAccel * (simulatedTime -(t1+t2));
00672                                         std::cout << "Phase 3, maxVel ->";
00673                                 }
00674                                 else
00675                                 {
00676                                         deltaPhi = 0.0;
00677                                         currVels[cubeNo] = 0.0;
00678                                         std::cout << "Phase 4, maxVel ->";
00679                                 }
00680                         }
00681                         
00682                         else
00683                         {
00684                                 if (simulatedTime < t)
00685                                 {
00686                                         
00687                                         deltaPhi = 0.5*maxAccel*(n*deltaT*n*deltaT - (n-1)*deltaT*(n-1)*deltaT);
00688                                         currVels[cubeNo] = maxAccel * simulatedTime;
00689                                         std::cout  << "Phase 1 ->";
00690                                 }
00691                                 else if ((simulatedTime > t) && (simulatedTime <= 2*t))
00692                                 {
00693                                         
00694                                         deltaPhi = maxAccel*t*deltaT - 0.5*maxAccel*((n*deltaT-t)*(n*deltaT-t)-((n-1)*deltaT-t)*((n-1)*deltaT-t));
00695                                         currVels[cubeNo] = maxAccel*t - maxAccel * (simulatedTime -t);
00696                                         std::cout  << "Phase 2 ->";
00697                                 }
00698                                 else
00699                                 {
00700                                         deltaPhi = 0.0;
00701                                         currVels[cubeNo] = 0.0;
00702                                         std::cout  << "Phase 3 ->" << t << "\n";
00703                                 }
00704 
00705                         }
00706                         cubeSimPtr->getConfig(currAngles);
00707 
00708                         currAngles[cubeNo] = currAngles[cubeNo]+deltaPhi;
00709                         currDeltaAngle = targetAngle - currAngles[cubeNo];
00710                         
00711 
00712                         
00713                         cubeSimPtr->setCurrentAngles(currAngles);
00714                         cubeSimPtr->setCurrentJointVelocities(currVels);
00715                 }
00716         }
00717 
00718         
00719         cubeSimPtr->setStatusMoving(cubeNo,false);
00720         currVels[cubeNo] = 0.0;
00721         cubeSimPtr->setCurrentJointVelocities(currVels);
00722 
00723         
00724         pthread_exit(NULL);
00725 }
00726 
00727 
00728 int PowerCubeSim::startSimulatedMovement(std::vector<double> target)
00729 {
00730 
00731         if (statusMoving())
00732         {
00733                 std::cout << "startSimulatedMovement: Movement already in progress, preemption not implemented yet! Aborting .."<<endl;
00734         }
00735         else
00736         {
00737                 
00738 
00739                 for (int i = 0; i < m_DOF; i++)
00740                 {
00741                         setStatusMoving(i,true);
00742                         m_SimThreadArgs[i]->targetAngle = target[i];
00743                         pthread_create(&m_SimThreadID[i],NULL,SimThreadRoutine,(void*)m_SimThreadArgs[i]);
00744                 }
00745         }
00746         return 0;
00747 
00748 }
00749 void PowerCubeSim::millisleep(unsigned int milliseconds) const
00750 {
00751         timespec warten;
00752         
00753         warten.tv_sec = milliseconds / 1000;
00754         warten.tv_nsec = (milliseconds % 1000) * 1000000;
00755         timespec gewartet;
00756         nanosleep(&warten, &gewartet);
00757 }
00758 
00759 
00762 
00763 
00764 
00765 
00766 
00767 
00768 
00769 
00770 
00771 
00772 
00773 
00774 
00775 
00776 
00777 
00778 
00779 
00780 
00781 
00782 
00783 
00784 
00785 
00786 
00787 
00788 
00789 
00790 
00791 
00792 
00793 
00794 
00795 
00796 
00797 
00798 
00799 
00800 
00801 
00802 
00803 
00804 
00805 
00806 
00807 
00808 
00809 
00810 
00811 
00812 
00813 
00814 
00815 
00816 
00817 
00818 
00819 
00820 
00821 
00822 
00823 
00824 
00825 
00826 
00827 
00828 
00829 
00830 
00831 
00832 
00833 
00834 
00835 
00836 
00837 
00838 
00839 
00840 
00841 
00842 
00843 
00844 
00845 
00846 
00847 
00848 
00849 
00850 
00851 
00852 
00853 
00854 
00855 
00856 
00857 
00858 
00859 
00860