00001 #include "MotionSequenceMC.h"
00002 #include "Shared/get_time.h"
00003 #include "Shared/WorldState.h"
00004 #include "Shared/Config.h"
00005 #include <iostream>
00006
00007 using std::cout;
00008 using std::endl;
00009
00010 MotionSequenceEngine::Move_idx_t MotionSequenceEngine::invalid_move=-1U;
00011
00012 int MotionSequenceEngine::updateOutputs() {
00013 if(isPlaying()) {
00014 if(lasttime==0)
00015 play();
00016 float diff=(get_time()-lasttime)*playspeed;
00017 if(playtime<-diff)
00018 setTime(0);
00019 else
00020 setTime(static_cast<unsigned int>(diff+playtime));
00021 lasttime=get_time();
00022 return 1;
00023 } else {
00024 lasttime=get_time();
00025 return 0;
00026 }
00027 }
00028
00029 const OutputCmd& MotionSequenceEngine::getOutputCmd(unsigned int i) {
00030 if(curstamps[i]!=playtime) {
00031 if(nexts[i]!=invalid_move)
00032 calcOutput(curs[i],playtime,getKeyFrame(prevs[i]),getKeyFrame(nexts[i]));
00033 else if(hold)
00034 curs[i]=getKeyFrame(prevs[i]).cmd;
00035 else
00036 curs[i].unset();
00037 curstamps[i]=playtime;
00038 }
00039 return curs[i];
00040 }
00041
00042 unsigned int MotionSequenceEngine::getBinSize() const {
00043 char buf[128];
00044 unsigned int len=128;
00045 unsigned int used=strlen("#MSq\n");
00046 used+=snprintf(buf,len,isSaveRadians()?"radians\n":"degrees\n");
00047 unsigned int t=0;
00048 Move_idx_t tprevs[NumOutputs];
00049 Move_idx_t tnexts[NumOutputs];
00050 bool hasInitialFrame=false;
00051 for(unsigned int i=0;i<NumOutputs;i++) {
00052 tnexts[i]=getKeyFrame(tprevs[i]=starts[i]).next;
00053 if(getKeyFrame(starts[i]).cmd.weight!=0)
00054 hasInitialFrame=true;
00055 }
00056 if(hasInitialFrame)
00057 used+=snprintf(buf,len,"setTime\t0\n");
00058 while(t!=-1U) {
00059 for(unsigned int i=0; i<NumOutputs; i++) {
00060 if((t!=0 || getKeyFrame(tprevs[i]).cmd.weight!=0) && getKeyFrame(tprevs[i]).starttime==t) {
00061 if(getKeyFrame(tprevs[i]).cmd.weight==1)
00062 used+=snprintf(buf,len,"%s\t%g\n",outputNames[i],getKeyFrame(tprevs[i]).cmd.value/loadSaveMode);
00063 else
00064 used+=snprintf(buf,len,"%s\t%g\t%g\n",outputNames[i],getKeyFrame(tprevs[i]).cmd.value/loadSaveMode,getKeyFrame(tprevs[i]).cmd.weight);
00065 }
00066 }
00067 unsigned int last=t;
00068 t=setNextFrameTime(tprevs,tnexts);
00069 if(t!=-1U)
00070 used+=snprintf(buf,len,"advanceTime\t%d\n",t-last);
00071 }
00072 used+=strlen("#END\n");
00073 return used+1;
00074 }
00075
00076 unsigned int MotionSequenceEngine::LoadBuffer(const char buf[], unsigned int len) {
00077 unsigned int origlen=len;
00078 if(strncmp("#POS",buf,4)==0) {
00079
00080 PostureEngine pose;
00081 unsigned int used=pose.LoadBuffer(buf,len);
00082 if(used!=0)
00083 setPose(pose);
00084 return used;
00085 }
00086 if(strncmp("#MSq",buf,4)!=0) {
00087
00088
00089
00090
00091 return 0;
00092 }
00093 unsigned int linenum=1;
00094 unsigned int lastOutputIdx=0;
00095 while(len<=origlen && len>0) {
00096 int written;
00097
00098 if(buf[0]=='\r') {
00099 buf++; len--;
00100 if(buf[0]=='\n') {
00101 buf++; len--;
00102 }
00103 linenum++;
00104 continue;
00105 }
00106 if(buf[0]=='\n') {
00107 buf++; len--;
00108 linenum++;
00109 continue;
00110 }
00111 if(buf[0]=='#') {
00112 if(strncmp("#END\n",buf,5)==0 || strncmp("#END\r",buf,5)==0) {
00113 return origlen-len+5;
00114 } else if(strncmp("#END\r\n",buf,6)==0) {
00115 return origlen-len+6;
00116 } else {
00117 while(len>0 && *buf!='\n' && *buf!='\r') {len--;buf++;}
00118 if(*buf=='\n') {
00119 buf++;
00120 len--;
00121 }
00122 linenum++;
00123 continue;
00124 }
00125 }
00126 written=-1;
00127 const unsigned int cmdlen=16, arglen=32;
00128 char command[cmdlen];
00129 char arg1[arglen];
00130 char arg2[arglen];
00131 written=readWord(buf,&buf[len],command,cmdlen);
00132 if(!ChkAdvance(written,&buf,&len,"*** ERROR MotionSequenceEngine load corrupted - line %d\n",linenum)) return 0;
00133 written=readWord(buf,&buf[len],arg1,arglen);
00134 if(written>0)
00135 if(!ChkAdvance(written,&buf,&len,"*** ERROR MotionSequenceEngine load corrupted - line %d\n",linenum)) return 0;
00136 written=readWord(buf,&buf[len],arg2,arglen);
00137 if(written!=0)
00138 if(!ChkAdvance(written,&buf,&len,"*** ERROR MotionSequenceEngine load corrupted - line %d\n",linenum)) return 0;
00139 for(;len>0 && *buf!='\n' && *buf!='\r';buf++,len--) {}
00140 if(*buf=='\n') {
00141 buf++;
00142 len--;
00143 }
00144
00145 if(strcasecmp(command,"delay")==0 || strcasecmp(command,"advanceTime")==0) {
00146 char* used;
00147 int delay = strtol(arg1,&used,0);
00148 if(*used!='\0') {
00149 cout << "*** WARNING illegal delay argument: " << arg1 << " - line " << linenum << endl;
00150 } else {
00151 setTime(playtime+delay);
00152 }
00153 } else if(strcasecmp(command,"settime")==0) {
00154 char* used;
00155 int newtime = strtol(arg1,&used,0);
00156 if(*used!='\0') {
00157 cout << "*** WARNING illegal settime argument: " << arg1 << " - line " << linenum << endl;
00158 } else {
00159 setTime(newtime);
00160 }
00161 } else if(strcasecmp(command,"load")==0) {
00162 PostureEngine pose;
00163 std::string f;
00164 if(arg1[0]!='/')
00165 f="/ms/data/motion/";
00166 f+=arg1;
00167 if(pose.LoadFile(f.c_str())!=0) {
00168 setPose(pose);
00169 } else
00170 cout << "*** WARNING could not read file " << arg1 << " for load - line " << linenum << endl;
00171 } else if(strcasecmp(command,"overlay")==0) {
00172 PostureEngine pose;
00173 std::string f;
00174 if(arg1[0]!='/')
00175 f="/ms/data/motion/";
00176 f+=arg1;
00177 if(pose.LoadFile(f.c_str())!=0)
00178 overlayPose(pose);
00179 else if(LoadFile(f.c_str())==0)
00180 cout << "*** WARNING could not read file " << arg1 << " for overlay - line " << linenum << endl;
00181 } else if(strcasecmp(command,"degrees")==0) {
00182 setSaveDegrees();
00183 } else if(strcasecmp(command,"radians")==0) {
00184 setSaveRadians();
00185 } else {
00186 lastOutputIdx=getOutputIndex(command,lastOutputIdx+1);
00187 if(lastOutputIdx==NumOutputs)
00188 cout << "*** WARNING " << command << " is not a valid joint on this model." << endl;
00189 else {
00190 char* used;
00191 double value=strtod(arg1,&used), weight=1;
00192 if(*used!='\0')
00193 cout << "*** WARNING illegal value argument: " << arg1 << " - line " << linenum << endl;
00194 else {
00195 if(arg2[0]!='\0') {
00196 weight=strtod(arg2,&used);
00197 if(*used!='\0') {
00198 cout << "*** WARNING illegal weight argument: " << arg2 << " - line " << linenum << endl;
00199 weight=1;
00200 }
00201 }
00202 setOutputCmd(lastOutputIdx,OutputCmd(value*loadSaveMode,weight));
00203 }
00204 }
00205 }
00206
00207 linenum++;
00208
00209 }
00210 cout << "*** WARNING MotionSequenceEngine load missing #END" << endl;
00211 return origlen-len;
00212 }
00213
00214 unsigned int MotionSequenceEngine::SaveBuffer(char buf[], unsigned int len) const {
00215
00216 unsigned int origlen=len;
00217 int written=snprintf(buf,len,"#MSq\n");
00218 if(!ChkAdvance(written,(const char**)&buf,&len,"*** ERROR MotionSequenceEngine save failed on header\n")) return 0; if(len==0 || len>origlen) {
00219 cout << "*** ERROR MotionSequenceEngine save overflow on header" << endl;
00220 return 0;
00221 }
00222 written=snprintf(buf,len,isSaveRadians()?"radians\n":"degrees\n");
00223 if(!ChkAdvance(written,(const char**)&buf,&len,"*** ERROR MotionSequenceEngine save failed on mode\n")) return 0; if(len==0 || len>origlen) {
00224 cout << "*** ERROR MotionSequenceEngine save overflow" << endl;
00225 return 0;
00226 }
00227 unsigned int t=0;
00228 Move_idx_t tprevs[NumOutputs];
00229 Move_idx_t tnexts[NumOutputs];
00230 bool hasInitialFrame=false;
00231 for(unsigned int i=0;i<NumOutputs;i++) {
00232 tnexts[i]=getKeyFrame(tprevs[i]=starts[i]).next;
00233 if(getKeyFrame(starts[i]).cmd.weight!=0)
00234 hasInitialFrame=true;
00235 }
00236 if(hasInitialFrame) {
00237 written=snprintf(buf,len,"setTime\t0\n");
00238 if(!ChkAdvance(written,(const char**)&buf,&len,"*** ERROR MotionSequenceEngine save failed on initial frame spec\n")) return 0;
00239 }
00240 while(t!=-1U) {
00241
00242 for(unsigned int i=0; i<NumOutputs; i++) {
00243
00244
00245 if((t!=0 || getKeyFrame(tprevs[i]).cmd.weight!=0) && getKeyFrame(tprevs[i]).starttime==t) {
00246 if(getKeyFrame(tprevs[i]).cmd.weight==1) {
00247 written=snprintf(buf,len,"%s\t%g\n",outputNames[i],getKeyFrame(tprevs[i]).cmd.value/loadSaveMode);
00248 if(!ChkAdvance(written,(const char**)&buf,&len,"*** ERROR MotionSequenceEngine save failed\n")) return 0;
00249 } else {
00250 written=snprintf(buf,len,"%s\t%g\t%g\n",outputNames[i],getKeyFrame(tprevs[i]).cmd.value/loadSaveMode,getKeyFrame(tprevs[i]).cmd.weight);
00251 if(!ChkAdvance(written,(const char**)&buf,&len,"*** ERROR MotionSequenceEngine save failed\n")) return 0;
00252 }
00253 if(len==0 || len>origlen) {
00254 cout << "*** ERROR MotionSequenceEngine save overflow" << endl;
00255 return 0;
00256 }
00257 }
00258 }
00259 unsigned int last=t;
00260 t=setNextFrameTime(tprevs,tnexts);
00261 if(t!=-1U) {
00262 written=snprintf(buf,len,"delay\t%d\n",t-last);
00263 if(!ChkAdvance(written,(const char**)&buf,&len,"*** ERROR MotionSequenceEngine save failed\n")) return 0;
00264 if(len==0 || len>origlen) {
00265 cout << "*** ERROR MotionSequenceEngine save overflow" << endl;
00266 return 0;
00267 }
00268 }
00269 }
00270 written=snprintf(buf,len,"#END\n");
00271 if(!ChkAdvance(written,(const char**)&buf,&len,"*** ERROR MotionSequenceEngine save failed on #END\n")) return 0;
00272 if(len==0 || len>origlen) {
00273 cout << "*** ERROR MotionSequenceEngine save overflow on #END" << endl;
00274 return 0;
00275 }
00276 return origlen-len;
00277 cout << "SAVE-done!" << endl;
00278 }
00279
00280 unsigned int MotionSequenceEngine::LoadFile(const char filename[]) {
00281 return LoadSave::LoadFile(config->motion.makePath(filename).c_str());
00282 }
00283 unsigned int MotionSequenceEngine::SaveFile(const char filename[]) const {
00284 return LoadSave::SaveFile(config->motion.makePath(filename).c_str());
00285 }
00286
00287 void MotionSequenceEngine::setTime(unsigned int x) {
00288 playtime=x;
00289 for(unsigned int i=0; i<NumOutputs; i++)
00290 setRange(x,prevs[i],nexts[i]);
00291 }
00292
00293 void MotionSequenceEngine::setOutputCmd(unsigned int i, const OutputCmd& cmd) {
00294 Move& p_m=getKeyFrame(prevs[i]);
00295 if(playtime==p_m.starttime) {
00296 p_m.cmd=cmd;
00297 } else {
00298 Move_idx_t x = newKeyFrame();
00299 if(x==invalid_move)
00300 return;
00301 Move& cur=getKeyFrame(x);
00302 Move& prev_m=getKeyFrame(prevs[i]);
00303 cur.cmd=cmd;
00304 cur.starttime=playtime;
00305 cur.prev=prevs[i];
00306 cur.next=nexts[i];
00307 prev_m.next=x;
00308 if(nexts[i]!=invalid_move)
00309 getKeyFrame(nexts[i]).prev=x;
00310 else {
00311 if(playtime>endtime)
00312 endtime=playtime;
00313 }
00314 prevs[i]=x;
00315
00316 }
00317 }
00318
00319 void MotionSequenceEngine::setPose(const PostureEngine& pose) {
00320 for(unsigned int i=0; i<NumOutputs; i++)
00321 setOutputCmd(i,pose.getOutputCmd(i));
00322 }
00323
00324 PostureEngine MotionSequenceEngine::getPose() {
00325 PostureEngine pose;
00326 getPose(pose);
00327 return pose;
00328 }
00329
00330 void MotionSequenceEngine::getPose(PostureEngine& pose) {
00331 for(unsigned int i=0; i<NumOutputs; i++)
00332 pose.setOutputCmd(i,getOutputCmd(i));
00333 }
00334
00335 void MotionSequenceEngine::overlayPose(const PostureEngine& pose) {
00336 for(unsigned int i=0; i<NumOutputs; i++)
00337 if(pose.getOutputCmd(i).weight>0)
00338 setOutputCmd(i,pose.getOutputCmd(i));
00339 }
00340
00341 void MotionSequenceEngine::compress() {
00342 for(unsigned int i=0; i<NumOutputs; i++) {
00343 Move_idx_t prev=getKeyFrame(starts[i]).next;
00344 if(prev==(Move_idx_t)-1)
00345 break;
00346 Move_idx_t cur=getKeyFrame(prev).next;
00347 if(cur==(Move_idx_t)-1)
00348 break;
00349 Move_idx_t next=getKeyFrame(cur).next;
00350 while(next!=(Move_idx_t)-1) {
00351 OutputCmd tmp;
00352 Move& prev_m=getKeyFrame(prev);
00353 Move& cur_m=getKeyFrame(cur);
00354 Move& next_m=getKeyFrame(next);
00355 calcOutput(tmp,cur_m.starttime,prev_m,next_m);
00356 if(tmp==cur_m.cmd || tmp.weight==0 && cur_m.cmd.weight==0) {
00357 prev_m.next=next;
00358 next_m.prev=prev;
00359 eraseKeyFrame(cur);
00360 } else
00361 prev=cur;
00362 cur=next;
00363 next=next_m.next;
00364 }
00365 }
00366 }
00367
00368 void MotionSequenceEngine::makeSafe(const float vels[NumOutputs], float margin) {
00369 float comps[NumOutputs];
00370 for(unsigned int i=0;i<NumOutputs;i++)
00371 comps[i]=vels[i]*margin;
00372 unsigned int t=0;
00373 Move_idx_t tprevs[NumOutputs];
00374 Move_idx_t tnexts[NumOutputs];
00375 for(unsigned int i=0;i<NumOutputs;i++)
00376 tnexts[i]=getKeyFrame(tprevs[i]=starts[i]).next;
00377 while(t!=-1U) {
00378 for(unsigned int i=0; i<NumOutputs; i++) {
00379
00380 if(tnexts[i]!=(Move_idx_t)-1 && (getKeyFrame(tprevs[i]).cmd.weight!=0 || getKeyFrame(tnexts[i]).cmd.weight!=0) && getKeyFrame(tprevs[i]).starttime==t) {
00381 float dv=fabs(getKeyFrame(tprevs[i]).cmd.value-getKeyFrame(tnexts[i]).cmd.value);
00382 unsigned int dt=getKeyFrame(tnexts[i]).starttime-getKeyFrame(tprevs[i]).starttime;
00383 if(dv/dt>comps[i]) {
00384 unsigned int delay=(unsigned int)(dv/comps[i])-dt;
00385 for(unsigned int j=0; j<NumOutputs; j++)
00386 for(Move_idx_t c=tnexts[j]; c!=(Move_idx_t)-1; c=getKeyFrame(c).next)
00387 getKeyFrame(c).starttime+=delay;
00388 }
00389 }
00390 }
00391 t=setNextFrameTime(tprevs,tnexts);
00392 }
00393
00394 }
00395
00396 bool MotionSequenceEngine::isPlaying() {
00397 return playing && ((playspeed>0) ? (playtime<=endtime) : (playtime>0));
00398 }
00399
00400
00401 void MotionSequenceEngine::play() {
00402 if(playspeed>0)
00403 setTime(0);
00404 else
00405 setTime(endtime);
00406 resume();
00407 }
00408
00409 void MotionSequenceEngine::resume() {
00410 playing=true;
00411 lasttime=get_time();
00412 for(unsigned int i=0; i<NumOutputs; i++) {
00413 Move_idx_t cur=starts[i];
00414 while(cur!=(Move_idx_t)-1) {
00415 if(getKeyFrame(cur).cmd.weight!=0) {
00416 getKeyFrame(starts[i]).cmd.value=state->outputs[i];
00417 break;
00418 }
00419 cur=getKeyFrame(cur).next;
00420 }
00421 }
00422 }
00423
00424 unsigned int MotionSequenceEngine::setNextFrameTime(Move_idx_t p[NumOutputs], Move_idx_t n[NumOutputs]) const {
00425 unsigned int ans=-1U;
00426 for(unsigned int i=0; i<NumOutputs; i++)
00427 if(n[i]!=invalid_move && getKeyFrame(n[i]).starttime<ans)
00428 ans=getKeyFrame(n[i]).starttime;
00429 if(ans!=-1U)
00430 for(unsigned int i=0; i<NumOutputs; i++)
00431 setRange(ans,p[i],n[i]);
00432 return ans;
00433 }
00434
00435 unsigned int MotionSequenceEngine::readWord(const char buf[], const char * const bufend, char wrd[], const unsigned int wordlen) {
00436 const char* origbuf=buf;
00437 wrd[0]='\0';
00438 unsigned int i;
00439
00440 for(;buf<bufend && isspace(*buf) && *buf!='\n' && *buf!='\r';buf++) {}
00441
00442 for(i=0; buf<bufend && !isspace(*buf); buf++)
00443 if(i<wordlen-1)
00444 wrd[i++]=*buf;
00445 wrd[i]='\0';
00446 if(buf>=bufend)
00447 return -1U;
00448 return buf-origbuf;
00449 }
00450
00451 unsigned int MotionSequenceEngine::getOutputIndex(const char name[], unsigned int idx) {
00452 if(idx<NumOutputs) {
00453 unsigned int startidx=idx;
00454 for(;idx<NumOutputs;idx++)
00455 if(strcmp(name,outputNames[idx])==0)
00456 return idx;
00457 for(idx=0;idx<startidx;idx++)
00458 if(strcmp(name,outputNames[idx])==0)
00459 return idx;
00460 return NumOutputs;
00461 } else {
00462 for(idx=0;idx<NumOutputs;idx++)
00463 if(strcmp(name,outputNames[idx])==0)
00464 return idx;
00465 return idx;
00466 }
00467 }
00468
00469
00470 void MotionSequenceEngine::setPlayTime(unsigned int x) {
00471 setTime(x);
00472 }
00473
00474
00475 unsigned int MotionSequenceEngine::getPlayTime() const {
00476 return getTime();
00477 }
00478
00479
00480 void MotionSequenceEngine::setPlaySpeed(float x) {
00481 setSpeed(x);
00482 }
00483
00484
00485 float MotionSequenceEngine::getPlaySpeed() const {
00486 return getSpeed();
00487 }
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499