Commits

Mark Moll  committed 147935d

add methods to specify default parameter ranges and values, to be used to automatically construct the right GUI widgets for planner parameters

  • Participants
  • Parent commits 4d0dc3b

Comments (0)

Files changed (19)

File py-bindings/ompl/__init__.py

         else:
             raise ImportError
 
+class PlanningAlgorithms(object):
+    UNKNOWN = 0
+    BOOL = 1
+    ENUM = 2
+    INT = 3
+    DOUBLE = 4
+
+    def __init__(self, module):
+        self.plannerMap = {}
+        for obj in dir(module):
+            obj2 = '%s.%s' % (module.__name__, obj)
+            self.addPlanner(obj2)
+
+    def addPlanner(self, planner):
+        from inspect import isclass
+        import ompl
+        if eval('isclass(%s) and issubclass(%s,ompl.base.Planner)' % (planner, planner)):
+            try:
+                # Get a parameter dictionary by creating a bogus planner instance.
+                # Note that ompl.control.SpaceInformation is derived from
+                # ompl.base.SpaceInformation and geometric planner constructors
+                # happily accept an ompl.control.SpaceInformation object.
+                params = eval("""%s(ompl.control.SpaceInformation(
+                    ompl.base.RealVectorStateSpace(1),
+                    ompl.control.RealVectorControlSpace(
+                        ompl.base.RealVectorStateSpace(1),1))).params()""" % planner)
+            except:
+                # skip planners like Syclop that don't have a basic constructor
+                return
+            pnames = ompl.util.vectorString()
+            params.getParamNames(pnames)
+            paramMap = {}
+            for pname in pnames:
+                p = params[pname]
+                rangeSuggestion = p.getRangeSuggestion()
+                if rangeSuggestion == '': continue
+                rangeSuggestion = rangeSuggestion.split(':')
+                defaultValue = p.getDefaultValue()
+                if len(rangeSuggestion)==1:
+                    print planner
+                    print rangeSuggestion
+                    rangeSuggestion = rangeSuggestion[0].split(',')
+                    if len(rangeSuggestion)==1:
+                        raise Exception('Cannot parse range suggestion')
+                    elif len(rangeSuggestion)==2:
+                        rangeType = self.BOOL
+                        defaultValue = False if defaultValue==rangeSuggestion[0] else True
+                        rangeSuggestion = ''
+                    else:
+                        rangeType = self.ENUM
+                else:
+                    if ('.' in rangeSuggestion[0] or '.' in rangeSuggestion[-1]):
+                        rangeType = self.DOUBLE
+                        rangeSuggestion = [float(r) for r in rangeSuggestion]
+                        defaultValue = 0. if defaultValue=='' else float(defaultValue)
+                    else:
+                        rangeType = self.INT
+                        rangeSuggestion = [int(r) for r in rangeSuggestion]
+                        defaultValue = 0 if defaultValue=='' else int(defaultValue)
+                    if len(rangeSuggestion)==2:
+                        rangeSuggestion = [rangeSuggestion[0], 1, rangeSuggestion[1]]
+                if rangeSuggestion != '':
+                    name = p.getName()
+                    displayName = name.replace('_', ' ').capitalize()
+                    paramMap[p.getName()] = (displayName, rangeType, rangeSuggestion, defaultValue)
+            self.plannerMap[planner] = paramMap
+
+    def getPlanners(self):
+        return self.plannerMap
+
+def initializePlannerLists():
+    import ompl.geometric, ompl.control
+    if ompl.geometric.planners == None:
+        ompl.geometric.planners = ompl.PlanningAlgorithms(ompl.geometric)
+    if ompl.control.planners == None:
+        ompl.control.planners = ompl.PlanningAlgorithms(ompl.control)

File py-bindings/ompl/control/__init__.py

 from ompl import base
 from ompl.control._control import *
+
+# call ompl.initializePlannerLists() to properly initialize this variable
+# with a dictionary of dictionaries, containing planners and associated
+# parameter info
+planners = None

File py-bindings/ompl/geometric/__init__.py

 from ompl import base
 from ompl.geometric._geometric import *
+
+# call ompl.initializePlannerLists() to properly initialize this variable
+# with a dictionary of dictionaries, containing planners and associated
+# parameter info
+planners = None

File src/ompl/base/GenericParam.h

                 return *this;
             }
 
+            /** Set a suggested range */
+            void setRangeSuggestion(std::string rangeSuggestion)
+            {
+                rangeSuggestion_ = rangeSuggestion;
+            }
+
+            /** Get the suggested range of values */
+            std::string getRangeSuggestion()
+            {
+                return rangeSuggestion_;
+            }
+
+            /** Set a default value */
+            void setDefaultValue(std::string defaultValue)
+            {
+                defaultValue_ = defaultValue;
+            }
+
+            /** Return the default value */
+            std::string getDefaultValue()
+            {
+                return defaultValue_;
+            }
+
         protected:
 
             /** \brief The name of the parameter */
             std::string name_;
+
+            /** \brief Suggested range for the parameter
+
+                This can be used to provide a hint to, e.g., a GUI. The
+                convention used in OMPL is to denote ranges for the
+                following types as follows:
+                * bool: "false,true"
+                * enum: "<enum_val0>,<enum_val1>,<enum_val2>,..."
+                * int, double: either "first:last" or "first:stepsize:last".
+                  In the first case, the stepsize is assumed to be 1. It is
+                  important to use floating point representations for double
+                  ranges (i.e., "1." instead of "1") to make sure the type is
+                  deduced correctly.
+            */
+            std::string rangeSuggestion_;
+
+            /** \brief Default value for the paramer
+
+                This suggested default value can be used by, e.g., a GUI.
+            */
+            std::string defaultValue_;
         };
 
 

File src/ompl/control/planners/est/src/EST.cpp

 
     Planner::declareParam<double>("range", this, &EST::setRange, &EST::getRange);
     Planner::declareParam<double>("goal_bias", this, &EST::setGoalBias, &EST::getGoalBias);
+    params_["range"].setRangeSuggestion("0.:1.:10000.");
+    params_["goal_bias"].setRangeSuggestion("0.:.05:1.");
+    params_["goal_bias"].setDefaultValue(boost::lexical_cast<std::string>(goalBias_));
 }
 
 ompl::control::EST::~EST(void)

File src/ompl/control/planners/kpiece/src/KPIECE1.cpp

     Planner::declareParam<unsigned int>("max_close_samples", this, &KPIECE1::setMaxCloseSamplesCount, &KPIECE1::getMaxCloseSamplesCount);
     Planner::declareParam<double>("bad_score_factor", this, &KPIECE1::setBadCellScoreFactor, &KPIECE1::getBadCellScoreFactor);
     Planner::declareParam<double>("good_score_factor", this, &KPIECE1::setGoodCellScoreFactor, &KPIECE1::getGoodCellScoreFactor);
+
+    params_["goal_bias"].setRangeSuggestion("0.:.05:1.");
+    params_["border_fraction"].setRangeSuggestion("0.:0.05:1.");
+    params_["goal_bias"].setDefaultValue(boost::lexical_cast<std::string>(goalBias_));
+    params_["border_fraction"].setDefaultValue(boost::lexical_cast<std::string>(selectBorderFraction_));
 }
 
 ompl::control::KPIECE1::~KPIECE1(void)

File src/ompl/control/planners/rrt/src/RRT.cpp

 
     Planner::declareParam<double>("goal_bias", this, &RRT::setGoalBias, &RRT::getGoalBias);
     Planner::declareParam<bool>("intermediate_states", this, &RRT::setIntermediateStates, &RRT::getIntermediateStates);
+    params_["goal_bias"].setRangeSuggestion("0.:.05:1.");
+    params_["goal_bias"].setDefaultValue(boost::lexical_cast<std::string>(goalBias_));
 }
 
 ompl::control::RRT::~RRT(void)

File src/ompl/geometric/planners/est/src/EST.cpp

 
     Planner::declareParam<double>("range", this, &EST::setRange, &EST::getRange);
     Planner::declareParam<double>("goal_bias", this, &EST::setGoalBias, &EST::getGoalBias);
+    params_["range"].setRangeSuggestion("0.:1.:10000.");
+    params_["goal_bias"].setRangeSuggestion("0.:.05:1.");
+    params_["goal_bias"].setDefaultValue(boost::lexical_cast<std::string>(goalBias_));
 }
 
 ompl::geometric::EST::~EST(void)

File src/ompl/geometric/planners/kpiece/src/BKPIECE1.cpp

     Planner::declareParam<double>("border_fraction", this, &BKPIECE1::setBorderFraction, &BKPIECE1::getBorderFraction);
     Planner::declareParam<double>("failed_expansion_score_factor", this, &BKPIECE1::setFailedExpansionCellScoreFactor, &BKPIECE1::getFailedExpansionCellScoreFactor);
     Planner::declareParam<double>("min_valid_path_fraction", this, &BKPIECE1::setMinValidPathFraction, &BKPIECE1::getMinValidPathFraction);
+    params_["range"].setRangeSuggestion("0.:1.:10000.");
+    params_["border_fraction"].setRangeSuggestion("0.:.05:1.");
+    params_["border_fraction"].setDefaultValue(".9");
 }
 
 ompl::geometric::BKPIECE1::~BKPIECE1(void)

File src/ompl/geometric/planners/kpiece/src/KPIECE1.cpp

     Planner::declareParam<double>("border_fraction", this, &KPIECE1::setBorderFraction, &KPIECE1::getBorderFraction);
     Planner::declareParam<double>("failed_expansion_score_factor", this, &KPIECE1::setFailedExpansionCellScoreFactor, &KPIECE1::getFailedExpansionCellScoreFactor);
     Planner::declareParam<double>("min_valid_path_fraction", this, &KPIECE1::setMinValidPathFraction, &KPIECE1::getMinValidPathFraction);
+
+    params_["range"].setRangeSuggestion("0.:1.:10000.");
+    params_["goal_bias"].setRangeSuggestion("0.:.05:1.");
+    params_["border_fraction"].setRangeSuggestion("0.:0.05:1.");
+    params_["goal_bias"].setDefaultValue(boost::lexical_cast<std::string>(goalBias_));
+    params_["border_fraction"].setDefaultValue(".9");
 }
 
 ompl::geometric::KPIECE1::~KPIECE1(void)

File src/ompl/geometric/planners/kpiece/src/LBKPIECE1.cpp

     Planner::declareParam<double>("range", this, &LBKPIECE1::setRange, &LBKPIECE1::getRange);
     Planner::declareParam<double>("border_fraction", this, &LBKPIECE1::setBorderFraction, &LBKPIECE1::getBorderFraction);
     Planner::declareParam<double>("min_valid_path_fraction", this, &LBKPIECE1::setMinValidPathFraction, &LBKPIECE1::getMinValidPathFraction);
+    params_["range"].setRangeSuggestion("0.:1.:10000");
+    params_["border_fraction"].setRangeSuggestion("0.:.05:1.");
+    params_["border_fraction"].setDefaultValue(".9");
 }
 
  ompl::geometric::LBKPIECE1::~LBKPIECE1(void)

File src/ompl/geometric/planners/prm/src/PRM.cpp

     specs_.optimizingPaths = true;
 
     Planner::declareParam<unsigned int>("max_nearest_neighbors", this, &PRM::setMaxNearestNeighbors);
+    params_["max_nearest_neighbors"].setRangeSuggestion("1:1000");
+    params_["max_nearest_neighbors"].setDefaultValue("10");
 }
 
 ompl::geometric::PRM::~PRM(void)

File src/ompl/geometric/planners/rrt/src/LazyRRT.cpp

 
     Planner::declareParam<double>("range", this, &LazyRRT::setRange, &LazyRRT::getRange);
     Planner::declareParam<double>("goal_bias", this, &LazyRRT::setGoalBias, &LazyRRT::getGoalBias);
+    params_["range"].setRangeSuggestion("0.:1.:10000.");
+    params_["goal_bias"].setRangeSuggestion("0.:.05:1.");
+    params_["goal_bias"].setDefaultValue(boost::lexical_cast<std::string>(goalBias_));
 }
 
 ompl::geometric::LazyRRT::~LazyRRT(void)

File src/ompl/geometric/planners/rrt/src/RRT.cpp

 
     Planner::declareParam<double>("range", this, &RRT::setRange, &RRT::getRange);
     Planner::declareParam<double>("goal_bias", this, &RRT::setGoalBias, &RRT::getGoalBias);
+    params_["range"].setRangeSuggestion("0.:1.:10000.");
+    params_["goal_bias"].setRangeSuggestion("0.:.05:1.");
+    params_["goal_bias"].setDefaultValue(boost::lexical_cast<std::string>(goalBias_));
 }
 
 ompl::geometric::RRT::~RRT(void)

File src/ompl/geometric/planners/rrt/src/RRTConnect.cpp

     maxDistance_ = 0.0;
 
     Planner::declareParam<double>("range", this, &RRTConnect::setRange, &RRTConnect::getRange);
+    params_["range"].setRangeSuggestion("0.:1.:10000.");
     connectionPoint_ = std::make_pair<base::State*, base::State*>(NULL, NULL);
 }
 

File src/ompl/geometric/planners/rrt/src/TRRT.cpp

 
     Planner::declareParam<double>("range", this, &TRRT::setRange, &TRRT::getRange);
     Planner::declareParam<double>("goal_bias", this, &TRRT::setGoalBias, &TRRT::getGoalBias);
+    params_["range"].setRangeSuggestion("0.:1.:10000.");
+    params_["goal_bias"].setRangeSuggestion("0.:.05:1.");
+    params_["goal_bias"].setDefaultValue(boost::lexical_cast<std::string>(goalBias_));
 
     // TRRT Specific Variables
     frontier_threshold_ = 0.0; // set in setup()

File src/ompl/geometric/planners/rrt/src/pRRT.cpp

     Planner::declareParam<double>("range", this, &pRRT::setRange, &pRRT::getRange);
     Planner::declareParam<double>("goal_bias", this, &pRRT::setGoalBias, &pRRT::getGoalBias);
     Planner::declareParam<unsigned int>("thread_count", this, &pRRT::setThreadCount, &pRRT::getThreadCount);
+    params_["range"].setRangeSuggestion("0.:1.:10000.");
+    params_["goal_bias"].setRangeSuggestion("0.:.05:1.");
+    params_["border_fraction"].setRangeSuggestion("0.:0.05:1.");
+    params_["thread_count"].setRangeSuggestion("1:64");
+    params_["goal_bias"].setDefaultValue(boost::lexical_cast<std::string>(goalBias_));
+    params_["thread_count"].setDefaultValue("2");
 }
 
 ompl::geometric::pRRT::~pRRT(void)

File src/ompl/geometric/planners/sbl/src/SBL.cpp

     connectionPoint_ = std::make_pair<base::State*, base::State*>(NULL, NULL);
 
     Planner::declareParam<double>("range", this, &SBL::setRange, &SBL::getRange);
+    params_["range"].setRangeSuggestion("0.:1.:10000.");
 }
 
 ompl::geometric::SBL::~SBL(void)

File src/ompl/geometric/planners/sbl/src/pSBL.cpp

 
     Planner::declareParam<double>("range", this, &pSBL::setRange, &pSBL::getRange);
     Planner::declareParam<unsigned int>("thread_count", this, &pSBL::setThreadCount, &pSBL::getThreadCount);
+    params_["range"].setRangeSuggestion("0.:1.:10000.");
+    params_["thread_count"].setRangeSuggestion("1:64");
+    params_["thread_count"].setDefaultValue("2");
 }
 
 ompl::geometric::pSBL::~pSBL(void)