00001 #include <qapplication.h>
00002 #include <qwindowsstyle.h>
00003 #include <qstring.h>
00004 #include <qtextstream.h>
00005
00006 #include <csignal>
00007
00008 #include "SIGEL_Tools/SIG_IO.h"
00009 #include "SIGEL_SlaveGUI/SIG_SimulationWindow.h"
00010 #include "SIGEL_Program/SIG_Program.h"
00011 #include "SIGEL_Robot/SIG_Robot.h"
00012 #include "SIGEL_Environment/SIG_Environment.h"
00013 #include "SIGEL_Simulation/SIG_SimulationParameters.h"
00014 #include "SIGEL_GP/SIG_GPPVMData.h"
00015 #include "SIGEL_GP/SIG_GPFitnessFunction.h"
00016 #include "SIGEL_GP/SIG_GPExperiment.h"
00017 #include "SIGEL_Tools/SIG_Exception.h"
00018
00019 #include "SIGEL_GP/SIG_GPSimpleFitnessFunction.h"
00020 #include "SIGEL_GP/SIG_GPRealSpeedFitnessFunction.h"
00021 #include "SIGEL_GP/SIG_GPNiceWalkingFitnessFunction.h"
00022
00023 #include <pvm3.h>
00024
00025 using namespace SIGEL_SlaveGUI;
00026
00027 extern "C"
00028 {
00029 int masterTaskId = 0;
00030
00031 void sigelStandardSignalHandler(int signal)
00032 {
00033
00034 int result = 1;
00035
00036 switch ( signal )
00037 {
00038 case SIGABRT:
00039 SIGEL_Tools::SIG_IO::cerr << "Abort\n";
00040 break;
00041 case SIGFPE:
00042 SIGEL_Tools::SIG_IO::cerr << "Arithmetic error signal\n";
00043 break;
00044 case SIGILL:
00045 SIGEL_Tools::SIG_IO::cerr << "Invalid execution\n";
00046 break;
00047 case SIGINT:
00048 SIGEL_Tools::SIG_IO::cerr << "Asynchronous interactive attention\n";
00049 break;
00050 case SIGSEGV:
00051 SIGEL_Tools::SIG_IO::cerr << "Invalid storage access\n";
00052 break;
00053 case SIGTERM:
00054
00055 result = 0;
00056 break;
00057 };
00058
00059 double fitnessValue = 0;
00060
00061 pvm_initsend( PvmDataDefault );
00062 pvm_pkdouble( &fitnessValue, 1, 1 );
00063 pvm_send( masterTaskId, 5 );
00064
00065 pvm_exit();
00066
00067 exit( result );
00068
00069 };
00070 };
00071
00072
00073 int main( int argc, char *argv[] )
00074 {
00075
00076 std::signal( SIGABRT, sigelStandardSignalHandler );
00077 std::signal( SIGFPE, sigelStandardSignalHandler );
00078 std::signal( SIGILL, sigelStandardSignalHandler );
00079 std::signal( SIGINT, sigelStandardSignalHandler );
00080 std::signal( SIGSEGV, sigelStandardSignalHandler );
00081 std::signal( SIGTERM, sigelStandardSignalHandler );
00082
00083 SIGEL_Robot::SIG_Robot *robot = 0;
00084 SIGEL_Environment::SIG_Environment *environment = 0;
00085 SIGEL_Simulation::SIG_SimulationParameters *simulationParameters = 0;
00086 SIGEL_Program::SIG_Program *program = 0;
00087 SIGEL_GP::SIG_GPExperiment *experiment = 0;
00088 bool visualize = false;
00089 QString fitnessFunctionName;
00090
00091 bool standAlone = false;
00092
00093 if (argc >= 2)
00094 {
00095 QString option( argv[1] );
00096 if (option == "-visualize")
00097 standAlone = true;
00098 else
00099 standAlone = false;
00100 };
00101
00102 if (standAlone)
00103 {
00104 SIGEL_Tools::SIG_IO::cerr << "Slave started manually to visualize!\n";
00105
00106 if (argc < 3)
00107 {
00108 SIGEL_Tools::SIG_IO::cerr << "No experiment name supplied! Cannot visualize!\n";
00109 return 1;
00110 };
00111
00112 QString experimentName( argv[2] );
00113 QFile experimentFile( experimentName );
00114 if (!experimentFile.open( IO_ReadOnly ))
00115 {
00116 SIGEL_Tools::SIG_IO::cerr << "Error opening " << experimentName << "!\n";
00117 pvm_halt();
00118 return 1;
00119 };
00120
00121 experiment = new SIGEL_GP::SIG_GPExperiment();
00122 QTextStream experimentStream( &experimentFile );
00123
00124 try
00125 {
00126 experiment->loadExperiment( experimentStream );
00127 }
00128 catch (SIGEL_Tools::SIG_Exception &e)
00129 {
00130 SIGEL_Tools::SIG_IO::cerr << e.getMessage();
00131 return 1;
00132 };
00133
00134 experimentFile.close();
00135
00136 robot = &experiment->robot;
00137 environment = &experiment->environment;
00138 simulationParameters = &experiment->simulationParameter;
00139 program = &experiment->population.getIndividual( 0 ).getProgramVar();
00140 visualize = true;
00141 }
00142 else
00143 {
00144 robot = new SIGEL_Robot::SIG_Robot();
00145 environment = new SIGEL_Environment::SIG_Environment();
00146 simulationParameters = new SIGEL_Simulation::SIG_SimulationParameters();
00147 program = new SIGEL_Program::SIG_Program();
00148
00149
00150 int myTaskID = pvm_mytid();
00151 masterTaskId = pvm_parent();
00152
00153 if ((masterTaskId==PvmSysErr) || (masterTaskId==PvmNoParent))
00154 {
00155 SIGEL_Tools::SIG_IO::cerr << "Program hasn't been started as a PVM slave!\n";
00156 exit(1);
00157 };
00158
00159 SIGEL_GP::SIG_GPPVMData pvmData( *robot,
00160 *environment,
00161 *simulationParameters,
00162 "",
00163 false );
00164
00165 QString pvmDataString = pvmData.getQStringFromPVM( masterTaskId, 23 );
00166
00167 QTextStream pvmDataStream( &pvmDataString, IO_ReadWrite );
00168
00169 try
00170 {
00171 pvmData.loadPVMDataTransfer( pvmDataStream, *program );
00172 }
00173 catch (SIGEL_Tools::SIG_Exception &e)
00174 {
00175 SIGEL_Tools::SIG_IO::cerr << e.getMessage();
00176 return 1;
00177 };
00178
00179 visualize = pvmData.getVisualize();
00180
00181 fitnessFunctionName = pvmData.getFitnessFunctionName();
00182 };
00183
00184 int returnValue = 0;
00185
00186 if ( visualize )
00187 {
00188 #ifdef SIG_DEBUG
00189 SIGEL_Tools::SIG_IO::cerr << "Slave is used to visualize!\n";
00190 #endif
00191
00192 SIGEL_Robot::SIG_Robot *modifiedRobot;
00193
00194 if (standAlone)
00195 {
00196 modifiedRobot = new SIGEL_Robot::SIG_Robot( *robot );
00197
00198 switch (simulationParameters->getSimulationLibrary())
00199 {
00200 case SIGEL_Simulation::SIG_SimulationParameters::DynaMo:
00201 try
00202 {
00203 modifiedRobot->prepareDynaMo();
00204 }
00205 catch (SIGEL_Tools::SIG_Exception &e)
00206 {
00207 SIGEL_Tools::SIG_IO::cerr << e.getMessage();
00208 return 1;
00209 };
00210 break;
00211 case SIGEL_Simulation::SIG_SimulationParameters::DynaMechs:
00212 try
00213 {
00214 modifiedRobot->prepareDynaMechs();
00215 }
00216 catch (SIGEL_Tools::SIG_Exception &e)
00217 {
00218 SIGEL_Tools::SIG_IO::cerr << e.getMessage();
00219 return 1;
00220 };
00221 break;
00222 };
00223 }
00224 else
00225 modifiedRobot = robot;
00226
00227 QApplication a(argc, argv);
00228 QApplication::setStyle( new QWindowsStyle() );
00229 SIG_SimulationWindow *simWindow = new SIG_SimulationWindow(0,
00230 "simWindow");
00231 a.setMainWidget(simWindow);
00232
00233 simWindow->setCaption("Simulation Visualisation");
00234 simWindow->show();
00235
00236 try
00237 {
00238 simWindow->visualizeThis( *modifiedRobot,
00239 *environment,
00240 *simulationParameters,
00241 *program );
00242 }
00243 catch (SIGEL_Tools::SIG_Exception &e)
00244 {
00245 SIGEL_Tools::SIG_IO::cerr << e.getMessage();
00246 return 1;
00247 };
00248
00249 returnValue = a.exec();
00250
00251 delete simWindow;
00252
00253 if ( !standAlone )
00254 pvm_exit();
00255 }
00256 else
00257 {
00258 #ifdef SIG_DEBUG
00259 SIGEL_Tools::SIG_IO::cerr << "Slave is used to calculate a fitness!\n";
00260 #endif
00261
00262 SIGEL_GP::SIG_GPFitnessFunction *fitnessFunction = 0;
00263
00264 if (fitnessFunctionName == "SimpleFitnessFunction")
00265 fitnessFunction = new SIGEL_GP::SIG_GPSimpleFitnessFunction( *program,
00266 *robot,
00267 *environment,
00268 *simulationParameters );
00269 else if (fitnessFunctionName == "RealSpeedFitnessFunction")
00270 fitnessFunction = new SIGEL_GP::SIG_GPRealSpeedFitnessFunction( *program,
00271 *robot,
00272 *environment,
00273 *simulationParameters );
00274 else if (fitnessFunctionName == "NiceWalkingFitnessFunction")
00275 fitnessFunction = new SIGEL_GP::SIG_GPNiceWalkingFitnessFunction( *program,
00276 *robot,
00277 *environment,
00278 *simulationParameters );
00279 else
00280 SIGEL_Tools::SIG_IO::cerr << "Error: Unknown fitness function!\n";
00281
00282 double fitnessValue = 0;
00283
00284 if (fitnessFunction)
00285 {
00286 try
00287 {
00288 fitnessValue = fitnessFunction->evalFitness();
00289 delete fitnessFunction;
00290 }
00291 catch (SIGEL_Tools::SIG_Exception &e)
00292 {
00293 fitnessValue = 0;
00294 };
00295 };
00296
00297 pvm_initsend( PvmDataDefault );
00298 pvm_pkdouble( &fitnessValue, 1, 1 );
00299 pvm_send( masterTaskId, 5 );
00300
00301 pvm_exit();
00302
00303 };
00304
00305 return returnValue;
00306
00307 };
00308
00309
00310
00311