00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef _MSC_VER
00025 #include <windows_config.h>
00026 #else
00027 #include <config.h>
00028 #endif
00029
00030 #include <string>
00031 #include <fstream>
00032
00033 #include <utils/common/ToString.h>
00034 #include <utils/common/StringUtils.h>
00035 #include "GUIParameterTracker.h"
00036 #include <utils/gui/windows/GUIAppEnum.h>
00037 #include <utils/gui/globjects/GUIGlObject.h>
00038 #include <utils/foxtools/MFXUtils.h>
00039 #include <utils/gui/images/GUITexturesHelper.h>
00040 #include <utils/gui/windows/GUIMainWindow.h>
00041 #include <utils/gui/div/GUIIOGlobals.h>
00042 #include <utils/gui/images/GUIIconSubSys.h>
00043 #include <utils/common/SUMOTime.h>
00044 #include <foreign/polyfonts/polyfonts.h>
00045 #include <utils/iodevices/OutputDevice.h>
00046
00047 #ifdef _WIN32
00048 #include <windows.h>
00049 #endif
00050
00051 #include <GL/gl.h>
00052
00053 #ifdef CHECK_MEMORY_LEAKS
00054 #include <foreign/nvwa/debug_new.h>
00055 #endif // CHECK_MEMORY_LEAKS
00056
00057
00058
00059
00060
00061 FXDEFMAP(GUIParameterTracker) GUIParameterTrackerMap[]={
00062 FXMAPFUNC(SEL_CONFIGURE, 0, GUIParameterTracker::onConfigure),
00063 FXMAPFUNC(SEL_PAINT, 0, GUIParameterTracker::onPaint),
00064 FXMAPFUNC(SEL_COMMAND, MID_SIMSTEP, GUIParameterTracker::onSimStep),
00065 FXMAPFUNC(SEL_COMMAND, GUIParameterTracker::MID_AGGREGATIONINTERVAL, GUIParameterTracker::onCmdChangeAggregation),
00066 FXMAPFUNC(SEL_COMMAND, GUIParameterTracker::MID_SAVE, GUIParameterTracker::onCmdSave),
00067
00068 };
00069
00070
00071 FXIMPLEMENT(GUIParameterTracker,FXMainWindow,GUIParameterTrackerMap,ARRAYNUMBER(GUIParameterTrackerMap))
00072
00073
00074
00075
00076
00077 GUIParameterTracker::GUIParameterTracker(GUIMainWindow &app,
00078 const std::string &name)
00079 : FXMainWindow(app.getApp(),"Tracker",NULL,NULL,DECOR_ALL,20,20,300,200),
00080 myApplication(&app) {
00081 buildToolBar();
00082 app.addChild(this, true);
00083 FXVerticalFrame *glcanvasFrame =
00084 new FXVerticalFrame(this,FRAME_SUNKEN|LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0,0,0,0,0);
00085 myPanel = new GUIParameterTrackerPanel(glcanvasFrame,
00086 *myApplication, *this);
00087 setTitle(name.c_str());
00088 setIcon(GUIIconSubSys::getIcon(ICON_APP_TRACKER));
00089 }
00090
00091
00092 GUIParameterTracker::GUIParameterTracker(GUIMainWindow &app,
00093 const std::string &name,
00094 GUIGlObject &,
00095 int , int )
00096 : FXMainWindow(app.getApp(),"Tracker",NULL,NULL,DECOR_ALL,20, 20,300,200),
00097 myApplication(&app) {
00098 buildToolBar();
00099 app.addChild(this, true);
00100 FXVerticalFrame *glcanvasFrame =
00101 new FXVerticalFrame(this,
00102 FRAME_SUNKEN|LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y,
00103 0,0,0,0,0,0,0,0);
00104 myPanel = new GUIParameterTrackerPanel(glcanvasFrame,
00105 *myApplication, *this);
00106 setTitle(name.c_str());
00107 setIcon(GUIIconSubSys::getIcon(ICON_APP_TRACKER));
00108 }
00109
00110
00111 GUIParameterTracker::~GUIParameterTracker() {
00112 myApplication->removeChild(this);
00113 for (TrackedVarsVector::iterator i1=myTracked.begin(); i1!=myTracked.end(); i1++) {
00114 delete(*i1);
00115 }
00116
00117 for (ValuePasserVector::iterator i2=myValuePassers.begin(); i2!=myValuePassers.end(); i2++) {
00118 delete(*i2);
00119 }
00120 delete myToolBarDrag;
00121 delete myToolBar;
00122 }
00123
00124
00125 void
00126 GUIParameterTracker::create() {
00127 FXMainWindow::create();
00128 myToolBarDrag->create();
00129 }
00130
00131
00132 void
00133 GUIParameterTracker::addVariable(GUIGlObject *o, const std::string &name,
00134 size_t recordBegin) {
00135 TrackerValueDesc *newTracked =
00136 new TrackerValueDesc(name, RGBColor(0, 0, 0), o, recordBegin);
00137 myTracked.push_back(newTracked);
00138 }
00139
00140
00141 void
00142 GUIParameterTracker::buildToolBar() {
00143 myToolBarDrag = new FXToolBarShell(this,FRAME_NORMAL);
00144 myToolBar = new FXToolBar(this,myToolBarDrag, LAYOUT_SIDE_TOP|LAYOUT_FILL_X|FRAME_RAISED);
00145 new FXToolBarGrip(myToolBar, myToolBar, FXToolBar::ID_TOOLBARGRIP, TOOLBARGRIP_DOUBLE);
00146
00147 new FXButton(myToolBar,"\t\tSave the data...",
00148 GUIIconSubSys::getIcon(ICON_SAVE), this, GUIParameterTracker::MID_SAVE,
00149 ICON_ABOVE_TEXT|BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT);
00150
00151 myAggregationInterval =
00152 new FXComboBox(myToolBar, 8, this, MID_AGGREGATIONINTERVAL,
00153 FRAME_SUNKEN|LAYOUT_LEFT|LAYOUT_TOP|COMBOBOX_STATIC);
00154 myAggregationInterval->appendItem("1s");
00155 myAggregationInterval->appendItem("1min");
00156 myAggregationInterval->appendItem("5min");
00157 myAggregationInterval->appendItem("15min");
00158 myAggregationInterval->appendItem("30min");
00159 myAggregationInterval->appendItem("60min");
00160 myAggregationInterval->setNumVisible(6);
00161 }
00162
00163
00164 void
00165 GUIParameterTracker::addTracked(GUIGlObject &o,
00166 ValueSource<SUMOReal> *src,
00167 TrackerValueDesc *newTracked) {
00168 myTracked.push_back(newTracked);
00169
00170 myValuePassers.push_back(new GLObjectValuePassConnector<SUMOReal>(o,
00171 src, newTracked));
00172 }
00173
00174
00175 long
00176 GUIParameterTracker::onConfigure(FXObject *sender, FXSelector sel, void *data) {
00177 myPanel->onConfigure(sender, sel, data);
00178 return FXMainWindow::onConfigure(sender, sel, data);
00179 }
00180
00181
00182 long
00183 GUIParameterTracker::onPaint(FXObject *sender, FXSelector sel, void *data) {
00184 myPanel->onPaint(sender, sel, data);
00185 return FXMainWindow::onPaint(sender, sel, data);
00186 }
00187
00188
00189 long
00190 GUIParameterTracker::onSimStep(FXObject*,FXSelector,void*) {
00191 update();
00192 return 1;
00193 }
00194
00195
00196 long
00197 GUIParameterTracker::onCmdChangeAggregation(FXObject*,FXSelector,void*) {
00198 int index = myAggregationInterval->getCurrentItem();
00199 size_t aggInt = 0;
00200 switch (index) {
00201 case 0:
00202 aggInt = 1;
00203 break;
00204 case 1:
00205 aggInt = 60;
00206 break;
00207 case 2:
00208 aggInt = 60 * 5;
00209 break;
00210 case 3:
00211 aggInt = 60 * 15;
00212 break;
00213 case 4:
00214 aggInt = 60 * 30;
00215 break;
00216 case 5:
00217 aggInt = 60 * 60;
00218 break;
00219 default:
00220 throw 1;
00221 break;
00222 }
00223 TrackedVarsVector::iterator i1;
00224 for (i1=myTracked.begin(); i1!=myTracked.end(); i1++) {
00225 (*i1)->setAggregationSpan(aggInt);
00226 }
00227 return 1;
00228 }
00229
00230
00231 long
00232 GUIParameterTracker::onCmdSave(FXObject*,FXSelector,void*) {
00233 FXString file = MFXUtils::getFilename2Write(this, "Save Data", ".csv", GUIIconSubSys::getIcon(ICON_EMPTY), gCurrentFolder);
00234 if (file=="") {
00235 return 1;
00236 }
00237 try {
00238 OutputDevice &dev = OutputDevice::getDevice(file.text());
00239
00240 TrackedVarsVector::iterator i;
00241 dev << "# ";
00242 for (i=myTracked.begin(); i!=myTracked.end(); ++i) {
00243 if (i!=myTracked.begin()) {
00244 dev << ';';
00245 }
00246 TrackerValueDesc *tvd = *i;
00247 dev << tvd->getName();
00248 }
00249 dev << '\n';
00250
00251 size_t max = 0;
00252 for (i=myTracked.begin(); i!=myTracked.end(); ++i) {
00253 TrackerValueDesc *tvd = *i;
00254 size_t sizei = tvd->getAggregatedValues().size();
00255 if (max<sizei) {
00256 max = sizei;
00257 }
00258 tvd->unlockValues();
00259 }
00260
00261 for (unsigned int j=0; j<max; j++) {
00262 for (i=myTracked.begin(); i!=myTracked.end(); ++i) {
00263 if (i!=myTracked.begin()) {
00264 dev << ';';
00265 }
00266 TrackerValueDesc *tvd = *i;
00267 dev << tvd->getAggregatedValues()[j];
00268 tvd->unlockValues();
00269 }
00270 dev << '\n';
00271 }
00272 dev.close();
00273 } catch (IOError &e) {
00274 FXMessageBox::error(this, MBOX_OK, "Storing failed!", e.what());
00275 }
00276 return 1;
00277 }
00278
00279
00280
00281
00282
00283 FXDEFMAP(GUIParameterTracker::GUIParameterTrackerPanel) GUIParameterTrackerPanelMap[]={
00284 FXMAPFUNC(SEL_CONFIGURE, 0, GUIParameterTracker::GUIParameterTrackerPanel::onConfigure),
00285 FXMAPFUNC(SEL_PAINT, 0, GUIParameterTracker::GUIParameterTrackerPanel::onPaint),
00286
00287 };
00288
00289
00290 FXIMPLEMENT(GUIParameterTracker::GUIParameterTrackerPanel,FXGLCanvas,GUIParameterTrackerPanelMap,ARRAYNUMBER(GUIParameterTrackerPanelMap))
00291
00292
00293
00294 GUIParameterTracker::GUIParameterTrackerPanel::GUIParameterTrackerPanel(
00295 FXComposite *c, GUIMainWindow &app,
00296 GUIParameterTracker &parent)
00297 : FXGLCanvas(c, app.getGLVisual(), app.getBuildGLCanvas(), (FXObject*) 0, (FXSelector) 0, LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0, 0, 300, 200),
00298 myParent(&parent), myApplication(&app) {}
00299
00300
00301 GUIParameterTracker::GUIParameterTrackerPanel::~GUIParameterTrackerPanel() {}
00302
00303
00304 void
00305 GUIParameterTracker::GUIParameterTrackerPanel::drawValues() {
00306
00307
00308
00309
00310
00311
00312 pfSetScale((SUMOReal) 0.1);
00313 pfSetScaleXY((SUMOReal)(.1*300./myWidthInPixels), (SUMOReal)(.1*300./(SUMOReal) myHeightInPixels));
00314
00315
00316
00317 glMatrixMode(GL_PROJECTION);
00318 glLoadIdentity();
00319 glMatrixMode(GL_MODELVIEW);
00320 glLoadIdentity();
00321 glDisable(GL_TEXTURE_2D);
00322 size_t run = 0;
00323 for (TrackedVarsVector::iterator i=myParent->myTracked.begin(); i!=myParent->myTracked.end(); i++) {
00324 TrackerValueDesc *desc = *i;
00325 drawValue(*desc,
00326 (SUMOReal) myWidthInPixels / (SUMOReal) myParent->myTracked.size() *(SUMOReal) run);
00327 run++;
00328 }
00329
00330 }
00331
00332
00333 void
00334 GUIParameterTracker::GUIParameterTrackerPanel::drawValue(TrackerValueDesc &desc,
00335 SUMOReal ) {
00336
00337 glPushMatrix();
00338
00339
00340 glScaled(0.8, 0.8, 1);
00341
00342 SUMOReal ys = (SUMOReal) 2.0 / (SUMOReal) desc.getRange();
00343 glScaled(1.0, ys, 1.0);
00344 glTranslated(-1.0, -desc.getYCenter(), 0);
00345
00346
00347 const RGBColor &col = desc.getColor();
00348 SUMOReal red = (SUMOReal) col.red();
00349 SUMOReal green = (SUMOReal) col.green();
00350 SUMOReal blue = (SUMOReal) col.blue();
00351
00352
00353 glBegin(GL_LINES);
00354 glVertex2d(0, desc.getMin());
00355 glVertex2d(2.0, desc.getMin());
00356 glEnd();
00357 glBegin(GL_LINES);
00358 glVertex2d(0, desc.getMax());
00359 glVertex2d(2.0, desc.getMax());
00360 glEnd();
00361 glColor4f(red, green, blue, 0.3f);
00362 for (int a=1; a<6; a++) {
00363 SUMOReal ypos = (desc.getRange()) / (SUMOReal) 6.0 * (SUMOReal) a + desc.getMin();
00364 glBegin(GL_LINES);
00365 glVertex2d(0, ypos);
00366 glVertex2d(2.0, ypos);
00367 glEnd();
00368 }
00369 const std::vector<SUMOReal> &values = desc.getAggregatedValues();
00370 SUMOReal latest = 0;
00371 if (values.size()<2) {
00372 glPopMatrix();
00373 desc.unlockValues();
00374 return;
00375 } else {
00376 latest = values.back();
00377
00378 SUMOReal xStep = (SUMOReal) 2.0 / (SUMOReal) values.size();
00379 std::vector<SUMOReal>::const_iterator i = values.begin();
00380 SUMOReal yp = (*i);
00381 SUMOReal xp = 0;
00382 i++;
00383 glColor4f(red, green, blue, 1.0f);
00384 for (; i!=values.end(); i++) {
00385 SUMOReal yn = (*i);
00386 SUMOReal xn = xp + xStep;
00387 glBegin(GL_LINES);
00388 glVertex2d(xp, yp);
00389 glVertex2d(xn, yn);
00390 glEnd();
00391 yp = yn;
00392 xp = xn;
00393 }
00394 desc.unlockValues();
00395 glPopMatrix();
00396 }
00397
00398
00399 glColor3d(red, green, blue);
00400
00401
00402
00403 SUMOTime beginStep = desc.getRecordingBegin();
00404 std::string begStr = toString((SUMOReal) beginStep);
00405 SUMOReal w = pfdkGetStringWidth(begStr.c_str());
00406 glRotated(180, 1, 0, 0);
00407 pfSetPosition(0, 0);
00408 glTranslated(-0.8-w/2., 0.88, 0);
00409 pfDrawString(begStr.c_str());
00410 glTranslated(0.8+w/2., -0.88, 0);
00411 glRotated(-180, 1, 0, 0);
00412
00413
00414 glRotated(180, 1, 0, 0);
00415 pfSetPosition(0, 0);
00416 glTranslated(0.75, 0.88, 0);
00417 pfDrawString(toString(
00418 (SUMOReal) beginStep + (SUMOReal) values.size() *(SUMOReal) desc.getAggregationSpan()).c_str());
00419 glTranslated(-0.75, -0.88, 0);
00420 glRotated(-180, 1, 0, 0);
00421
00422
00423 glRotated(180, 1, 0, 0);
00424 pfSetPosition(0, 0);
00425 glTranslated(-0.98, 0.82, 0);
00426 pfDrawString(toString(desc.getMin()).c_str());
00427 glTranslated(0.98, -0.82, 0);
00428 glRotated(-180, 1, 0, 0);
00429
00430
00431 glRotated(180, 1, 0, 0);
00432 pfSetPosition(0, 0);
00433 glTranslated(-0.98, -0.78, 0);
00434 pfDrawString(toString(desc.getMax()).c_str());
00435 glTranslated(0.98, 0.78, 0);
00436 glRotated(-180, 1, 0, 0);
00437
00438
00439 glRotated(180, 1, 0, 0);
00440 pfSetPosition(0, 0);
00441 SUMOReal p = (SUMOReal) 0.8 -
00442 ((SUMOReal) 1.6 / (desc.getMax()-desc.getMin()) * (latest-desc.getMin()));
00443 glTranslated(-0.98, p+.02, 0);
00444 pfDrawString(toString(latest).c_str());
00445 glTranslated(0.98, -(p+.02), 0);
00446 glRotated(-180, 1, 0, 0);
00447
00448
00449 glRotated(180, 1, 0, 0);
00450 pfSetPosition(0, 0);
00451 glTranslated(-0.98, -.92, 0);
00452 pfDrawString(desc.getName().c_str());
00453 glTranslated(0.98, .92, 0);
00454 glRotated(-180, 1, 0, 0);
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527 }
00528
00529
00530 SUMOReal
00531 GUIParameterTracker::GUIParameterTrackerPanel::patchHeightVal(TrackerValueDesc &desc,
00532 SUMOReal d) {
00533 SUMOReal height = (SUMOReal) myHeightInPixels;
00534 SUMOReal range = (SUMOReal) desc.getRange();
00535 SUMOReal yoff = (SUMOReal) desc.getYCenter();
00536 SUMOReal abs = (height) * (((SUMOReal)d-yoff)/range) * 0.8f;
00537 return (height * 0.5f) - abs - 6;
00538 }
00539
00540
00541 long
00542 GUIParameterTracker::GUIParameterTrackerPanel::onConfigure(FXObject*,
00543 FXSelector,void*) {
00544 if (makeCurrent()) {
00545 myWidthInPixels = myParent->getWidth();
00546 myHeightInPixels = myParent->getHeight();
00547 if (myWidthInPixels!=0&&myHeightInPixels!=0) {
00548 glViewport(0, 0, myWidthInPixels-1, myHeightInPixels-1);
00549 glClearColor(1.0, 1.0, 1.0, 1);
00550 glDisable(GL_DEPTH_TEST);
00551 glDisable(GL_LIGHTING);
00552 glDisable(GL_LINE_SMOOTH);
00553 glEnable(GL_BLEND);
00554 glEnable(GL_ALPHA_TEST);
00555 glDisable(GL_COLOR_MATERIAL);
00556 glLineWidth(1);
00557 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00558 }
00559 makeNonCurrent();
00560 }
00561 return 1;
00562 }
00563
00564
00565 long
00566 GUIParameterTracker::GUIParameterTrackerPanel::onPaint(FXObject*,
00567 FXSelector,void*) {
00568 if (!isEnabled()) {
00569 return 1;
00570 }
00571 if (makeCurrent()) {
00572 myWidthInPixels = getWidth();
00573 myHeightInPixels = getHeight();
00574 if (myWidthInPixels!=0&&myHeightInPixels!=0) {
00575 glViewport(0, 0, myWidthInPixels-1, myHeightInPixels-1);
00576 glClearColor(1.0, 1.0, 1.0, 1);
00577 glDisable(GL_DEPTH_TEST);
00578 glDisable(GL_LIGHTING);
00579 glDisable(GL_LINE_SMOOTH);
00580 glEnable(GL_BLEND);
00581 glEnable(GL_ALPHA_TEST);
00582 glDisable(GL_COLOR_MATERIAL);
00583 glLineWidth(1);
00584 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00585
00586 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
00587 drawValues();
00588 glFlush();
00589 swapBuffers();
00590 }
00591 makeNonCurrent();
00592 }
00593 return 1;
00594 }
00595
00596
00597
00598
00599