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 #include <QLabel>
00039 #include <QTimer>
00040 #include <QVBoxLayout>
00041 #include <QHBoxLayout>
00042 #include <QMessageBox>
00043 #include <QString>
00044 #include <QApplication>
00045 #include <QFont>
00046 #include <QFileDialog>
00047 #include <QTextEdit>
00048
00049 #include <ros/ros.h>
00050 #include <ros/package.h>
00051
00052 #include "header_widget.h"
00053 #include "start_screen_widget.h"
00054
00055 #include <fstream>
00056 #include <streambuf>
00057
00058 #include <boost/algorithm/string.hpp>
00059 #include <boost/filesystem.hpp>
00060 #include <boost/algorithm/string.hpp>
00061
00062 namespace moveit_setup_assistant
00063 {
00064
00065 namespace fs = boost::filesystem;
00066
00067
00068
00069
00070 StartScreenWidget::StartScreenWidget(QWidget* parent, moveit_setup_assistant::MoveItConfigDataPtr config_data)
00071 : SetupScreenWidget(parent), config_data_(config_data)
00072 {
00073
00074 QVBoxLayout* layout = new QVBoxLayout(this);
00075
00076
00077 QHBoxLayout* hlayout = new QHBoxLayout();
00078
00079 QVBoxLayout* left_layout = new QVBoxLayout();
00080
00081 QVBoxLayout* right_layout = new QVBoxLayout();
00082
00083
00084 right_image_ = new QImage();
00085 right_image_label_ = new QLabel(this);
00086 std::string image_path = "./resources/MoveIt_Setup_Asst_xSm.png";
00087 if (chdir(config_data_->setup_assistant_path_.c_str()) != 0)
00088 {
00089 ROS_ERROR("FAILED TO CHANGE PACKAGE TO moveit_setup_assistant");
00090 }
00091
00092 if (right_image_->load(image_path.c_str()))
00093 {
00094 right_image_label_->setPixmap(QPixmap::fromImage(*right_image_));
00095 right_image_label_->setMinimumHeight(384);
00096
00097 }
00098 else
00099 {
00100 ROS_ERROR_STREAM("FAILED TO LOAD " << image_path);
00101 }
00102
00103 logo_image_ = new QImage();
00104 logo_image_label_ = new QLabel(this);
00105 image_path = "./resources/moveit_logo.png";
00106
00107 if (logo_image_->load(image_path.c_str()))
00108 {
00109 logo_image_label_->setPixmap(QPixmap::fromImage(logo_image_->scaledToHeight(50)));
00110 logo_image_label_->setMinimumWidth(96);
00111 }
00112 else
00113 {
00114 ROS_ERROR_STREAM("FAILED TO LOAD " << image_path);
00115 }
00116
00117
00118 HeaderWidget* header = new HeaderWidget(
00119 "MoveIt Setup Assistant", "Welcome to the MoveIt Setup Assistant! These tools will assist you in creating a "
00120 "MoveIt configuration package that is required to run MoveIt. This includes generating "
00121 "a Semantic Robot Description Format (SRDF) file, kinematics configuration file and "
00122 "OMPL planning configuration file. It also involves creating launch files for move "
00123 "groups, OMPL planner, planning contexts and the planning warehouse.",
00124 this);
00125 layout->addWidget(header);
00126
00127 left_layout->addWidget(logo_image_label_);
00128 left_layout->setAlignment(logo_image_label_, Qt::AlignLeft | Qt::AlignTop);
00129
00130
00131 select_mode_ = new SelectModeWidget(this);
00132 connect(select_mode_->btn_new_, SIGNAL(clicked()), this, SLOT(showNewOptions()));
00133 connect(select_mode_->btn_exist_, SIGNAL(clicked()), this, SLOT(showExistingOptions()));
00134 left_layout->addWidget(select_mode_);
00135
00136
00137
00138
00139 stack_path_ = new LoadPathWidget("Load MoveIt Configuration Package Path",
00140 "Specify the package name or path of an existing MoveIt configuration package to be "
00141 "edited for your robot. Example package name: <i>pr2_moveit_config</i>",
00142 true, this);
00143 stack_path_->hide();
00144 left_layout->addWidget(stack_path_);
00145
00146
00147 urdf_file_ =
00148 new LoadPathWidget("Load a URDF or COLLADA Robot Model",
00149 "Specify the location of an existing Universal Robot Description Format or COLLADA file for "
00150 "your robot. The robot model will be loaded to the parameter server for you.",
00151 false, true, this);
00152 urdf_file_->hide();
00153 left_layout->addWidget(urdf_file_);
00154
00155
00156
00157
00158 chk_use_jade_xacro_ = new QCheckBox("Enable Jade+ xacro extensions", urdf_file_);
00159 chk_use_jade_xacro_->setToolTip("Enables the use of the xacro extensions that are available on ROS Jade and\n"
00160 "newer in ROS Indigo. Enable this if the xacro that will be loaded makes use\n"
00161 "of any of those features.");
00162 urdf_file_->layout()->addWidget(chk_use_jade_xacro_);
00163
00164
00165 QHBoxLayout* load_files_layout = new QHBoxLayout();
00166
00167 progress_bar_ = new QProgressBar(this);
00168 progress_bar_->setMaximum(100);
00169 progress_bar_->setMinimum(0);
00170 progress_bar_->hide();
00171 load_files_layout->addWidget(progress_bar_);
00172
00173
00174 btn_load_ = new QPushButton("&Load Files", this);
00175 btn_load_->setMinimumWidth(180);
00176 btn_load_->setMinimumHeight(40);
00177 btn_load_->hide();
00178 load_files_layout->addWidget(btn_load_);
00179 load_files_layout->setAlignment(btn_load_, Qt::AlignRight);
00180 connect(btn_load_, SIGNAL(clicked()), this, SLOT(loadFilesClick()));
00181
00182
00183 next_label_ = new QLabel(this);
00184 QFont next_label_font("Arial", 11, QFont::Bold);
00185 next_label_->setFont(next_label_font);
00186
00187 next_label_->setText("Success! Use the left navigation pane to continue.");
00188
00189 next_label_->hide();
00190
00191 right_layout->addWidget(right_image_label_);
00192 right_layout->setAlignment(right_image_label_, Qt::AlignRight | Qt::AlignTop);
00193
00194
00195
00196 layout->setAlignment(Qt::AlignTop);
00197 hlayout->setAlignment(Qt::AlignTop);
00198 left_layout->setAlignment(Qt::AlignTop);
00199 right_layout->setAlignment(Qt::AlignTop);
00200
00201
00202 left_layout->setSpacing(30);
00203
00204
00205
00206 hlayout->addLayout(left_layout);
00207 hlayout->addLayout(right_layout);
00208 layout->addLayout(hlayout);
00209
00210
00211 QWidget* vspacer = new QWidget(this);
00212 vspacer->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
00213 layout->addWidget(vspacer);
00214
00215
00216 layout->addWidget(next_label_);
00217 layout->setAlignment(next_label_, Qt::AlignRight);
00218 layout->addLayout(load_files_layout);
00219
00220 this->setLayout(layout);
00221
00222
00223
00224 if (config_data_->debug_)
00225 {
00226
00227
00228 QTimer* update_timer = new QTimer(this);
00229 update_timer->setSingleShot(true);
00230 connect(update_timer, SIGNAL(timeout()), btn_load_, SLOT(click()));
00231 update_timer->start(100);
00232 }
00233 }
00234
00235
00236
00237
00238 StartScreenWidget::~StartScreenWidget()
00239 {
00240 delete right_image_;
00241 delete logo_image_;
00242 }
00243
00244
00245
00246
00247 void StartScreenWidget::showNewOptions()
00248 {
00249
00250 select_mode_->btn_exist_->setChecked(false);
00251 select_mode_->btn_new_->setChecked(true);
00252 urdf_file_->show();
00253 stack_path_->hide();
00254 btn_load_->show();
00255
00256
00257 create_new_package_ = true;
00258 }
00259
00260
00261
00262
00263 void StartScreenWidget::showExistingOptions()
00264 {
00265
00266 select_mode_->btn_exist_->setChecked(true);
00267 select_mode_->btn_new_->setChecked(false);
00268 urdf_file_->hide();
00269 stack_path_->show();
00270 btn_load_->show();
00271
00272
00273 create_new_package_ = false;
00274 }
00275
00276
00277
00278
00279 void StartScreenWidget::loadFilesClick()
00280 {
00281
00282 urdf_file_->setDisabled(true);
00283
00284 stack_path_->setDisabled(true);
00285 select_mode_->setDisabled(true);
00286 btn_load_->setDisabled(true);
00287 progress_bar_->show();
00288
00289 bool result;
00290
00291
00292 if (create_new_package_)
00293 {
00294 result = loadNewFiles();
00295 }
00296 else
00297 {
00298 result = loadExistingFiles();
00299 }
00300
00301
00302 if (!result)
00303 {
00304
00305 urdf_file_->setDisabled(false);
00306
00307 stack_path_->setDisabled(false);
00308 select_mode_->setDisabled(false);
00309 btn_load_->setDisabled(false);
00310 progress_bar_->hide();
00311 }
00312 else
00313 {
00314
00315 right_image_label_->hide();
00316 }
00317 }
00318
00319
00320
00321
00322 bool StartScreenWidget::loadExistingFiles()
00323 {
00324
00325 progress_bar_->setValue(10);
00326 QApplication::processEvents();
00327
00328
00329 if (!createFullPackagePath())
00330 return false;
00331
00332 std::string setup_assistant_path;
00333
00334
00335 if (!config_data_->getSetupAssistantYAMLPath(setup_assistant_path))
00336 {
00337 QMessageBox::warning(
00338 this, "Incorrect Directory/Package",
00339 QString("The chosen package location exists but was not previously created using this MoveIt Setup Assistant. "
00340 "If this is a mistake, replace the missing file: ")
00341 .append(setup_assistant_path.c_str()));
00342 return false;
00343 }
00344
00345
00346 if (!config_data_->inputSetupAssistantYAML(setup_assistant_path))
00347 {
00348 QMessageBox::warning(this, "Setup Assistant File Error",
00349 QString("Unable to correctly parse the setup assistant configuration file: ")
00350 .append(setup_assistant_path.c_str()));
00351 return false;
00352 }
00353
00354
00355 progress_bar_->setValue(30);
00356 QApplication::processEvents();
00357
00358
00359 if (!createFullURDFPath())
00360 return false;
00361
00362
00363 if (!loadURDFFile(config_data_->urdf_path_, config_data_->urdf_requires_jade_xacro_))
00364 return false;
00365
00366
00367 if (!createFullSRDFPath(config_data_->config_pkg_path_))
00368 return false;
00369
00370
00371 progress_bar_->setValue(50);
00372 QApplication::processEvents();
00373
00374
00375 if (!loadSRDFFile(config_data_->srdf_path_))
00376 return false;
00377
00378
00379 progress_bar_->setValue(60);
00380 QApplication::processEvents();
00381
00382
00383 config_data_->loadAllowedCollisionMatrix();
00384
00385
00386 fs::path kinematics_yaml_path = config_data_->config_pkg_path_;
00387 kinematics_yaml_path /= "config/kinematics.yaml";
00388
00389 if (!config_data_->inputKinematicsYAML(kinematics_yaml_path.make_preferred().native().c_str()))
00390 {
00391 QMessageBox::warning(this, "No Kinematic YAML File",
00392 QString("Failed to parse kinematics yaml file. This file is not critical but any previous "
00393 "kinematic solver settings have been lost. To re-populate this file edit each "
00394 "existing planning group and choose a solver, then save each change. \n\nFile error "
00395 "at location ")
00396 .append(kinematics_yaml_path.make_preferred().native().c_str()));
00397 }
00398
00399
00400
00401
00402 Q_EMIT readyToProgress();
00403
00404
00405 progress_bar_->setValue(70);
00406 QApplication::processEvents();
00407
00408
00409 Q_EMIT loadRviz();
00410
00411
00412 progress_bar_->setValue(100);
00413 QApplication::processEvents();
00414
00415 next_label_->show();
00416
00417 ROS_INFO("Loading Setup Assistant Complete");
00418 return true;
00419 }
00420
00421
00422
00423
00424 bool StartScreenWidget::loadNewFiles()
00425 {
00426
00427 config_data_->urdf_path_ = urdf_file_->getPath();
00428
00429 config_data_->urdf_requires_jade_xacro_ = chk_use_jade_xacro_->isChecked();
00430
00431
00432 if (config_data_->urdf_path_.empty())
00433 {
00434 QMessageBox::warning(this, "Error Loading Files", "No robot model file specefied");
00435 return false;
00436 }
00437
00438
00439 if (!fs::is_regular_file(config_data_->urdf_path_))
00440 {
00441 QMessageBox::warning(this, "Error Loading Files",
00442 QString("Unable to locate the URDF file: ").append(config_data_->urdf_path_.c_str()));
00443 return false;
00444 }
00445
00446
00447 if (!extractPackageNameFromPath())
00448 {
00449 return false;
00450 }
00451
00452
00453 progress_bar_->setValue(20);
00454 QApplication::processEvents();
00455
00456
00457 if (!loadURDFFile(config_data_->urdf_path_, config_data_->urdf_requires_jade_xacro_))
00458 return false;
00459
00460
00461 progress_bar_->setValue(50);
00462 QApplication::processEvents();
00463
00464
00465 const std::string blank_srdf = "<?xml version='1.0'?><robot name='" + config_data_->urdf_model_->getName() + "'></"
00466 "robot>";
00467
00468
00469 if (!setSRDFFile(blank_srdf))
00470 {
00471 QMessageBox::warning(this, "Error Loading Files", "Failure loading blank SRDF file.");
00472 return false;
00473 }
00474
00475
00476 progress_bar_->setValue(60);
00477 QApplication::processEvents();
00478
00479
00480
00481
00482 Q_EMIT readyToProgress();
00483
00484
00485 progress_bar_->setValue(70);
00486 QApplication::processEvents();
00487
00488
00489 Q_EMIT loadRviz();
00490
00491
00492 progress_bar_->setValue(100);
00493 QApplication::processEvents();
00494
00495 next_label_->show();
00496
00497 ROS_INFO("Loading Setup Assistant Complete");
00498 return true;
00499 }
00500
00501
00502
00503
00504 bool StartScreenWidget::loadURDFFile(const std::string& urdf_file_path, bool use_jade_xacro)
00505 {
00506
00507 std::ifstream urdf_stream(urdf_file_path.c_str());
00508 if (!urdf_stream.good())
00509 {
00510 QMessageBox::warning(this, "Error Loading Files",
00511 QString("URDF/COLLADA file not found: ").append(urdf_file_path.c_str()));
00512 return false;
00513 }
00514 std::string urdf_string;
00515 bool xacro = false;
00516
00517 if (urdf_file_path.find(".xacro") != std::string::npos)
00518 {
00519 std::string cmd("rosrun xacro xacro.py ");
00520
00521
00522 if (use_jade_xacro)
00523 cmd += "--inorder ";
00524
00525 cmd += urdf_file_path;
00526 ROS_INFO("Running '%s'...", cmd.c_str());
00527
00528 FILE* pipe = popen(cmd.c_str(), "r");
00529 if (!pipe)
00530 {
00531 QMessageBox::warning(this, "Error Loading Files",
00532 QString("XACRO file or parser not found: ").append(urdf_file_path.c_str()));
00533 return false;
00534 }
00535 char buffer[128] = { 0 };
00536 while (!feof(pipe))
00537 {
00538 if (fgets(buffer, sizeof(buffer), pipe) != NULL)
00539 urdf_string += buffer;
00540 }
00541 pclose(pipe);
00542
00543 if (urdf_string.empty())
00544 {
00545 QMessageBox::warning(this, "Error Loading Files",
00546 QString("Unable to parse XACRO file: ").append(urdf_file_path.c_str()));
00547 return false;
00548 }
00549 xacro = true;
00550 }
00551 else
00552 {
00553
00554 urdf_stream.seekg(0, std::ios::end);
00555 urdf_string.reserve(urdf_stream.tellg());
00556 urdf_stream.seekg(0, std::ios::beg);
00557 urdf_string.assign((std::istreambuf_iterator<char>(urdf_stream)), std::istreambuf_iterator<char>());
00558 urdf_stream.close();
00559 }
00560
00561 if (!config_data_->urdf_model_->initString(urdf_string))
00562 {
00563 QMessageBox::warning(this, "Error Loading Files", "URDF/COLLADA file is not a valid robot model.");
00564 return false;
00565 }
00566 config_data_->urdf_from_xacro_ = xacro;
00567
00568 ROS_INFO_STREAM("Loaded " << config_data_->urdf_model_->getName() << " robot model.");
00569
00570
00571 ros::NodeHandle nh;
00572 int steps = 0;
00573 while (!nh.ok() && steps < 4)
00574 {
00575 ROS_WARN("Waiting for node handle");
00576 sleep(1);
00577 steps++;
00578 ros::spinOnce();
00579 }
00580
00581 ROS_INFO("Setting Param Server with Robot Description");
00582
00583 nh.setParam("/robot_description", urdf_string);
00584
00585 return true;
00586 }
00587
00588
00589
00590
00591 bool StartScreenWidget::loadSRDFFile(const std::string& srdf_file_path)
00592 {
00593
00594 std::ifstream srdf_stream(srdf_file_path.c_str());
00595 if (!srdf_stream.good())
00596 {
00597 QMessageBox::warning(this, "Error Loading Files",
00598 QString("SRDF file not found: ").append(config_data_->srdf_path_.c_str()));
00599 return false;
00600 }
00601
00602
00603 std::string srdf_string;
00604 srdf_stream.seekg(0, std::ios::end);
00605 srdf_string.reserve(srdf_stream.tellg());
00606 srdf_stream.seekg(0, std::ios::beg);
00607 srdf_string.assign((std::istreambuf_iterator<char>(srdf_stream)), std::istreambuf_iterator<char>());
00608 srdf_stream.close();
00609
00610
00611 return setSRDFFile(srdf_string);
00612 }
00613
00614
00615
00616
00617 bool StartScreenWidget::setSRDFFile(const std::string& srdf_string)
00618 {
00619
00620 if (!config_data_->srdf_->initString(*config_data_->urdf_model_, srdf_string))
00621 {
00622 QMessageBox::warning(this, "Error Loading Files", "SRDF file not a valid semantic robot description model.");
00623 return false;
00624 }
00625 ROS_INFO_STREAM("Robot semantic model successfully loaded.");
00626
00627
00628 ros::NodeHandle nh;
00629 int steps = 0;
00630 while (!nh.ok() && steps < 4)
00631 {
00632 ROS_WARN("Waiting for node handle");
00633 sleep(1);
00634 steps++;
00635 ros::spinOnce();
00636 }
00637
00638 ROS_INFO("Setting Param Server with Robot Semantic Description");
00639 nh.setParam("/robot_description_semantic", srdf_string);
00640
00641 return true;
00642 }
00643
00644
00645
00646
00647
00648
00649
00650 bool StartScreenWidget::extractPackageNameFromPath()
00651 {
00652
00653 fs::path urdf_path = config_data_->urdf_path_;
00654 fs::path urdf_directory = urdf_path;
00655 urdf_directory.remove_filename();
00656
00657 fs::path sub_path;
00658 fs::path relative_path;
00659 std::string package_name;
00660
00661
00662 fs::path package_path;
00663
00664 std::vector<std::string> path_parts;
00665
00666
00667 for (fs::path::iterator it = urdf_directory.begin(); it != urdf_directory.end(); ++it)
00668 path_parts.push_back(it->native());
00669
00670 bool packageFound = false;
00671
00672
00673 for (int segment_length = path_parts.size(); segment_length > 0; --segment_length)
00674 {
00675
00676 sub_path.clear();
00677
00678
00679 for (int segment_count = 0; segment_count < segment_length; ++segment_count)
00680 {
00681 sub_path /= path_parts[segment_count];
00682
00683
00684 if (segment_count == segment_length - 1)
00685 {
00686 package_name = path_parts[segment_count];
00687 }
00688 }
00689
00690
00691 package_path = sub_path;
00692 package_path /= "package.xml";
00693 ROS_DEBUG_STREAM("Checking for " << package_path.make_preferred().native());
00694
00695
00696 if (fs::is_regular_file(package_path) || fs::is_regular_file(sub_path / "manifest.xml"))
00697 {
00698
00699 for (size_t relative_count = segment_length; relative_count < path_parts.size(); ++relative_count)
00700 relative_path /= path_parts[relative_count];
00701
00702
00703 relative_path /= urdf_path.filename();
00704
00705
00706 segment_length = 0;
00707 packageFound = true;
00708 break;
00709 }
00710 }
00711
00712
00713 if (!packageFound)
00714 {
00715
00716 config_data_->urdf_pkg_name_ = "";
00717 config_data_->urdf_pkg_relative_path_ = config_data_->urdf_path_;
00718 }
00719 else
00720 {
00721
00722 const std::string robot_desc_pkg_path = ros::package::getPath(config_data_->urdf_pkg_name_) + "/";
00723
00724 if (robot_desc_pkg_path.empty())
00725 {
00726 QMessageBox::warning(this, "Package Not Found In ROS Workspace",
00727 QString("ROS was unable to find the package name '")
00728 .append(config_data_->urdf_pkg_name_.c_str())
00729 .append("' within the ROS workspace. This may cause issues later."));
00730 }
00731
00732
00733 config_data_->urdf_pkg_name_ = package_name;
00734 config_data_->urdf_pkg_relative_path_ = relative_path.make_preferred().native();
00735 }
00736
00737 ROS_DEBUG_STREAM("URDF Package Name: " << config_data_->urdf_pkg_name_);
00738 ROS_DEBUG_STREAM("URDF Package Path: " << config_data_->urdf_pkg_relative_path_);
00739
00740 return true;
00741 }
00742
00743
00744
00745
00746 bool StartScreenWidget::createFullURDFPath()
00747 {
00748 if (!config_data_->createFullURDFPath())
00749 {
00750 if (config_data_->urdf_path_.empty())
00751 {
00752 QMessageBox::warning(this, "Error Loading Files", QString("ROS was unable to find the package name '")
00753 .append(config_data_->urdf_pkg_name_.c_str())
00754 .append("'. Verify this package is inside your ROS "
00755 "workspace and is a proper ROS package."));
00756 }
00757 else
00758 {
00759 QMessageBox::warning(
00760 this, "Error Loading Files",
00761 QString("Unable to locate the URDF file in package. File: ").append(config_data_->urdf_path_.c_str()));
00762 }
00763 return false;
00764 }
00765 fs::path urdf_path;
00766
00767
00768 if (config_data_->urdf_pkg_name_.empty())
00769 {
00770 ROS_WARN("The URDF path is absolute to the filesystem and not relative to a ROS package/stack");
00771 }
00772
00773 return true;
00774 }
00775
00776
00777
00778
00779 bool StartScreenWidget::createFullSRDFPath(const std::string& package_path)
00780 {
00781 if (!config_data_->createFullSRDFPath(package_path))
00782 {
00783 QMessageBox::warning(this, "Error Loading Files",
00784 QString("Unable to locate the SRDF file: ").append(config_data_->srdf_path_.c_str()));
00785 return false;
00786 }
00787
00788 return true;
00789 }
00790
00791
00792
00793
00794 bool StartScreenWidget::createFullPackagePath()
00795 {
00796
00797 std::string package_path_input = stack_path_->getPath();
00798
00799 if (package_path_input.empty())
00800 {
00801 QMessageBox::warning(this, "Error Loading Files", "Please specify a configuration package path to load.");
00802 return false;
00803 }
00804
00805
00806 if (!config_data_->setPackagePath(package_path_input))
00807 {
00808 QMessageBox::critical(this, "Error Loading Files", "The specified path is not a directory or is not accessable");
00809 return false;
00810 }
00811 return true;
00812 }
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823 SelectModeWidget::SelectModeWidget(QWidget* parent) : QFrame(parent)
00824 {
00825
00826 setFrameShape(QFrame::StyledPanel);
00827 setFrameShadow(QFrame::Raised);
00828 setLineWidth(1);
00829 setMidLineWidth(0);
00830
00831
00832 QVBoxLayout* layout = new QVBoxLayout(this);
00833
00834
00835 QHBoxLayout* hlayout = new QHBoxLayout();
00836
00837
00838 QLabel* widget_title = new QLabel(this);
00839 widget_title->setText("Choose mode:");
00840 QFont widget_title_font("Arial", 12, QFont::Bold);
00841 widget_title->setFont(widget_title_font);
00842 layout->addWidget(widget_title);
00843 layout->setAlignment(widget_title, Qt::AlignTop);
00844
00845
00846 QTextEdit* widget_instructions = new QTextEdit(this);
00847 widget_instructions->setText("All settings for MoveIt are stored in a Moveit configuration package. Here you have "
00848 "the option to create a new configuration package, or load an existing one. Note: any "
00849 "changes to a MoveIt configuration package outside this setup assistant will likely be "
00850 "overwritten by this tool.");
00851 widget_instructions->setWordWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
00852
00853 layout->addWidget(widget_instructions);
00854 layout->setAlignment(widget_instructions, Qt::AlignTop);
00855
00856
00857 btn_new_ = new QPushButton(this);
00858 btn_new_->setText("Create &New MoveIt\nConfiguration Package");
00859 hlayout->addWidget(btn_new_);
00860
00861
00862 btn_exist_ = new QPushButton(this);
00863 btn_exist_->setText("&Edit Existing MoveIt\nConfiguration Package");
00864 btn_exist_->setCheckable(true);
00865 hlayout->addWidget(btn_exist_);
00866
00867
00868 layout->addLayout(hlayout);
00869 setLayout(layout);
00870 btn_new_->setCheckable(true);
00871 }
00872
00873 }