24 #include "evorobotviewer.h"
25 #include "abstracttest.h"
27 #include "total99resources.h"
28 #include <QGridLayout>
29 #include <QPushButton>
31 #include <QFileDialog>
32 #include <QVBoxLayout>
37 #include <QCoreApplication>
42 using namespace qglviewer;
49 #pragma warning(disable:4996)
57 ga = evorobot->
getGA();
63 QTimer* timer =
new QTimer(
this);
64 timer->setInterval( 40 );
65 timer->setSingleShot(
false );
71 connect( timer, SIGNAL(timeout()),
this, SLOT(onWorldAdvance()) );
75 connect( evorobot, SIGNAL(actionFinished()),
this, SLOT(onActionFinished()) );
85 actionsMenu->addAction(
"Evolve", evorobot, SLOT(evolve()) );
86 actionsMenu->addAction(
"Stop", evorobot, SLOT(stop()) );
90 QList<ParameterSettableUIViewer> viewsList;
91 viewsList.append( evogaControls( parent, flags ) );
93 viewsList.append( fitview( parent, flags ) );
94 viewsList.append( statview( parent, flags ) );
95 viewsList.append( renderWorld( parent, flags ) );
98 for (
int i = 0; i < testsList.size(); i++) {
100 if ( testIndividual ) {
101 viewsList.append( testIndividualUI( testIndividual, parent, flags ) );
108 QMenu* testMenu = menuBar->addMenu(
"Tests" );
110 for (
int i = 0; i < testsList.size(); i++) {
112 QAction* action = testMenu->addAction( test->
menuText(), evorobot, SLOT(runTestFromQAction()) );
113 action->setData( QVariant(testsList[i]) );
114 action->setToolTip( test->
tooltip() );
128 ParameterSettableUIViewer EvoRobotViewer::evogaControls( QWidget* parent, Qt::WindowFlags flags ) {
129 QWidget* widget =
new QWidget( parent, flags );
130 QGridLayout* lay =
new QGridLayout( widget );
134 infoEvoga =
new QLabel(
"Information", widget );
135 infoEvoga->setStyleSheet(
"QLabel { font: bold normal large \"Courier\" }" );
136 lay->addWidget( infoEvoga, 0, 0, 1, 2 );
138 QPushButton* bt =
new QPushButton(
"Do Step", widget );
139 bt->setAutoRepeat(
true);
140 bt->setEnabled(
false );
141 connect( bt, SIGNAL(clicked(
bool)), ga, SLOT(doNextStep()) );
143 QCheckBox* cb =
new QCheckBox(
"Step by Step Mode", widget );
144 connect( cb, SIGNAL(clicked(
bool)), ga, SLOT(enableStepByStep(
bool)) );
145 connect( cb, SIGNAL(clicked(
bool)), bt, SLOT(setEnabled(
bool)) );
147 lay->addWidget( cb, 1, 0 );
148 lay->addWidget( bt, 1, 1 );
150 bt =
new QPushButton(
"Next Trial", widget );
151 connect( bt, SIGNAL(clicked()),
this, SLOT(evogaNextTrial()) );
152 lay->addWidget( bt, 2, 0, 1, 2 );
157 QLabel* lb =
new QLabel(
"Simulation Throttle - speed regulator", widget );
158 lay->addWidget( lb, 3, 0, 1, 2 );
159 simulationThrottle =
new QSlider( widget );
160 simulationThrottle->setMinimum( 0 );
161 simulationThrottle->setMaximum( 100 );
162 simulationThrottle->setMinimumHeight( 200 );
163 simulationThrottle->setOrientation( Qt::Vertical );
165 simulationThrottle->setValue( floor(13.0*std::log((
float)currDelay)) );
166 connect( simulationThrottle, SIGNAL(valueChanged(
int)),
this, SLOT(onSimulationThrottleChanges(
int)) );
167 lay->addWidget( simulationThrottle, 4, 0, 3, 1 );
168 lb =
new QLabel(
"slow", widget );
169 lay->addWidget( lb, 4, 1 );
171 QString str =
"Running as fast as possible";
172 if ( currDelay > 0 ) {
175 extra =
"Running approximately at real time";
177 str = QString(
"Speed: %1 frames/second [%2 ms]\n%3")
178 .arg(1000.0/currDelay)
182 simulationSpeed =
new QLabel( str, widget );
183 lay->addWidget( simulationSpeed, 5, 1 );
184 lb =
new QLabel(
"fast", widget );
185 lay->addWidget( lb, 6, 1 );
187 return ParameterSettableUIViewer( widget,
"Evoga Controls" );
190 void EvoRobotViewer::evogaNextTrial() {
194 void EvoRobotViewer::onSimulationThrottleChanges(
int newvalue ) {
196 int delay = ceil(std::exp( newvalue/13.0 )-1.0);
201 extra =
"Running approximately at real time";
203 simulationSpeed->setText( QString(
"Speed: %1 frames/second [%2 ms]\n%3")
208 simulationSpeed->setText(
"Running as fast as possible" );
212 ParameterSettableUIViewer EvoRobotViewer::fitview( QWidget* parent, Qt::WindowFlags flags )
215 ftv =
new FitViewer(3,4000,parent,flags);
216 ftv->setChunkProperties(0,
"MaxFit", Qt::red,
true);
217 ftv->setChunkProperties(1,
"AverageFit", Qt::green,
true);
218 ftv->setChunkProperties(2,
"MinFit", Qt::blue,
true);
219 ftv->setLabels(QString(
"EvoICub Fitness Monitor"), QString(
"Generations"), QString(
"Fitness"));
220 ftv->setGeometry(50, 50, 500, 500);
221 ftv->setWindowTitle(
"Fitness Curves" );
222 connect( ga, SIGNAL(startingReplication(
int)),
223 this, SLOT(onEvogaStartingReplication(
int)), Qt::QueuedConnection );
224 connect( ga, SIGNAL(recoveredInterruptedEvolution(QString)),
225 this, SLOT(onEvogaRecoveredInterruptedEvolution(QString)), Qt::QueuedConnection );
226 connect( ga, SIGNAL(endGeneration(
int,
double,
double,
double)),
227 this, SLOT(onEvogaEndGeneration(
int,
double,
double,
double)), Qt::QueuedConnection );
228 return ParameterSettableUIViewer( ftv,
"Fitness monitor" );
240 ParameterSettableUIViewer EvoRobotViewer::statview( QWidget* parent, Qt::WindowFlags flags )
242 statViewer =
new QWidget( parent, flags );
243 statViewer->setWindowTitle(
"Statictis Viewer" );
244 QGridLayout* lay =
new QGridLayout( statViewer );
245 QPushButton* but =
new QPushButton(
"Load a Stat File", statViewer );
246 connect( but, SIGNAL(clicked()),
this, SLOT(loadStat()) );
247 lay->addWidget( but, 0, 0 );
248 but =
new QPushButton(
"Load All Stat", statViewer );
249 connect( but, SIGNAL(clicked()),
this, SLOT(loadAllStat()) );
250 lay->addWidget( but, 0, 1 );
251 return ParameterSettableUIViewer( statViewer,
"Statistic Viewer" );
254 void EvoRobotViewer::loadStat() {
255 QString filename = QFileDialog::getOpenFileName(statViewer, tr(
"Open Stat File"),
".", tr(
"Files with statistics (*.fit *.ini)"));
256 if (filename.isEmpty()) {
259 FitViewer* fitViewer = statViewer->findChild<FitViewer*>(
"statFitViewer" );
263 fitViewer =
new FitViewer(3, 4000, statViewer);
264 fitViewer->setObjectName(
"statFitViewer" );
265 fitViewer->setLabels(QString(
"Stat monitor. File: ").append(filename), QString(
"Generation"), QString(
"Fitnes"));
266 fitViewer->setChunkProperties(0,
"MaxFit", Qt::red,
true);
267 fitViewer->setChunkProperties(1,
"Average", Qt::green,
true);
268 fitViewer->setChunkProperties(2,
"Minimum", Qt::blue,
true);
269 fitViewer->loadRawData(0, filename, 0);
270 fitViewer->loadRawData(1, filename, 1);
271 fitViewer->loadRawData(2, filename, 2);
272 QGridLayout* lay = qobject_cast<QGridLayout*>( statViewer->layout() );
273 lay->addWidget( fitViewer, 1, 0, 1, 2 );
274 lay->setRowStretch( 1, 2 );
278 void EvoRobotViewer::loadAllStat()
280 FitViewer* fitViewer = statViewer->findChild<FitViewer*>(
"statFitViewer" );
286 QFileInfoList statFiles = currentDir.entryInfoList( QStringList() <<
"*.fit", QDir::Files, QDir::Name );
289 fitViewer->setObjectName(
"statFitViewer" );
290 QString title = QString(
"Stat monitor");
291 fitViewer->setLabels(title, QString(
"Generation"), QString(
"Fitness"));
293 QColor colors[10] = { QColor(Qt::red), QColor(Qt::green), QColor(Qt::blue), QColor(Qt::cyan),
294 QColor(Qt::magenta), QColor(Qt::darkYellow), QColor(Qt::gray), QColor(255, 140, 0, 255),
295 QColor(153, 50, 204, 255), QColor(Qt::black) };
296 for(
int i=0; i<statFiles.size(); i++ ) {
297 QFileInfo statFile = statFiles[i];
298 QColor col = colors[i%10];
299 fitViewer->setChunkProperties( i, QString(
"Seed:").append(statFile.baseName().split(
"S").last()), col,
true );
300 fitViewer->loadRawData( i, statFile.fileName(), 0 );
302 fitViewer->sortchunks();
303 QGridLayout* lay = qobject_cast<QGridLayout*>( statViewer->layout() );
304 lay->addWidget( fitViewer, 1, 0, 1, 2 );
305 lay->setRowStretch( 1, 2 );
309 ParameterSettableUIViewer EvoRobotViewer::testIndividualUI( TestIndividual* test, QWidget* parent, Qt::WindowFlags flags ) {
310 TestIndividualGUI* testIndUI =
new TestIndividualGUI( test, parent, flags );
311 testIndUI->setWindowTitle(
"Select the Individual to Test" );
312 return ParameterSettableUIViewer( testIndUI,
"Individual to Test", QString(),
"From this view you can select an individual to test using the \"TestIndividual\" from the \"Tests\" menu" );
315 void EvoRobotViewer::onWorldAdvance() {
318 EvoRobotExperiment* exp = getResource<EvoRobotExperiment>(
"experiment");
322 if ( exp->getActivityPhase() == EvoRobotExperiment::INTEST ) {
328 infoEvoga->setText( QString(
"Step %1 of %2 --- Trial %3 of %4" )
329 .arg( exp->getCurStep(), 5 ).arg( exp->getNSteps() )
330 .arg( exp->getCurTrial(), 5 ).arg( exp->getNTrials() ) );
333 void EvoRobotViewer::onEvogaStartingReplication(
int ) {
337 void EvoRobotViewer::onEvogaRecoveredInterruptedEvolution( QString statfile ) {
338 ftv->loadRawData(0,statfile,0);
339 ftv->loadRawData(1,statfile,1);
340 ftv->loadRawData(2,statfile,2);
343 void EvoRobotViewer::onEvogaEndGeneration(
int generation,
double fmax,
double faverage,
double fmin ) {
344 ftv->setChunkValue(0,generation,fmax);
345 ftv->setChunkValue(1,generation,faverage);
346 ftv->setChunkValue(2,generation,fmin);
347 ftv->diplayUntilStep(generation);
351 void EvoRobotViewer::onActionFinished() {
352 infoEvoga->setText( evorobot->
status() );
357 class ForceRenderWorldUpdateEvent :
public QEvent
360 ForceRenderWorldUpdateEvent() :
365 virtual ~ForceRenderWorldUpdateEvent()
372 QWidget(parent, flags),
375 m_layout(new QVBoxLayout(this)),
376 m_renderWorldStateRestored(false),
377 m_setCameraToLookAtRobot(false),
381 setWindowTitle(
"3D World");
382 m_layout->setContentsMargins(0, 0, 0, 0);
383 m_layout->addWidget(m_renderWorld);
384 const QString stateFileName =
".evolver.xml";
386 if (QFile::exists(stateFileName)) {
387 m_renderWorldStateRestored =
true;
402 if (m_setCameraToLookAtRobot) {
405 m_setCameraToLookAtRobot =
false;
407 m_renderWorldStateRestored =
true;
410 m_renderWorld->update();
422 void RenderWorldWrapperWidget::resourceChanged(QString resourceName, ResourceChangeType changeType)
424 if (resourceName ==
"robot") {
425 if ((changeType != Deleted) && (!m_renderWorldStateRestored)) {
427 m_robotTm = getResource<WObject>()->matrix();
428 }
catch (
const ResourceTypeMismatchException&) {
431 m_setCameraToLookAtRobot =
true;
434 Logger::info(
"Unknown resource " + resourceName +
" for RenderWorldWrapperWidget widget");
438 QCoreApplication::postEvent(
this,
new ForceRenderWorldUpdateEvent());
441 void RenderWorldWrapperWidget::customEvent(QEvent* event)
443 if (event->type() == QEvent::User) {
449 void RenderWorldWrapperWidget::lookAtRobot()
451 wVector cameraDefaultPosition = m_robotTm.
transformVector(wVector(-0.8f, 0.0f, +0.6f));
452 m_renderWorld->
camera()->setPosition(
Vec(cameraDefaultPosition[0], cameraDefaultPosition[1], cameraDefaultPosition[2]));
453 m_renderWorld->
camera()->setUpVector(
Vec(0.0f, 0.0f, 1.0f));
591 QWidget(parent, flags)
596 QGridLayout* mainLay =
new QGridLayout(
this );
599 QPushButton* bt =
new QPushButton(
"Refresh",
this );
600 connect( bt, SIGNAL(clicked()),
this, SLOT(populateCombo()) );
601 mainLay->addWidget(bt, 0, 0, 1, 2);
603 combo =
new QComboBox();
604 list =
new QListWidget();
605 mainLay->addWidget(
new QLabel(
"Select File to load:"), 1, 0);
606 mainLay->addWidget(combo, 1, 1);
607 mainLay->addWidget(list, 2, 0, 1, 2);
613 connect(combo, SIGNAL(activated(QString)),
this, SLOT(seedWasChosen()));
614 connect(list, SIGNAL(itemDoubleClicked(QListWidgetItem*)),
this, SLOT(agentClicked()));
617 void TestIndividualGUI::populateCombo()
622 QString bestF = test->component()->getGA()->bestsFilename();
623 QString genF = test->component()->getGA()->generationFilename();
626 QDir* dir =
new QDir();
627 QStringList expression = (QStringList() << bestF << genF);
628 fileList = dir->entryList(expression);
631 combo->addItems(fileList);
634 void TestIndividualGUI::seedWasChosen()
637 test->setPopulationToTest( combo->currentText(), false );
640 int loadindi = test->component()->getGA()->numLoadedGenotypes();
641 for(
int i=1; i<=loadindi; i++)
643 list->addItem(QString::number(i));
647 void TestIndividualGUI::agentClicked()
650 test->setIndividualToTest( list->currentRow() );
656 #if defined(_MSC_VER)