00001 #include "PostureEngine.h"
00002 #include "Shared/WorldState.h"
00003 #include "Motion/roboop/robot.h"
00004 #include "Shared/Config.h"
00005 #include <stdio.h>
00006 #include <iostream>
00007
00008 PostureEngine::~PostureEngine() {}
00009
00010 void PostureEngine::takeSnapshot() {
00011 takeSnapshot(*WorldState::getCurrent());
00012 }
00013
00014 void PostureEngine::takeSnapshot(const WorldState& st) {
00015 for(unsigned int i=0; i<NumOutputs; i++)
00016 cmds[i].value=st.outputs[i];
00017 }
00018
00019 void PostureEngine::setWeights(float w, unsigned int lowjoint, unsigned int highjoint) {
00020 for(unsigned int i=lowjoint; i<highjoint; i++)
00021 cmds[i].weight=w;
00022 }
00023
00024 void PostureEngine::clear() {
00025 for(unsigned int i=0; i<NumOutputs; i++)
00026 cmds[i].unset();
00027 }
00028
00029 PostureEngine& PostureEngine::setOverlay(const PostureEngine& pe) {
00030 for(unsigned int i=0; i<NumOutputs; i++)
00031 if(pe.cmds[i].weight>0)
00032 cmds[i]=pe.cmds[i];
00033 return *this;
00034 }
00035 PostureEngine PostureEngine::createOverlay(const PostureEngine& pe) const {
00036 PostureEngine tmp(*this);
00037 return tmp.setOverlay(pe);
00038 }
00039 PostureEngine& PostureEngine::setUnderlay(const PostureEngine& pe) {
00040 for(unsigned int i=0; i<NumOutputs; i++)
00041 if(cmds[i].weight<=0)
00042 cmds[i]=pe.cmds[i];
00043 return *this;
00044 }
00045 PostureEngine PostureEngine::createUnderlay(const PostureEngine& pe) const {
00046 PostureEngine tmp(*this);
00047 return tmp.setUnderlay(pe);
00048 }
00049
00050
00051
00052
00053
00054
00055
00056
00057 PostureEngine& PostureEngine::setAverage(const PostureEngine& pe, float w) {
00058 if(w<0.001)
00059 return *this;
00060 if(w>0.999)
00061 return (*this=pe);
00062 float wp=1-w;
00063 for(unsigned int i=0; i<NumOutputs; i++)
00064 if(cmds[i].weight>0) {
00065 if(pe.cmds[i].weight>0)
00066 cmds[i].set(cmds[i].value*wp+pe.cmds[i].value*w,cmds[i].weight*wp+pe.cmds[i].weight*w);
00067 else
00068 cmds[i].weight*=wp;
00069 } else
00070 cmds[i].set(pe.cmds[i].value,pe.cmds[i].weight*w);
00071 return *this;
00072 }
00073
00074
00075
00076
00077
00078
00079
00080
00081 PostureEngine PostureEngine::createAverage(const PostureEngine& pe, float w) const {
00082 PostureEngine tmp(*this);
00083 return tmp.setAverage(pe,w);
00084 }
00085 PostureEngine& PostureEngine::setCombine(const PostureEngine& pe) {
00086 for(unsigned int i=0; i<NumOutputs; i++) {
00087 float total=cmds[i].weight+pe.cmds[i].weight;
00088 cmds[i].set((cmds[i].value*cmds[i].weight+pe.cmds[i].value*pe.cmds[i].weight)/total,total);
00089 }
00090 return *this;
00091 }
00092 PostureEngine PostureEngine::createCombine(const PostureEngine& pe) const {
00093 PostureEngine tmp(*this);
00094 return tmp.setCombine(pe);
00095 }
00096
00097 float PostureEngine::diff(const PostureEngine& pe) const {
00098 float ans=0;
00099 for(unsigned int i=0; i<NumOutputs; i++)
00100 if(cmds[i].weight>0 && pe.cmds[i].weight>0) {
00101 float dif=cmds[i].value-pe.cmds[i].value;
00102 ans+=dif*dif;
00103 }
00104 return ans;
00105 }
00106
00107 float PostureEngine::avgdiff(const PostureEngine& pe) const {
00108 float ans=0;
00109 unsigned int cnt=0;
00110 for(unsigned int i=0; i<NumOutputs; i++)
00111 if(cmds[i].weight>0 && pe.cmds[i].weight>0) {
00112 float dif=cmds[i].value-pe.cmds[i].value;
00113 ans+=dif*dif;
00114 cnt++;
00115 }
00116 return ans/cnt;
00117 }
00118
00119 float PostureEngine::maxdiff(const PostureEngine& pe) const {
00120 float max=0;
00121 for(unsigned int i=0; i<NumOutputs; i++)
00122 if(cmds[i].weight>0 && pe.cmds[i].weight>0) {
00123 float dif=cmds[i].value-pe.cmds[i].value;
00124 if(dif>max)
00125 max=dif;
00126 }
00127 return max;
00128 }
00129
00130 void PostureEngine::setSaveFormat(bool condensed, WorldState* ws) {
00131 saveFormatCondensed=condensed;
00132 loadSaveSensors=ws;
00133 }
00134
00135 unsigned int PostureEngine::getBinSize() const {
00136 unsigned int written=11;
00137 const unsigned int len=0;
00138 char buf[len];
00139 if(saveFormatCondensed) {
00140 written+=snprintf(buf,len,"condensed %s\n",RobotName);
00141 if(loadSaveSensors!=NULL)
00142 written+=snprintf(buf,len,"meta-info = %u %u\n",loadSaveSensors->lastSensorUpdateTime,loadSaveSensors->frameNumber);
00143 bool weightsAllEqual=true;
00144 float weightsVal=cmds[0].weight;
00145 for(unsigned int i=1; i<NumOutputs && weightsAllEqual; i++)
00146 weightsAllEqual=(cmds[i].weight==weightsVal);
00147 if(!weightsAllEqual || weightsVal!=0) {
00148 written+=snprintf(buf,len,"outputs =");
00149 for(unsigned int i=0; i<NumOutputs; i++) {
00150 written+=snprintf(buf,len," %g",cmds[i].value);
00151 }
00152 if(!weightsAllEqual || weightsVal!=1) {
00153 written+=snprintf(buf,len,"\nweights =");
00154 for(unsigned int i=0; i<NumOutputs; i++) {
00155 written+=snprintf(buf,len," %g",cmds[i].weight);
00156 }
00157 }
00158 written+=snprintf(buf,len,"\n");
00159 }
00160 if(loadSaveSensors!=NULL) {
00161 written+=snprintf(buf,len,"buttons =");
00162 for(unsigned int i=0; i<NumButtons; i++) {
00163 written+=snprintf(buf,len," %g",loadSaveSensors->buttons[i]);
00164 }
00165 written+=snprintf(buf,len,"\nsensors =");
00166 for(unsigned int i=0; i<NumSensors; i++) {
00167 written+=snprintf(buf,len," %g",loadSaveSensors->sensors[i]);
00168 }
00169 written+=snprintf(buf,len,"\npidduties =");
00170 for(unsigned int i=0; i<NumPIDJoints; i++) {
00171 written+=snprintf(buf,len," %g",loadSaveSensors->pidduties[i]);
00172 }
00173 written+=snprintf(buf,len,"\n");
00174 }
00175 } else {
00176 if(loadSaveSensors!=NULL)
00177 written+=snprintf(buf,len,"<meta-info>\n timestamp\t%u\n framenumber\t%u\n</meta-info>\n",loadSaveSensors->lastSensorUpdateTime,loadSaveSensors->frameNumber);
00178 for(unsigned int i=0; i<NumOutputs; i++)
00179 if(cmds[i].weight>0) {
00180 written+=snprintf(buf,len,"%s\t% .4f\t% .4f\n",outputNames[i],cmds[i].value,cmds[i].weight);
00181 }
00182 if(loadSaveSensors!=NULL) {
00183 written+=snprintf(buf,len,"<buttons>\n");
00184 for(unsigned int i=0; i<NumButtons; i++) {
00185 written+=snprintf(buf,len," %s\t% .4f\t\n",buttonNames[i],loadSaveSensors->buttons[i]);
00186 }
00187 written+=snprintf(buf,len,"</buttons><sensors>\n");
00188 for(unsigned int i=0; i<NumSensors; i++) {
00189 written+=snprintf(buf,len," %s\t% .4f\t\n",sensorNames[i],loadSaveSensors->sensors[i]);
00190 }
00191 written+=snprintf(buf,len,"</sensors><pidduties>\n");
00192 for(unsigned int i=0; i<NumPIDJoints; i++) {
00193 written+=snprintf(buf,len," duty-%s\t% .4f\t\n",outputNames[i],loadSaveSensors->pidduties[i]);
00194 }
00195 written+=snprintf(buf,len,"</pidduties>\n");
00196 }
00197 }
00198 return written;
00199 }
00200
00201 unsigned int PostureEngine::loadBuffer(const char buf[], unsigned int len) {
00202 unsigned int origlen=len;
00203 clear();
00204 if(strncmp("#POS",buf,4)!=0) {
00205
00206
00207
00208
00209 return 0;
00210 }
00211 saveFormatCondensed=false;
00212 char formatstring[64];
00213 snprintf(formatstring,64,"%%%dc %%g %%g%%n",outputNameLen);
00214 unsigned int idx=0;
00215 unsigned int linenum=1;
00216 enum section_t {
00217 SECTION_METAINFO, SECTION_OUTPUTS, SECTION_BUTTONS, SECTION_SENSORS, SECTION_PIDDUTIES
00218 } curSection=SECTION_OUTPUTS;
00219 char jname[outputNameLen+1];
00220 jname[outputNameLen]='\0';
00221 while(len<=origlen && len>0) {
00222 float fval, fwht=1;
00223 int written;
00224
00225 if(buf[0]=='\r') {
00226 buf++; len--;
00227 if(buf[0]=='\n') {
00228 buf++; len--;
00229 }
00230 linenum++;
00231 continue;
00232 }
00233 if(buf[0]=='\n') {
00234 buf++; len--;
00235 linenum++;
00236 continue;
00237 }
00238 if(buf[0]=='#') {
00239 if(strncmp("#END\n",buf,5)==0 || strncmp("#END\r",buf,5)==0) {
00240 return origlen-len+5;
00241 } else if(strncmp("#END\r\n",buf,6)==0) {
00242 return origlen-len+6;
00243 } else {
00244 while(len>0 && *buf!='\n' && *buf!='\r') {len--;buf++;}
00245 if(*buf=='\n') {
00246 buf++;
00247 len--;
00248 }
00249 linenum++;
00250 continue;
00251 }
00252 }
00253 if(isspace(buf[0])) {
00254 buf++; len--;
00255 continue;
00256 }
00257 written=-1;
00258 if(strncmp(buf,"condensed ",strlen("condensed"))==0) {
00259 char model[64];
00260 written=0; sscanf(buf,"condensed %64s%n",model,&written);
00261 if(!checkInc(written,buf,len,"*** ERROR PostureEngine load corrupted - line %d\n",linenum)) return 0;
00262 if(strncmp(model,RobotName,64)!=0) {
00263 printf("*** ERROR line %d, specified model (%.64s) for condensed mode does not match current robot (%s)\n",linenum,model,RobotName);
00264 return 0;
00265 }
00266 saveFormatCondensed=true;
00267 for(unsigned int i=0; i<NumOutputs; i++)
00268 cmds[i].unset();
00269
00270
00271
00272
00273 } else {
00274 if(saveFormatCondensed) {
00275 const unsigned int sectionLen=64;
00276 char section[sectionLen];
00277 written=0; sscanf(buf,"%64s = %n",section,&written);
00278 if(!checkInc(written,buf,len,"*** ERROR PostureEngine load corrupted - line %d\n",linenum)) return 0;
00279 if(strncmp(section,"outputs",sectionLen)==0) {
00280 for(unsigned int i=0; i<NumOutputs; i++) {
00281 float val;
00282 written=0; sscanf(buf,"%g%n",&val,&written);
00283 if(!checkInc(written,buf,len,"*** ERROR PostureEngine load corrupted - line %d\n",linenum)) return 0;
00284 cmds[i].set(val);
00285 }
00286 } else if(strncmp(section,"weights",sectionLen)==0) {
00287 for(unsigned int i=0; i<NumOutputs; i++) {
00288 written=0; sscanf(buf,"%g%n",&cmds[i].weight,&written);
00289 if(!checkInc(written,buf,len,"*** ERROR PostureEngine load corrupted - line %d\n",linenum)) return 0;
00290 }
00291 } else if(strncmp(section,"buttons",sectionLen)==0) {
00292 for(unsigned int i=0; i<NumButtons; i++) {
00293 written=0; sscanf(buf,"%g%n",&loadSaveSensors->buttons[i],&written);
00294 if(!checkInc(written,buf,len,"*** ERROR PostureEngine load corrupted - line %d\n",linenum)) return 0;
00295 }
00296 } else if(strncmp(section,"sensors",sectionLen)==0) {
00297 for(unsigned int i=0; i<NumSensors; i++) {
00298 written=0; sscanf(buf,"%g%n",&loadSaveSensors->sensors[i],&written);
00299 if(!checkInc(written,buf,len,"*** ERROR PostureEngine load corrupted - line %d\n",linenum)) return 0;
00300 }
00301 } else if(strncmp(section,"pidduties",sectionLen)==0) {
00302 for(unsigned int i=0; i<NumPIDJoints; i++) {
00303 written=0; sscanf(buf,"%g%n",&loadSaveSensors->pidduties[i],&written);
00304 if(!checkInc(written,buf,len,"*** ERROR PostureEngine load corrupted - line %d\n",linenum)) return 0;
00305 }
00306 } else if(strncmp(section,"meta-info",sectionLen)==0) {
00307 written=0; sscanf(buf,"%u %u%n",&loadSaveSensors->lastSensorUpdateTime,&loadSaveSensors->frameNumber,&written);
00308 if(!checkInc(written,buf,len,"*** ERROR PostureEngine load corrupted - line %d\n",linenum)) return 0;
00309 } else {
00310 printf("*** Warning: line %d, unknown section '%.64s', skipping.\n",linenum,section);
00311 }
00312 } else {
00313 if(strncmp(buf,"<meta-info>",strlen("<meta-info>"))==0) {
00314 written=0; sscanf(buf,"<meta-info>%n",&written);
00315 if(!checkInc(written,buf,len,"*** ERROR PostureEngine load corrupted - line %d\n",linenum)) return 0;
00316 if(curSection!=SECTION_OUTPUTS)
00317 printf("*** WARNING PostureEngine encountered nested <meta-info> - line %d\n",linenum);
00318 curSection=SECTION_METAINFO;
00319 idx=0;
00320 continue;
00321 } else if(strncmp(buf,"</meta-info>",strlen("</meta-info>"))==0) {
00322 written=0; sscanf(buf,"</meta-info>%n",&written);
00323 if(!checkInc(written,buf,len,"*** ERROR PostureEngine load corrupted - line %d\n",linenum)) return 0;
00324 if(curSection!=SECTION_METAINFO)
00325 printf("*** WARNING PostureEngine encountered </meta-info> when not in sensor section - line %d\n",linenum);
00326 curSection=SECTION_OUTPUTS;
00327 idx=0;
00328 continue;
00329 } else if(strncmp(buf,"<buttons>",strlen("<buttons>"))==0) {
00330 written=0; sscanf(buf,"<buttons>%n",&written);
00331 if(!checkInc(written,buf,len,"*** ERROR PostureEngine load corrupted - line %d\n",linenum)) return 0;
00332 if(curSection!=SECTION_OUTPUTS)
00333 printf("*** WARNING PostureEngine encountered nested <buttons> - line %d\n",linenum);
00334 curSection=SECTION_BUTTONS;
00335 idx=0;
00336 continue;
00337 } else if(strncmp(buf,"</buttons>",strlen("</buttons>"))==0) {
00338 written=0; sscanf(buf,"</buttons>%n",&written);
00339 if(!checkInc(written,buf,len,"*** ERROR PostureEngine load corrupted - line %d\n",linenum)) return 0;
00340 if(curSection!=SECTION_BUTTONS)
00341 printf("*** WARNING PostureEngine encountered </buttons> when not in sensor section - line %d\n",linenum);
00342 curSection=SECTION_OUTPUTS;
00343 idx=0;
00344 continue;
00345 } else if(strncmp(buf,"<sensors>",strlen("<sensors>"))==0) {
00346 written=0; sscanf(buf,"<sensors>%n",&written);
00347 if(!checkInc(written,buf,len,"*** ERROR PostureEngine load corrupted - line %d\n",linenum)) return 0;
00348 if(curSection!=SECTION_OUTPUTS)
00349 printf("*** WARNING PostureEngine encountered nested <sensors> - line %d\n",linenum);
00350 curSection=SECTION_SENSORS;
00351 idx=0;
00352 continue;
00353 } else if(strncmp(buf,"</sensors>",strlen("</sensors>"))==0) {
00354 written=0; sscanf(buf,"</sensors>%n",&written);
00355 if(!checkInc(written,buf,len,"*** ERROR PostureEngine load corrupted - line %d\n",linenum)) return 0;
00356 if(curSection!=SECTION_SENSORS)
00357 printf("*** WARNING PostureEngine encountered </sensors> when not in sensor section - line %d\n",linenum);
00358 curSection=SECTION_OUTPUTS;
00359 idx=0;
00360 continue;
00361 } else if(strncmp(buf,"<pidduties>",strlen("<pidduties>"))==0) {
00362 written=0; sscanf(buf,"<pidduties>%n",&written);
00363 if(!checkInc(written,buf,len,"*** ERROR PostureEngine load corrupted - line %d\n",linenum)) return 0;
00364 if(curSection!=SECTION_OUTPUTS)
00365 printf("*** WARNING PostureEngine encountered nested <pidduties> - line %d\n",linenum);
00366 curSection=SECTION_PIDDUTIES;
00367 idx=0;
00368 continue;
00369 } else if(strncmp(buf,"</pidduties>",strlen("</pidduties>"))==0) {
00370 written=0; sscanf(buf,"</pidduties>%n",&written);
00371 if(!checkInc(written,buf,len,"*** ERROR PostureEngine load corrupted - line %d\n",linenum)) return 0;
00372 if(curSection!=SECTION_PIDDUTIES)
00373 printf("*** WARNING PostureEngine encountered </pidduties> when not in sensor section - line %d\n",linenum);
00374 curSection=SECTION_OUTPUTS;
00375 idx=0;
00376 continue;
00377 } else {
00378 if(curSection==SECTION_METAINFO) {
00379 const unsigned int nameLen=64;
00380 char name[nameLen];
00381 unsigned int ival;
00382 written=0; sscanf(buf,"%64s %u%n",name,&ival,&written);
00383 if(!checkInc(written,buf,len,"*** ERROR PostureEngine load corrupted - line %d\n",linenum)) return 0;
00384 if(strncmp(name,"timestamp",nameLen)==0) {
00385 loadSaveSensors->lastSensorUpdateTime=ival;
00386 } else if(strncmp(name,"framenumber",nameLen)==0) {
00387 loadSaveSensors->frameNumber=ival;
00388 } else {
00389 std::cout << "*** WARNING '" << name << "' is not a valid meta-info on this model. (ignoring line " << linenum << ")" << std::endl;
00390 }
00391 } else if(curSection==SECTION_BUTTONS) {
00392 const unsigned int nameLen=64;
00393 char name[nameLen];
00394 written=0; sscanf(buf,"%64s %g%n",name,&fval,&written);
00395 if(!checkInc(written,buf,len,"*** ERROR PostureEngine load corrupted - line %d\n",linenum)) return 0;
00396 unsigned int startidx=idx;
00397 for(;idx<NumButtons;idx++)
00398 if(strncmp(name,buttonNames[idx],nameLen)==0) {
00399 loadSaveSensors->buttons[idx]=fval;
00400 break;
00401 }
00402 if(idx==NumButtons) {
00403 for(idx=0;idx<startidx;idx++)
00404 if(strncmp(name,buttonNames[idx],nameLen)==0) {
00405 loadSaveSensors->buttons[idx]=fval;
00406 break;
00407 }
00408 if(idx==startidx && strcmp(name,buttonNames[idx])!=0)
00409 std::cout << "*** WARNING '" << name << "' is not a valid button on this model. (ignoring line " << linenum << ")" << std::endl;
00410 }
00411 } else if(curSection==SECTION_SENSORS) {
00412 const unsigned int nameLen=64;
00413 char name[nameLen];
00414 written=0; sscanf(buf,"%64s %g%n",name,&fval,&written);
00415 if(!checkInc(written,buf,len,"*** ERROR PostureEngine load corrupted - line %d\n",linenum)) return 0;
00416 unsigned int startidx=idx;
00417 for(;idx<NumSensors;idx++)
00418 if(strncmp(name,sensorNames[idx],nameLen)==0) {
00419 loadSaveSensors->sensors[idx]=fval;
00420 break;
00421 }
00422 if(idx==NumSensors) {
00423 for(idx=0;idx<startidx;idx++)
00424 if(strncmp(name,sensorNames[idx],nameLen)==0) {
00425 loadSaveSensors->sensors[idx]=fval;
00426 break;
00427 }
00428 if(idx==startidx && strcmp(name,sensorNames[idx])!=0)
00429 std::cout << "*** WARNING '" << name << "' is not a valid sensor on this model. (ignoring line " << linenum << ")" << std::endl;
00430 }
00431 } else if(curSection==SECTION_PIDDUTIES) {
00432 const unsigned int nameLen=64;
00433 char name[nameLen];
00434 written=0; sscanf(buf,"%64s %g%n",name,&fval,&written);
00435 if(!checkInc(written,buf,len,"*** ERROR PostureEngine load corrupted - line %d\n",linenum)) return 0;
00436 unsigned int startidx=idx;
00437 for(;idx<NumPIDJoints;idx++)
00438 if(strncmp(name,outputNames[idx],nameLen)==0) {
00439 loadSaveSensors->pidduties[PIDJointOffset+idx]=fval;
00440 break;
00441 }
00442 if(idx==NumPIDJoints) {
00443 for(idx=0;idx<startidx;idx++)
00444 if(strncmp(name,outputNames[idx],nameLen)==0) {
00445 loadSaveSensors->pidduties[PIDJointOffset+idx]=fval;
00446 break;
00447 }
00448 if(idx==startidx && strcmp(name,outputNames[idx])!=0)
00449 std::cout << "*** WARNING '" << name << "' is not a valid PID joint on this model. (ignoring line " << linenum << ")" << std::endl;
00450 }
00451 } else {
00452 jname[0]='\0';
00453 written=0; sscanf(buf,formatstring,jname,&fval,&fwht,&written);
00454 if(!checkInc(written,buf,len,"*** ERROR PostureEngine load corrupted - line %d\n",linenum)) return 0;
00455
00456
00457
00458 unsigned int startidx=idx;
00459 for(;idx<NumOutputs;idx++)
00460 if(strncmp(jname,outputNames[idx],outputNameLen+1)==0) {
00461 cmds[idx].set(fval,fwht);
00462 break;
00463 }
00464 if(idx==NumOutputs) {
00465 for(idx=0;idx<startidx;idx++)
00466 if(strncmp(jname,outputNames[idx],outputNameLen+1)==0) {
00467 cmds[idx].set(fval,fwht);
00468 break;
00469 }
00470 if(idx==startidx && strcmp(jname,outputNames[idx])!=0) {
00471 unsigned int lidx=NumOutputs, ridx=NumOutputs;
00472 char tname[outputNameLen+1];
00473 strncpy(tname+1,jname,outputNameLen);
00474 tname[0]='L';
00475 for(idx=0;idx<NumOutputs;idx++) {
00476 if(strncmp(tname,outputNames[idx],outputNameLen+1)==0) {
00477 lidx=idx;
00478 break;
00479 }
00480 }
00481 tname[0]='R';
00482 for(idx=0;idx<NumOutputs;idx++) {
00483 if(strncmp(tname,outputNames[idx],outputNameLen+1)==0) {
00484 ridx=idx;
00485 break;
00486 }
00487 }
00488 if(lidx!=NumOutputs && ridx!=NumOutputs) {
00489 cmds[lidx].set(fval,fwht);
00490 cmds[ridx].set(fval,fwht);
00491 } else {
00492 idx=startidx;
00493 std::cout << "*** WARNING '" << jname << "' is not a valid joint on this model. (ignoring line " << linenum << ")" << std::endl;
00494 }
00495 }
00496 }
00497 }
00498 }
00499 }
00500 }
00501 while(*buf!='\n' && *buf!='\r') {
00502 buf++; len--;
00503 }
00504 if(buf[0]=='\r' && buf[1]=='\n') {
00505 buf+=2; len-=2;
00506 } else {
00507 buf++; len--;
00508 }
00509 linenum++;
00510 }
00511 std::cout << "*** WARNING PostureEngine load missing #END" << std::endl;
00512 return origlen-len;
00513 }
00514
00515
00516 unsigned int PostureEngine::saveBuffer(char buf[], unsigned int len) const {
00517 unsigned int origlen=len;
00518 int written=snprintf(buf,len,"#POS\n");
00519 if(!checkInc(written,buf,len,"*** ERROR PostureEngine save failed on header\n")) return 0;
00520 if(saveFormatCondensed) {
00521 written=snprintf(buf,len,"condensed %s\n",RobotName);
00522 if(!checkInc(written,buf,len,"*** ERROR PostureEngine save condensed header failed\n")) return 0;
00523 if(loadSaveSensors!=NULL) {
00524 written=snprintf(buf,len,"meta-info = %u %u\n",loadSaveSensors->lastSensorUpdateTime,loadSaveSensors->frameNumber);
00525 if(!checkInc(written,buf,len,"*** ERROR PostureEngine save pidduty failed\n")) return 0;
00526 }
00527 bool weightsAllEqual=true;
00528 float weightsVal=cmds[0].weight;
00529 for(unsigned int i=1; i<NumOutputs && weightsAllEqual; i++)
00530 weightsAllEqual=(cmds[i].weight==weightsVal);
00531 if(!weightsAllEqual || weightsVal!=0) {
00532 written=snprintf(buf,len,"outputs =");
00533 if(!checkInc(written,buf,len,"*** ERROR PostureEngine save outputs header failed\n")) return 0;
00534 for(unsigned int i=0; i<NumOutputs; i++) {
00535 written=snprintf(buf,len," %g",cmds[i].value);
00536 if(!checkInc(written,buf,len,"*** ERROR PostureEngine save output failed\n")) return 0;
00537 }
00538 if(!weightsAllEqual || weightsVal!=1) {
00539 written=snprintf(buf,len,"\nweights =");
00540 if(!checkInc(written,buf,len,"*** ERROR PostureEngine save weights header failed\n")) return 0;
00541 for(unsigned int i=0; i<NumOutputs; i++) {
00542 written=snprintf(buf,len," %g",cmds[i].weight);
00543 if(!checkInc(written,buf,len,"*** ERROR PostureEngine save weight failed\n")) return 0;
00544 }
00545 }
00546 written=snprintf(buf,len,"\n");
00547 if(!checkInc(written,buf,len,"*** ERROR PostureEngine save final newline failed\n")) return 0;
00548 }
00549 if(loadSaveSensors!=NULL) {
00550 written=snprintf(buf,len,"buttons =");
00551 if(!checkInc(written,buf,len,"*** ERROR PostureEngine save buttons header failed\n")) return 0;
00552 for(unsigned int i=0; i<NumButtons; i++) {
00553 written=snprintf(buf,len," %g",loadSaveSensors->buttons[i]);
00554 if(!checkInc(written,buf,len,"*** ERROR PostureEngine save button failed\n")) return 0;
00555 }
00556 written=snprintf(buf,len,"\nsensors =");
00557 if(!checkInc(written,buf,len,"*** ERROR PostureEngine save sensors header failed\n")) return 0;
00558 for(unsigned int i=0; i<NumSensors; i++) {
00559 written=snprintf(buf,len," %g",loadSaveSensors->sensors[i]);
00560 if(!checkInc(written,buf,len,"*** ERROR PostureEngine save sensor failed\n")) return 0;
00561 }
00562 written=snprintf(buf,len,"\npidduties =");
00563 if(!checkInc(written,buf,len,"*** ERROR PostureEngine save pidduties header failed\n")) return 0;
00564 for(unsigned int i=0; i<NumPIDJoints; i++) {
00565 written=snprintf(buf,len," %g",loadSaveSensors->pidduties[i]);
00566 if(!checkInc(written,buf,len,"*** ERROR PostureEngine save pidduty failed\n")) return 0;
00567 }
00568 written=snprintf(buf,len,"\n");
00569 if(!checkInc(written,buf,len,"*** ERROR PostureEngine save final newline failed\n")) return 0;
00570 }
00571 } else {
00572 if(loadSaveSensors!=NULL) {
00573 written=snprintf(buf,len,"<meta-info>\n timestamp\t%u\n framenumber\t%u\n</meta-info>\n",loadSaveSensors->lastSensorUpdateTime,loadSaveSensors->frameNumber);
00574 if(!checkInc(written,buf,len,"*** ERROR PostureEngine sensor begin save failed\n")) return 0;
00575 }
00576 for(unsigned int i=0; i<NumOutputs; i++)
00577 if(cmds[i].weight>0) {
00578 written=snprintf(buf,len,"%s\t% .4f\t% .4f\n",outputNames[i],cmds[i].value,cmds[i].weight);
00579 if(!checkInc(written,buf,len,"*** ERROR PostureEngine save failed\n")) return 0;
00580 }
00581 if(loadSaveSensors!=NULL) {
00582 written=snprintf(buf,len,"<buttons>\n");
00583 if(!checkInc(written,buf,len,"*** ERROR PostureEngine sensor begin save failed\n")) return 0;
00584 for(unsigned int i=0; i<NumButtons; i++) {
00585 written=snprintf(buf,len," %s\t% .4f\t\n",buttonNames[i],loadSaveSensors->buttons[i]);
00586 if(!checkInc(written,buf,len,"*** ERROR PostureEngine save button failed\n")) return 0;
00587 }
00588 written=snprintf(buf,len,"</buttons><sensors>\n");
00589 if(!checkInc(written,buf,len,"*** ERROR PostureEngine sensor end save failed\n")) return 0;
00590 for(unsigned int i=0; i<NumSensors; i++) {
00591 written=snprintf(buf,len," %s\t% .4f\t\n",sensorNames[i],loadSaveSensors->sensors[i]);
00592 if(!checkInc(written,buf,len,"*** ERROR PostureEngine save sensor failed\n")) return 0;
00593 }
00594 written=snprintf(buf,len,"</sensors><pidduties>\n");
00595 if(!checkInc(written,buf,len,"*** ERROR PostureEngine sensor end save failed\n")) return 0;
00596 for(unsigned int i=0; i<NumPIDJoints; i++) {
00597 written=snprintf(buf,len," %s\t% .4f\t\n",outputNames[i],loadSaveSensors->pidduties[i]);
00598 if(!checkInc(written,buf,len,"*** ERROR PostureEngine save pidduties failed\n")) return 0;
00599 }
00600 written=snprintf(buf,len,"</pidduties>\n");
00601 if(!checkInc(written,buf,len,"*** ERROR PostureEngine sensor end save failed\n")) return 0;
00602 }
00603 }
00604 written=snprintf(buf,len,"#END\n");
00605 if(!checkInc(written,buf,len,"*** ERROR PostureEngine save failed on #END\n")) return 0;
00606 return origlen-len;
00607 }
00608
00609 unsigned int PostureEngine::loadFile(const char filename[]) {
00610 return LoadSave::loadFile(config->motion.makePath(filename).c_str());
00611 }
00612 unsigned int PostureEngine::saveFile(const char filename[]) const {
00613 return LoadSave::saveFile(config->motion.makePath(filename).c_str());
00614 }
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648 bool
00649 PostureEngine::solveLinkPosition(const NEWMAT::ColumnVector& Pobj, unsigned int j, const NEWMAT::ColumnVector& Plink) {
00650 unsigned int c=-1U,l=-1U;
00651 if(!lookup(j,c,l))
00652 return false;
00653 update(c,l);
00654 bool conv=false;
00655 NEWMAT::ColumnVector q=chains[c]->inv_kin_pos(Pobj,0,l,Plink,conv);
00656 for(unsigned int i=1; i<=l && i<=chainMaps[c].size(); i++)
00657 if(chainMaps[c][i]<NumOutputs)
00658 setOutputCmd(chainMaps[c][i],chains[c]->get_q(i));
00659 return conv;
00660 }
00661
00662 bool
00663 PostureEngine::solveLinkVector(const NEWMAT::ColumnVector& Pobj, unsigned int j, const NEWMAT::ColumnVector& Plink) {
00664 solveLinkPosition(Pobj,j,Plink);
00665
00666
00667
00668 NEWMAT::ColumnVector poE=baseToLink(j)*Pobj;
00669 if(poE.nrows()>3 && poE(4)!=0) {
00670 poE/=poE(4);
00671 }
00672 poE=poE.SubMatrix(1,3,1,1);
00673 NEWMAT::ColumnVector plE=Plink.SubMatrix(1,3,1,1);
00674 if(Plink.nrows()>3 && Plink(4)!=0)
00675 plE/=Plink(4);
00676 float plE2=plE.SumSquare();
00677 float plE_len=sqrt(plE2);
00678 float obj_comp_link=NEWMAT::DotProduct(plE,poE)/plE_len;
00679 if(obj_comp_link<plE_len)
00680 obj_comp_link=obj_comp_link*.975;
00681 else
00682 obj_comp_link=obj_comp_link/.975;
00683 NEWMAT::ColumnVector obj_proj_link(4);
00684 obj_proj_link.SubMatrix(1,3,1,1)=obj_comp_link*plE/plE_len;
00685 obj_proj_link(4)=1;
00686 return solveLinkPosition(Pobj,j,obj_proj_link);
00687 }
00688
00689 void
00690 PostureEngine::update(unsigned int c, unsigned int l) {
00691 for(unsigned int j=1; j<=l; j++) {
00692 unsigned int tkout=chainMaps[c][j];
00693 if(tkout<NumOutputs)
00694 chains[c]->set_q(getOutputCmd(tkout).value,j);
00695 }
00696 }
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708