Playback.cpp

Go to the documentation of this file.
00001 /* 
00002 
00003      The contents of this file are subject to the Mozilla Public License
00004          Version 1.1 (the "License"); you may not use this file except in
00005      compliance with the License. You may obtain a copy of the License at
00006      http://www.mozilla.org/MPL/
00007 
00008      Software distributed under the License is distributed on an "AS IS"
00009      basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
00010      License for the specific language governing rights and limitations
00011      under the License.
00012 
00013      The Original Code is the PID trajectory playback library.
00014 
00015      The Initial Developers of the Original Code are Andrew Crossan (ac@dcs.gla.ac.uk) 
00016          and John Williamson (jhw@dcs.gla.ac.uk) from University of Glasgow.
00017          
00018      Portions created by Andrew Crossan and John Williamson are Copyright (C) 2006.
00019      All Rights Reserved.
00020 
00021      Contributor(s): ______________________________________.
00022 
00023 */
00024 
00025 
00026 // Playback.cpp : Defines the initialization routines for the DLL.
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 // Playback construction
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         //debug_fp = fopen("debug.txt", "w");
00057 }
00058 
00059 Playback::~Playback()
00060 {
00061         SetIdle();
00062         ClearPath();
00063         //fclose(debug_fp);
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         /* Position controller */
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         /* Position controller */
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         //StickToPoint(ps, ds);
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         /* Position controller */
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 // start playback of the path referenced by pt
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         //find and store the end of the list
00200         PtsList *tmp = pt;
00201         while(tmp->next != 0)
00202                 tmp = tmp->next;
00203         
00204         // tmp is now the end of the list
00205         end = tmp;
00206         
00207         if(!absolutePositioning) // then just play the gesture from where we are
00208                 mode = PID_PLAY;
00209         else{                                   // else, move to the start point first
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         //ResetControllerState();
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) // then just play the gesture from where we are
00243                 mode = PID_PLAY;
00244         else{                                   // else, move to the start point first
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         //ResetControllerState();
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                         //then reached the stick point so hold there
00301                         force[0] += control(control_x, pt[0], endToPt->xPos) /*+ control(control_vx, vel[0], 0)*/; 
00302                         force[1] += control(control_y, pt[1], endToPt->yPos) /*+ control(control_vy, vel[1], 0)*/;
00303                         force[2] += control(control_z, pt[2], endToPt->zPos) /*+ control(control_vz, vel[2], 0)*/;
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                         //fprintf(debug_fp, "%f, %f, %f, %f, %f, %f, %f, 1\n", dt, pt[0], pt[1], pt[2], 
00313                         //      endToPt->xPos, endToPt->yPos, endToPt->zPos);
00314 
00315                         if(mode == PID_MOVE_TO_STICK_POINT) // if we were moving to the stick point, then we've reached it
00316                                 mode = PID_STICK_TO_POINT;
00317 
00318                         if(mode == PID_MOVE_TO_PLAY_POINT) // if we were moving to the start of a gesture, then play gesture
00319                                 mode = PID_PLAY;
00320 
00321                         if(mode == PID_MOVE_TO_CONSTRAIN_POINT) // if we were moving to the start of a gesture, then play gesture
00322                                 mode = PID_CONSTRAIN;
00323 
00324                         return true;
00325                 }
00326 
00327                 if(curToPt->next == 0){
00328                         //then reached the stick point so hold there
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                         //fprintf(debug_fp, "%f, %f, %f, %f, %f, %f, %f, 2\n", dt, pt[0], pt[1], pt[2], 
00335 
00336                         if(mode == PID_MOVE_TO_STICK_POINT) // if we were moving to the stick point, then we've reached it
00337                                 mode = PID_STICK_TO_POINT;
00338 
00339                         if(mode == PID_MOVE_TO_PLAY_POINT) // if we were moving to the start of a gesture, then play gesture
00340                                 mode = PID_PLAY;
00341 
00342                         if(mode == PID_MOVE_TO_CONSTRAIN_POINT) // if we were moving to the start of a gesture, then play gesture
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                         // work out distance to the next point
00354                         // check if it passes the current point
00355                         // then move the bead onwards
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]) /*+ control(control_vx, vel[0], 0)*/; 
00387                 force[1] += control(control_y, pt[1], stickBeadPos[1]) /*+ control(control_vy, vel[1], 0)*/;
00388                 force[2] += control(control_z, pt[2], stickBeadPos[2]) /*+ control(control_vz, vel[2], 0)*/;
00389 
00390                 //fprintf(debug_fp, "%f, %f, %f, %f, %f, %f, %f, 0\n", dt, pt[0], pt[1], pt[2], 
00391                 //      stickBeadPos[0], stickBeadPos[1], stickBeadPos[2]);
00392 
00393                 return true; // end stick to point
00394         }
00395         
00396         // if we reach here then the mode is play
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         // work out path of bead movement
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                 // work out distance to the next point
00424                 // check if it passes the current point
00425                 // then move the bead onwards
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         /* Do control */
00478         // Change the last zero to cur->xVel etc for vel. control as well
00479         if(absolutePositioning){
00480                 force[0] += control(control_x, pt[0], beadPos[0]) /*+ control(control_vx, vel[0], 0)*/; 
00481                 force[1] += control(control_y, pt[1], beadPos[1]) /*+ control(control_vy, vel[1], 0)*/;
00482                 force[2] += control(control_z, pt[2], beadPos[2]) /*+ control(control_vz, vel[2], 0)*/;
00483         }
00484         else{
00485                 force[0] += control(control_x, pt[0]-startPos[0], beadPos[0]-head->xPos) /*+ control(control_vx, vel[0], 0)*/; 
00486                 force[1] += control(control_y, pt[1]-startPos[1], beadPos[1]-head->yPos) /*+ control(control_vy, vel[1], 0)*/;
00487                 force[2] += control(control_z, pt[2]-startPos[2], beadPos[2]-head->zPos) /*+ control(control_vz, vel[2], 0)*/;
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         // add to the end of the list
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){ // then first value in the list
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 //      ResetControllerState();
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 //      reset_state(control_x);
00643 //      reset_state(control_y);
00644 //      reset_state(control_z);
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         //ResetControllerState();
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 // this version of DoConstrain Allows the playback to move backwards
00759 // and foorwards but struggles when the trajectory constains sharp turns
00760 //bool Playback::DoConstrain(double pPos[3], double force[3]){
00761 //      
00762 //      force[0] = 0;
00763 //      force[1] = 0;
00764 //      force[2] = 0;
00765 //
00766 //      if(cur == 0)
00767 //              return false;
00768 //
00769 //      if(cur->prev == 0){     // then at the start of the trajectory
00770 //              beadPos[0] = cur->xPos;
00771 //              beadPos[1] = cur->yPos;
00772 //              beadPos[2] = cur->zPos;
00773 //
00774 //              cur = cur->next;
00775 //
00776 //      }
00777 //      else{                                   //in the middle of the trajectory
00778 //              
00779 //              double prevToCur[3], prevToPhntm[3], magPrevToCur, magPrevToPhntm;
00780 //
00781 //              prevToCur[0] = cur->xPos - cur->prev->xPos;
00782 //              prevToCur[1] = cur->yPos - cur->prev->yPos;
00783 //              prevToCur[2] = cur->zPos - cur->prev->zPos;
00784 //
00785 //              magPrevToCur = sqrt(pow(prevToCur[0], 2.0) + pow(prevToCur[1], 2.0) + 
00786 //                      pow(prevToCur[2], 2.0));
00787 //
00788 //              prevToPhntm[0] = (pPos[0]/*-startPos[0]*/) - cur->prev->xPos;
00789 //              prevToPhntm[1] = (pPos[1]/*-startPos[1]*/) - cur->prev->yPos;
00790 //              prevToPhntm[2] = (pPos[2]/*-startPos[2]*/) - cur->prev->zPos;
00791 //
00792 //              magPrevToPhntm = sqrt(pow(prevToPhntm[0], 2.0) + pow(prevToPhntm[1], 2.0) + 
00793 //                      pow(prevToPhntm[2], 2.0));
00794 //              
00795 //              a = 0;  
00796 //                      
00797 //              if(magPrevToCur != 0 && magPrevToPhntm != 0){
00798 //                      a = acos(((prevToCur[0] * prevToPhntm[0]) + (prevToCur[1] * prevToPhntm[1])+
00799 //                                      (prevToCur[2] * prevToPhntm[2]))/(magPrevToCur * magPrevToPhntm));
00800 //              }
00801 //
00802 //        distFromPrev = cos(a) * magPrevToPhntm;
00803 //              double distToTravel = distFromPrev;// - magPrevToCur;
00804 //              bool done = false;
00805 //
00806 //              if(a > PID_PI_BY_2 && a < 3.0 * PID_PI_BY_2 && cur != 0 && distFromPrev < magPrevToCur){ // then move backwards
00807 //                      if(cur->prev != 0){
00808 //                              if(cur->prev->prev)
00809 //                              cur = cur->prev;
00810 //                      }       
00811 //                      beadPos[0] = cur->xPos;
00812 //                      beadPos[1] = cur->yPos;
00813 //                      beadPos[2] = cur->zPos;
00814 //                      
00815 //              }
00816 //              else{
00817 //                      while(cur != 0 && !done){
00818 //
00819 //                              if(distToTravel > magPrevToCur){
00820 //                                      distToTravel -= magPrevToCur;
00821 //              
00822 //                                      if(a < PID_PI_BY_2 || a > 3.0 * PID_PI_BY_2)// then move forwards
00823 //                                              cur = cur->next;
00824 //                                      else 
00825 //
00826 //                                      if(cur == 0)
00827 //                                              return false;
00828 //
00829 //                                      prevToCur[0] = cur->xPos - cur->prev->xPos;
00830 //                                      prevToCur[1] = cur->yPos - cur->prev->yPos;
00831 //                                      prevToCur[2] = cur->zPos - cur->prev->zPos;
00832 //                                      
00833 //                                      magPrevToCur = sqrt(pow(prevToCur[0], 2.0) + pow(prevToCur[1], 2.0) + 
00834 //                                              pow(prevToCur[2], 2.0));
00835 //                              }
00836 //                              else{
00837 //                                      done = true;
00838 //                              }
00839 //                              
00840 //                      }
00841 //              
00842 //                      if(cur == 0)
00843 //                              return false;
00844 //
00845 //                      if(a < PID_PI_BY_2 || a > 3.0 * PID_PI_BY_2){// then move forwards
00846 //                              beadPos[0] = cur->prev->xPos + (prevToCur[0]/magPrevToCur) * distToTravel;
00847 //                              beadPos[1] = cur->prev->yPos + (prevToCur[1]/magPrevToCur) * distToTravel;
00848 //                              beadPos[2] = cur->prev->zPos + (prevToCur[2]/magPrevToCur) * distToTravel;
00849 //                      }
00850 //                      else if(a > PID_PI_BY_2 && a < 3.0 * PID_PI_BY_2){ // then move backwards
00851 //                              beadPos[0] = cur->prev->xPos + (prevToCur[0]/magPrevToCur) * distToTravel;
00852 //                              beadPos[1] = cur->prev->yPos + (prevToCur[1]/magPrevToCur) * distToTravel;
00853 //                              beadPos[2] = cur->prev->zPos + (prevToCur[2]/magPrevToCur) * distToTravel;
00854 //                              beadPos[0] = cur->xPos - (prevToCur[0]/magPrevToCur) * distToTravel;
00855 //                              beadPos[1] = cur->yPos - (prevToCur[1]/magPrevToCur) * distToTravel;
00856 //                              beadPos[2] = cur->zPos - (prevToCur[2]/magPrevToCur) * distToTravel;
00857 //                      }
00858 //                      else{
00859 //                              beadPos[0] = cur->xPos;
00860 //                              beadPos[1] = cur->yPos;
00861 //                              beadPos[2] = cur->zPos;
00862 //                      }
00863 //              }
00864 //      }
00865 //
00866 //
00867 //      force[0] = control(control_x, pPos[0]/*-startPos[0]*/, beadPos[0]); 
00868 //      force[1] = control(control_y, pPos[1]/*-startPos[0]*/, beadPos[1]);
00869 //      force[2] = control(control_z, pPos[2]/*-startPos[0]*/, beadPos[2]);
00870 //
00871 //      return true;
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){     // then at the start of the trajectory
00884                 beadPos[0] = cur->xPos;
00885                 beadPos[1] = cur->yPos;
00886                 beadPos[2] = cur->zPos;
00887 
00888                 cur = cur->next;
00889 
00890         }
00891         else{                                   //in the middle of the trajectory
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]/*-startPos[0]*/) - cur->prev->xPos;
00903                 prevToPhntm[1] = (pPos[1]/*-startPos[1]*/) - cur->prev->yPos;
00904                 prevToPhntm[2] = (pPos[2]/*-startPos[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]/*-startPos[0]*/, beadPos[0]); 
00956         force[1] = control(control_y, pPos[1]/*-startPos[0]*/, beadPos[1]);
00957         force[2] = control(control_z, pPos[2]/*-startPos[0]*/, 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) // then just play the gesture from where we are
00974                 mode = PID_CONSTRAIN;
00975         else{                                   // else, move to the start point first
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 //double Playback::AngleBetweenVecs(double p1[3], double p2[3]){
00996 //
00997 //      double magP1, magP2;
00998 //
00999 //      magP1 = sqrt(pow(p1[0], 2.0) + pow(p1[1], 2.0) + pow(p1[2], 2.0));
01000 //
01001 //      magP2 = sqrt(pow(p2[0], 2.0) + pow(p2[1], 2.0) + pow(p2[2], 2.0));
01002 //      
01003 //      double a = 0;
01004 //              
01005 //      if(magP1 != 0 && magP2 != 0){
01006 //              a = acos(((p1[0] * p2[0]) + (p1[1] * p2[1]) + (p1[2] * p2[2]))/(magP1 * magP2));
01007 //      }
01008 //
01009 //      return a;
01010 //
01011 //}
01012 //
01013 //double Playback::GetAdjacentDist(double ang, double hypot){
01014 //
01015 //}

Generated on Tue Oct 16 17:10:43 2007 for Micole by  doxygen 1.4.7