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
00026
00027
00028
00029 #include "stdafx.h"
00030 #include "Playback.h"
00031 #include "math.h"
00032 #include "time.h"
00033 #include "stdlib.h"
00034 #include "stdio.h"
00035
00036
00037
00038
00039 Playback::Playback()
00040 {
00041 beadSpeed = BEAD_SPEED;
00042 head = 0;
00043 cur = 0;
00044 end = 0;
00045
00046 headToPt = 0;
00047 curToPt = 0;
00048 endToPt = 0;
00049
00050 mode = PID_IDLE;
00051
00052 playAtSampleRate = PLAY_AT_SAMPLE_RATE;
00053 absolutePositioning = ABSOLUTE_POSITIONING;
00054 err_thresh = ERROR_THRESHOLD;
00055
00056
00057 }
00058
00059 Playback::~Playback()
00060 {
00061 SetIdle();
00062 ClearPath();
00063
00064 }
00065
00066 void Playback::CreateControllers(double p, double i, double d, double f, double out_filter,
00067 double gain, double sat_low, double sat_high, double dead_zone)
00068 {
00069
00070 control_x = init_state(p, i, d, f, out_filter, gain, dead_zone, sat_low, sat_high);
00071 control_y = init_state(p, i, d, f, out_filter, gain, dead_zone,sat_low, sat_high);
00072 control_z = init_state(p, i, d, f, out_filter, gain, dead_zone,sat_low, sat_high);
00073
00074 head = 0;
00075 cur = 0;
00076 end = 0;
00077
00078 mode = PID_IDLE;
00079 }
00080
00081 void Playback::SetIntegratorForceCap(double maxforce)
00082 {
00083 double wind_up_max = 1/control_x->gain * 1/control_x->cn_i * maxforce;
00084 set_integrator_cap(control_x, wind_up_max);
00085 set_integrator_cap(control_y, wind_up_max);
00086 set_integrator_cap(control_z, wind_up_max);
00087 }
00088
00089 void Playback::ResetControllerState(){
00090 reset_state(control_x);
00091 reset_state(control_y);
00092 reset_state(control_z);
00093 }
00094
00095 void Playback::CreateControllersForOmni(){
00096
00097
00098 double p = 0.3;
00099 double i = 0.0005;
00100 double d = 20.0;
00101 double f = 0.09;
00102 double out_filter = 0.09;
00103 double gain = 0.2;
00104 double sat_low = -3.0;
00105 double sat_high = 3.0;
00106 double dead_zone = 0.0;
00107
00108 double wind_up_max = 1/gain * 1/i * sat_high;
00109
00110
00111
00112 control_x = init_state(p, i, d, f, out_filter, gain, dead_zone, sat_low, sat_high);
00113 control_y = init_state(p, i, d, f, out_filter, gain, dead_zone,sat_low, sat_high);
00114 control_z = init_state(p, i, d, f, out_filter, gain, dead_zone,sat_low, sat_high);
00115 set_integrator_cap(control_x, wind_up_max);
00116 set_integrator_cap(control_y, wind_up_max);
00117 set_integrator_cap(control_z, wind_up_max);
00118
00119
00120 }
00121
00122 void Playback::CreatePDControllersForOmni(){
00123
00124
00125 double p = 0.3;
00126 double i = 0.0;
00127 double d = 20.0;
00128 double f = 0.09;
00129 double out_filter = 0.09;
00130 double gain = 0.2;
00131 double sat_low = -3.0;
00132 double sat_high = 3.0;
00133 double dead_zone = 0.0;
00134
00135 control_x = init_state(p, i, d, f, out_filter, gain, dead_zone, sat_low, sat_high);
00136 control_y = init_state(p, i, d, f, out_filter, gain, dead_zone,sat_low, sat_high);
00137 control_z = init_state(p, i, d, f, out_filter, gain, dead_zone,sat_low, sat_high);
00138
00139
00140
00141 }
00142
00143 void Playback::stickToPointAndGetForce(Vec3f pos, Vec3f dest, Vec3f &force)
00144 {
00145 double ps[3] = {pos.x, pos.y, pos.z};
00146 double ds[3] = {dest.x, dest.y, dest.z};
00147 double fs[3] = {0, 0, 0};
00148
00149 MoveToPoint(ps, ds, PID_PLAY);
00150 GetForce(ps, fs);
00151 force.x = fs[0]*_PLAY_MICOLE_RATE;
00152 force.y = fs[1]*_PLAY_MICOLE_RATE;
00153 force.z = fs[2]*_PLAY_MICOLE_RATE;
00154 }
00155
00156 void Playback::CreateControllersForPremium15(){
00157
00158
00159 double p = 0.3;
00160 double i = 0.00005;
00161 double d = 30.0;
00162 double f = 0.09;
00163 double out_filter = 0.09;
00164 double gain = 0.20;
00165 double sat_low = -1.5;
00166 double sat_high = 1.5;
00167 double dead_zone = 0.0;
00168
00169 double wind_up_max = 1/gain * 1/i * sat_high;
00170
00171 control_x = init_state(p, i, d, f, out_filter, gain, dead_zone, sat_low, sat_high);
00172 control_y = init_state(p, i, d, f, out_filter, gain, dead_zone,sat_low, sat_high);
00173 control_z = init_state(p, i, d, f, out_filter, gain, dead_zone,sat_low, sat_high);
00174
00175 set_integrator_cap(control_x, wind_up_max);
00176 set_integrator_cap(control_y, wind_up_max);
00177 set_integrator_cap(control_z, wind_up_max);
00178
00179
00180 }
00181
00182 void Playback::SetPlaybackSpeed(double v){
00183 beadSpeed = v;
00184 }
00185
00186 void Playback::StartPlayback(PtsList *pt, double curPos[3]){
00187
00188
00189 if(pt == 0)
00190 return;
00191
00192 startTime = ((double)clock()/(double)CLOCKS_PER_SEC);
00193
00194 ClearPath();
00195
00196 head = pt;
00197 cur = head;
00198
00199
00200 PtsList *tmp = pt;
00201 while(tmp->next != 0)
00202 tmp = tmp->next;
00203
00204
00205 end = tmp;
00206
00207 if(!absolutePositioning)
00208 mode = PID_PLAY;
00209 else{
00210 double pt[3];
00211 pt[0] = head->xPos; pt[1] = head->yPos; pt[2] = head->zPos;
00212
00213 MoveToPoint(curPos, pt, PID_PLAY);
00214 }
00215
00216 prevTime = 0;
00217
00218 startPos[0] = curPos[0];
00219 startPos[1] = curPos[1];
00220 startPos[2] = curPos[2];
00221
00222 if(cur != 0){
00223 beadPos[0] = cur->xPos;
00224 beadPos[1] = cur->yPos;
00225 beadPos[2] = cur->zPos;
00226 }
00227
00228
00229
00230 }
00231
00232 void Playback::StartPlayback(double curPos[3]){
00233
00234 if(head == 0)
00235 return;
00236
00237 startTime = ((double)clock()/(double)CLOCKS_PER_SEC);
00238 prevTime = 0;
00239 cur = head;
00240
00241
00242 if(!absolutePositioning)
00243 mode = PID_PLAY;
00244 else{
00245 double pt[3];
00246 pt[0] = head->xPos; pt[1] = head->yPos; pt[2] = head->zPos;
00247
00248 MoveToPoint(curPos, pt, PID_PLAY);
00249 }
00250
00251
00252
00253 startPos[0] = curPos[0];
00254 startPos[1] = curPos[1];
00255 startPos[2] = curPos[2];
00256
00257 if(cur != 0){
00258 beadPos[0] = cur->xPos;
00259 beadPos[1] = cur->yPos;
00260 beadPos[2] = cur->zPos;
00261 }
00262 }
00263
00264 bool Playback::GetForce(double pt[3], double force[3]){
00265
00266 force[0] = 0;
00267 force[1] = 0;
00268 force[2] = 0;
00269
00270 if(mode == PID_IDLE || mode == PID_PAUSE)
00271 return true;
00272
00273 if(mode == PID_CONSTRAIN){
00274 bool continueConstrain = DoConstrain(pt, force);
00275
00276 if(!continueConstrain)
00277 mode = PID_IDLE;
00278
00279 return continueConstrain;
00280 }
00281
00282 double theTime = ((double)clock()/(double)CLOCKS_PER_SEC) - startTime;
00283 double distToTravel;
00284
00285 double dt = theTime - prevTime;
00286 if(dt < 0.001)
00287 dt = 0.001;
00288
00289 prevTime = theTime;
00290
00291 force[0] = 0; force[1] = 0; force[2] = 0;
00292
00293 double magBeadToNext;
00294
00295 if(mode == PID_STICK_TO_POINT || mode == PID_MOVE_TO_STICK_POINT
00296 || mode == PID_MOVE_TO_PLAY_POINT || mode == PID_MOVE_TO_CONSTRAIN_POINT){
00297
00298
00299 if(curToPt == 0){
00300
00301 force[0] += control(control_x, pt[0], endToPt->xPos) ;
00302 force[1] += control(control_y, pt[1], endToPt->yPos) ;
00303 force[2] += control(control_z, pt[2], endToPt->zPos) ;
00304
00305
00306 FILE *fp;
00307 fopen_s(&fp, "d.txt", "a");
00308 fprintf(fp, "%f, %f, %f, %f, %f, %f, %f, %f\n", control_x->p, control_x->i, control_x->d,
00309 control_x->x, control_x->target_x, force[0], force[1], force[2]);
00310 fclose(fp);
00311
00312
00313
00314
00315 if(mode == PID_MOVE_TO_STICK_POINT)
00316 mode = PID_STICK_TO_POINT;
00317
00318 if(mode == PID_MOVE_TO_PLAY_POINT)
00319 mode = PID_PLAY;
00320
00321 if(mode == PID_MOVE_TO_CONSTRAIN_POINT)
00322 mode = PID_CONSTRAIN;
00323
00324 return true;
00325 }
00326
00327 if(curToPt->next == 0){
00328
00329 force[0] += control(control_x, pt[0], endToPt->xPos);
00330 force[1] += control(control_y, pt[1], endToPt->yPos);
00331 force[2] += control(control_z, pt[2], endToPt->zPos);
00332
00333
00335
00336 if(mode == PID_MOVE_TO_STICK_POINT)
00337 mode = PID_STICK_TO_POINT;
00338
00339 if(mode == PID_MOVE_TO_PLAY_POINT)
00340 mode = PID_PLAY;
00341
00342 if(mode == PID_MOVE_TO_CONSTRAIN_POINT)
00343 mode = PID_CONSTRAIN;
00344
00345 return true;
00346 }
00347
00348
00349 if(!(abs(control_x->p)>err_thresh
00350 || abs(control_y->p)>err_thresh
00351 || abs(control_z->p)>err_thresh)) {
00352
00353
00354
00355
00356
00357 double stickBeadToNext[3];
00358 stickBeadToNext[0] = curToPt->next->xPos - stickBeadPos[0];
00359 stickBeadToNext[1] = curToPt->next->yPos - stickBeadPos[1];
00360 stickBeadToNext[2] = curToPt->next->zPos - stickBeadPos[2];
00361
00362 magBeadToNext = sqrt(pow(stickBeadToNext[0], 2.0) +
00363 pow(stickBeadToNext[1], 2.0) + pow(stickBeadToNext[2], 2.0));
00364
00365 distToTravel = beadSpeed * dt;
00366
00367 if(magBeadToNext < distToTravel){
00368
00369 curToPt = curToPt->next;
00370
00371 stickBeadPos[0] = endToPt->xPos;
00372 stickBeadPos[1] = endToPt->yPos;
00373 stickBeadPos[2] = endToPt->zPos;
00374
00375
00376 distToTravel = 0;
00377
00378 }
00379 else if(magBeadToNext > 0){
00380 stickBeadPos[0] += distToTravel * (stickBeadToNext[0]/magBeadToNext);
00381 stickBeadPos[1] += distToTravel * (stickBeadToNext[1]/magBeadToNext);
00382 stickBeadPos[2] += distToTravel * (stickBeadToNext[2]/magBeadToNext);
00383 }
00384 }
00385
00386 force[0] += control(control_x, pt[0], stickBeadPos[0]) ;
00387 force[1] += control(control_y, pt[1], stickBeadPos[1]) ;
00388 force[2] += control(control_z, pt[2], stickBeadPos[2]) ;
00389
00390
00391
00392
00393 return true;
00394 }
00395
00396
00397
00398 if(cur == 0){
00399 mode = PID_IDLE;
00400
00401 return false;
00402 }
00403
00404 if(cur->next == 0){
00405 mode = PID_IDLE;
00406
00407 return false;
00408 }
00409
00410
00411 if(playAtSampleRate){
00412 beadPos[0] = cur->xPos;
00413 beadPos[1] = cur->yPos;
00414 beadPos[2] = cur->zPos;
00415
00416 cur = cur->next;
00417
00418 }
00419 else if(!(abs(control_x->p)>err_thresh
00420 || abs(control_y->p)>err_thresh
00421 || abs(control_z->p)>err_thresh)) {
00422
00423
00424
00425
00426
00427 double beadToNext[3];
00428 beadToNext[0] = cur->next->xPos - beadPos[0];
00429 beadToNext[1] = cur->next->yPos - beadPos[1];
00430 beadToNext[2] = cur->next->zPos - beadPos[2];
00431
00432 double magBeadToNext = sqrt(pow(beadToNext[0], 2.0) +
00433 pow(beadToNext[1], 2.0) + pow(beadToNext[2], 2.0));
00434
00435 double distToTravel = beadSpeed * dt;
00436
00437 while(cur->next != 0 && magBeadToNext < distToTravel){
00438
00439 cur = cur->next;
00440
00441 beadPos[0] = cur->xPos;
00442 beadPos[1] = cur->yPos;
00443 beadPos[2] = cur->zPos;
00444
00445 distToTravel -= magBeadToNext;
00446
00447 if(cur->next == 0){
00448 distToTravel = 0;
00449 break;
00450 }
00451
00452
00453 beadToNext[0] = cur->next->xPos - beadPos[0];
00454 beadToNext[1] = cur->next->yPos - beadPos[1];
00455 beadToNext[2] = cur->next->zPos - beadPos[2];
00456
00457 magBeadToNext = sqrt(pow(beadToNext[0], 2.0) +
00458 pow(beadToNext[1], 2.0) + pow(beadToNext[2], 2.0));
00459
00460 }
00461
00462 if(cur->next == 0){
00463 mode = PID_IDLE;
00464
00465 return false;
00466 }
00467
00468 beadPos[0] += distToTravel * (beadToNext[0]/magBeadToNext);
00469 beadPos[1] += distToTravel * (beadToNext[1]/magBeadToNext);
00470 beadPos[2] += distToTravel * (beadToNext[2]/magBeadToNext);
00471
00472 }
00473 else
00474 {
00475
00476 }
00477
00478
00479 if(absolutePositioning){
00480 force[0] += control(control_x, pt[0], beadPos[0]) ;
00481 force[1] += control(control_y, pt[1], beadPos[1]) ;
00482 force[2] += control(control_z, pt[2], beadPos[2]) ;
00483 }
00484 else{
00485 force[0] += control(control_x, pt[0]-startPos[0], beadPos[0]-head->xPos) ;
00486 force[1] += control(control_y, pt[1]-startPos[1], beadPos[1]-head->yPos) ;
00487 force[2] += control(control_z, pt[2]-startPos[2], beadPos[2]-head->zPos) ;
00488 }
00489 return true;
00490 }
00491
00492 void Playback::ClearPath(){
00493
00494
00495 PtsList *pt = head, *next_pt;
00496
00497 while(pt != 0){
00498 next_pt = pt->next;
00499
00500 free(pt);
00501 pt = next_pt;
00502 }
00503
00504 head = 0; end = 0;
00505 cur = 0;
00506 }
00507
00508 bool Playback::LoadGestureFile(char *fName){
00509
00510 FILE *fp;
00511 fopen_s(&fp, fName, "r");
00512
00513 if(!fp)
00514 return false;
00515
00516 int ret;
00517 float t, x, y, z;
00518 double pt[3];
00519
00520 ClearPath();
00521 do{
00522 ret = fscanf_s(fp, "%f, %f, %f, %f\n", &t, &x, &y, &z);
00523 pt[0] = x; pt[1] = y; pt[2] = z;
00524 AddWaypoint(pt);
00525 }
00526 while(ret != EOF && ret == 4);
00527
00528 fclose(fp);
00529
00530 return true;
00531 }
00532
00533 bool Playback::SaveGestureFile(char *fName)
00534 {
00535 FILE *fp;
00536 fopen_s(&fp, fName, "w");
00537
00538 if(!fp)
00539 return false;
00540
00541 PtsList *tmp = head;
00542 while(tmp != 0){
00543 fprintf(fp, "0.0, %f, %f, %f\n", tmp->xPos, tmp->yPos, tmp->zPos);
00544 tmp = tmp->next;
00545 }
00546
00547 fclose(fp);
00548
00549 return true;
00550 }
00551
00552 void Playback::AddWaypoint(double pt[3]){
00553
00554
00555 PtsList *tmp = new PtsList;
00556 tmp->xPos = pt[0];
00557 tmp->yPos = pt[1];
00558 tmp->zPos = pt[2];
00559
00560 tmp->next = 0;
00561
00562 if(head == 0){
00563 head = tmp;
00564 end = tmp;
00565 tmp->prev = 0;
00566 }
00567 else{
00568 end->next = tmp;
00569 tmp->prev = end;
00570 end = tmp;
00571 }
00572 }
00573
00574
00575 void Playback::MoveToStartOfGesture(){
00576 cur = head;
00577 }
00578
00579 void Playback::SetIdle(){
00580
00581 mode = PID_IDLE;
00582 cur = head;
00583
00584
00585 }
00586
00587 void Playback::TogglePauseGesture(){
00588
00589 if(mode == PID_PLAY)
00590 mode = PID_PAUSE;
00591 else if(mode == PID_PAUSE)
00592 mode = PID_PLAY;
00593
00594 }
00595
00596
00597 Mode Playback::GetMode(){
00598 return mode;
00599 }
00600
00601 void Playback::CreateGestureToPoint(double curPos[3], double thePoint[3]){
00602
00603 FreeGestureToPoint();
00604
00605 PtsList *tmp;
00606 tmp = (PtsList *) malloc(sizeof(PtsList));
00607 tmp->xPos = curPos[0];
00608 tmp->yPos = curPos[1];
00609 tmp->zPos = curPos[2];
00610 tmp->next = 0;
00611 tmp->prev = 0;
00612
00613 headToPt = tmp;
00614 endToPt = tmp;
00615
00616 tmp = (PtsList *) malloc(sizeof(PtsList));
00617 tmp->xPos = thePoint[0];
00618 tmp->yPos = thePoint[1];
00619 tmp->zPos = thePoint[2];
00620 tmp->next = 0;
00621 tmp->prev = endToPt;
00622
00623 endToPt->next = tmp;
00624 endToPt = tmp;
00625
00626 tmp = (PtsList *) malloc(sizeof(PtsList));
00627 tmp->xPos = thePoint[0];
00628 tmp->yPos = thePoint[1];
00629 tmp->zPos = thePoint[2];
00630 tmp->next = 0;
00631 tmp->prev = endToPt;
00632
00633 endToPt->next = tmp;
00634 endToPt = tmp;
00635
00636 curToPt = headToPt;
00637
00638 stickBeadPos[0] = curToPt->xPos;
00639 stickBeadPos[1] = curToPt->yPos;
00640 stickBeadPos[2] = curToPt->zPos;
00641
00642
00643
00644
00645
00646 }
00647
00648
00649 void Playback::FreeGestureToPoint(){
00650
00651 PtsList *pt = headToPt, *next_pt;
00652
00653 while(pt != 0){
00654 next_pt = pt->next;
00655
00656 free(pt);
00657 pt = next_pt;
00658 }
00659
00660 headToPt = 0; endToPt = 0;
00661 curToPt = 0;
00662
00663 }
00664
00665 void Playback::StickToThisPoint(double curPos[3]){
00666 FreeGestureToPoint();
00667
00668 startTime = ((double)clock()/(double)CLOCKS_PER_SEC);
00669 prevTime = 0;
00670
00671 PtsList *tmp = (PtsList *) malloc(sizeof(PtsList));
00672 tmp->xPos = curPos[0];
00673 tmp->yPos = curPos[1];
00674 tmp->zPos = curPos[2];
00675 tmp->next = 0;
00676 tmp->prev = 0;
00677
00678 endToPt = tmp;
00679 curToPt = 0;
00680
00681 mode = PID_STICK_TO_POINT;
00682
00683 ResetControllerState();
00684 }
00685
00686 void Playback::StickToPoint(double curPos[3], double pt[3]){
00687 FreeGestureToPoint();
00688 CreateGestureToPoint(curPos, pt);
00689 startTime = ((double)clock()/(double)CLOCKS_PER_SEC);
00690 prevTime = 0;
00691
00692 mode = PID_MOVE_TO_STICK_POINT;
00693
00694 ResetControllerState();
00695 }
00696
00697 void Playback::MoveToPoint(double curPos[3], double pt[3], Mode m){
00698
00699 CreateGestureToPoint(curPos, pt);
00700
00701 startTime = ((double)clock()/(double)CLOCKS_PER_SEC);
00702 prevTime = 0;
00703
00704 if(m == PID_PLAY)
00705 mode = PID_MOVE_TO_PLAY_POINT;
00706 else if(mode == PID_CONSTRAIN)
00707 mode = PID_MOVE_TO_CONSTRAIN_POINT;
00708
00709
00710 }
00711
00712 void Playback::SetPlayAtSampleRate(bool pasr){
00713 playAtSampleRate = pasr;
00714 }
00715
00716 bool Playback::GetPlayAtSampleRate(){
00717 return playAtSampleRate;
00718 }
00719
00720 void Playback::UseAbsolutePositioning(bool absPos){
00721 absolutePositioning = absPos;
00722 }
00723
00724 bool Playback::GetPlaybackPos(double pPos[3]){
00725 if(mode == PID_IDLE)
00726 return false;
00727
00728 if(mode == PID_PLAY || mode == PID_PAUSE){
00729 pPos[0] = beadPos[0];
00730 pPos[1] = beadPos[1];
00731 pPos[2] = beadPos[2];
00732 }
00733 else if(mode == PID_STICK_TO_POINT){
00734 pPos[0] = stickPoint[0];
00735 pPos[1] = stickPoint[1];
00736 pPos[2] = stickPoint[2];
00737 }
00738 else if(mode == PID_MOVE_TO_PLAY_POINT || mode == PID_MOVE_TO_CONSTRAIN_POINT
00739 || mode == PID_MOVE_TO_STICK_POINT){
00740 pPos[0] = stickBeadPos[0];
00741 pPos[1] = stickBeadPos[1];
00742 pPos[2] = stickBeadPos[2];
00743 }
00744
00745 return true;
00746 }
00747
00748
00749 double Playback::GetErrorThreshold(){
00750 return err_thresh;
00751 }
00752
00753 void Playback::SetErrorThreshold(double e){
00754 err_thresh = e;
00755 }
00756
00757
00758
00759
00760
00761
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
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874 bool Playback::DoConstrain(double pPos[3], double force[3]){
00875
00876 force[0] = 0;
00877 force[1] = 0;
00878 force[2] = 0;
00879
00880 if(cur == 0)
00881 return false;
00882
00883 if(cur->prev == 0){
00884 beadPos[0] = cur->xPos;
00885 beadPos[1] = cur->yPos;
00886 beadPos[2] = cur->zPos;
00887
00888 cur = cur->next;
00889
00890 }
00891 else{
00892
00893 double prevToCur[3], prevToPhntm[3], magPrevToCur, magPrevToPhntm;
00894
00895 prevToCur[0] = cur->xPos - cur->prev->xPos;
00896 prevToCur[1] = cur->yPos - cur->prev->yPos;
00897 prevToCur[2] = cur->zPos - cur->prev->zPos;
00898
00899 magPrevToCur = sqrt(pow(prevToCur[0], 2.0) + pow(prevToCur[1], 2.0) +
00900 pow(prevToCur[2], 2.0));
00901
00902 prevToPhntm[0] = (pPos[0]) - cur->prev->xPos;
00903 prevToPhntm[1] = (pPos[1]) - cur->prev->yPos;
00904 prevToPhntm[2] = (pPos[2]) - cur->prev->zPos;
00905
00906 magPrevToPhntm = sqrt(pow(prevToPhntm[0], 2.0) + pow(prevToPhntm[1], 2.0) +
00907 pow(prevToPhntm[2], 2.0));
00908
00909 a = 0;
00910
00911 if(magPrevToCur != 0 && magPrevToPhntm != 0){
00912 a = acos(((prevToCur[0] * prevToPhntm[0]) + (prevToCur[1] * prevToPhntm[1])+
00913 (prevToCur[2] * prevToPhntm[2]))/(magPrevToCur * magPrevToPhntm));
00914 }
00915
00916 distFromPrev = cos(a) * magPrevToPhntm;
00917 double distToTravel = distFromPrev;
00918 bool done = false;
00919
00920 while(cur != 0 && !done){
00921
00922 if(distToTravel > magPrevToCur){
00923 distToTravel -= magPrevToCur;
00924
00925 cur = cur->next;
00926 if(cur == 0)
00927 return false;
00928
00929 curConstrainDist = 0;
00930
00931 prevToCur[0] = cur->xPos - cur->prev->xPos;
00932 prevToCur[1] = cur->yPos - cur->prev->yPos;
00933 prevToCur[2] = cur->zPos - cur->prev->zPos;
00934
00935 magPrevToCur = sqrt(pow(prevToCur[0], 2.0) + pow(prevToCur[1], 2.0) +
00936 pow(prevToCur[2], 2.0));
00937 }
00938 else{
00939 done = true;
00940 }
00941
00942 if(distToTravel > curConstrainDist)
00943 curConstrainDist = distToTravel;
00944 }
00945
00946 if(cur == 0)
00947 return false;
00948
00949 beadPos[0] = cur->prev->xPos + (prevToCur[0]/magPrevToCur) * curConstrainDist;
00950 beadPos[1] = cur->prev->yPos + (prevToCur[1]/magPrevToCur) * curConstrainDist;
00951 beadPos[2] = cur->prev->zPos + (prevToCur[2]/magPrevToCur) * curConstrainDist;
00952 }
00953
00954
00955 force[0] = control(control_x, pPos[0], beadPos[0]);
00956 force[1] = control(control_y, pPos[1], beadPos[1]);
00957 force[2] = control(control_z, pPos[2], beadPos[2]);
00958
00959 return true;
00960 }
00961
00962
00963 void Playback::StartConstrain(double curPos[3]){
00964
00965 if(head == 0)
00966 return;
00967
00968 startTime = ((double)clock()/(double)CLOCKS_PER_SEC);
00969 prevTime = 0;
00970 cur = head->next;
00971
00972
00973 if(!absolutePositioning)
00974 mode = PID_CONSTRAIN;
00975 else{
00976 double pt[3];
00977 pt[0] = head->xPos; pt[1] = head->yPos; pt[2] = head->zPos;
00978
00979 MoveToPoint(curPos, pt, PID_CONSTRAIN);
00980 }
00981
00982 startPos[0] = curPos[0];
00983 startPos[1] = curPos[1];
00984 startPos[2] = curPos[2];
00985
00986 if(cur != 0){
00987 beadPos[0] = cur->prev->xPos;
00988 beadPos[1] = cur->prev->yPos;
00989 beadPos[2] = cur->prev->zPos;
00990 }
00991
00992 curConstrainDist = 0;
00993 }
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015