SUMO - Simulation of Urban MObility

GUIParameterTracker.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // A window which displays the time line of one (or more) value(s)
00008 /****************************************************************************/
00009 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00010 // Copyright (C) 2001-2011 DLR (http://www.dlr.de/) and contributors
00011 /****************************************************************************/
00012 //
00013 //   This program is free software; you can redistribute it and/or modify
00014 //   it under the terms of the GNU General Public License as published by
00015 //   the Free Software Foundation; either version 2 of the License, or
00016 //   (at your option) any later version.
00017 //
00018 /****************************************************************************/
00019 
00020 
00021 // ===========================================================================
00022 // included modules
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 #include <foreign/polyfonts/polyfonts.h>
00033 #include <utils/foxtools/MFXUtils.h>
00034 #include <utils/iodevices/OutputDevice.h>
00035 #include <utils/common/ToString.h>
00036 #include <utils/common/StringUtils.h>
00037 #include <utils/common/SUMOTime.h>
00038 #include <utils/gui/globjects/GUIGlObject.h>
00039 #include <utils/gui/div/GUIIOGlobals.h>
00040 #include <utils/gui/windows/GUIAppEnum.h>
00041 #include <utils/gui/windows/GUIMainWindow.h>
00042 #include <utils/gui/images/GUIIconSubSys.h>
00043 #include "GUIParameterTracker.h"
00044 
00045 #ifdef _WIN32
00046 #include <windows.h>
00047 #endif
00048 
00049 #include <GL/gl.h>
00050 
00051 #ifdef CHECK_MEMORY_LEAKS
00052 #include <foreign/nvwa/debug_new.h>
00053 #endif // CHECK_MEMORY_LEAKS
00054 
00055 
00056 // ===========================================================================
00057 // FOX callback mapping
00058 // ===========================================================================
00059 FXDEFMAP(GUIParameterTracker) GUIParameterTrackerMap[]= {
00060     FXMAPFUNC(SEL_CONFIGURE, 0,                       GUIParameterTracker::onConfigure),
00061     FXMAPFUNC(SEL_PAINT,     0,                       GUIParameterTracker::onPaint),
00062     FXMAPFUNC(SEL_COMMAND,   MID_SIMSTEP,             GUIParameterTracker::onSimStep),
00063     FXMAPFUNC(SEL_COMMAND,   GUIParameterTracker::MID_AGGREGATIONINTERVAL, GUIParameterTracker::onCmdChangeAggregation),
00064     FXMAPFUNC(SEL_COMMAND,   GUIParameterTracker::MID_SAVE, GUIParameterTracker::onCmdSave),
00065 
00066 };
00067 
00068 // Macro for the GLTestApp class hierarchy implementation
00069 FXIMPLEMENT(GUIParameterTracker,FXMainWindow,GUIParameterTrackerMap,ARRAYNUMBER(GUIParameterTrackerMap))
00070 
00071 
00072 // ===========================================================================
00073 // method definitions
00074 // ===========================================================================
00075 GUIParameterTracker::GUIParameterTracker(GUIMainWindow& app,
00076         const std::string& name) throw()
00077     : FXMainWindow(app.getApp(),"Tracker",NULL,NULL,DECOR_ALL,20,20,300,200),
00078       myApplication(&app) {
00079     buildToolBar();
00080     app.addChild(this, true);
00081     FXVerticalFrame* glcanvasFrame = new FXVerticalFrame(this, FRAME_SUNKEN|LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0,0,0,0,0,0,0,0);
00082     myPanel = new GUIParameterTrackerPanel(glcanvasFrame, *myApplication, *this);
00083     setTitle(name.c_str());
00084     setIcon(GUIIconSubSys::getIcon(ICON_APP_TRACKER));
00085 }
00086 
00087 
00088 GUIParameterTracker::~GUIParameterTracker() throw() {
00089     myApplication->removeChild(this);
00090     for (std::vector<TrackerValueDesc*>::iterator i1=myTracked.begin(); i1!=myTracked.end(); i1++) {
00091         delete(*i1);
00092     }
00093     // deleted by GUINet
00094     for (std::vector<GLObjectValuePassConnector<SUMOReal>*>::iterator i2=myValuePassers.begin(); i2!=myValuePassers.end(); i2++) {
00095         delete(*i2);
00096     }
00097     delete myToolBarDrag;
00098     delete myToolBar;
00099 }
00100 
00101 
00102 void
00103 GUIParameterTracker::create() {
00104     FXMainWindow::create();
00105     myToolBarDrag->create();
00106 }
00107 
00108 
00109 void
00110 GUIParameterTracker::buildToolBar() throw() {
00111     myToolBarDrag = new FXToolBarShell(this,FRAME_NORMAL);
00112     myToolBar = new FXToolBar(this,myToolBarDrag, LAYOUT_SIDE_TOP|LAYOUT_FILL_X|FRAME_RAISED);
00113     new FXToolBarGrip(myToolBar, myToolBar, FXToolBar::ID_TOOLBARGRIP, TOOLBARGRIP_DOUBLE);
00114     // save button
00115     new FXButton(myToolBar,"\t\tSave the data...",
00116                  GUIIconSubSys::getIcon(ICON_SAVE), this, GUIParameterTracker::MID_SAVE,
00117                  ICON_ABOVE_TEXT|BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_TOP|LAYOUT_LEFT);
00118     // aggregation interval combo
00119     myAggregationInterval =
00120         new FXComboBox(myToolBar, 8, this, MID_AGGREGATIONINTERVAL,
00121                        FRAME_SUNKEN|LAYOUT_LEFT|LAYOUT_TOP|COMBOBOX_STATIC);
00122     myAggregationInterval->appendItem("1s");
00123     myAggregationInterval->appendItem("1min");
00124     myAggregationInterval->appendItem("5min");
00125     myAggregationInterval->appendItem("15min");
00126     myAggregationInterval->appendItem("30min");
00127     myAggregationInterval->appendItem("60min");
00128     myAggregationInterval->setNumVisible(6);
00129 }
00130 
00131 
00132 void
00133 GUIParameterTracker::addTracked(GUIGlObject& o, ValueSource<SUMOReal> *src,
00134                                 TrackerValueDesc* newTracked) throw() {
00135     myTracked.push_back(newTracked);
00136     // build connection (is automatically set into an execution map)
00137     myValuePassers.push_back(new GLObjectValuePassConnector<SUMOReal>(o, src, newTracked));
00138 }
00139 
00140 
00141 long
00142 GUIParameterTracker::onConfigure(FXObject* sender, FXSelector sel, void* data) {
00143     myPanel->onConfigure(sender, sel, data);
00144     return FXMainWindow::onConfigure(sender, sel, data);
00145 }
00146 
00147 
00148 long
00149 GUIParameterTracker::onPaint(FXObject* sender, FXSelector sel, void* data) {
00150     myPanel->onPaint(sender, sel, data);
00151     return FXMainWindow::onPaint(sender, sel, data);
00152 }
00153 
00154 
00155 long
00156 GUIParameterTracker::onSimStep(FXObject*,FXSelector,void*) {
00157     update();
00158     return 1;
00159 }
00160 
00161 
00162 long
00163 GUIParameterTracker::onCmdChangeAggregation(FXObject*,FXSelector,void*) {
00164     int index = myAggregationInterval->getCurrentItem();
00165     size_t aggInt = 0;
00166     switch (index) {
00167     case 0:
00168         aggInt = 1;
00169         break;
00170     case 1:
00171         aggInt = 60;
00172         break;
00173     case 2:
00174         aggInt = 60 * 5;
00175         break;
00176     case 3:
00177         aggInt = 60 * 15;
00178         break;
00179     case 4:
00180         aggInt = 60 * 30;
00181         break;
00182     case 5:
00183         aggInt = 60 * 60;
00184         break;
00185     default:
00186         throw 1;
00187         break;
00188     }
00189     for (std::vector<TrackerValueDesc*>::iterator i1=myTracked.begin(); i1!=myTracked.end(); i1++) {
00190         (*i1)->setAggregationSpan(TIME2STEPS(aggInt));
00191     }
00192     return 1;
00193 }
00194 
00195 
00196 long
00197 GUIParameterTracker::onCmdSave(FXObject*,FXSelector,void*) {
00198     FXString file = MFXUtils::getFilename2Write(this, "Save Data", ".csv", GUIIconSubSys::getIcon(ICON_EMPTY), gCurrentFolder);
00199     if (file=="") {
00200         return 1;
00201     }
00202     try {
00203         OutputDevice& dev = OutputDevice::getDevice(file.text());
00204         // write header
00205         std::vector<TrackerValueDesc*>::iterator i;
00206         dev << "# ";
00207         for (i=myTracked.begin(); i!=myTracked.end(); ++i) {
00208             if (i!=myTracked.begin()) {
00209                 dev << ';';
00210             }
00211             TrackerValueDesc* tvd = *i;
00212             dev << tvd->getName();
00213         }
00214         dev << '\n';
00215         // count entries
00216         size_t max = 0;
00217         for (i=myTracked.begin(); i!=myTracked.end(); ++i) {
00218             TrackerValueDesc* tvd = *i;
00219             size_t sizei = tvd->getAggregatedValues().size();
00220             if (max<sizei) {
00221                 max = sizei;
00222             }
00223             tvd->unlockValues();
00224         }
00225         // write entries
00226         for (unsigned int j=0; j<max; j++) {
00227             for (i=myTracked.begin(); i!=myTracked.end(); ++i) {
00228                 if (i!=myTracked.begin()) {
00229                     dev << ';';
00230                 }
00231                 TrackerValueDesc* tvd = *i;
00232                 dev << tvd->getAggregatedValues()[j];
00233                 tvd->unlockValues();
00234             }
00235             dev << '\n';
00236         }
00237         dev.close();
00238     } catch (IOError& e) {
00239         FXMessageBox::error(this, MBOX_OK, "Storing failed!", e.what());
00240     }
00241     return 1;
00242 }
00243 
00244 
00245 /* -------------------------------------------------------------------------
00246  * GUIParameterTracker::GUIParameterTrackerPanel-methods
00247  * ----------------------------------------------------------------------- */
00248 FXDEFMAP(GUIParameterTracker::GUIParameterTrackerPanel) GUIParameterTrackerPanelMap[]= {
00249     FXMAPFUNC(SEL_CONFIGURE, 0, GUIParameterTracker::GUIParameterTrackerPanel::onConfigure),
00250     FXMAPFUNC(SEL_PAINT,     0, GUIParameterTracker::GUIParameterTrackerPanel::onPaint),
00251 
00252 };
00253 
00254 // Macro for the GLTestApp class hierarchy implementation
00255 FXIMPLEMENT(GUIParameterTracker::GUIParameterTrackerPanel,FXGLCanvas,GUIParameterTrackerPanelMap,ARRAYNUMBER(GUIParameterTrackerPanelMap))
00256 
00257 
00258 
00259 GUIParameterTracker::GUIParameterTrackerPanel::GUIParameterTrackerPanel(
00260     FXComposite* c, GUIMainWindow& app,
00261     GUIParameterTracker& parent) throw()
00262     : FXGLCanvas(c, app.getGLVisual(), app.getBuildGLCanvas(), (FXObject*) 0, (FXSelector) 0, LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0, 0, 300, 200),
00263       myParent(&parent), myApplication(&app) {}
00264 
00265 
00266 GUIParameterTracker::GUIParameterTrackerPanel::~GUIParameterTrackerPanel() throw() {}
00267 
00268 
00269 void
00270 GUIParameterTracker::GUIParameterTrackerPanel::drawValues() throw() {
00271     pfSetScale((SUMOReal) 0.1);
00272     pfSetScaleXY((SUMOReal)(.1*300./myWidthInPixels), (SUMOReal)(.1*300./(SUMOReal) myHeightInPixels));
00273     //
00274     glMatrixMode(GL_PROJECTION);
00275     glLoadIdentity();
00276     glMatrixMode(GL_MODELVIEW);
00277     glLoadIdentity();
00278     glDisable(GL_TEXTURE_2D);
00279     size_t run = 0;
00280     for (std::vector<TrackerValueDesc*>::iterator i=myParent->myTracked.begin(); i!=myParent->myTracked.end(); i++) {
00281         TrackerValueDesc* desc = *i;
00282         drawValue(*desc,
00283                   (SUMOReal) myWidthInPixels / (SUMOReal) myParent->myTracked.size() *(SUMOReal) run);
00284         run++;
00285     }
00286 }
00287 
00288 
00289 void
00290 GUIParameterTracker::GUIParameterTrackerPanel::drawValue(TrackerValueDesc& desc,
00291         SUMOReal /*namePos*/) throw() {
00292     // apply scaling
00293     glPushMatrix();
00294 
00295     // apply the positiopn offset of the display
00296     glScaled(0.8, 0.8, 1);
00297     // apply value range scaling
00298     SUMOReal ys = (SUMOReal) 2.0 / (SUMOReal) desc.getRange();
00299     glScaled(1.0, ys, 1.0);
00300     glTranslated(-1.0, -desc.getYCenter(), 0);
00301 
00302     // set color
00303     const RGBColor& col = desc.getColor();
00304     SUMOReal red = (SUMOReal) col.red();
00305     SUMOReal green = (SUMOReal) col.green();
00306     SUMOReal blue = (SUMOReal) col.blue();
00307     // draw value bounderies
00308     // draw minimum boundary
00309     glBegin(GL_LINES);
00310     glVertex2d(0, desc.getMin());
00311     glVertex2d(2.0, desc.getMin());
00312     glEnd();
00313     glBegin(GL_LINES);
00314     glVertex2d(0, desc.getMax());
00315     glVertex2d(2.0, desc.getMax());
00316     glEnd();
00317     glColor4f(red, green, blue, 0.3f);
00318     for (int a=1; a<6; a++) {
00319         SUMOReal ypos = (desc.getRange()) / (SUMOReal) 6.0 * (SUMOReal) a + desc.getMin();
00320         glBegin(GL_LINES);
00321         glVertex2d(0, ypos);
00322         glVertex2d(2.0, ypos);
00323         glEnd();
00324     }
00325     const std::vector<SUMOReal> &values = desc.getAggregatedValues();
00326     SUMOReal latest = 0;
00327     if (values.size()<2) {
00328         glPopMatrix();
00329         desc.unlockValues();
00330         return;
00331     } else {
00332         latest = values.back();
00333         // init values
00334         SUMOReal xStep = (SUMOReal) 2.0 / (SUMOReal) values.size();
00335         std::vector<SUMOReal>::const_iterator i = values.begin();
00336         SUMOReal yp = (*i);
00337         SUMOReal xp = 0;
00338         i++;
00339         glColor4f(red, green, blue, 1.0f);
00340         for (; i!=values.end(); i++) {
00341             SUMOReal yn = (*i);
00342             SUMOReal xn = xp + xStep;
00343             glBegin(GL_LINES);
00344             glVertex2d(xp, yp);
00345             glVertex2d(xn, yn);
00346             glEnd();
00347             yp = yn;
00348             xp = xn;
00349         }
00350         desc.unlockValues();
00351         glPopMatrix();
00352     }
00353 
00354     // draw value bounderies and descriptions
00355     glColor3d(red, green, blue);
00356 
00357     // draw min time
00358     SUMOTime beginStep = desc.getRecordingBegin();
00359     std::string begStr = time2string(beginStep);
00360     SUMOReal w = pfdkGetStringWidth(begStr.c_str());
00361     glRotated(180, 1, 0, 0);
00362     pfSetPosition(0, 0);
00363     glTranslated(-0.8-w/2., 0.88, 0);
00364     pfDrawString(begStr.c_str());
00365     glTranslated(0.8+w/2., -0.88, 0);
00366     glRotated(-180, 1, 0, 0);
00367 
00368     // draw max time
00369     glRotated(180, 1, 0, 0);
00370     pfSetPosition(0, 0);
00371     glTranslated(0.75, 0.88, 0);
00372     pfDrawString(time2string(beginStep + static_cast<SUMOTime>(values.size() * desc.getAggregationSpan())).c_str());
00373     glTranslated(-0.75, -0.88, 0);
00374     glRotated(-180, 1, 0, 0);
00375 
00376     // draw min value
00377     glRotated(180, 1, 0, 0);
00378     pfSetPosition(0, 0);
00379     glTranslated(-0.98, 0.82, 0);
00380     pfDrawString(toString(desc.getMin()).c_str());
00381     glTranslated(0.98, -0.82, 0);
00382     glRotated(-180, 1, 0, 0);
00383 
00384     // draw max value
00385     glRotated(180, 1, 0, 0);
00386     pfSetPosition(0, 0);
00387     glTranslated(-0.98, -0.78, 0);
00388     pfDrawString(toString(desc.getMax()).c_str());
00389     glTranslated(0.98, 0.78, 0);
00390     glRotated(-180, 1, 0, 0);
00391 
00392     // draw current value
00393     glRotated(180, 1, 0, 0);
00394     pfSetPosition(0, 0);
00395     SUMOReal p = (SUMOReal) 0.8 -
00396                  ((SUMOReal) 1.6 / (desc.getMax()-desc.getMin()) * (latest-desc.getMin()));
00397     glTranslated(-0.98, p+.02, 0);
00398     pfDrawString(toString(latest).c_str());
00399     glTranslated(0.98, -(p+.02), 0);
00400     glRotated(-180, 1, 0, 0);
00401 
00402     // draw name
00403     glRotated(180, 1, 0, 0);
00404     pfSetPosition(0, 0);
00405     glTranslated(-0.98, -.92, 0);
00406     pfDrawString(desc.getName().c_str());
00407     glTranslated(0.98, .92, 0);
00408     glRotated(-180, 1, 0, 0);
00409 }
00410 
00411 
00412 long
00413 GUIParameterTracker::GUIParameterTrackerPanel::onConfigure(FXObject*,
00414         FXSelector,void*) {
00415     if (makeCurrent()) {
00416         myWidthInPixels = myParent->getWidth();
00417         myHeightInPixels = myParent->getHeight();
00418         if (myWidthInPixels!=0&&myHeightInPixels!=0) {
00419             glViewport(0, 0, myWidthInPixels-1, myHeightInPixels-1);
00420             glClearColor(1.0, 1.0, 1.0, 1);
00421             glDisable(GL_DEPTH_TEST);
00422             glDisable(GL_LIGHTING);
00423             glDisable(GL_LINE_SMOOTH);
00424             glEnable(GL_BLEND);
00425             glEnable(GL_ALPHA_TEST);
00426             glDisable(GL_COLOR_MATERIAL);
00427             glLineWidth(1);
00428             glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00429         }
00430         makeNonCurrent();
00431     }
00432     return 1;
00433 }
00434 
00435 
00436 long
00437 GUIParameterTracker::GUIParameterTrackerPanel::onPaint(FXObject*,
00438         FXSelector,void*) {
00439     if (!isEnabled()) {
00440         return 1;
00441     }
00442     if (makeCurrent()) {
00443         myWidthInPixels = getWidth();
00444         myHeightInPixels = getHeight();
00445         if (myWidthInPixels!=0&&myHeightInPixels!=0) {
00446             glViewport(0, 0, myWidthInPixels-1, myHeightInPixels-1);
00447             glClearColor(1.0, 1.0, 1.0, 1);
00448             glDisable(GL_DEPTH_TEST);
00449             glDisable(GL_LIGHTING);
00450             glDisable(GL_LINE_SMOOTH);
00451             glEnable(GL_BLEND);
00452             glEnable(GL_ALPHA_TEST);
00453             glDisable(GL_COLOR_MATERIAL);
00454             glLineWidth(1);
00455             glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00456             // draw
00457             glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
00458             drawValues();
00459             swapBuffers();
00460         }
00461         makeNonCurrent();
00462     }
00463     return 1;
00464 }
00465 
00466 
00467 
00468 /****************************************************************************/
00469 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines