00001 #include "Shared/RobotInfo.h"
00002 #ifdef TGT_HAS_LEDS
00003
00004 #include "LedEngine.h"
00005 #include "MotionManager.h"
00006 #include "Shared/WorldState.h"
00007 #include "Shared/ERS210Info.h"
00008 #include "Shared/ERS220Info.h"
00009 #include "Shared/ERS7Info.h"
00010
00011 #ifdef TGT_HAS_LED_PANEL
00012
00013 const LEDBitMask_t LedEngine::defaultMimicNumMasks[11] = {
00014 BotRLEDMask|BotLLEDMask|TopBrLEDMask,
00015 BotLLEDMask|MidLLEDMask|TopLLEDMask,
00016 BotRLEDMask|BotLLEDMask|TopLLEDMask|TopBrLEDMask,
00017 BotRLEDMask|BotLLEDMask|MidRLEDMask|TopLLEDMask|TopBrLEDMask,
00018 BotLLEDMask|MidLLEDMask|TopRLEDMask|TopLLEDMask,
00019 BotRLEDMask|BotLLEDMask|TopRLEDMask|TopBrLEDMask,
00020 BotRLEDMask|BotLLEDMask|MidRLEDMask|MidLLEDMask|TopRLEDMask|TopBrLEDMask,
00021 BotLLEDMask|MidLLEDMask|TopLLEDMask|TopBrLEDMask,
00022 BotRLEDMask|BotLLEDMask|MidRLEDMask|MidLLEDMask|TopRLEDMask|TopLLEDMask|TopBrLEDMask,
00023 BotLLEDMask|MidLLEDMask|TopRLEDMask|TopLLEDMask|TopBrLEDMask,
00024 BotLLEDMask
00025 };
00026
00027 const LEDBitMask_t LedEngine::ERS220numMasks[11] = {
00028 ERS220Info::ModeLEDMask,
00029
00030 ERS220Info::FaceBackLeftLEDMask,
00031
00032 ERS220Info::FaceBackLeftLEDMask|ERS220Info::FaceCenterLeftLEDMask,
00033
00034 ERS220Info::FaceBackLeftLEDMask|ERS220Info::FaceCenterLeftLEDMask|ERS220Info::FaceFrontLeftLEDMask,
00035
00036 ERS220Info::FaceBackLeftLEDMask|ERS220Info::FaceCenterLeftLEDMask|ERS220Info::FaceFrontLeftLEDMask
00037 |ERS220Info::FaceFrontRightLEDMask,
00038
00039 ERS220Info::FaceBackLeftLEDMask|ERS220Info::FaceCenterLeftLEDMask|ERS220Info::FaceFrontLeftLEDMask
00040 |ERS220Info::FaceFrontRightLEDMask|ERS220Info::FaceCenterRightLEDMask,
00041
00042 ERS220Info::FaceBackLeftLEDMask|ERS220Info::FaceCenterLeftLEDMask|ERS220Info::FaceFrontLeftLEDMask
00043 |ERS220Info::FaceFrontRightLEDMask|ERS220Info::FaceCenterRightLEDMask|ERS220Info::FaceBackRightLEDMask,
00044
00045 ERS220Info::FaceBackLeftLEDMask|ERS220Info::FaceCenterLeftLEDMask|ERS220Info::FaceFrontLeftLEDMask
00046 |ERS220Info::FaceFrontRightLEDMask|ERS220Info::FaceCenterRightLEDMask|ERS220Info::FaceBackRightLEDMask
00047 |ERS220Info::FaceFrontALEDMask,
00048
00049 ERS220Info::FaceBackLeftLEDMask|ERS220Info::FaceCenterLeftLEDMask|ERS220Info::FaceFrontLeftLEDMask
00050 |ERS220Info::FaceFrontRightLEDMask|ERS220Info::FaceCenterRightLEDMask|ERS220Info::FaceBackRightLEDMask
00051 |ERS220Info::FaceFrontALEDMask|ERS220Info::FaceFrontBLEDMask,
00052
00053 ERS220Info::FaceBackLeftLEDMask|ERS220Info::FaceCenterLeftLEDMask|ERS220Info::FaceFrontLeftLEDMask
00054 |ERS220Info::FaceFrontRightLEDMask|ERS220Info::FaceCenterRightLEDMask|ERS220Info::FaceBackRightLEDMask
00055 |ERS220Info::FaceFrontALEDMask|ERS220Info::FaceFrontBLEDMask|ERS220Info::FaceFrontCLEDMask,
00056
00057 ERS220Info::FaceFrontLeftLEDMask
00058 };
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 const LEDBitMask_t LedEngine::ERS7numMasks[11] = {
00077 0,
00078 (ERS7Info::FaceLEDPanelMask<<11),
00079
00080 (ERS7Info::FaceLEDPanelMask<< 4)|(ERS7Info::FaceLEDPanelMask<< 5),
00081
00082 (ERS7Info::FaceLEDPanelMask<< 2)|(ERS7Info::FaceLEDPanelMask<<11)|(ERS7Info::FaceLEDPanelMask<< 3),
00083
00084 (ERS7Info::FaceLEDPanelMask<< 2)|(ERS7Info::FaceLEDPanelMask<< 3)|(ERS7Info::FaceLEDPanelMask<< 8)
00085 |(ERS7Info::FaceLEDPanelMask<<9),
00086
00087 (ERS7Info::FaceLEDPanelMask<< 2)|(ERS7Info::FaceLEDPanelMask<< 3)|(ERS7Info::FaceLEDPanelMask<< 8)
00088 |(ERS7Info::FaceLEDPanelMask<<9)|(ERS7Info::FaceLEDPanelMask<<11),
00089
00090 (ERS7Info::FaceLEDPanelMask<< 0)|(ERS7Info::FaceLEDPanelMask<< 1)|(ERS7Info::FaceLEDPanelMask<< 4)
00091 |(ERS7Info::FaceLEDPanelMask<<5)|(ERS7Info::FaceLEDPanelMask<< 6)|(ERS7Info::FaceLEDPanelMask<< 7),
00092
00093 (ERS7Info::FaceLEDPanelMask<< 0)|(ERS7Info::FaceLEDPanelMask<< 1)|(ERS7Info::FaceLEDPanelMask<< 4)
00094 |(ERS7Info::FaceLEDPanelMask<<5)|(ERS7Info::FaceLEDPanelMask<< 6)|(ERS7Info::FaceLEDPanelMask<< 7)
00095 |(ERS7Info::FaceLEDPanelMask<<11),
00096
00097 (ERS7Info::FaceLEDPanelMask<< 2)|(ERS7Info::FaceLEDPanelMask<< 3)|(ERS7Info::FaceLEDPanelMask<< 4)
00098 |(ERS7Info::FaceLEDPanelMask<<5)|(ERS7Info::FaceLEDPanelMask<< 6)|(ERS7Info::FaceLEDPanelMask<< 7)
00099 |(ERS7Info::FaceLEDPanelMask<< 8)|(ERS7Info::FaceLEDPanelMask<<9),
00100
00101 (ERS7Info::FaceLEDPanelMask<< 2)|(ERS7Info::FaceLEDPanelMask<< 3)|(ERS7Info::FaceLEDPanelMask<< 4)
00102 |(ERS7Info::FaceLEDPanelMask<<5)|(ERS7Info::FaceLEDPanelMask<< 6)|(ERS7Info::FaceLEDPanelMask<< 7)
00103 |(ERS7Info::FaceLEDPanelMask<< 8)|(ERS7Info::FaceLEDPanelMask<<9)|(ERS7Info::FaceLEDPanelMask<<11),
00104
00105 (ERS7Info::FaceLEDPanelMask<< 1)
00106 };
00107 #endif // has led panel
00108
00109
00110 const LEDBitMask_t LedEngine::defaultCountNumMasks[11] = {
00111 (1<<0)|(1<<8),
00112 (1<<0),
00113 (1<<0)|(1<<1),
00114 (1<<0)|(1<<1)|(1<<2),
00115 (1<<0)|(1<<1)|(1<<2)|(1<<3),
00116 (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4),
00117 (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5),
00118 (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6),
00119 (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7),
00120 (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<8),
00121 (1<<1)|(1<<3)|(1<<5)|(1<<7)
00122 };
00123
00124
00125 LedEngine::LedEngine() : dirty(true), numCycling(0), nextFlashEnd((unsigned int)-1) {
00126 for(unsigned int i=0; i<NumLEDs; i++) {
00127 infos[i].flashtime=0;
00128 infos[i].starttime=0;
00129 }
00130 clear();
00131 }
00132
00133 void LedEngine::recalcFlashEnd(void) {
00134 unsigned int t = get_time();
00135 nextFlashEnd=(unsigned int)-1;
00136 for(unsigned int i=0; i<NumLEDs; i++)
00137 if(infos[i].flashtime>t && nextFlashEnd>infos[i].flashtime)
00138 nextFlashEnd=infos[i].flashtime;
00139 }
00140
00141 int LedEngine::isDirty() {
00142 unsigned int t = get_time();
00143 if(t>nextFlashEnd) {
00144 dirty=true;
00145 recalcFlashEnd();
00146 };
00147 return dirty;
00148 }
00149
00150 int LedEngine::updateLEDs(const MotionCommand* caller, LEDBitMask_t mask) {
00151 unsigned int t = get_time();
00152 if (t>nextFlashEnd) recalcFlashEnd();
00153 #ifdef TGT_HAS_LEDS
00154 for(unsigned int i=0; i<NumLEDs; i++)
00155 if((mask>>i)&1)
00156 for(unsigned int f=0; f<NumFrames; f++)
00157 motman->setOutput(caller, i+LEDOffset,calcValue(i,t+f*FrameTime),f);
00158 #endif
00159 bool tmp=dirty;
00160 dirty = numCycling>0;
00161 return tmp;
00162 }
00163
00164 int LedEngine::updateLEDs(OutputCmd cmds[NumLEDs]) {
00165 unsigned int t = get_time();
00166 if (t>nextFlashEnd) recalcFlashEnd();
00167 for(unsigned int i=0; i<NumLEDs; i++)
00168 cmds[i].value=calcValue(i,t);
00169 bool tmp=dirty;
00170 dirty = numCycling>0;
00171 return tmp;
00172 }
00173
00174 int LedEngine::updateLEDFrames(OutputCmd cmds[NumLEDs][NumFrames]) {
00175 unsigned int t = get_time();
00176 if (t>nextFlashEnd) recalcFlashEnd();
00177 for(unsigned int i=0; i<NumLEDs; i++)
00178 for(unsigned int f=0; f<NumFrames; f++)
00179 cmds[i][f].value=calcValue(i,t+f*FrameTime);
00180 bool tmp=dirty;
00181 dirty = numCycling>0;
00182 return tmp;
00183 }
00184
00185 void LedEngine::invert(LEDBitMask_t leds) {
00186 if(leds!=0) {
00187 dirty=true;
00188 for(unsigned int i=0; i<NumLEDs; i++) {
00189 if((leds>>i)&1) {
00190 if(infos[i].isCycling)
00191 infos[i].amp*=-1;
00192 else
00193 infos[i].value=1-infos[i].value;
00194 }
00195 }
00196 }
00197 }
00198 void LedEngine::set(LEDBitMask_t leds, float value) {
00199 if(leds!=0) {
00200 dirty=true;
00201 for(unsigned int i=0; i<NumLEDs; i++)
00202 if((leds>>i)&1) {
00203 infos[i].value=value;
00204 if(infos[i].isCycling) {
00205 numCycling--;
00206 infos[i].isCycling=false;
00207 }
00208 }
00209 }
00210 }
00211 void LedEngine::cflash(LEDBitMask_t leds, float value, unsigned int ms) {
00212 dirty=true;
00213 unsigned int t = get_time();
00214 if(t+ms<nextFlashEnd)
00215 nextFlashEnd=t+ms;
00216 for(unsigned int i=0; i<NumLEDs; i++) {
00217 infos[i].flashvalue=((leds>>i)&1)*value;
00218 infos[i].flashtime=t+ms;
00219 }
00220 }
00221 void LedEngine::flash(LEDBitMask_t leds, float value, unsigned int ms) {
00222 if(leds!=0) {
00223 dirty=true;
00224 unsigned int t = get_time();
00225 if(t+ms<nextFlashEnd)
00226 nextFlashEnd=t+ms;
00227 for(unsigned int i=0; i<NumLEDs; i++)
00228 if((leds>>i)&1) {
00229 infos[i].flashvalue=value;
00230 infos[i].flashtime=t+ms;
00231 }
00232 }
00233 }
00234 void LedEngine::flash(LEDBitMask_t leds, unsigned int ms) {
00235 if(leds!=0) {
00236 dirty=true;
00237 unsigned int t = get_time();
00238 if(t+ms<nextFlashEnd)
00239 nextFlashEnd=t+ms;
00240 for(unsigned int i=0; i<NumLEDs; i++)
00241 if((leds>>i)&1) {
00242 infos[i].flashvalue=calcFlash(calcValue(i,t));
00243 infos[i].flashtime=t+ms;
00244 }
00245 }
00246 }
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263 void LedEngine::cycle(LEDBitMask_t leds, unsigned int period, float amp, float offset, int phase) {
00264
00265 if(leds!=0) {
00266 dirty=true;
00267 unsigned int start = get_time()+phase;
00268 for(unsigned int i=0; i<NumLEDs; i++)
00269 if((leds>>i)&1) {
00270 if(!infos[i].isCycling)
00271 numCycling++;
00272 infos[i].isCycling=true;
00273 infos[i].amp=amp;
00274 infos[i].period=period;
00275 infos[i].starttime=start;
00276 infos[i].offset=offset;
00277 }
00278 }
00279 }
00280 void LedEngine::clear() {
00281 for(unsigned int i=0; i<NumLEDs; i++) {
00282 infos[i].value=0;
00283 infos[i].flashtime=0;
00284 infos[i].isCycling=false;
00285 }
00286 numCycling=0;
00287 dirty=true;
00288 }
00289
00290 void LedEngine::extendFlash(unsigned int ms) {
00291 for(unsigned int i=0; i<NumLEDs; i++)
00292 if(infos[i].flashtime!=0)
00293 infos[i].flashtime+=ms;
00294 if(nextFlashEnd!=0)
00295 nextFlashEnd+=ms;
00296 dirty=true;
00297 }
00298
00299 void LedEngine::displayNumber(int x, numStyle_t style) {
00300 switch(style) {
00301 case onedigit: {
00302 #ifdef TGT_HAS_LED_PANEL
00303 const LEDBitMask_t * numMasks=defaultCountNumMasks;
00304 if(RobotName == ERS210Info::TargetName)
00305 numMasks=defaultMimicNumMasks;
00306 else if(RobotName == ERS220Info::TargetName)
00307 numMasks=ERS220numMasks;
00308 else if(RobotName == ERS7Info::TargetName)
00309 numMasks=ERS7numMasks;
00310 if(x>9 || x<-9) {
00311 ccycle(FaceLEDMask&~TopBrLEDMask,333,10,-5);
00312 infos[TopBrLEDOffset-LEDOffset].value=x<0?1:0;
00313 } else {
00314 clear();
00315 if(x<0) {
00316 set(numMasks[-x],1);
00317 infos[TopBrLEDOffset-LEDOffset].value=infos[TopBrLEDOffset-LEDOffset].value*.5f+.25f;
00318 } else
00319 set(numMasks[x],1);
00320 }
00321 #elif defined(TGT_HAS_LEDS)
00322 if(NumLEDs<9)
00323 return;
00324 const LEDBitMask_t * numMasks=defaultCountNumMasks;
00325 if(x>9 || x<-9) {
00326 ccycle((LEDBitMask_t)~(1<<(NumLEDs-1)),333,10,-5);
00327 infos[NumLEDs-1].value=x<0?1:0;
00328 } else {
00329 clear();
00330 if(x<0) {
00331 set(numMasks[-x],1);
00332 infos[NumLEDs-1].value=infos[NumLEDs-1].value*.5f+.25f;
00333 } else
00334 set(numMasks[x],1);
00335 }
00336 #endif
00337 } break;
00338 case twodigit:
00339 #ifdef TGT_HAS_LED_PANEL
00340 if(x>99 || x<-99) {
00341 ccycle(FaceLEDMask&~TopBrLEDMask,333,10,-5);
00342 infos[TopBrLEDOffset-LEDOffset].value=x<0?1:0;
00343 } else {
00344 clear();
00345 if(x<0) {
00346 infos[TopBrLEDOffset-LEDOffset].value=1;
00347 x=-x;
00348 }
00349 setOneOfTwo(x/10,BotRLEDOffset-LEDOffset,MidRLEDOffset-LEDOffset,TopRLEDOffset-LEDOffset);
00350 setOneOfTwo(x%10,BotLLEDOffset-LEDOffset,MidLLEDOffset-LEDOffset,TopLLEDOffset-LEDOffset);
00351 }
00352 #elif defined(TGT_HAS_LEDS)
00353 if(NumLEDs<3)
00354 return;
00355 if(x>99 || x<-99) {
00356 ccycle((LEDBitMask_t)~(1<<(NumLEDs-1)),333,10,-5);
00357 infos[NumLEDs-1].value=x<0?1:0;
00358 } else {
00359 clear();
00360 if(x<0) {
00361 infos[NumLEDs-1].value=1;
00362 x=-x;
00363 }
00364 setOneOfTwo(x/10,NumLEDs-3,NumLEDs-2,NumLEDs-1);
00365 setOneOfTwo(x%10,2,1,0);
00366 }
00367 #endif
00368 break;
00369 }
00370 }
00371 void LedEngine::setOneOfTwo(unsigned int x, unsigned int low, unsigned int mid, unsigned int high) {
00372 if(x==0)
00373 return;
00374 float bg = ((x-1)/3)/3.f;
00375 float fg = bg+1/3.f;
00376 if(RobotName == ERS7Info::TargetName)
00377 bg*=bg;
00378 switch(x%3) {
00379 case 1:
00380 infos[high].value=bg;
00381 infos[mid].value=bg;
00382 infos[low].value=fg;
00383 break;
00384 case 2:
00385 infos[high].value=bg;
00386 infos[mid].value=fg;
00387 infos[low].value=bg;
00388 break;
00389 case 0:
00390 infos[high].value=fg;
00391 infos[mid].value=bg;
00392 infos[low].value=bg;
00393 break;
00394 }
00395 }
00396
00397 void LedEngine::displayPercent(float x, percentStyle_t left_style, percentStyle_t right_style) {
00398 clear();
00399 #ifdef TGT_HAS_LED_PANEL
00400 if(x<0) {
00401 set(FaceLEDMask,.25f);
00402 return;
00403 }
00404 if(x>1) {
00405 set(FaceLEDMask,.75f);
00406 return;
00407 }
00408 if(left_style==major)
00409 setColumn(x,BotLLEDMask,MidLLEDMask,TopLLEDMask,TopBrLEDMask);
00410 if(right_style==major)
00411 setColumn(x,BotRLEDMask,MidRLEDMask,TopRLEDMask,TopBrLEDMask);
00412 x*=4;
00413 x-=(int)x;
00414 if(left_style==minor)
00415 setColumn(x,BotLLEDMask,MidLLEDMask,TopLLEDMask,TopBrLEDMask);
00416 if(right_style==minor)
00417 setColumn(x,BotRLEDMask,MidRLEDMask,TopRLEDMask,TopBrLEDMask);
00418 #else
00419 if(x<0) {
00420 set(AllLEDMask,.25f);
00421 return;
00422 }
00423 if(x>1) {
00424 set(AllLEDMask,.75f);
00425 return;
00426 }
00427 if(left_style==major)
00428 setColumn(x,3,2,1,0);
00429 if(right_style==major)
00430 setColumn(x,NumLEDs-4,NumLEDs-3,NumLEDs-2,NumLEDs-1);
00431 x*=4;
00432 x-=(int)x;
00433 if(left_style==minor)
00434 setColumn(x,3,2,1,0);
00435 if(right_style==minor)
00436 setColumn(x,NumLEDs-4,NumLEDs-3,NumLEDs-2,NumLEDs-1);
00437 #endif
00438 }
00439
00440 void LedEngine::setColumn(float x, unsigned int low, unsigned int mid, unsigned int high, unsigned int top) {
00441 LEDBitMask_t solid=0;
00442 LEDBitMask_t partial=0;
00443 switch((int)(4*x)) {
00444 case 4:
00445 solid|=top;
00446 case 3:
00447 solid|=high;
00448 case 2:
00449 solid|=mid;
00450 case 1:
00451 solid|=low;
00452 }
00453 switch((int)(4*x)) {
00454 case 3:
00455 partial=top; break;
00456 case 2:
00457 partial=high; break;
00458 case 1:
00459 partial=mid; break;
00460 case 0:
00461 partial=low; break;
00462 }
00463 float partialvalue=(x*4)-(int)(x*4);
00464 set(partial,partialvalue);
00465 set(solid,1);
00466 }
00467
00468 #endif
00469
00470
00471
00472
00473