parameters: (object,source_robot,target_robot,link_map=None)
docstring: Converts a Klampt object that refers to a source robot to an object that
      refers to a target robot, assuming matched link names.
  
      Args:
          object: any Klampt object. This is only meaningful for int, list of int
              (IntArray), vector (Config), list of vector (Configs),
              Trajectory, IKGoal, RobotModelLink, or SubRobotModel types.
          source_robot (str or RobotModel): the robot for which ``object`` is
              meaningful.  If str, this is the filename of the source robot.
          target_robot (str or RobotModel): the robot that will use the return
              result.  If str, this is the filename of the target robot.
          link_map (dict, optional): if given, maps source link names to target
              link names, or source link indices to target link indices.  This
              can also be a 1-element dict {'*':'prefix:*'} indicating that the
              links of source_robot map to 'prefix:'+[LINK_NAME], or a dict
              {'prefix:*':'*'} indicating the reverse.
      Returns:
          same type as object: the object, with links mapped to the target robot.
docstring_summary: Converts a Klampt object that refers to a source robot to an object that
      refers to a target robot, assuming matched link names.
docstring_tokens: Converts a Klampt object that refers to a source robot to an object that refers to a target robot assuming matched link names .
function: def transfer(object,source_robot,target_robot,link_map=None):
      """Converts a Klampt object that refers to a source robot to an object that
      refers to a target robot, assuming matched link names.
  
      Args:
          object: any Klampt object. This is only meaningful for int, list of int
              (IntArray), vector (Config), list of vector (Configs),
              Trajectory, IKGoal, RobotModelLink, or SubRobotModel types.
          source_robot (str or RobotModel): the robot for which ``object`` is
              meaningful.  If str, this is the filename of the source robot.
          target_robot (str or RobotModel): the robot that will use the return
              result.  If str, this is the filename of the target robot.
          link_map (dict, optional): if given, maps source link names to target
              link names, or source link indices to target link indices.  This
              can also be a 1-element dict {'*':'prefix:*'} indicating that the
              links of source_robot map to 'prefix:'+[LINK_NAME], or a dict
              {'prefix:*':'*'} indicating the reverse.
      Returns:
          same type as object: the object, with links mapped to the target robot.
  
      """
      from ..robotsim import WorldModel,RobotModelLink
      from .subrobot import SubRobotModel
      temp_world = None
      if isinstance(source_robot,str):
          temp_world = WorldModel()
          if not temp_world.readFile(source_robot):
              raise ValueError("Couldn't load source robot model "+source_robot)
          source_robot = temp_world.robot(0)
      if isinstance(target_robot,str):
          if temp_world is None:
              temp_world = WorldModel()
          if not temp_world.readFile(target_robot):
              raise ValueError("Couldn't load target robot model "+target_robot)
          target_robot = temp_world.robot(temp_world.numRobots()-1)
      if link_map is None:
          link_map = dict()
          for i in range(source_robot.numLinks()):
              sname = source_robot.link(i).getName()
              tlink = target_robot.link(sname)
              if tlink.index >= 0:
                  link_map[i] = tlink.index
          warn_threshold = min(source_robot.numLinks()//2,target_robot.numLinks()//2)
          if len(link_map) < warn_threshold:
              print("klampt.model.types.transfer: warning, auto-detected link map:")
              print(link_map)
              print("Source links:")
              for i in range(source_robot.numLinks()):
                  print(" ",source_robot.link(i).getName())
              print("Target links:")
              for i in range(target_robot.numLinks()):
                  print(" ",target_robot.link(i).getName())
      if len(link_map)==1:
          items = list(link_map.items())
          if items[0][0] =='*':
              if not items[0][1].endswith('*'):
                  if '*' not in items[0][1]:
                      raise NotImplementedError("TODO: match * inside target string")
                  raise ValueError("Invalid wildcard match string")
              prefix = items[0][1][:-1]
              link_map = dict()
              for i in range(source_robot.numLinks()):
                  sname = source_robot.link(i).getName()
                  tlink = target_robot.link(prefix+sname)
                  if tlink.index >= 0:
                      link_map[i] = tlink.index
          elif items[0][1] == '*':
              if not items[0][0].endswith('*'):
                  if '*' not in items[0][0]:
                      raise NotImplementedError("TODO: match * inside source string")
                  raise ValueError("Invalid wildcard match string")
              prefix = items[0][0][:-1]
              link_map = dict()
              for i in range(target_robot.numLinks()):
                  tname = target_robot.link(i).getName()
                  slink = source_robot.link(prefix+tname)
                  if slink.index >= 0:
                      link_map[slink.index] = i
      if len(link_map)==0:
          raise ValueError("The source and target robot have no links in common")
      #convert to indices    
      link_map_indices = dict()
      for (k,v) in link_map.items():
          if isinstance(k,str):
              kindex = source_robot.link(k).index
              if kindex < 0:
                  raise ValueError("Invalid source link "+k)
              k = kindex
          elif k < 0 or k >= source_robot.numLinks():
              raise ValueError("Invalid source link {}".format(k))
          if isinstance(v,str):
              vindex = target_robot.link(v).index
              if vindex < 0:
                  raise ValueError("Invalid target link "+v)
              v = vindex
          elif k < 0 or k >= target_robot.numLinks():
              raise ValueError("Invalid target link {}".format(k))
          link_map_indices[k]=v
      if isinstance(object,int):
          return link_map_indices.get(object,-1)
      elif isinstance(object,RobotModelLink):
          return target_robot.link(link_map_indices.get(object.index,-1))
      elif isinstance(object,SubRobotModel):
          assert object._robot is source_robot,"Incorrect source robot for transferring SubRobotModel"
          tlinks = transfer(object._links,source_robot,target_robot,link_map_indices)
          if any(v < 0 for v in tlinks):
              raise ValueError("Can't transfer SubRobotModel; one or more links of the source subrobot does not appear in the target robot")
          return SubRobotModel(target_robot,tlinks)
  
      try:
          otypes = object_to_types(object,temp_world)
          if isinstance(otypes,str):
              otypes = [otypes]
      except ValueError:
          return object
      if 'IntArray' in otypes:
          return [link_map_indices.get(ind,-1) for ind in object]
      elif 'Config' in otypes:
          qres = target_robot.getConfig()
          for i,j in link_map_indices.items():
              qres[j] = object[i]
          return qres
      elif 'Configs' in otypes:
          res = []
          qres = target_robot.getConfig()
          for q in object:
              for i,j in link_map_indices.items():
                  qres[j] = q[i]
              res.append([v for v in qres])
          return res
      elif 'IKGoal' in otypes:
          source_link,dest_link = object.link(),object.destLink()
          res = object.copy()
          res.setLinks(source_link,dest_link)
          return res
      elif 'Trajectory' in otypes:
          if isinstance(object,RobotTrajectory):
              return RobotTrajectory(target_robot,object.times,transfer(object.milestones,source_robot,target_robot,link_map_indices))
          return object.constructor(object.times,transfer(object.milestones,source_robot,target_robot,link_map_indices))
      else:
          return object
function_tokens: def transfer ( object , source_robot , target_robot , link_map = None ) : from . . robotsim import WorldModel , RobotModelLink from . subrobot import SubRobotModel temp_world = None if isinstance ( source_robot , str ) : temp_world = WorldModel ( ) if not temp_world . readFile ( source_robot ) : raise ValueError ( "Couldn't load source robot model " + source_robot ) source_robot = temp_world . robot ( 0 ) if isinstance ( target_robot , str ) : if temp_world is None : temp_world = WorldModel ( ) if not temp_world . readFile ( target_robot ) : raise ValueError ( "Couldn't load target robot model " + target_robot ) target_robot = temp_world . robot ( temp_world . numRobots ( ) - 1 ) if link_map is None : link_map = dict ( ) for i in range ( source_robot . numLinks ( ) ) : sname = source_robot . link ( i ) . getName ( ) tlink = target_robot . link ( sname ) if tlink . index >= 0 : link_map [ i ] = tlink . index warn_threshold = min ( source_robot . numLinks ( ) // 2 , target_robot . numLinks ( ) // 2 ) if len ( link_map ) < warn_threshold : print ( "klampt.model.types.transfer: warning, auto-detected link map:" ) print ( link_map ) print ( "Source links:" ) for i in range ( source_robot . numLinks ( ) ) : print ( " " , source_robot . link ( i ) . getName ( ) ) print ( "Target links:" ) for i in range ( target_robot . numLinks ( ) ) : print ( " " , target_robot . link ( i ) . getName ( ) ) if len ( link_map ) == 1 : items = list ( link_map . items ( ) ) if items [ 0 ] [ 0 ] == '*' : if not items [ 0 ] [ 1 ] . endswith ( '*' ) : if '*' not in items [ 0 ] [ 1 ] : raise NotImplementedError ( "TODO: match * inside target string" ) raise ValueError ( "Invalid wildcard match string" ) prefix = items [ 0 ] [ 1 ] [ : - 1 ] link_map = dict ( ) for i in range ( source_robot . numLinks ( ) ) : sname = source_robot . link ( i ) . getName ( ) tlink = target_robot . link ( prefix + sname ) if tlink . index >= 0 : link_map [ i ] = tlink . index elif items [ 0 ] [ 1 ] == '*' : if not items [ 0 ] [ 0 ] . endswith ( '*' ) : if '*' not in items [ 0 ] [ 0 ] : raise NotImplementedError ( "TODO: match * inside source string" ) raise ValueError ( "Invalid wildcard match string" ) prefix = items [ 0 ] [ 0 ] [ : - 1 ] link_map = dict ( ) for i in range ( target_robot . numLinks ( ) ) : tname = target_robot . link ( i ) . getName ( ) slink = source_robot . link ( prefix + tname ) if slink . index >= 0 : link_map [ slink . index ] = i if len ( link_map ) == 0 : raise ValueError ( "The source and target robot have no links in common" ) #convert to indices     link_map_indices = dict ( ) for ( k , v ) in link_map . items ( ) : if isinstance ( k , str ) : kindex = source_robot . link ( k ) . index if kindex < 0 : raise ValueError ( "Invalid source link " + k ) k = kindex elif k < 0 or k >= source_robot . numLinks ( ) : raise ValueError ( "Invalid source link {}" . format ( k ) ) if isinstance ( v , str ) : vindex = target_robot . link ( v ) . index if vindex < 0 : raise ValueError ( "Invalid target link " + v ) v = vindex elif k < 0 or k >= target_robot . numLinks ( ) : raise ValueError ( "Invalid target link {}" . format ( k ) ) link_map_indices [ k ] = v if isinstance ( object , int ) : return link_map_indices . get ( object , - 1 ) elif isinstance ( object , RobotModelLink ) : return target_robot . link ( link_map_indices . get ( object . index , - 1 ) ) elif isinstance ( object , SubRobotModel ) : assert object . _robot is source_robot , "Incorrect source robot for transferring SubRobotModel" tlinks = transfer ( object . _links , source_robot , target_robot , link_map_indices ) if any ( v < 0 for v in tlinks ) : raise ValueError ( "Can't transfer SubRobotModel; one or more links of the source subrobot does not appear in the target robot" ) return SubRobotModel ( target_robot , tlinks ) try : otypes = object_to_types ( object , temp_world ) if isinstance ( otypes , str ) : otypes = [ otypes ] except ValueError : return object if 'IntArray' in otypes : return [ link_map_indices . get ( ind , - 1 ) for ind in object ] elif 'Config' in otypes : qres = target_robot . getConfig ( ) for i , j in link_map_indices . items ( ) : qres [ j ] = object [ i ] return qres elif 'Configs' in otypes : res = [ ] qres = target_robot . getConfig ( ) for q in object : for i , j in link_map_indices . items ( ) : qres [ j ] = q [ i ] res . append ( [ v for v in qres ] ) return res elif 'IKGoal' in otypes : source_link , dest_link = object . link ( ) , object . destLink ( ) res = object . copy ( ) res . setLinks ( source_link , dest_link ) return res elif 'Trajectory' in otypes : if isinstance ( object , RobotTrajectory ) : return RobotTrajectory ( target_robot , object . times , transfer ( object . milestones , source_robot , target_robot , link_map_indices ) ) return object . constructor ( object . times , transfer ( object . milestones , source_robot , target_robot , link_map_indices ) ) else : return object