Exemple #1
0
 def updateFromWorld(self):
     """For any frames with associated world elements, updates the
     transforms from the world elements."""
     for (n, f) in self.frames.iteritems():
         if f._data == None: continue
         if hasattr(f._data, 'getTransform'):
             worldCoordinates = f._data.getTransform()
             if hasattr(f._data, 'getParent'):
                 p = f._data.getParent()
                 if p >= 0:
                     plink = f._data.robot().link(p)
                     parentCoordinates = plink.getTransform()
                     f._relativeCoordinates = se3.mul(
                         se3.inv(parentCoordinates), worldCoordinates)
                 else:
                     f._relativeCoordinates = worldCoordinates
             else:
                 f._relativeCoordinates = worldCoordinates
             f._worldCoordinates = worldCoordinates
             #update downstream non-link items
             for c in self.childLists[f._name]:
                 if c.data == None or not hasattr(c._data, 'getTransform'):
                     c._worldCoordinates = se3.mul(f._worldCoordinates,
                                                   c._relativeCoordinates)
                     self.updateDependentFrames(c)
         if isinstance(f._data, tuple) and isinstance(
                 f._data[0], SimRobotController):
             controller, index, itemtype = f._data
             #TODO: update the frame from the controller data
     for (n, g) in self.subgroups.iteritems():
         g.updateFromWorld()
Exemple #2
0
 def __init__(self,
              name,
              worldCoordinates=se3.identity(),
              parent=None,
              relativeCoordinates=None):
     self._name = name
     self._parent = parent
     self._worldCoordinates = worldCoordinates
     self._data = None
     if relativeCoordinates == None:
         if worldCoordinates == None:
             raise ValueError(
                 "One of relativeCoordinates or worldCoordinates must be provided"
             )
         if parent == None:
             self._relativeCoordinates = worldCoordinates
         else:
             self._relativeCoordinates = se3.mul(
                 se3.inv(parent.worldCoordinates()), worldCoordinates)
     else:
         self._relativeCoordinates = relativeCoordinates
         if worldCoordinates == None:
             if parent == None:
                 self._worldcoordinates = relativeCoordinates
             else:
                 self._worldCoordinates = se3.mul(parent.worldCoordinates(),
                                                  relativeCoordinates)
Exemple #3
0
 def updateFromWorld(self):
     """For any frames with associated world elements, updates the
     transforms from the world elements."""
     for (n,f) in self.frames.iteritems():
         if f._data == None: continue
         if hasattr(f._data,'getTransform'):
             worldCoordinates = f._data.getTransform()
             if hasattr(f._data,'getParent'):
                 p = f._data.getParent()
                 if p >= 0:
                     plink = f._data.robot().link(p)
                     parentCoordinates = plink.getTransform()
                     f._relativeCoordinates = se3.mul(se3.inv(parentCoordinates),worldCoordinates)
                 else:
                     f._relativeCoordinates = worldCoordinates
             else:
                 f._relativeCoordinates = worldCoordinates
             f._worldCoordinates = worldCoordinates
             #update downstream non-link items
             for c in self.childLists[f._name]:
                 if c.data == None or not hasattr(c._data,'getTransform'):
                     c._worldCoordinates = se3.mul(f._worldCoordinates,c._relativeCoordinates)
                     self.updateDependentFrames(c)
         if isinstance(f._data,tuple) and isinstance(f._data[0],SimRobotController):
             controller,index,itemtype = f._data
             #TODO: update the frame from the controller data
     for (n,g) in self.subgroups.iteritems():
         g.updateFromWorld()
Exemple #4
0
 def setFrameCoordinates(self,name,coordinates,parent='relative'):
     """Sets the coordinates of the frame, given as an se3 element.
     The coordinates can be given either in 'relative' mode, where the
     coordinates are the natural coordinates of the frame relative to
     its parent, or in 'world' mode, where the coordinates are the
     global world coordinates, or they can be given relative to any
     other frame in this coordinate Group.  If None, this defaults
     to the root frame of this Group."""
     f = self.frame(name)
     if parent==None:
         parent = 'root'
     if isinstance(parent,str):
         if parent=='relative':
             parent = f._parent
         elif parent=='world':
             parent = None
         else:
             parent = self.frames[parent]
     if parent:
         worldCoordinates = se3.mul(parent._worldCoordinates,coordinates)
     else:
         worldCoordinates = coordinates
     if parent == f._parent:
         f._relativeCoordinates = coordinates
     else:
         f._relativeCoordinates = se3.mul(se3.inv(f._parent._worldCoordinates),worldCoordinates)
     f._worldCoordinates = worldCoordinates
     self.updateDependentFrames(f)
Exemple #5
0
 def setFrameCoordinates(self, name, coordinates, parent='relative'):
     """Sets the coordinates of the frame, given as an se3 element.
     The coordinates can be given either in 'relative' mode, where the
     coordinates are the natural coordinates of the frame relative to
     its parent, or in 'world' mode, where the coordinates are the
     global world coordinates, or they can be given relative to any
     other frame in this coordinate Group.  If None, this defaults
     to the root frame of this Group."""
     f = self.frame(name)
     if parent == None:
         parent = 'root'
     if isinstance(parent, str):
         if parent == 'relative':
             parent = f._parent
         elif parent == 'world':
             parent = None
         else:
             parent = self.frames[parent]
     if parent:
         worldCoordinates = se3.mul(parent._worldCoordinates, coordinates)
     else:
         worldCoordinates = coordinates
     if parent == f._parent:
         f._relativeCoordinates = coordinates
     else:
         f._relativeCoordinates = se3.mul(
             se3.inv(f._parent._worldCoordinates), worldCoordinates)
     f._worldCoordinates = worldCoordinates
     self.updateDependentFrames(f)
Exemple #6
0
def fixed_objective(link,ref=None,local=None,world=None):
    """Convenience function for fixing the given link at the current position
    in space.  If local and world are not provided, the entire link is
    constrained.  If only local is provided, these points are fixed
    to their current positions in space.  If only world is provided,
    the points on the link with the given world position are constrained in
    place."""
    refcoords = ref.getTransform() if ref is not None else se3.identity()
    Tw = link.getTransform()
    Trel = se3.mul(se3.inv(refcoords),Tw)
    if local is not None and not hasattr(local[0],'__iter__'):
        #just a single point, make it a list of points
        local = [local]
    if world is not None and not hasattr(world[0],'__iter__'):
        #just a single point, make it a list of points
        world = [world]
    if local is None and world is None:
        #fixed rotation/position objective
        return objective(link,ref,R=Trel[0],t=Trel[1])
    elif local is None:
        #fixed point, given by world coordinates
        Trelinv = se3.inv(Trel)
        local = [se3.apply(trelinv,p) for p in world]
        return objective(link,ref,local=local,world=world)
    elif world is None:
        #fixed point, given by local coordinates
        world = [se3.apply(Trel,p) for p in local]
        return objective(link,ref,local=local,world=world)
    else:
        raise ValueError("ik.fixed_objective does not accept both local and world keyword arguments")
Exemple #7
0
	def postTransform(self,R):
		"""Postmultiplies every rotation in here by the se3 element
		R. In other words, if R rotates a local frame F to frame F',
		this method converts this SO3Trajectory from describing how F'
		rotates to how F rotates."""
		for i,m in enumerate(self.milestones):
			self.milestones[i] = se3.mul(m,T)
Exemple #8
0
def fixed_objective(link, ref=None, local=None, world=None):
    """Convenience function for fixing the given link at the current position
    in space.  If local and world are not provided, the entire link is
    constrained.  If only local is provided, these points are fixed
    to their current positions in space.  If only world is provided,
    the points on the link with the given world position are constrained in
    place."""
    refcoords = ref.getTransform() if ref is not None else se3.identity()
    Tw = link.getTransform()
    Trel = se3.mul(se3.inv(refcoords), Tw)
    if local is not None and not hasattr(local[0], '__iter__'):
        #just a single point, make it a list of points
        local = [local]
    if world is not None and not hasattr(world[0], '__iter__'):
        #just a single point, make it a list of points
        world = [world]
    if local is None and world is None:
        #fixed rotation/position objective
        return objective(link, ref, R=Trel[0], t=Trel[1])
    elif local is None:
        #fixed point, given by world coordinates
        Trelinv = se3.inv(Trel)
        local = [se3.apply(trelinv, p) for p in world]
        return objective(link, ref, local=local, world=world)
    elif world is None:
        #fixed point, given by local coordinates
        world = [se3.apply(Trel, p) for p in local]
        return objective(link, ref, local=local, world=world)
    else:
        raise ValueError(
            "ik.fixed_objective does not accept both local and world keyword arguments"
        )
Exemple #9
0
 def coordinates(self):
     """Returns the SE(3) coordinates that transform elements from the
     source to the destination Frame."""
     if self._destination == None:
         return self._source.worldCoodinates()
     return se3.mul(se3.inv(self._destination.worldCoordinates()),
                    self._source.worldCoordinates())
 def __init__(self, name, value, description, world, frame=None):
     _VisualEditorBase.__init__(self, name, value, description, world)
     self.frame = se3.identity() if frame == None else frame
     self.xformposer = TransformPoser()
     self.xformposer.set(*se3.mul(self.frame, value))
     self.xformposer.enableRotation(True)
     self.xformposer.enableTranslation(True)
     self.addWidget(self.xformposer)
Exemple #11
0
	def postTransform(self,T):
		"""Postmultiplies every transform in here by the se3 element
		T. In other words, if T transforms a local frame F to frame F',
		this method converts this SE3Trajectory from describing how F'
		moves to how F moves."""
		for i,m in enumerate(self.milestones):
			Tm = (m[:9],m[9:])
			self.milestones[i] = se3.mul(Tm,T)
Exemple #12
0
	def preTransform(self,T):
		"""Premultiplies every transform in here by the se3 element
		T. In other words, if T transforms a local frame F to frame F',
		this method converts this SE3Trajectory from coordinates in F
		to coordinates in F'"""
		for i,m in enumerate(self.milestones):
			Tm = (m[:9],m[9:])
			self.milestones[i] = se3.mul(T,Tm)
 def __init__(self,name,value,description,world,frame=None):
     _VisualEditorBase.__init__(self,name,value,description,world)
     self.frame = se3.identity() if frame==None else frame
     self.xformposer = TransformPoser()
     self.xformposer.set(*se3.mul(self.frame,value))
     self.xformposer.enableRotation(True)
     self.xformposer.enableTranslation(True)
     self.addWidget(self.xformposer)
Exemple #14
0
 def updateDependentFrames(self,frame):
     """Whenever Frame's world coordinates are updated, call this to update
     the downstream frames. This will be called automatically via
     setFrameCoordinates but not if you change a Frame's coordinates
     manually."""
     for c in self.childLists[frame._name]:
         c._worldCoordinates = se3.mul(frame._worldCoordinates,c._relativeCoordinates)
         self.updateDependentFrames(c)
Exemple #15
0
 def updateDependentFrames(self, frame):
     """Whenever Frame's world coordinates are updated, call this to update
     the downstream frames. This will be called automatically via
     setFrameCoordinates but not if you change a Frame's coordinates
     manually."""
     for c in self.childLists[frame._name]:
         c._worldCoordinates = se3.mul(frame._worldCoordinates,
                                       c._relativeCoordinates)
         self.updateDependentFrames(c)
Exemple #16
0
 def __init__(self, name, worldCoordinates=se3.identity(), parent=None, relativeCoordinates=None):
     self._name = name
     self._parent = parent
     self._worldCoordinates = worldCoordinates
     self._data = None
     if relativeCoordinates == None:
         if worldCoordinates == None:
             raise ValueError("One of relativeCoordinates or worldCoordinates must be provided")
         if parent == None:
             self._relativeCoordinates = worldCoordinates
         else:
             self._relativeCoordinates = se3.mul(se3.inv(parent.worldCoordinates()), worldCoordinates)
     else:
         self._relativeCoordinates = relativeCoordinates
         if worldCoordinates == None:
             if parent == None:
                 self._worldcoordinates = relativeCoordinates
             else:
                 self._worldCoordinates = se3.mul(parent.worldCoordinates(), relativeCoordinates)
Exemple #17
0
 def integrate(self,x,d):
     w = [d[0],d[4],d[8]]
     v = d[9:]
     return se3.mul(x,(so3.from_moment(w),v))
Exemple #18
0
def ik_objective(obj, target):
    """Returns an IK objective that attempts to fix the given
    klampt.coordinates object 'obj' at given target object 'target'. 

    Arguments:
     - obj: An instance of one of the
       {Point,Direction,Transform,Frame} classes.
     - target: If 'obj' is a Point, Direction, or  Frame objects, this
       must be an object of the same type of 'obj' denoting the target to
       which 'obj' should be fixed.  In other words, the local coordinates
       of 'obj' relative to 'target's parent frame will be equal to 'target's
       local coordinates.
       If obj is a Transform object, this element is an se3 object.
    Return value:
     - An IK objective to be used with the klampt.ik module.

    Since the klampt.ik module is not aware about custom frames, an
    ancestor of the object must be attached to a RobotModelLink or a
    RigidObjectModel, or else None will be returned.  The same goes for target,
    if provided.

    TODO: support lists of objects to fix.

    TODO: support Direction constraints.
    """
    body = None
    coords = None
    ref = None
    if isinstance(obj, Frame):
        assert isinstance(
            target, Frame), "ik_objective: target must be of same type as obj"
        body = obj
        ref = target.parent()
        coords = target.relativeCoordinates()
    elif isinstance(obj, Transform):
        if ref != None:
            print "ik_objective: Warning, ref argument passed with Transform object, ignoring"
        body = obj.source()
        ref = obj.destination()
        coords = target
    elif isinstance(obj, (Point, Direction)):
        assert type(target) == type(
            obj), "ik_objective: target must be of same type as obj"
        body = obj.frame()
        ref = target.frame()
        coords = target.localCoordinates()
    else:
        raise ValueError(
            "Argument to ik_objective must be an object from the coordinates module"
        )

    linkframe = _ancestor_with_link(body)
    if linkframe == None:
        print "Warning: object provided to ik_objective is not attached to a robot link or rigid object, returning None"
        return None
    linkbody = linkframe._data

    #find the movable frame attached to ref
    refframe = _ancestor_with_link(ref) if ref != None else None
    refbody = (refframe._data if refframe != None else None)
    if isinstance(obj, (Frame, Transform)):
        #figure out the desired transform T[linkbody->refbody], given
        #coords = T[obj->ref], T[obj->linkbody], T[ref->refbody]
        #result = (T[ref->refbody] * coords * T[obj->linkbody]^-1)
        if linkframe != body:
            coords = se3.mul(coords, Transform(linkframe, body).coordinates())
        if refframe != ref:
            coords = se3.mul(Transform(ref, refframe).coordinates(), coords)
        return ik.objective(linkbody, ref=refbody, R=coords[0], t=coords[1])
    elif isinstance(obj, Point):
        #figure out the local and world points
        local = obj.to(linkframe).localCoordinates()
        world = target.to(refframe).localCoordinates()
        return ik.objective(linkbody, local=[local], world=[world])
    elif isinstance(obj, Direction):
        raise ValueError(
            "Axis constraints are not yet supported in the klampt.ik module")
    return None
Exemple #19
0
 def integrate(self, x, d):
     w = [d[0], d[4], d[8]]
     v = d[9:]
     return se3.mul(x, (so3.from_moment(w), v))
 def mousefunc(self,button,state,x,y):
     if _VisualEditorBase.mousefunc(self,button,state,x,y):
         self.value = se3.mul(se3.inv(self.frame),self.xformposer.get())
Exemple #21
0
 def coordinates(self):
     """Returns the SE(3) coordinates that transform elements from the
     source to the destination Frame."""
     if self._destination==None:
         return self._source.worldCoodinates()
     return se3.mul(se3.inv(self._destination.worldCoordinates()),self._source.worldCoordinates())
Exemple #22
0
    def draw(self,world=None):
        """Draws the specified item in the specified world.  If name
        is given and text_hidden != False, then the name of the item is
        shown."""
        if self.hidden: return
       
        item = self.item
        name = self.name
        #set appearance
        if not self.useDefaultAppearance and hasattr(item,'appearance'):
            if not hasattr(self,'oldAppearance'):
                self.oldAppearance = item.appearance().clone()
            if self.customAppearance != None:
                print "Changing appearance of",name
                item.appearance().set(self.customAppearance)
            elif "color" in self.attributes:
                print "Changing color of",name
                item.appearance().setColor(*self.attributes["color"])

        if hasattr(item,'drawGL'):
            item.drawGL()
        elif len(self.subAppearances)!=0:
            for n,app in self.subAppearances.iteritems():
                app.widget = self.widget
                app.draw(world)            
        elif isinstance(item,coordinates.Point):
            def drawRaw():
                glDisable(GL_DEPTH_TEST)
                glDisable(GL_LIGHTING)
                glEnable(GL_POINT_SMOOTH)
                glPointSize(self.attributes.get("size",5.0))
                glColor4f(*self.attributes.get("color",[0,0,0,1]))
                glBegin(GL_POINTS)
                glVertex3f(0,0,0)
                glEnd()
                glEnable(GL_DEPTH_TEST)
                #write name
            self.displayCache[0].draw(drawRaw,[so3.identity(),item.worldCoordinates()])
            if name != None:
                self.drawText(name,vectorops.add(item.worldCoordinates(),[0,0,-0.05]))
        elif isinstance(item,coordinates.Direction):
            def drawRaw():
                glDisable(GL_LIGHTING)
                glDisable(GL_DEPTH_TEST)
                L = self.attributes.get("length",0.15)
                source = [0,0,0]
                glColor4f(*self.attributes.get("color",[0,1,1,1]))
                glBegin(GL_LINES)
                glVertex3f(*source)
                glVertex3f(*vectorops.mul(item.localCoordinates(),L))
                glEnd()
                glEnable(GL_DEPTH_TEST)
                #write name
            self.displayCache[0].draw(drawRaw,item.frame().worldCoordinates(),parameters = item.localCoordinates())
            if name != None:
                self.drawText(name,vectorops.add(vectorops.add(item.frame().worldCoordinates()[1],item.worldCoordinates()),[0,0,-0.05]))
        elif isinstance(item,coordinates.Frame):
            t = item.worldCoordinates()
            if item.parent() != None:
                tp = item.parent().worldCoordinates()
            else:
                tp = se3.identity()
            tlocal = item.relativeCoordinates()
            def drawRaw():
                glDisable(GL_DEPTH_TEST)
                glDisable(GL_LIGHTING)
                glLineWidth(2.0)
                gldraw.xform_widget(tlocal,self.attributes.get("length",0.1),self.attributes.get("width",0.01))
                glLineWidth(1.0)
                #draw curve between frame and parent
                if item.parent() != None:
                    d = vectorops.norm(tlocal[1])
                    vlen = d*0.5
                    v1 = so3.apply(tlocal[0],[-vlen]*3)
                    v2 = [vlen]*3
                    #glEnable(GL_BLEND)
                    #glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)
                    #glColor4f(1,1,0,0.5)
                    glColor3f(1,1,0)
                    gldraw.hermite_curve(tlocal[1],v1,[0,0,0],v2,0.03)
                    #glDisable(GL_BLEND)
                glEnable(GL_DEPTH_TEST)

            #For some reason, cached drawing is causing OpenGL problems
            #when the frame is rapidly changing
            #self.displayCache[0].draw(drawRaw,transform=tp, parameters = tlocal)
            glPushMatrix()
            glMultMatrixf(sum(zip(*se3.homogeneous(tp)),()))
            drawRaw()
            glPopMatrix()
            #write name
            if name != None:
                self.drawText(name,se3.apply(t,[-0.05]*3))
        elif isinstance(item,coordinates.Transform):
            #draw curve between frames
            t1 = item.source().worldCoordinates()
            if item.destination() != None:
                t2 = item.destination().worldCoordinates()
            else:
                t2 = se3.identity()
            d = vectorops.distance(t1[1],t2[1])
            vlen = d*0.5
            v1 = so3.apply(t1[0],[-vlen]*3)
            v2 = so3.apply(t2[0],[vlen]*3)
            def drawRaw():
                glDisable(GL_DEPTH_TEST)
                glDisable(GL_LIGHTING)
                glColor3f(1,1,1)
                gldraw.hermite_curve(t1[1],v1,t2[1],v2,0.03)
                glEnable(GL_DEPTH_TEST)
                #write name at curve
            self.displayCache[0].draw(drawRaw,transform=None,parameters = (t1,t2))
            if name != None:
                self.drawText(name,spline.hermite_eval(t1[1],v1,t2[1],v2,0.5))
        else:
            types = resource.objectToTypes(item,world)
            if isinstance(types,(list,tuple)):
                #ambiguous, still need to figure out what to draw
                validtypes = []
                for t in types:
                    if t == 'Config':
                        if world != None and len(t) == world.robot(0).numLinks():
                            validtypes.append(t)
                    elif t=='Vector3':
                        validtypes.append(t)
                    elif t=='RigidTransform':
                        validtypes.append(t)
                if len(validtypes) > 1:
                    print "Unable to draw item of ambiguous types",validtypes
                    return
                if len(validtypes) == 0:
                    print "Unable to draw any of types",types
                    return
                types = validtypes[0]
            if types == 'Config':
                if world:
                    robot = world.robot(0)
                    if not self.useDefaultAppearance:
                        oldAppearance = [robot.link(i).appearance().clone() for i in xrange(robot.numLinks())]
                        for i in xrange(robot.numLinks()):
                            robot.link(i).appearance().set(self.customAppearance)
                    oldconfig = robot.getConfig()
                    robot.setConfig(item)
                    robot.drawGL()
                    robot.setConfig(oldconfig)
                    if not self.useDefaultAppearance:
                        for (i,app) in enumerate(oldAppearance):
                            robot.link(i).appearance().set(app)
                else:
                    print "Unable to draw Config's without a world"
            elif types == 'Vector3':
                def drawRaw():
                    glDisable(GL_LIGHTING)
                    glEnable(GL_POINT_SMOOTH)
                    glPointSize(self.attributes.get("size",5.0))
                    glColor4f(*self.attributes.get("color",[0,0,0,1]))
                    glBegin(GL_POINTS)
                    glVertex3f(0,0,0)
                    glEnd()
                self.displayCache[0].draw(drawRaw,[so3.identity(),item])
                if name != None:
                    self.drawText(name,vectorops.add(item,[0,0,-0.05]))
            elif types == 'RigidTransform':
                def drawRaw():
                    gldraw.xform_widget(se3.identity(),self.attributes.get("length",0.1),self.attributes.get("width",0.01))
                self.displayCache[0].draw(drawRaw,transform=item)
                if name != None:
                    self.drawText(name,se3.apply(item,[-0.05]*3))
            elif types == 'IKGoal':
                if hasattr(item,'robot'):
                    #need this to be built with a robot element.
                    #Otherwise, can't determine the correct transforms
                    robot = item.robot
                elif world:
                    if world.numRobots() >= 1:
                        robot = world.robot(0)
                    else:
                        robot = None
                else:
                    robot = None
                if robot != None:
                    link = robot.link(item.link())
                    dest = robot.link(item.destLink()) if item.destLink()>=0 else None
                    while len(self.displayCache) < 3:
                        self.displayCache.append(CachedGLObject())
                    self.displayCache[1].name = self.name+" target position"
                    self.displayCache[2].name = self.name+" curve"
                    if item.numPosDims() != 0:
                        lp,wp = item.getPosition()
                        #set up parameters of connector
                        p1 = se3.apply(link.getTransform(),lp)
                        if dest != None:
                            p2 = se3.apply(dest.getTransform(),wp)
                        else:
                            p2 = wp
                        d = vectorops.distance(p1,p2)
                        v1 = [0.0]*3
                        v2 = [0.0]*3
                        if item.numRotDims()==3: #full constraint
                            R = item.getRotation()
                            def drawRaw():
                                gldraw.xform_widget(se3.identity(),self.attributes.get("length",0.1),self.attributes.get("width",0.01))
                            t1 = se3.mul(link.getTransform(),(so3.identity(),lp))
                            t2 = (R,wp) if dest==None else se3.mul(dest.getTransform(),(R,wp))
                            self.displayCache[0].draw(drawRaw,transform=t1)
                            self.displayCache[1].draw(drawRaw,transform=t2)
                            vlen = d*0.1
                            v1 = so3.apply(t1[0],[-vlen]*3)
                            v2 = so3.apply(t2[0],[vlen]*3)
                        elif item.numRotDims()==0: #point constraint
                            def drawRaw():
                                glDisable(GL_LIGHTING)
                                glEnable(GL_POINT_SMOOTH)
                                glPointSize(self.attributes.get("size",5.0))
                                glColor4f(*self.attributes.get("color",[0,0,0,1]))
                                glBegin(GL_POINTS)
                                glVertex3f(0,0,0)
                                glEnd()
                            self.displayCache[0].draw(drawRaw,transform=(so3.identity(),p1))
                            self.displayCache[1].draw(drawRaw,transform=(so3.identity(),p2))
                            #set up the connecting curve
                            vlen = d*0.5
                            d = vectorops.sub(p2,p1)
                            v1 = vectorops.mul(d,0.5)
                            #curve in the destination
                            v2 = vectorops.cross((0,0,0.5),d)
                        else: #hinge constraint
                            p = [0,0,0]
                            d = [0,0,0]
                            def drawRawLine():
                                glDisable(GL_LIGHTING)
                                glEnable(GL_POINT_SMOOTH)
                                glPointSize(self.attributes.get("size",5.0))
                                glColor4f(*self.attributes.get("color",[0,0,0,1]))
                                glBegin(GL_POINTS)
                                glVertex3f(*p)
                                glEnd()
                                glColor4f(*self.attributes.get("color",[0.5,0,0.5,1]))
                                glLineWidth(self.attributes.get("width",3.0))
                                glBegin(GL_LINES)
                                glVertex3f(*p)
                                glVertex3f(*vectorops.madd(p,d,self.attributes.get("length",0.1)))
                                glEnd()
                                glLineWidth(1.0)
                            ld,wd = item.getRotationAxis()
                            p = lp
                            d = ld
                            self.displayCache[0].draw(drawRawLine,transform=link.getTransform(),parameters=(p,d))
                            p = wp
                            d = wd
                            self.displayCache[1].draw(drawRawLine,transform=dest.getTransform() if dest else se3.identity(),parameters=(p,d))
                            #set up the connecting curve
                            d = vectorops.sub(p2,p1)
                            v1 = vectorops.mul(d,0.5)
                            #curve in the destination
                            v2 = vectorops.cross((0,0,0.5),d)
                        def drawConnection():
                            glDisable(GL_DEPTH_TEST)
                            glDisable(GL_LIGHTING)
                            glColor3f(1,0.5,0)
                            gldraw.hermite_curve(p1,v1,p2,v2,0.03)
                            glEnable(GL_DEPTH_TEST)
                        self.displayCache[2].draw(drawConnection,transform=None,parameters = (p1,v1,p2,v2))
                        if name != None:
                            self.drawText(name,vectorops.add(wp,[-0.05]*3))
                    else:
                        wp = link.getTransform()[1]
                        if item.numRotDims()==3: #full constraint
                            R = item.getRotation()
                            def drawRaw():
                                gldraw.xform_widget(se3.identity(),self.attributes.get("length",0.1),self.attributes.get("width",0.01))
                            self.displayCache[0].draw(drawRaw,transform=link.getTransform())
                            self.displayCache[1].draw(drawRaw,transform=se3.mul(link.getTransform(),(R,[0,0,0])))
                        elif item.numRotDims() > 0:
                            #axis constraint
                            d = [0,0,0]
                            def drawRawLine():
                                glDisable(GL_LIGHTING)
                                glColor4f(*self.attributes.get("color",[0.5,0,0.5,1]))
                                glLineWidth(self.attributes.get("width",3.0))
                                glBegin(GL_LINES)
                                glVertex3f(0,0,0)
                                glVertex3f(*vectorops.mul(d,self.attributes.get("length",0.1)))
                                glEnd()
                                glLineWidth(1.0)
                            ld,wd = item.getRotationAxis()
                            d = ld
                            self.displayCache[0].draw(drawRawLine,transform=link.getTransform(),parameters=d)
                            d = wd
                            self.displayCache[1].draw(drawRawLine,transform=(dest.getTransform()[0] if dest else so3.identity(),wp),parameters=d)
                        else:
                            #no drawing
                            pass
                        if name != None:
                            self.drawText(name,se3.apply(wp,[-0.05]*3))
            else:
                print "Unable to draw item of type",types

        #revert appearance
        if not self.useDefaultAppearance and hasattr(item,'appearance'):
            item.appearance().set(self.oldAppearance)
 def mousefunc(self, button, state, x, y):
     if _VisualEditorBase.mousefunc(self, button, state, x, y):
         self.value = se3.mul(se3.inv(self.frame), self.xformposer.get())
Exemple #24
0
def ik_objective(obj,target):
    """Returns an IK objective that attempts to fix the given
    klampt.coordinates object 'obj' at given target object 'target'. 

    Arguments:
     - obj: An instance of one of the
       {Point,Direction,Transform,Frame} classes.
     - target: If 'obj' is a Point, Direction, or  Frame objects, this
       must be an object of the same type of 'obj' denoting the target to
       which 'obj' should be fixed.  In other words, the local coordinates
       of 'obj' relative to 'target's parent frame will be equal to 'target's
       local coordinates.
       If obj is a Transform object, this element is an se3 object.
    Return value:
     - An IK objective to be used with the klampt.ik module.

    Since the klampt.ik module is not aware about custom frames, an
    ancestor of the object must be attached to a RobotModelLink or a
    RigidObjectModel, or else None will be returned.  The same goes for target,
    if provided.

    TODO: support lists of objects to fix.

    TODO: support Direction constraints.
    """
    body = None
    coords = None
    ref = None
    if isinstance(obj,Frame):
        assert isinstance(target,Frame),"ik_objective: target must be of same type as obj"
        body = obj
        ref = target.parent()
        coords = target.relativeCoordinates()
    elif isinstance(obj,Transform):
        if ref != None: print "ik_objective: Warning, ref argument passed with Transform object, ignoring"
        body = obj.source()
        ref = obj.destination()
        coords = target
    elif isinstance(obj,(Point,Direction)):
        assert type(target)==type(obj),"ik_objective: target must be of same type as obj"
        body = obj.frame()
        ref = target.frame()
        coords = target.localCoordinates()
    else:
        raise ValueError("Argument to ik_objective must be an object from the coordinates module")
    
    linkframe = _ancestor_with_link(body)
    if linkframe == None:
        print "Warning: object provided to ik_objective is not attached to a robot link or rigid object, returning None"
        return None
    linkbody = linkframe._data

    #find the movable frame attached to ref
    refframe = _ancestor_with_link(ref) if ref != None else None
    refbody = (refframe._data if refframe!=None else None)
    if isinstance(obj,(Frame,Transform)):
        #figure out the desired transform T[linkbody->refbody], given
        #coords = T[obj->ref], T[obj->linkbody], T[ref->refbody]
        #result = (T[ref->refbody] * coords * T[obj->linkbody]^-1)
        if linkframe != body: coords = se3.mul(coords,Transform(linkframe,body).coordinates())
        if refframe != ref: coords = se3.mul(Transform(ref,refframe).coordinates(),coords)
        return ik.objective(linkbody,ref=refbody,R=coords[0],t=coords[1])
    elif isinstance(obj,Point):
        #figure out the local and world points
        local = obj.to(linkframe).localCoordinates()
        world = target.to(refframe).localCoordinates()
        return ik.objective(linkbody,local=[local],world=[world])
    elif isinstance(obj,Direction):
        raise ValueError("Axis constraints are not yet supported in the klampt.ik module")
    return None