parameters: (self,name,type=None,initialValue=None,encoding='auto',constraints=True,optimize=True)
return_statement: return kv
docstring: Adds one or more variables of a given Klamp't type (e.g., "Config", "Rotation", "RigidTransform"). 
          If necessary, constraints on the object will also be added, e.g., joint limits, or a quaternion unit
          norm constraint.
  
          At least one of type / initialValue must be provided.
  
          Args:
              name (str): a name for the variable.
              type (str, optional): a supported variable type (default None determines the type by initialValue). 
                  Supported types include "Config", "Configs", Rotation", "RigidTransform", "Vector3".  Future
                  work may support Trajectory and other types.
              initialValue (optional): the configuration of the variable.  If it's a float, the type will be set to 
                  numeric, if it's a list it will be set to a vector, or if its a supported object, the type will
                  be set appropriately and config.getConfig(initialValue) will be used for its parameter setting.
              encoding (str, optional): only supported for Rotation and RigidTransform types, and defines how the
                  variable will be parameterized in optimization.  Can be:
  
                  - 'rotation_vector' (default) for rotation vector,  3 parameters
                  - 'quaternion' for quaternion encoding, 4 parameters + 1 constraint
                  - 'rpy' for roll-pitch-yaw euler angles, 3 parameters
                  - None for full rotation matrix (9 parameters, 6 constraints)
                  - 'auto' (equivalent to to 'rotation_vector')
              constraints (bool, optional): True if all default constraints are to be added.  For Config / Configs
                  types, bound constraints at the robot's joint limits are added.
              optimize (bool, optional): If True, adds the parameterized variables to the list of optimization
                  variables.
  
          Returns:
              KlamptVariable: an object containing information about the encoding of the variable.
                  Note that extra symbolic Variable names may be decorated with extensions in the form of "_ext" if
                  the encoding is not direct.
docstring_summary: Adds one or more variables of a given Klamp't type (e.g., "Config", "Rotation", "RigidTransform"). 
          If necessary, constraints on the object will also be added, e.g., joint limits, or a quaternion unit
          norm constraint.
docstring_tokens: Adds one or more variables of a given Klamp t type ( e . g . Config Rotation RigidTransform ) . If necessary constraints on the object will also be added e . g . joint limits or a quaternion unit norm constraint .
function: def addKlamptVar(self,name,type=None,initialValue=None,encoding='auto',constraints=True,optimize=True):
          """Adds one or more variables of a given Klamp't type (e.g., "Config", "Rotation", "RigidTransform"). 
          If necessary, constraints on the object will also be added, e.g., joint limits, or a quaternion unit
          norm constraint.
  
          At least one of type / initialValue must be provided.
  
          Args:
              name (str): a name for the variable.
              type (str, optional): a supported variable type (default None determines the type by initialValue). 
                  Supported types include "Config", "Configs", Rotation", "RigidTransform", "Vector3".  Future
                  work may support Trajectory and other types.
              initialValue (optional): the configuration of the variable.  If it's a float, the type will be set to 
                  numeric, if it's a list it will be set to a vector, or if its a supported object, the type will
                  be set appropriately and config.getConfig(initialValue) will be used for its parameter setting.
              encoding (str, optional): only supported for Rotation and RigidTransform types, and defines how the
                  variable will be parameterized in optimization.  Can be:
  
                  - 'rotation_vector' (default) for rotation vector,  3 parameters
                  - 'quaternion' for quaternion encoding, 4 parameters + 1 constraint
                  - 'rpy' for roll-pitch-yaw euler angles, 3 parameters
                  - None for full rotation matrix (9 parameters, 6 constraints)
                  - 'auto' (equivalent to to 'rotation_vector')
              constraints (bool, optional): True if all default constraints are to be added.  For Config / Configs
                  types, bound constraints at the robot's joint limits are added.
              optimize (bool, optional): If True, adds the parameterized variables to the list of optimization
                  variables.
  
          Returns:
              KlamptVariable: an object containing information about the encoding of the variable.
                  Note that extra symbolic Variable names may be decorated with extensions in the form of "_ext" if
                  the encoding is not direct.
          """
          if type is None:
              assert initialValue is not None,"Either type or initialValue must be provided"
              type = types.object_to_type(initialValue)
          if type in ['Vector3','Point']:
              if initialValue is None:
                  initialValue = [0.0]*3
              else:
                  assert len(initialValue)==3
              type = 'Vector'
  
          def default(name,value):
              v = self.context.addVar(name,"V",len(value))
              v.value = value[:]
              return v
  
          if name in self.managedVariables:
              raise ValueError("Klamp't variable name "+name+" already defined")
          kv = KlamptVariable(name,type)
  
          if type == 'Config':
              if initialValue is None:
                  initialValue = self.robot.getConfig()
              else:
                  assert len(initialValue) == self.robot.numLinks()
              v = default(name,initialValue)
              if constraints:
                  self.setBounds(v.name,*self.robot.getJointLimits())
                  kv.constraints = [self.robot.getJointLimits()]
          elif type == 'Vector':
              assert initialValue is not None,"Need to provide initialValue for "+type+" type variables"
              v = default(name,initialValue)
              kv.expr = VariableExpression(v)
          elif type == 'Configs':
              assert initialValue is not None,"Need to provide initialValue for "+type+" type variables"
              vals = []
              for i,v in enumerate(initialValue):
                  vals.append(default(name+"_"+str(i),v))
                  if constraints:
                      self.setBounds(vals[-1].name,*self.robot.getJointLimits())
                      kv.constraints.append(self.robot.getJointLimits())
              kv.variables = vals
              kv.expr = symbolic.list_(*vals)
          elif type == 'Rotation':
              if encoding == 'auto': encoding='rotation_vector'
              if encoding == 'rotation_vector':
                  if initialValue is not None:
                      initialValue2 = so3.rotation_vector(initialValue)
                  else:
                      initialValue = so3.identity()
                      initialValue2 = [0.0]*3
                  v = default(name+"_rv",initialValue2)
                  kv.expr = self.context.so3.from_rotation_vector(v)
                  kv.decoder = so3.from_rotation_vector
                  kv.encoder = so3.rotation_vector
              elif encoding == 'quaternion':
                  if initialValue is not None:
                      initialValue2 = so3.quaternion(initialValue)
                  else:
                      initialValue = so3.identity()
                      initialValue2 = [1,0,0,0]
                  v = default(name+"_q",initialValue2)
                  kv.expr = self.context.so3.from_quaternion(v)
                  kv.decoder = so3.from_quaternion
                  kv.encoder = so3.quaternion
                  if constraints:
                      f = self.addEquality(self.context.so3.quaternion_constraint(v))
                      f.name = name+"_q_constraint"
                      kv.constraints = [f]
              elif encoding == 'rpy':
                  if initialValue is not None:
                      initialValue2 = so3.rpy(initialValue)
                  else:
                      initialValue = so3.identity()
                      initialValue2 = [0.0]*3
                  v = default(name+"_rpy",initialValue2)
                  kv.expr = self.context.so3.from_rpy(v)
                  kv.decoder = so3.from_rpy
                  kv.encoder = so3.rpy
              elif encoding is None:
                  if initialValue is None:
                      initialValue = so3.identity()
                  v = self.addVar(name,"Vector",initialValue)
                  if constraints:
                      f = self.addEquality(self.context.so3.eq_constraint(v))
                      f.name = name+"_constraint"
                      kv.constraints = [f]
              else:
                  raise ValueError("Invalid encoding "+str(encoding))
              kv.encoding = encoding
          elif type == 'RigidTransform':
              if initialValue is None:
                  Ri,ti = None,[0.0]*3
              else:
                  Ri,ti = initialValue
              kR = self.addKlamptVar(name+'_R','Rotation',Ri,constraints=constraints,encoding=encoding)
              t = default(name+'_t',ti)
              kv.variables = kR.variables+[t]
              kv.constraints = kR.constraints
              kv.expr = symbolic.list_(kR.expr,t)
              kv.encoding = encoding
              if kR.encoder is not None:
                  kv.encoder = lambda T:(kR.encoder(T[0]),T[1])
                  kv.decoder = lambda T:(kR.decoder(T[0]),T[1])
              del self.managedVariables[kR.name]
          else:
              raise ValueError("Unsupported object type "+type)
  
          if kv.variables is None:
              kv.variables = [v]
          if kv.expr is None:
              kv.expr = symbolic.VariableExpression(v)
          self.context.addExpr(name,kv.expr)
          if optimize:
              for v in kv.variables:
                  self.optimizationVariables.append(v)
          self.managedVariables[name] = kv
          return kv
function_tokens: def addKlamptVar ( self , name , type = None , initialValue = None , encoding = 'auto' , constraints = True , optimize = True ) : if type is None : assert initialValue is not None , "Either type or initialValue must be provided" type = types . object_to_type ( initialValue ) if type in [ 'Vector3' , 'Point' ] : if initialValue is None : initialValue = [ 0.0 ] * 3 else : assert len ( initialValue ) == 3 type = 'Vector' def default ( name , value ) : v = self . context . addVar ( name , "V" , len ( value ) ) v . value = value [ : ] return v if name in self . managedVariables : raise ValueError ( "Klamp't variable name " + name + " already defined" ) kv = KlamptVariable ( name , type ) if type == 'Config' : if initialValue is None : initialValue = self . robot . getConfig ( ) else : assert len ( initialValue ) == self . robot . numLinks ( ) v = default ( name , initialValue ) if constraints : self . setBounds ( v . name , * self . robot . getJointLimits ( ) ) kv . constraints = [ self . robot . getJointLimits ( ) ] elif type == 'Vector' : assert initialValue is not None , "Need to provide initialValue for " + type + " type variables" v = default ( name , initialValue ) kv . expr = VariableExpression ( v ) elif type == 'Configs' : assert initialValue is not None , "Need to provide initialValue for " + type + " type variables" vals = [ ] for i , v in enumerate ( initialValue ) : vals . append ( default ( name + "_" + str ( i ) , v ) ) if constraints : self . setBounds ( vals [ - 1 ] . name , * self . robot . getJointLimits ( ) ) kv . constraints . append ( self . robot . getJointLimits ( ) ) kv . variables = vals kv . expr = symbolic . list_ ( * vals ) elif type == 'Rotation' : if encoding == 'auto' : encoding = 'rotation_vector' if encoding == 'rotation_vector' : if initialValue is not None : initialValue2 = so3 . rotation_vector ( initialValue ) else : initialValue = so3 . identity ( ) initialValue2 = [ 0.0 ] * 3 v = default ( name + "_rv" , initialValue2 ) kv . expr = self . context . so3 . from_rotation_vector ( v ) kv . decoder = so3 . from_rotation_vector kv . encoder = so3 . rotation_vector elif encoding == 'quaternion' : if initialValue is not None : initialValue2 = so3 . quaternion ( initialValue ) else : initialValue = so3 . identity ( ) initialValue2 = [ 1 , 0 , 0 , 0 ] v = default ( name + "_q" , initialValue2 ) kv . expr = self . context . so3 . from_quaternion ( v ) kv . decoder = so3 . from_quaternion kv . encoder = so3 . quaternion if constraints : f = self . addEquality ( self . context . so3 . quaternion_constraint ( v ) ) f . name = name + "_q_constraint" kv . constraints = [ f ] elif encoding == 'rpy' : if initialValue is not None : initialValue2 = so3 . rpy ( initialValue ) else : initialValue = so3 . identity ( ) initialValue2 = [ 0.0 ] * 3 v = default ( name + "_rpy" , initialValue2 ) kv . expr = self . context . so3 . from_rpy ( v ) kv . decoder = so3 . from_rpy kv . encoder = so3 . rpy elif encoding is None : if initialValue is None : initialValue = so3 . identity ( ) v = self . addVar ( name , "Vector" , initialValue ) if constraints : f = self . addEquality ( self . context . so3 . eq_constraint ( v ) ) f . name = name + "_constraint" kv . constraints = [ f ] else : raise ValueError ( "Invalid encoding " + str ( encoding ) ) kv . encoding = encoding elif type == 'RigidTransform' : if initialValue is None : Ri , ti = None , [ 0.0 ] * 3 else : Ri , ti = initialValue kR = self . addKlamptVar ( name + '_R' , 'Rotation' , Ri , constraints = constraints , encoding = encoding ) t = default ( name + '_t' , ti ) kv . variables = kR . variables + [ t ] kv . constraints = kR . constraints kv . expr = symbolic . list_ ( kR . expr , t ) kv . encoding = encoding if kR . encoder is not None : kv . encoder = lambda T : ( kR . encoder ( T [ 0 ] ) , T [ 1 ] ) kv . decoder = lambda T : ( kR . decoder ( T [ 0 ] ) , T [ 1 ] ) del self . managedVariables [ kR . name ] else : raise ValueError ( "Unsupported object type " + type ) if kv . variables is None : kv . variables = [ v ] if kv . expr is None : kv . expr = symbolic . VariableExpression ( v ) self . context . addExpr ( name , kv . expr ) if optimize : for v in kv . variables : self . optimizationVariables . append ( v ) self . managedVariables [ name ] = kv return kv