00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00034 #include <acado/bindings/acado_gnuplot/gnuplot_window.hpp>
00035
00036 #ifdef WIN32
00037 #include <windows.h>
00038
00039 #define round( value ) floor( value + 0.5 )
00040 #else
00041 #include <unistd.h>
00042 #endif
00043
00044 #include <cstdlib>
00045 #include <string>
00046
00047 using namespace std;
00048
00049 BEGIN_NAMESPACE_ACADO
00050
00051
00052
00053
00054
00055
00056 int GnuplotWindow::counter = 0;
00057
00058
00059 GnuplotWindow::GnuplotWindow( ) : PlotWindow()
00060 {
00061 gnuPipe = 0;
00062 mouseEvent = BT_FALSE;
00063
00064 ++counter;
00065 }
00066
00067
00068 GnuplotWindow::GnuplotWindow( PlotFrequency _frequency
00069 ) : PlotWindow( _frequency )
00070 {
00071 gnuPipe = 0;
00072 mouseEvent = BT_FALSE;
00073
00074 ++counter;
00075 }
00076
00077
00078 GnuplotWindow::GnuplotWindow( const GnuplotWindow& arg ) : PlotWindow( arg )
00079 {
00080 gnuPipe = 0;
00081
00082 mouseEvent = arg.mouseEvent;
00083 }
00084
00085
00086 GnuplotWindow::~GnuplotWindow( ){
00087
00088 if( gnuPipe != 0 )
00089 fclose(gnuPipe);
00090 }
00091
00092
00093 GnuplotWindow& GnuplotWindow::operator=( const GnuplotWindow& arg ){
00094
00095 if( this != &arg ){
00096
00097 PlotWindow::operator=( arg );
00098
00099 if( gnuPipe != 0 )
00100 fclose(gnuPipe);
00101
00102 gnuPipe = 0;
00103
00104 mouseEvent = arg.mouseEvent;
00105 }
00106
00107 return *this;
00108 }
00109
00110
00111 PlotWindow* GnuplotWindow::clone( ) const
00112 {
00113 return new GnuplotWindow( *this );
00114 }
00115
00116
00117 returnValue GnuplotWindow::init()
00118 {
00119 if (gnuPipe != 0)
00120 {
00121 fclose(gnuPipe);
00122 gnuPipe = 0;
00123 }
00124
00125 #ifndef __NO_PIPES__
00126 gnuPipe = popen("gnuplot -persist -background white", "w");
00127
00128
00129
00130 if ( !gnuPipe )
00131 ACADOWARNING( RET_PLOT_WINDOW_CAN_NOT_BE_OPEN );
00132 #endif
00133
00134 return SUCCESSFUL_RETURN;
00135 }
00136
00137
00138 returnValue GnuplotWindow::replot( PlotFrequency _frequency
00139 )
00140 {
00141 if ( ( _frequency == PLOT_IN_ANY_CASE ) || ( _frequency == getPlotFrequency( ) ) )
00142 {
00143 if( gnuPipe == 0 )
00144 {
00145 init();
00146 }
00147
00148 return sendDataToGnuplot( );
00149 }
00150
00151 return SUCCESSFUL_RETURN;
00152 }
00153
00154
00155 returnValue GnuplotWindow::waitForMouseEvents(){
00156
00157 mouseEvent = BT_TRUE;
00158 return SUCCESSFUL_RETURN;
00159 }
00160
00161
00162 BooleanType GnuplotWindow::getMouseEvent( double &mouseX, double &mouseY )
00163 {
00164 DVector tmp;
00165 if (tmp.read( "mouse.dat" ) != SUCCESSFUL_RETURN)
00166 return BT_FALSE;
00167
00168 mouseX = tmp( tmp.getDim()-2 );
00169 mouseY = tmp( tmp.getDim()-1 );
00170
00171 if ( system("rm mouse.dat") )
00172 return BT_FALSE;
00173
00174 return BT_TRUE;
00175 }
00176
00177
00178 returnValue GnuplotWindow::waitForMouseEvent( double &mouseX, double &mouseY ){
00179
00180 if (gnuPipe == 0)
00181 {
00182 ACADOWARNING( RET_NOT_YET_IMPLEMENTED );
00183 return SUCCESSFUL_RETURN;
00184 }
00185
00186 FILE *check;
00187 check = fopen( "mouse.dat", "r" );
00188
00189 if( check != 0 )
00190 {
00191 fclose( check );
00192
00193 if (system("rm mouse.dat") )
00194 return RET_PLOTTING_FAILED;
00195 }
00196
00197 fprintf(gnuPipe,"pause mouse\n");
00198 fflush(gnuPipe);
00199 fprintf(gnuPipe,"a = MOUSE_X \n");
00200 fflush(gnuPipe);
00201 fprintf(gnuPipe,"b = MOUSE_Y \n");
00202 fflush(gnuPipe);
00203 fprintf(gnuPipe,"save var 'mouse.dat'\n");
00204 fflush(gnuPipe);
00205
00206 while(1){
00207 if( getMouseEvent(mouseX,mouseY) == BT_TRUE ){
00208 break;
00209 }
00210 usleep(20000);
00211 }
00212 return SUCCESSFUL_RETURN;
00213 }
00214
00215
00216
00217
00218
00219
00220
00221
00222 returnValue GnuplotWindow::sendDataToGnuplot( )
00223 {
00224 #ifndef __NO_PLOTTING__
00225
00226
00227 BooleanType toFile = (BooleanType)( gnuPipe == 0 );
00228 if( toFile == BT_TRUE )
00229 gnuPipe = fopen( "acado2gnuplot_tmp.dat","w" );
00230
00231 uint run1, run2, run3, run4;
00232
00233 uint nRows;
00234 uint nCols;
00235
00236 switch ( getNumSubplots( ) )
00237 {
00238 case 0:
00239 nRows = 0;
00240 nCols = 0;
00241 break;
00242
00243 case 1:
00244 nRows = 1;
00245 nCols = 1;
00246 break;
00247
00248 case 2:
00249 nRows = 2;
00250 nCols = 1;
00251 break;
00252
00253 case 3:
00254 case 4:
00255 nRows = 2;
00256 nCols = 2;
00257 break;
00258
00259 case 5:
00260 case 6:
00261 nRows = 3;
00262 nCols = 2;
00263 break;
00264
00265 case 7:
00266 case 8:
00267 case 9:
00268 nRows = 3;
00269 nCols = 3;
00270 break;
00271
00272 default:
00273 nRows = 4;
00274 nCols = 3;
00275 break;
00276 }
00277
00278 VariableType myType;
00279
00280 Grid discretizationGrid;
00281 VariablesGrid dataGrid, dataGridX, dataGridTmp;
00282 MatrixVariablesGrid dataMatrixGrid;
00283
00284 string plotDataString;
00285 string userDataString;
00286 string plotModeString;
00287 string plotStyleString;
00288
00289 returnValue returnvalue;
00290
00291 fprintf( gnuPipe,"set multiplot;\n" );
00292
00293 run1 = 0;
00294 for( run3 = 0; run3<nRows; run3++ )
00295 {
00296 for( run2 = 0; run2<nCols; run2++ )
00297 {
00298 if( run1 < getNumSubplots( ) )
00299 {
00300 discretizationGrid.init( );
00301
00302
00303 switch ( operator()(run1).getSubPlotType( ) )
00304 {
00305
00306 case SPT_VARIABLE:
00307 if ( getVariableDataGrids( operator()( run1 ).plotVariableY,myType,dataGrid,discretizationGrid ) != SUCCESSFUL_RETURN )
00308 return ACADOERROR( RET_PLOTTING_FAILED );
00309 break;
00310
00311 case SPT_VARIABLE_VARIABLE:
00312 if ( getVariableDataGrids( operator()( run1 ).plotVariableX,myType,dataGridX,discretizationGrid ) != SUCCESSFUL_RETURN )
00313 return ACADOERROR( RET_PLOTTING_FAILED );
00314
00315 if ( getVariableDataGrids( operator()( run1 ).plotVariableY,myType,dataGrid,discretizationGrid ) != SUCCESSFUL_RETURN )
00316 return ACADOERROR( RET_PLOTTING_FAILED );
00317
00318 dataGridX.appendValues( dataGrid );
00319 dataGrid = dataGridX;
00320 break;
00321
00322 case SPT_VARIABLE_EXPRESSION:
00323 if ( getVariableDataGrids( operator()( run1 ).plotVariableX,myType,dataGridX,discretizationGrid ) != SUCCESSFUL_RETURN )
00324 return ACADOERROR( RET_PLOTTING_FAILED );
00325
00326 if ( getExpressionDataGrids( operator()( run1 ).plotExpressionY,myType,dataGrid,discretizationGrid ) != SUCCESSFUL_RETURN )
00327 return ACADOERROR( RET_PLOTTING_FAILED );
00328
00329 dataGridX.appendValues( dataGrid );
00330 dataGrid = dataGridX;
00331 break;
00332
00333
00334 case SPT_VARIABLES_GRID:
00335 if ( getDataGrids( operator()(run1).plotVariablesGrid,myType,dataGrid,discretizationGrid ) != SUCCESSFUL_RETURN )
00336 return ACADOERROR( RET_PLOTTING_FAILED );
00337 break;
00338
00339 case SPT_EXPRESSION:
00340 if ( getExpressionDataGrids( operator()( run1 ).plotExpressionY,myType,dataGrid,discretizationGrid ) != SUCCESSFUL_RETURN )
00341 return ACADOERROR( RET_PLOTTING_FAILED );
00342 break;
00343
00344 case SPT_EXPRESSION_EXPRESSION:
00345 if ( getExpressionDataGrids( operator()( run1 ).plotExpressionX,myType,dataGridX,discretizationGrid ) != SUCCESSFUL_RETURN )
00346 return ACADOERROR( RET_PLOTTING_FAILED );
00347
00348 if ( getExpressionDataGrids( operator()( run1 ).plotExpressionY,myType,dataGrid,discretizationGrid ) != SUCCESSFUL_RETURN )
00349 return ACADOERROR( RET_PLOTTING_FAILED );
00350
00351 dataGridX.appendValues( dataGrid );
00352 dataGrid = dataGridX;
00353 break;
00354
00355 case SPT_EXPRESSION_VARIABLE:
00356 if ( getExpressionDataGrids( operator()( run1 ).plotExpressionX,myType,dataGridX,discretizationGrid ) != SUCCESSFUL_RETURN )
00357 return ACADOERROR( RET_PLOTTING_FAILED );
00358
00359 if ( getVariableDataGrids( operator()( run1 ).plotVariableY,myType,dataGrid,discretizationGrid ) != SUCCESSFUL_RETURN )
00360 return ACADOERROR( RET_PLOTTING_FAILED );
00361
00362 dataGridX.appendValues( dataGrid );
00363 dataGrid = dataGridX;
00364 break;
00365
00366 case SPT_ENUM:
00367 myType = operator()( run1 ).getYVariableType( );
00368
00369 returnvalue = plotDataRecord.getAll( convertPlotToLogName( operator()( run1 ).getPlotEnum( ) ),dataMatrixGrid );
00370 if( returnvalue != SUCCESSFUL_RETURN )
00371 return ACADOERROR( returnvalue );
00372
00373 dataGrid = dataMatrixGrid;
00374 break;
00375
00376 default:
00377 ACADOERROR( RET_UNKNOWN_BUG );
00378 }
00379
00380
00381
00382 fprintf(gnuPipe," set size %.16e,%.16e;\n", (1.0 /nCols), (1.0 /nRows) );
00383 fprintf(gnuPipe," set origin %.16e,%.16e;\n", (double) run2/((double) nCols),
00384 (double) (nRows-1-run3)/((double) nRows) );
00385
00386
00387 if ( operator()( run1 ).title.empty() == false )
00388 fprintf(gnuPipe," set title '%s'\n", operator()( run1 ).title.c_str() );
00389 else
00390 fprintf(gnuPipe," set title ' '\n" );
00391
00392
00393 if ( operator()( run1 ).xLabel.empty() == false )
00394 fprintf(gnuPipe," set xlabel '%s'\n", operator()( run1 ).xLabel.c_str() );
00395 else
00396 fprintf(gnuPipe," set xlabel ' '\n" );
00397
00398 if ( operator()( run1 ).yLabel.empty() == false )
00399 fprintf(gnuPipe," set ylabel '%s'\n", operator()( run1 ).yLabel.c_str() );
00400 else
00401 fprintf(gnuPipe," set ylabel ' '\n" );
00402
00403 if( ( acadoIsFinite( operator()( run1 ).xRangeLowerLimit ) == BT_TRUE ) &&
00404 ( acadoIsFinite( operator()( run1 ).xRangeUpperLimit ) == BT_TRUE ) )
00405 {
00406 fprintf(gnuPipe," set xrange [%.16e:%.16e]\n", operator()( run1 ).xRangeLowerLimit, operator()( run1 ).xRangeUpperLimit );
00407 }
00408 else
00409 {
00410 fprintf(gnuPipe," set autoscale x\n" );
00411 }
00412
00413 if( ( acadoIsFinite( operator()( run1 ).yRangeLowerLimit ) == BT_TRUE ) &&
00414 ( acadoIsFinite( operator()( run1 ).yRangeUpperLimit ) == BT_TRUE ) )
00415 {
00416 fprintf(gnuPipe," set yrange [%.16e:%.16e]\n", operator()( run1 ).yRangeLowerLimit, operator()( run1 ).yRangeUpperLimit );
00417 }
00418 else
00419 {
00420 if ( ( operator()( run1 ).nLines == 0 ) && ( operator()( run1 ).nData == 0 ) )
00421 {
00422 double lowerLimit, upperLimit;
00423 getAutoScaleYLimits( dataGrid,operator()( run1 ).plotFormat,lowerLimit,upperLimit );
00424 fprintf(gnuPipe," set yrange [%.16e:%.16e]\n", lowerLimit, upperLimit );
00425 }
00426 else
00427 {
00428 fprintf(gnuPipe," set autoscale y\n" );
00429 }
00430 }
00431
00432 if ( operator()( run1 ).getPlotFormat( ) == PF_LOG )
00433 fprintf(gnuPipe," set logscale y\n" );
00434
00435 if ( operator()( run1 ).plot3D == BT_FALSE )
00436 fprintf(gnuPipe," plot ");
00437 else
00438 fprintf(gnuPipe," splot ");
00439
00440
00441 if ( operator()( run1 ).nLines > 0 )
00442 for( run4 = 0; run4 < operator()( run1 ).nLines; run4++ )
00443 fprintf(gnuPipe,"%.16e title '' lt 2 lw 2,\\\n", operator()( run1 ).lineValues[run4] );
00444
00445
00446 getPlotModeString(operator()(run1).plotMode, plotModeString);
00447 getPlotStyleString(myType, plotStyleString);
00448
00449 switch ( operator()(run1).getSubPlotType( ) )
00450 {
00451 case SPT_VARIABLE:
00452 case SPT_EXPRESSION:
00453 if ( discretizationGrid.getNumPoints() > 1 )
00454 for( run4=0; run4<discretizationGrid.getNumPoints()-2; ++run4 )
00455 fprintf(gnuPipe,"'-' using 1:2 title '' with %s %s,\\\n", plotModeString.c_str(),plotStyleString.c_str() );
00456
00457 fprintf(gnuPipe,"'-' using 1:2 title '' with %s %s", plotModeString.c_str(),plotStyleString.c_str() );
00458 break;
00459
00460 case SPT_VARIABLE_VARIABLE:
00461 case SPT_VARIABLE_EXPRESSION:
00462 case SPT_EXPRESSION_EXPRESSION:
00463 case SPT_EXPRESSION_VARIABLE:
00464 if ( discretizationGrid.getNumPoints() > 1 )
00465 for( run4=0; run4<discretizationGrid.getNumPoints()-2; ++run4 )
00466 fprintf(gnuPipe,"'-' using 2:3 title '' with %s %s,\\\n", plotModeString.c_str(),plotStyleString.c_str() );
00467
00468 fprintf(gnuPipe,"'-' using 2:3 title '' with %s %s", plotModeString.c_str(),plotStyleString.c_str() );
00469 break;
00470
00471 case SPT_VARIABLES_GRID:
00472 if ( dataGrid.getNumValues( ) == 0 )
00473 return ACADOERROR( RET_EMPTY_PLOT_DATA );
00474
00475 if( operator()( run1 ).plot3D == BT_FALSE )
00476 {
00477
00478
00479 if ( discretizationGrid.getNumPoints() > 1 )
00480 for( run4=0; run4<discretizationGrid.getNumPoints()-2; ++run4 )
00481 fprintf(gnuPipe,"'-' using 1:2 title '' with %s %s,\\\n", plotModeString.c_str(),plotStyleString.c_str() );
00482
00483 fprintf(gnuPipe,"'-' using 1:2 title '' with %s %s", plotModeString.c_str(),plotStyleString.c_str() );
00484 }
00485 else
00486 {
00487 if ( dataGrid.getNumValues( ) != 2 )
00488 return ACADOERROR( RET_INVALID_ARGUMENTS );
00489
00490 fprintf(gnuPipe,"'-' title '' with %s", plotModeString.c_str() );
00491 }
00492 break;
00493
00494 default:
00495 fprintf(gnuPipe,"'-' using 1:2 title '' with %s %s", plotModeString.c_str(),plotStyleString.c_str() );
00496 }
00497
00498
00499 if ( operator()(run1).nData > 0 )
00500 {
00501 returnvalue = obtainPlotDataString( *(operator()(run1).data[0]),userDataString );
00502 if( returnvalue != SUCCESSFUL_RETURN )
00503 return ACADOERROR( returnvalue );
00504 }
00505
00506 if( userDataString.empty() == false )
00507 fprintf(gnuPipe,",\\\n'-' using 1:2 title '' with points lt 3 lw 3\n" );
00508 else
00509 fprintf(gnuPipe,"\n");
00510
00511 if ( discretizationGrid.getNumPoints( ) == 0 )
00512 {
00513 if ( dataGrid.getNumValues( ) == 1 )
00514 {
00515 returnvalue = obtainPlotDataString( dataGrid,plotDataString );
00516 if( returnvalue != SUCCESSFUL_RETURN )
00517 return ACADOERROR( returnvalue );
00518
00519 fprintf( gnuPipe, "%s", plotDataString.c_str() );
00520 fprintf( gnuPipe, "e\n" );
00521 }
00522 else
00523 {
00524 for( run4=0; run4<dataGrid.getNumValues( ); ++run4 )
00525 {
00526 dataGridTmp = dataGrid(run4);
00527 returnvalue = obtainPlotDataString( dataGridTmp,plotDataString );
00528 if( returnvalue != SUCCESSFUL_RETURN )
00529 return ACADOERROR( returnvalue );
00530
00531 fprintf( gnuPipe, "%s", plotDataString.c_str() );
00532 fprintf( gnuPipe, "e\n" );
00533 }
00534 }
00535 }
00536 else
00537 {
00538 uint startIdx,endIdx;
00539
00540 for( run4=0; run4<discretizationGrid.getNumPoints()-1; ++run4 )
00541 {
00542 startIdx = (uint)round( discretizationGrid.getTime( run4 ) );
00543 endIdx = (uint)round( discretizationGrid.getTime( run4+1 ) ) - 1;
00544 dataGridTmp = dataGrid.getTimeSubGrid( startIdx,endIdx );
00545
00546 returnvalue = obtainPlotDataString( dataGridTmp, plotDataString );
00547 if( returnvalue != SUCCESSFUL_RETURN )
00548 return ACADOERROR( returnvalue );
00549
00550 fprintf( gnuPipe, "%s", plotDataString.c_str() );
00551 fprintf( gnuPipe, "e\n" );
00552 }
00553 }
00554
00555 if ( operator()( run1 ).getPlotFormat( ) == PF_LOG )
00556 fprintf(gnuPipe," unset logscale y\n" );
00557 }
00558
00559 fprintf( gnuPipe,"\n" );
00560 fflush( gnuPipe );
00561
00562 ++run1;
00563 }
00564 }
00565
00566 fprintf( gnuPipe,"unset multiplot\n" );
00567
00568 fflush( gnuPipe );
00569
00570
00571
00572 if ( toFile == BT_TRUE )
00573 {
00574
00575 fclose( gnuPipe );
00576 gnuPipe = 0;
00577
00578 #if defined(GNUPLOT_EXECUTABLE) && defined(WIN32)
00579 string tmp = string( GNUPLOT_EXECUTABLE ) + string(" -p acado2gnuplot_tmp.dat");
00580
00581 if ( system( tmp.c_str() ) )
00582 return RET_PLOTTING_FAILED;
00583
00584 if ( system("del acado2gnuplot_tmp.dat") )
00585 return RET_PLOTTING_FAILED;
00586 #else
00587 if ( system("gnuplot -persist -background white acado2gnuplot_tmp.dat") )
00588 return RET_PLOTTING_FAILED;
00589 if (system("rm -rf acado2gnuplot_tmp.dat") )
00590 return RET_PLOTTING_FAILED;
00591 #endif
00592
00593 return SUCCESSFUL_RETURN;
00594 }
00595
00596 if( mouseEvent == BT_TRUE )
00597 {
00598 fprintf(gnuPipe,"pause mouse\n");
00599 fflush(gnuPipe);
00600
00601 fprintf(gnuPipe,"a = MOUSE_X \n");
00602 fflush(gnuPipe);
00603
00604 fprintf(gnuPipe,"b = MOUSE_Y \n");
00605 fflush(gnuPipe);
00606
00607 fprintf(gnuPipe,"save var 'mouse.dat'\n");
00608 fflush(gnuPipe);
00609 }
00610
00611 #endif // __NO_PLOTTING__
00612
00613 return SUCCESSFUL_RETURN;
00614 }
00615
00616
00617 returnValue GnuplotWindow::getPlotModeString( PlotMode plotMode,
00618 std::string& plotModeString
00619 ) const
00620 {
00621 switch( plotMode )
00622 {
00623 case PM_LINES:
00624 plotModeString = "lines lw 2.5";
00625 break;
00626
00627 case PM_POINTS:
00628 plotModeString = "points pt 2.5";
00629 break;
00630
00631 default:
00632 plotModeString = "lines lw 2.5";
00633 }
00634
00635 return SUCCESSFUL_RETURN;
00636 }
00637
00638
00639 returnValue GnuplotWindow::getPlotStyleString( VariableType _type,
00640 std::string& plotStyleString
00641 ) const
00642 {
00643 switch( _type )
00644 {
00645 case VT_DIFFERENTIAL_STATE:
00646 plotStyleString = "lt -1";
00647 break;
00648
00649 case VT_ALGEBRAIC_STATE:
00650 plotStyleString = "lt 4";
00651 break;
00652
00653 case VT_PARAMETER:
00654 plotStyleString = "lt 8";
00655 break;
00656
00657 case VT_CONTROL:
00658 plotStyleString = "lt 3";
00659 break;
00660
00661 case VT_DISTURBANCE:
00662 plotStyleString = "lt 5";
00663 break;
00664
00665 case VT_INTERMEDIATE_STATE:
00666 plotStyleString = "lt 2";
00667 break;
00668
00669 default:
00670
00671 plotStyleString = "lt 1";
00672 }
00673
00674 return SUCCESSFUL_RETURN;
00675 }
00676
00677
00678 returnValue GnuplotWindow::obtainPlotDataString( VariablesGrid& _dataGrid,
00679 std::string& _plotDataString
00680 ) const
00681 {
00682 stringstream ss;
00683
00684 _dataGrid.sprint( ss );
00685
00686 _plotDataString = ss.str();
00687
00688 return SUCCESSFUL_RETURN;
00689 }
00690
00691
00692 CLOSE_NAMESPACE_ACADO
00693
00694
00695
00696
00697
00698