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