OpenRAVE Documentation

Source code for openravepy.databases

# -*- coding: utf-8 -*-
# Copyright (C) 2009-2012 Rosen Diankov <rosen.diankov@gmail.com>
# 
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#     http://www.apache.org/licenses/LICENSE-2.0
# 
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Kinematic, quasi-static, dynamic, and geometric analyses are precomputed and used as databases during the run-time. All database generators rely on a specific robot and provide many helpful methods to use the information after it has been generated.

The base abstract class is `databases.DatabaseGenerator` and always takes a robot as its
parameter. Sometimes database generators are dependent on a robot's manipulator, sensor, or target
object. These extra parameters are always required at the constructor level. The hashes of all
objects the generator relies on are used to produce a unique ID to index the database with
$OPENRAVE_DATABASE. For example, the grasping database will combine the robot manipulator hash and
the target object hash.
"""
from __future__ import with_statement # for python 2.5

try:
    import cPickle as pickle
except:
    import pickle

from .. import openravepy_int
from .. import metaclass
from ..misc import OpenRAVEGlobalArguments
import os.path
from os import getenv, makedirs
import time

import logging
log = logging.getLogger('openravepy.databases')

try:
    import h5py
except ImportError:
    pass
    
[docs]class DatabaseGenerator(metaclass.AutoReloader): """The base class defining the structure of the openrave database generators. """ def __init__(self,robot): """ :param robot: if not None, will use the robot's active manipulator :param manip: if not None, will the manipulator, takes precedence over robot """ self.robot = robot self.env = self.robot.GetEnv() self._databasefile = None # necessary if file handle needs to be open try: self.manip = self.robot.GetActiveManipulator() except: self.manip = None def _CloseDatabase(self): if self._databasefile is not None: try: if self._databasefile: self._databasefile.close() except Exception,e: log.warn(e) self._databasefile = None def __del__(self): self._CloseDatabase()
[docs] def clone(self,envother): """clones a database onto a different environment""" import copy clone = copy.copy(self) clone.env = envother clone.robot = clone.env.GetRobot(self.robot.GetName()) clone.manip = clone.robot.GetManipulators(self.manip.GetName())[0] if not self.manip is None else None return clone
[docs] def has(self): raise NotImplementedError()
[docs] def getfilename(self,read=False): return NotImplementedError()
[docs] def load(self): filename = self.getfilename(True) if len(filename) == 0: return None try: modelversion,params = pickle.load(open(filename, 'r')) if modelversion == self.getversion(): return params else: log.error('version is wrong %s!=%s ',modelversion,self.getversion()) except MemoryError,e: log.error('%s failed: ',filename,e) except: pass return None
[docs] def getversion(self): return 0
[docs] def save(self,params): filename=self.getfilename(False) log.info('saving model to %s',filename) try: makedirs(os.path.split(filename)[0]) except OSError: pass pickle.dump((self.getversion(),params), open(filename, 'w'))
def generate(self): raise NotImplementedError()
[docs] def show(self,options=None): raise NotImplementedError()
@staticmethod def _GetValue(value): if hasattr(value,'value'): return value.value else: return value
[docs] def autogenerateparams(self,options=None): """Caches parameters for most commonly used robots/objects and starts the generation process for them""" raise NotImplementedError()
[docs] def autogenerate(self,options=None): self.generate(*self.autogenerateparams(options)) self.save()
[docs] def generatepcg(self): """Generate producer, consumer, and gatherer functions allowing parallelization """ return NotImplementedError()
[docs] def generate(self,*args,**kwargs): starttime = time.time() producer,consumer,gatherer,numjobs = self.generatepcg(*args,**kwargs) log.info('database %s has %d items',self.__class__.__name__.split()[-1],numjobs) for work in producer(): results = consumer(*work) if len(results) > 0: gatherer(*results) gatherer() # gather results log.info('database %s finished in %fs',self.__class__.__name__,time.time()-starttime)
@staticmethod
[docs] def CreateOptionParser(useManipulator=True): """set basic option parsing options for using databasers through the command line """ from optparse import OptionParser, OptionGroup parser = OptionParser(description='OpenRAVE Database Generator.') OpenRAVEGlobalArguments.addOptions(parser) dbgroup = OptionGroup(parser,"OpenRAVE Database Generator General Options") dbgroup.add_option('--show',action='store_true',dest='show',default=False, help='Graphically shows the built model') dbgroup.add_option('--getfilename',action="store_true",dest='getfilename',default=False, help='If set, will return the final database filename where all data is stored') dbgroup.add_option('--gethas',action="store_true",dest='gethas',default=False, help='If set, will exit with 0 if datafile is generated and up to date, otherwise will return a 1. This will require loading the model and checking versions, so might be a little slow.') dbgroup.add_option('--robot',action='store',type='string',dest='robot',default=getenv('OPENRAVE_ROBOT',default='robots/barrettsegway.robot.xml'), help='OpenRAVE robot to load (default=%default)') dbgroup.add_option('--numthreads',action='store',type='int',dest='numthreads',default=1, help='number of threads to compute the database with (default=%default)') if useManipulator: dbgroup.add_option('--manipname',action='store',type='string',dest='manipname',default=None, help='The name of the manipulator on the robot to use') parser.add_option_group(dbgroup) return parser
@staticmethod
[docs] def InitializeFromParser(Model,parser=None,env=None,args=None,robotatts=dict(),defaultviewer=False,allowkinbody=False): """run the database generator from the command line using """ from numpy import eye import sys if parser is None: parser = DatabaseGenerator.CreateOptionParser() (options, args) = parser.parse_args(args=args) loadplugins=True level=openravepy_int.DebugLevel.Info if options.getfilename: loadplugins = False level = openravepy_int.DebugLevel.Fatal if options.gethas: level = openravepy_int.DebugLevel.Fatal openravepy_int.RaveInitialize(loadplugins,level) OpenRAVEGlobalArguments.parseGlobal(options) destroyenv = False if env is None: env = openravepy_int.Environment() destroyenv = True try: options.viewername=OpenRAVEGlobalArguments.parseEnvironment(options,env,defaultviewer=defaultviewer,returnviewer=True) with env: env.Load(options.robot,robotatts) # TODO: if exception is raised after this point, program exits with glibc double-link list corruption. most likely something in Load? if len(env.GetRobots()) > 0: robot = env.GetRobots()[0] elif allowkinbody: robot = env.GetBodies()[0] assert(robot is not None) if hasattr(options,'manipname') and robot.IsRobot(): if options.manipname is None: # prioritize manipulators with ik solvers indices = [i for i,m in enumerate(robot.GetManipulators()) if m.GetIkSolver() is not None] if len(indices) > 0: robot.SetActiveManipulator(indices[0]) else: robot.SetActiveManipulator([i for i,m in enumerate(robot.GetManipulators()) if m.GetName()==options.manipname][0]) model = Model(robot=robot) destroyenv = False return options,model finally: if destroyenv: robot = None model = None env.Destroy()
@staticmethod
[docs] def RunFromParser(Model=None,env=None,parser=None,args=None,robotatts=dict(),defaultviewer=False,allowkinbody=False,**kwargs): """run the database generator from the command line using """ import sys orgenv=env destroyenv = orgenv is None env = None try: options,model = DatabaseGenerator.InitializeFromParser(Model,parser,orgenv,args,robotatts,defaultviewer,allowkinbody) env=model.env if options.getfilename: # prioritize first available filename=model.getfilename(True) if len(filename) == 0: filename=model.getfilename(False) print filename openravepy_int.RaveDestroy() sys.exit(0) if options.gethas: hasmodel=model.load() if hasmodel: hasmodel = os.path.isfile(model.getfilename(True)) print int(hasmodel) openravepy_int.RaveDestroy() sys.exit(not hasmodel) if options.viewername is not None: env.SetViewer(options.viewername) if options.show: if not model.load(): raise ValueError('failed to find cached model %s : %s'%(model.getfilename(True),model.getfilename(False))) model.show(options=options) return model model.autogenerate(options=options) return model finally: if destroyenv and env is not None: env.Destroy()
import inversekinematics import grasping import convexdecomposition import linkstatistics import kinematicreachability import inversereachability # python 2.5 raises 'import *' not allowed with 'from .' from sys import version_info if version_info[0:3]>=(2,6,0): import visibilitymodel else: log.warn('some openravepy.datbases cannot be used python versions < 2.6')

Questions/Feedback

Having problems with OpenRAVE?