Go to the documentation of this file.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
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include <ros/ros.h>
00042 #include <ros/package.h>
00043
00044
00045 #include <ompl_rviz_viewer/utilities/ppm.h>
00046
00047
00048 #include <ompl_rviz_viewer/ompl_rviz_viewer.h>
00049
00050
00051 #include <ompl_rviz_viewer/two_dimensional_validity_checker.h>
00052
00053
00054 #include <ompl/geometric/SimpleSetup.h>
00055 #include <ompl/geometric/planners/rrt/RRT.h>
00056 #include <ompl/geometric/planners/rrt/TRRT.h>
00057
00058 namespace ob = ompl::base;
00059 namespace og = ompl::geometric;
00060 namespace bnu = boost::numeric::ublas;
00061
00062 namespace ompl_rviz_viewer
00063 {
00064
00068 class OmplRvizPlanner
00069 {
00070
00071 private:
00072
00073 PPMImage *image_;
00074
00075
00076 bnu::matrix<int> cost_;
00077
00078
00079 ob::PlannerDataPtr planner_data_;
00080
00081
00082 og::SimpleSetupPtr simple_setup_;
00083
00084
00085 ompl_rviz_viewer::OmplRvizViewerPtr viewer_;
00086
00087
00088 int max_cost_;
00089 int min_cost_;
00090
00091
00092 double max_threshold_;
00093
00094
00095
00096 static const double MAX_THRESHOLD_PERCENTAGE_ = 1;
00097
00098
00099 static const unsigned int DIMENSIONS = 2;
00100
00101
00102 static const bool USE_RANDOM_STATES = true;
00103
00104 public:
00105
00109 OmplRvizPlanner()
00110 {
00111 image_ = NULL;
00112
00113 bool verbose = true;
00114 viewer_.reset(new ompl_rviz_viewer::OmplRvizViewer(verbose));
00115 }
00116
00120 ~OmplRvizPlanner()
00121 {
00122 delete image_;
00123 }
00124
00128 void runImage( std::string image_path )
00129 {
00130
00131 image_ = readPPM( image_path.c_str() );
00132
00133
00134 if( !image_ )
00135 {
00136 ROS_ERROR( "No image data loaded " );
00137 return;
00138 }
00139
00140
00141 if( image_->x != image_->y )
00142 {
00143 ROS_ERROR( "Does not currently support non-square images because of some weird bug. Feel free to fork and fix!" );
00144 return;
00145 }
00146
00147 ROS_INFO_STREAM( "Map Height: " << image_->y << " Map Width: " << image_->x );
00148
00149
00150 cost_.resize( image_->x, image_->y );
00151
00152
00153 getMinMaxCost();
00154
00155
00156 createCostMap();
00157
00158 ROS_INFO_STREAM( "OMPL version: " << OMPL_VERSION );
00159
00160
00161
00162 if( planWithSimpleSetup() )
00163 {
00164
00165 std_msgs::ColorRGBA color;
00166 color.a = 1.0;
00167
00168
00169 viewer_->displayTriangles(image_, cost_);
00170 ros::Duration(0.1).sleep();
00171
00172
00173 viewer_->displayGraph(cost_, planner_data_);
00174 ros::Duration(0.1).sleep();
00175
00176
00177 viewer_->displaySamples(cost_, planner_data_);
00178 ros::Duration(0.1).sleep();
00179
00180
00181 if( false )
00182 {
00183
00184 color.r = 1.0;
00185 color.g = 0.0;
00186 color.b = 0.0;
00187 viewer_->displayResult( simple_setup_->getSolutionPath(), &color, cost_ );
00188 ros::Duration(0.25).sleep();
00189 }
00190
00191
00192 if( true )
00193 {
00194 simple_setup_->getSolutionPath().interpolate();
00195
00196
00197 color.r = 0.0;
00198 color.g = 1.0;
00199 color.b = 0.0;
00200 viewer_->displayResult( simple_setup_->getSolutionPath(), &color, cost_ );
00201
00202 }
00203
00204
00205 if( false )
00206 {
00207 simple_setup_->simplifySolution();
00208
00209
00210 color.r = 0.0;
00211 color.g = 0.5;
00212 color.b = 0.5;
00213 viewer_->displayResult( simple_setup_->getSolutionPath(), &color, cost_ );
00214 ros::Duration(0.25).sleep();
00215 }
00216 }
00217 else
00218 {
00219
00220 viewer_->displayTriangles(image_, cost_);
00221 ros::Duration(0.25).sleep();
00222 }
00223
00224 }
00225
00226 private:
00227
00231 void createCostMap()
00232 {
00233
00234 const double artistic_scale = 2.0;
00235
00236
00237 const double scale = (max_cost_ - min_cost_ ) / ( image_->x / artistic_scale );
00238
00239
00240 max_threshold_ = max_cost_ - ( MAX_THRESHOLD_PERCENTAGE_ / 100 * (max_cost_ - min_cost_) );
00241
00242
00243 for( size_t i = 0; i < image_->getSize(); ++i )
00244 {
00245
00246 cost_.data()[i] = ( image_->data[ i ].red ) / scale;
00247
00248
00249 if( !cost_.data()[i] )
00250 cost_.data()[i] = 1;
00251
00252
00253 if( cost_.data()[i] > max_threshold_ )
00254 {
00255 image_->data[ i ].red = 255;
00256 image_->data[ i ].green = image_->data[ i ].green;
00257 image_->data[ i ].blue = image_->data[ i ].blue;
00258 }
00259
00260 }
00261
00262 }
00263
00267 void getMinMaxCost()
00268 {
00269
00270 min_cost_ = image_->data[ 0 ].red;
00271 max_cost_ = image_->data[ 0 ].red;
00272
00273 for( size_t i = 0; i < image_->getSize(); ++i )
00274 {
00275
00276 if( image_->data[ i ].red > max_cost_ )
00277 max_cost_ = image_->data[ i ].red;
00278
00279 else if( image_->data[ i ].red < min_cost_ )
00280 min_cost_ = image_->data[ i ].red;
00281 }
00282 }
00283
00289 void showStartGoal(ob::ScopedState<> start, ob::ScopedState<> goal)
00290 {
00291
00292 image_->data[ image_->getID( start[0], start[1] ) ].red = 50;
00293 image_->data[ image_->getID( start[0], start[1] ) ].blue = 50;
00294 image_->data[ image_->getID( start[0], start[1] ) ].green = 255;
00295
00296 image_->data[ image_->getID( goal[0], goal[1] ) ].red = 255;
00297 image_->data[ image_->getID( goal[0], goal[1] ) ].blue = 255;
00298 image_->data[ image_->getID( goal[0], goal[1] ) ].green = 10;
00299 }
00300
00304 bool planWithSimpleSetup()
00305 {
00306
00307 ob::StateSpacePtr space( new ob::RealVectorStateSpace( DIMENSIONS ));
00308
00309
00310 ob::RealVectorBounds bounds( DIMENSIONS );
00311 bounds.setLow( 0 );
00312 bounds.setHigh( 0, image_->x - 1 );
00313 bounds.setHigh( 1, image_->y - 1 );
00314 space->as<ob::RealVectorStateSpace>()->setBounds( bounds );
00315
00316
00317 simple_setup_ = og::SimpleSetupPtr( new og::SimpleSetup(space) );
00318
00319
00320 og::TRRT *trrt = new og::TRRT( simple_setup_->getSpaceInformation() );
00321
00322
00323 simple_setup_->setPlanner(ob::PlannerPtr(trrt));
00324
00325
00326 simple_setup_->setStateValidityChecker( ob::StateValidityCheckerPtr( new TwoDimensionalValidityChecker( simple_setup_->getSpaceInformation(), cost_, max_threshold_ ) ) );
00327
00328
00329
00330
00331 ob::ScopedState<> start(space);
00332 if( USE_RANDOM_STATES )
00333 {
00334 start.random();
00335 }
00336 else
00337 {
00338 start[0] = 95;
00339 start[1] = 10;
00340 }
00341
00342
00343 ob::ScopedState<> goal(space);
00344 if( USE_RANDOM_STATES )
00345 {
00346 goal.random();
00347 }
00348 else
00349 {
00350 goal[0] = 40;
00351 goal[1] = 300;
00352 }
00353
00354
00355 showStartGoal(start, goal);
00356
00357
00358 simple_setup_->setStartAndGoalStates(start, goal);
00359
00360
00361
00362
00363 simple_setup_->setup();
00364
00365
00366
00367
00368
00369 simple_setup_->print();
00370
00371
00372 ROS_INFO( "Starting OMPL motion planner..." );
00373
00374
00375 ob::PlannerStatus solved = simple_setup_->solve( 10.0 );
00376
00377 if (solved)
00378 {
00379 ROS_INFO("Solution Found");
00380
00381
00382 planner_data_.reset( new ob::PlannerData( simple_setup_->getSpaceInformation() ) );
00383 simple_setup_->getPlannerData( *planner_data_ );
00384 }
00385 else
00386 {
00387 ROS_INFO("No Solution Found");
00388 }
00389
00390 return solved;
00391 }
00392
00393 };
00394
00395 }
00396
00397
00398
00399
00400
00401 int main( int argc, char** argv )
00402 {
00403 ros::init(argc, argv, "ompl_rviz_viewer");
00404 ROS_INFO( "OMPL RViz Viewer ----------------------------------------- " );
00405
00406
00407 ros::AsyncSpinner spinner(1);
00408 spinner.start();
00409
00410 bool verbose = true;
00411
00412 std::string image_path;
00413
00414
00415 if( argc > 1 )
00416 {
00417 image_path = argv[1];
00418 }
00419 else
00420 {
00421
00422 image_path = ros::package::getPath("ompl_rviz_viewer");
00423 if( image_path.empty() )
00424 {
00425 ROS_ERROR( "Unable to get OMPL RViz Viewer package path " );
00426 return false;
00427 }
00428
00429
00430 srand ( time(NULL) );
00431
00432
00433 switch( 0 )
00434 {
00435 case 0:
00436 image_path.append( "/resources/grand_canyon.ppm" );
00437 break;
00438 case 1:
00439 image_path.append( "/resources/height_map0.ppm" );
00440 break;
00441 case 2:
00442 image_path.append( "/resources/height_map1.ppm" );
00443 break;
00444 case 3:
00445 image_path.append( "/resources/height_map2.ppm" );
00446 break;
00447 }
00448 }
00449
00450
00451 ompl_rviz_viewer::OmplRvizPlanner planner;
00452
00453
00454 ROS_INFO_STREAM_NAMED("main","Loading image " << image_path);
00455 planner.runImage( image_path );
00456
00457
00458 ros::Duration(1).sleep();
00459
00460 ROS_INFO_STREAM("Shutting down. TESTING HERE");
00461
00462 return 0;
00463 }
00464
00465