def getCommandVelocity(self, q, dq, dt):
		"""Gets the command velocity from the current state of the
		robot.
		"""
		eP = self.getSensedError(q)
		#vcmd = hP*eP + hD*eV + hI*eI
		vP = gen_mul(self.hP,eP)
		vcmd = vP
		#D term
		vcur = self.getSensedVelocity(q,dq,dt)
		eD = None
		if vcur != None:
			eD = vectorops.sub(vcur, self.dxdes)
			vD = gen_mul(self.hD,eD)
			vcmd = vectorops.add(vcmd, vD)
		#I term
		if self.eI != None:
			vI = gen_mul(self.hI,self.eI)
			vcmd = vectorops.add(vcmd, vI)
		#print "task",self.name,"error P=",eP,"D=",eD,"E=",self.eI
		#do acceleration limiting
		if vcur != None:
			dvcmd = vectorops.div(vectorops.sub(vcmd,vcur),dt)
			dvnorm = vectorops.norm(dvcmd)
			if dvnorm > self.dvcmdmax:
				vcmd = vectorops.madd(vcur,dvcmd,self.dvcmdmax/dvnorm*dt)
				print self.name,"acceleration limited by factor",self.dvcmdmax/dvnorm*dt,"to",vcmd
		#do velocity limiting
		vnorm = vectorops.norm(vcmd)
		if vnorm > self.vcmdmax:
			vcmd = vectorops.mul(vcmd,self.vcmdmax/vnorm)
			print self.name,"velocity limited by factor",self.vcmdmax/vnorm,"to",vcmd
		return vcmd
Пример #2
0
    def getCommandVelocity(self, q, dq, dt):
        """Gets the command velocity from the current state of the
		robot.
		"""
        eP = self.getSensedError(q)
        #vcmd = hP*eP + hD*eV + hI*eI
        vP = gen_mul(self.hP, eP)
        vcmd = vP
        #D term
        vcur = self.getSensedVelocity(q, dq, dt)
        eD = None
        if vcur != None:
            eD = vectorops.sub(vcur, self.dxdes)
            vD = gen_mul(self.hD, eD)
            vcmd = vectorops.add(vcmd, vD)
        #I term
        if self.eI != None:
            vI = gen_mul(self.hI, self.eI)
            vcmd = vectorops.add(vcmd, vI)
        #print "task",self.name,"error P=",eP,"D=",eD,"E=",self.eI
        #do acceleration limiting
        if vcur != None:
            dvcmd = vectorops.div(vectorops.sub(vcmd, vcur), dt)
            dvnorm = vectorops.norm(dvcmd)
            if dvnorm > self.dvcmdmax:
                vcmd = vectorops.madd(vcur, dvcmd, self.dvcmdmax / dvnorm * dt)
                print self.name, "acceleration limited by factor", self.dvcmdmax / dvnorm * dt, "to", vcmd
        #do velocity limiting
        vnorm = vectorops.norm(vcmd)
        if vnorm > self.vcmdmax:
            vcmd = vectorops.mul(vcmd, self.vcmdmax / vnorm)
            print self.name, "velocity limited by factor", self.vcmdmax / vnorm, "to", vcmd
        return vcmd
Пример #3
0
def add_multiple_lights(properties,object,dist,numLight,gravity=[0,0,-9.81],tgt=None,color=[1.,1.,1.], \
              spotlight=False,radius=15.,falloff=20.,tightness=10., \
              area=0.,sample=9,adaptive=True,jitter=True):
    """This is a convenient function that calls add_light multiple times"""
    #normalize gravity
    g = op.mul(gravity, -1 / op.norm(gravity))

    #compute frame
    gabs = [abs(gi) for gi in g]
    id = gabs.index(min(gabs))
    t0 = [1. if i == id else 0. for i in range(3)]
    t1 = op.cross(t0, g)
    t1 = op.mul(t1, 1 / op.norm(t1))
    t0 = op.cross(t1, g)

    #find highest direction
    bb = compute_bb(object)
    ctr = op.mul(op.add(bb[0], bb[1]), 0.5)
    distg = sum([abs((bb[1][i] - bb[0][i]) / 2 * g[i]) for i in range(3)])

    #add each light
    for i in range(numLight):
        angle = math.pi * 2 * i / numLight
        d0 = op.mul(g, distg)
        d1 = op.mul(t0, math.sin(angle) * dist)
        d2 = op.mul(t1, math.cos(angle) * dist)
        add_light(properties, op.add(d0, op.add(d1,
                                                d2)), ctr, color, spotlight,
                  radius, falloff, tightness, area, sample, adaptive, jitter)
Пример #4
0
def solve_3R_forward_kinematics(q1,q2,q3,L1=1,L2=1,L3=1):
    """Returns a list of (x,y,theta) triples for each link
    for a planar, 3R manipulator with link lengths L1, L2, L3.
    It also returns the end effector transform."""
    T1 = (0,0,q1)
    dx1 = (L1*math.cos(T1[2]),L1*math.sin(T1[2]))
    T2 = vectorops.add((T1[0],T1[1]),dx1)+[T1[2]+q2]
    dx2 = (L2*math.cos(T2[2]),L2*math.sin(T2[2]))
    T3 = vectorops.add((T2[0],T2[1]),dx2)+[T2[2]+q3]
    dx3 = (L3*math.cos(T3[2]),L2*math.sin(T3[2]))
    T4 = vectorops.add((T3[0],T3[1]),dx3)+[T3[2]]
    return [T1,T2,T3,T4]
 def drawConfig(self, q=None):
     if self.drawJointLimitColors:
         testq = q
         if q is None:
             testq = self.robot.getConfig()
         oldColors = []
         for i in xrange(self.robot.numLinks()):
             oldColors.append(self.robot.link(i).appearance().getColor())
             if self.robot.getJointType(i) == 'normal':
                 a, b = self.jointLimits[0][i], self.jointLimits[1][i]
                 u = 1.0
                 u = min(1, (testq[i] - a) / (self.jointLimitColoringRatio *
                                              (b - a)))
                 u = min(1, (b - testq[i]) / (self.jointLimitColoringRatio *
                                              (b - a)))
                 if u != 1:
                     u = max(u, 0.0)
                     c = vectorops.add(
                         vectorops.mul(oldColors[i], u),
                         vectorops.mul(self.jointLimitColor, 1 - u))
                     self.robot.link(i).appearance().setColor(*c)
     if q is not None:
         self.robot.setConfig(q)
     self.robot.drawGL()
     if self.drawJointLimitColors:
         for i in xrange(self.robot.numLinks()):
             self.robot.link(i).appearance().setColor(*oldColors[i])
Пример #6
0
def opt_error_fun(est_input, *args):
    """

    :param est_input: {numpy.array} -- the initial guess of the transformation of Toct and Tneedle
    :param args: {tuple} -- the set of tranfermation of Tlink and ICP transformation matrix
    :return: error: {float} -- the error between the true transformation and estimated transformation
    """
    Roct = so3.from_rpy(est_input[0:3])
    toct = est_input[3:6]
    Rn = so3.from_rpy(est_input[6:9])
    tn = est_input[9:12]
    Tlink_set = args[0]
    Tneedle2oct_icp = args[1]
    fun_list = np.array([])
    for i in range(len(Tlink_set)):
        fun_list = np.append(
            fun_list,
            np.multiply(
                so3.error(so3.inv(Tneedle2oct_icp[i][0]),
                          so3.mul(so3.mul(so3.inv(Roct), Tlink_set[i][0]),
                                  Rn)), 1))
        fun_list = np.append(
            fun_list,
            np.multiply(
                vectorops.sub(
                    vectorops.sub([0., 0., 0.],
                                  so3.apply(so3.inv(Tneedle2oct_icp[i][0]),
                                            Tneedle2oct_icp[i][1])),
                    so3.apply(
                        so3.inv(Roct),
                        vectorops.add(vectorops.sub(Tlink_set[i][1], toct),
                                      so3.apply(Tlink_set[i][0], tn)))), 1000))

    return fun_list
 def get_camera_pos(self):
     cam = self.view.camera
     z = math.sin(-cam.rot[1])
     x = math.sin(cam.rot[2]) * math.cos(cam.rot[1])
     y = math.cos(cam.rot[2]) * math.cos(cam.rot[1])
     pos = [x, y, z]
     return op.add(cam.tgt, op.mul(pos, cam.dist))
Пример #8
0
 def feasible(self, q):
     """TODO: Implement this feasibility test.  It is used by the motion planner to
     determine whether the robot at configuration q is feasible."""
     robotRadius = self.robot.radius
     # bounds test
     if not CSpace.feasible(self, q): return False
     for o in self.obstacles:
         if o.distance(q) <= robotRadius: return False
     # bound the robot in a square defined by robot's radius
     bottomLeft = vectorops.add(q, (-robotRadius, -robotRadius))
     topRight = vectorops.add(q, (robotRadius, robotRadius))
     # make sure you can put the square in the config space
     # if topLeft is not feasible bottomLeft or topRight will be infeasible
     # if bottomRight is not feasible bottomLeft or topRight will be infeasible
     boundingSquareFeasible = CSpace.feasible(
         self, bottomLeft) and CSpace.feasible(self, topRight)
     return boundingSquareFeasible
Пример #9
0
def make_object_arrangement(world,
                            container,
                            objects,
                            container_wall_thickness=0.01,
                            max_iterations=100,
                            remove_failures=False):
    """For a given container and a list of objects in the world, places the objects inside the container with randomized x-y locations
    and z orientations so that they are initially collision free and on the bottom of the container.

    Args:
        world (WorldModel): the world containing the objects and obstacles
        container: the container RigidObject / Terrain in world into which
            objects should be spawned.  Assumed axis-aligned.
        objects (list of RigidObject): a list of RigidObjects in the world,
            at arbitrary locations.  They are placed in order.
        container_wall_thickness (float, optional): a margin subtracted from
            the container's outer dimensions into which the objects are spawned.
        max_iterations (int, optional): the maximum number of iterations used
            for sampling object initial poses
        remove_failures (bool): if True, then instead of returning None on
            failure, the objects that fail placement are removed from the world.
    
    Returns:
        (WorldModel): if successful, the positions of objects in world are
        modified and world is returned. On failure, None is returned.

    Note:
        Since world is modified in-place, if you wish to make multiple worlds with
        piles of the same objects, you should use world.copy() to store the
        configuration of the objects. You may also wish to randomize the object
        ordering using random.shuffle(objects) between instances.
    """
    container_outer_bb = _get_bound(container)
    container_inner_bb = (vectorops.add(container_outer_bb[0],
                                        [container_wall_thickness] * 3),
                          vectorops.sub(container_outer_bb[1],
                                        [container_wall_thickness] * 3))
    collision_margin = 0.0025
    for object in objects:
        #make sure the bottom of the object touches the bottom of the container
        obb = _get_bound(object)
        zmin = obb[0][2]
        R, t = object.getTransform()
        t[2] = container_inner_bb[2] - zmin + collision_margin
        object.setTransform(R, t)

    failures = xy_jiggle(world, rigid_objects, [container],
                         container_inner_bb[0], container_inner_bb[1],
                         max_iterations)
    if len(failures) > 0:
        if remove_failures:
            removeIDs = [objects[i].index for i in failures]
            for i in sorted(removeIDs)[::-1]:
                world.remove(world.rigidObject(i))
        else:
            return None
    return world
Пример #10
0
 def control_loop(self):
     #Calculate the desired velocity for each robot by adding up all
     #commands
     rvels = [[0] * 3 for r in range(self.world.numRobots())]
     for (c, (r, v)) in self.current_velocities.iteritems():
         rvels[r] = vectorops.add(rvels[r], v)
     #send to the robot(s)
     for r in range(self.world.numRobots()):
         self.spheros[r].process({'twist': rvels[r]}, self.dt)
     return
Пример #11
0
def configSolver(cur_target):
    global robot
    end_link = robot.link(robot.numLinks() - 1)
    ee_local_axis = end_link.getAxis()
    ee_local_position = (0, 0, 0)
    cur_target_axis = (0, 0, -1)
    goal = ik.objective(
        end_link,
        local=[
            ee_local_position,
            vectorops.add(ee_local_position, ee_local_axis)
        ],  # match end points 
        world=[cur_target,
               vectorops.add(cur_target, cur_target_axis)])
    ik.solve_global(goal)
    # ### Test Print
    # print('Local Coord: ', [ee_local_position, vectorops.add(ee_local_position, (0,0,-0.01))])
    # print('Global Coord: ', [cur_target, vectorops.add(cur_target, (0,0,0.01))])
    # ###
    return robot.getConfig()
Пример #12
0
 def keyboardfunc(self, c, x, y):
     #Put your keyboard handler here
     #the current example prints the config when [space] is pressed
     if c == 'h' or c == '?':
         print("Controls:")
         print("- [space]: print the widget's sub-robot configuration")
         print("- r: randomize the sub-robot configuration")
         print("- p: plan to the widget's sub-robot configuration")
         print("- i: test the IK functions")
     elif c == ' ':
         config = self.robotWidget.get()
         subconfig = self.subrobots[0].fromfull(config)
         print("Config:", subconfig)
         self.subrobots[0].setConfig(subconfig)
     elif c == 'r':
         self.subrobots[0].randomizeConfig()
         self.robotWidget.set(self.robot.getConfig())
     elif c == 'p':
         config = self.robotWidget.get()
         subconfig = self.subrobots[0].fromfull(config)
         self.subrobots[0].setConfig(self.subrobots[0].fromfull(
             self.startConfig))
         settings = {
             'type': "sbl",
             'perturbationRadius': 0.5,
             'bidirectional': 1,
             'shortcut': 1,
             'restart': 1,
             'restartTermCond': "{foundSolution:1,maxIters:1000}"
         }
         plan = robotplanning.planToConfig(self.world,
                                           self.subrobots[0],
                                           subconfig,
                                           movingSubset='all',
                                           **settings)
         plan.planMore(1000)
         print(plan.getPath())
     elif c == 'i':
         link = self.subrobots[0].link(self.subrobots[0].numLinks() - 1)
         print("IK solve for ee to go 10cm upward...")
         obj = ik.objective(link,
                            local=[0, 0, 0],
                            world=vectorops.add(
                                link.getWorldPosition([0, 0, 0]),
                                [0, 0, 0.1]))
         solver = ik.solver(obj)
         res = solver.solve()
         print("  result", res)
         print("  residual", solver.getResidual())
         print(self.robotWidget.set(self.robot.getConfig()))
     else:
         GLWidgetPlugin.keyboardfunc(self, c, x, y)
            def drawDisconnections(orientation=None):
                bmin, bmax = self.resolution.domain
                active = [
                    i for i, (a, b) in enumerate(zip(bmin, bmax)[:3]) if b != a
                ]
                if self.useboundary == None:
                    self.useboundary = (len(active) == 2)
                verts, faces = self.resolution.computeDiscontinuities(
                    self.useboundary, orientation)

                if len(active) == 3:
                    glEnable(GL_LIGHTING)
                    glEnable(GL_BLEND)
                    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
                    glDisable(GL_CULL_FACE)
                    #if self.walk_workspace_path != None:
                    #	gldraw.setcolor(1,0,1,0.25)
                    #else:
                    #	gldraw.setcolor(1,0,1,0.5)

                    for tri in faces:
                        tverts = [verts[v] for v in tri]
                        centroid = vectorops.div(vectorops.add(*tverts),
                                                 len(tri))
                        params = [
                            (x - a) / (b - a)
                            for (x, a,
                                 b) in zip(centroid, self.resolution.domain[0],
                                           self.resolution.domain[1])
                        ]
                        if self.walk_workspace_path != None:
                            gldraw.setcolor(params[0], params[1], params[2],
                                            0.25)
                        else:
                            gldraw.setcolor(params[0], params[1], params[2],
                                            1.0)
                        gldraw.triangle(*tverts)
                    glEnable(GL_CULL_FACE)
                else:
                    glDisable(GL_LIGHTING)
                    glEnable(GL_BLEND)
                    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
                    glColor4f(1, 0, 1, 0.5)

                    glLineWidth(4.0)
                    glBegin(GL_LINES)
                    for s in faces:
                        spts = verts[s[0]], verts[s[1]]
                        glVertex3f(spts[0][0], 0, spts[0][1])
                        glVertex3f(spts[1][0], 0, spts[1][1])
                    glEnd()
                    glLineWidth(1.0)
Пример #14
0
def planTransfer(world, objectIndex, hand, shift):
    """Plan a transfer path for the robot given in world, which is currently
    holding the object indexed by objectIndex in the hand hand.
    
    The desired motion should translate the object by shift without rotating
    the object.
    """
    globals = Globals(world)
    obj = world.rigidObject(objectIndex)
    cspace = TransferCSpace(globals, hand, obj)
    robot = world.robot(0)
    qmin, qmax = robot.getJointLimits()

    #get the start config
    q0 = robot.getConfig()
    q0arm = [q0[i] for i in hand.armIndices]
    if not cspace.feasible(q0arm):
        print "Warning, arm start configuration is infeasible"
        print "TODO: Complete 2.a to bypass this error"
        raw_input()
        cspace.close()
        return None

    #TODO: get the ungrasp config using an IK solver
    qungrasp = None
    qungrasparm = None
    print "TODO: Complete 2.b to find a feasible ungrasp config"
    raw_input()
    solver = hand.ikSolver(robot, vectorops.add(obj.getTransform()[1], shift),
                           (0, 0, 1))

    #plan the transfer path between q0arm and qungrasparm
    print "Planning transfer motion to ungrasp config..."
    MotionPlan.setOptions(connectionThreshold=5.0, perturbationRadius=0.5)
    planner = MotionPlan(cspace, 'sbl')
    planner.setEndpoints(q0arm, qungrasparm)
    #TODO: do the planning
    print "TODO: Complete 2.c to find a feasible transfer path"
    raw_input()

    cspace.close()
    #lift arm path to whole configuration space path
    path = []
    for qarm in planner.getPath():
        path.append(q0[:])
        for qi, i in zip(qarm, hand.armIndices):
            path[-1][i] = qi

    qpostungrasp = hand.open(qungrasp, 1.0)
    return path + [qpostungrasp]
Пример #15
0
def force(q, target, obstacles):
    """Returns the potential field force for a robot at configuration q,
    trying to reach the given target, with the specified obstacles.

    Input:
    - q: a 2D point giving the robot's configuration
    - robotRadius: the radius of the robot
    - target: a 2D point giving the robot's target
    - obstacles: a list of Circle's giving the obstacles
    """
    #basic target-tracking potential field implemented here
    #TODO: implement your own potential field
    att_force = vectorops.mul(vectorops.sub(target, q), attractiveConstant)
    total_rep_force = [0, 0]
    for each_ob in obstacles:
        cur_rep_force = repForce(q, each_ob, repulsiveDistance)
        total_rep_force = vectorops.add(total_rep_force, cur_rep_force)
    total_force = vectorops.add(att_force, total_rep_force)
    #limit the norm of f
    if vectorops.norm(total_force) > 1:
        total_force = vectorops.unit(vectorops.add(total_force,
                                                   (1e-10, 1e-10)))
    return total_force
Пример #16
0
 def solve_placement(self):
     """Implemented for you: come up with a collision-free target placement"""
     obmin,obmax = self.objbb
     ozmin = obmin[2]
     min_dims = min(obmax[0]-obmin[0],obmax[1]-obmin[1])
     center = [0.5*(obmax[0]+obmin[0]),0.5*(obmax[1]-obmin[1])]
     xmin,ymin,zmin = self.goal_bounds[0]
     xmax,ymax,zmax = self.goal_bounds[1]
     center_sampling_range = [(xmin+min_dims/2,xmax-min_dims/2),(ymin+min_dims/2,ymax-min_dims/2)]
     Tobj_feasible = []
     for iters in range(20):
         crand = [random.uniform(b[0],b[1]) for b in center_sampling_range]
         Robj = so3.rotation((0,0,1),random.uniform(0,math.pi*2))
         tobj = vectorops.add(so3.apply(Robj,[-center[0],-center[1],0]),[crand[0],crand[1],zmin-ozmin+0.002])
         self.object.setTransform(Robj,tobj)
         feasible = True
         for i in range(self.world.numTerrains()):
             if self.object.geometry().collides(self.world.terrain(i).geometry()):
                 feasible=False
                 break
         if not feasible:
             bmin,bmax = self.object.geometry().getBBTight()
             if bmin[0] < xmin:
                 tobj[0] += xmin-bmin[0]
             if bmax[0] > xmax:
                 tobj[0] -= bmin[0]-xmax
             if bmin[1] < ymin:
                 tobj[1] += ymin-bmin[1]
             if bmax[1] > ymax:
                 tobj[1] -= bmin[1]-ymax
             self.object.setTransform(Robj,tobj)
             feasible = True
             for i in range(self.world.numTerrains()):
                 if self.object.geometry().collides(self.world.terrain(i).geometry()):
                     feasible=False
                     break
             if not feasible:
                 continue
         for i in range(self.world.numRigidObjects()):
             if i == self.object.index: continue
             if self.object.geometry().collides(self.world.rigidObject(i).geometry()):
                 #raise it up a bit
                 bmin,bmax = self.world.rigidObject(i).geometry().getBB()
                 tobj[2] = bmax[2]-ozmin+0.002
                 self.object.setTransform(Robj,tobj)
         Tobj_feasible.append((Robj,tobj))
     print("Found",len(Tobj_feasible),"valid object placements")
     return Tobj_feasible
Пример #17
0
def make_object_arrangement(world,container,objects,container_wall_thickness=0.01,max_iterations=100,remove_failures=False):
    """For a given container and a list of objects in the world, places the objects inside the container with randomized x-y locations
    and z orientations so that they are initially collision free and on the bottom of the container.

    Args:
        world (WorldModel): the world containing the objects and obstacles
        container: the container RigidObject / Terrain in world into which
            objects should be spawned.  Assumed axis-aligned.
        objects (list of RigidObject): a list of RigidObjects in the world,
            at arbitrary locations.  They are placed in order.
        container_wall_thickness (float, optional): a margin subtracted from
            the container's outer dimensions into which the objects are spawned.
        max_iterations (int, optional): the maximum number of iterations used
            for sampling object initial poses
        remove_failures (bool): if True, then instead of returning None on
            failure, the objects that fail placement are removed from the world.
    
    Returns:
        (WorldModel): if successful, the positions of objects in world are
        modified and world is returned. On failure, None is returned.

    Note:
        Since world is modified in-place, if you wish to make multiple worlds with
        piles of the same objects, you should use world.copy() to store the
        configuration of the objects. You may also wish to randomize the object
        ordering using random.shuffle(objects) between instances.
    """
    container_outer_bb = _get_bound(container)
    container_inner_bb = (vectorops.add(container_outer_bb[0],[container_wall_thickness]*3),vectorops.sub(container_outer_bb[1],[container_wall_thickness]*3))
    collision_margin = 0.0025
    for object in objects:
        #make sure the bottom of the object touches the bottom of the container
        obb = _get_bound(object)
        zmin = obb[0][2]
        R,t = object.getTransform()
        t[2] = container_inner_bb[2] - zmin + collision_margin
        object.setTransform(R,t)

    failures = xy_jiggle(world,rigid_objects,[container],container_inner_bb[0],container_inner_bb[1],max_iterations)
    if len(failures) > 0:
        if remove_failures:
            removeIDs = [objects[i].index for i in failures]
            for i in sorted(removeIDs)[::-1]:
                world.remove(world.rigidObject(i))
        else:
            return None
    return world
Пример #18
0
def make_primitive_object(world, typename, name=None):
    """Adds an object to the world using its geometry / mass properties
    and places it in a default location (x,y)=(0,0) and resting on plane."""
    if name is None:
        name = typename
    fn = "data/objects/" + typename + ".obj"
    if not world.readFile(fn):
        raise IOError("Unable to read primitive from file", fn)
    T = obj.getTransform()
    spacing = 0.006
    T = (T[0],
         vectorops.add(T[1], (-(bmin[0] + bmax[0]) * 0.5,
                              -(bmin[1] + bmax[1]) * 0.5, -bmin[2] + spacing)))
    obj.setTransform(*T)
    obj.appearance().setColor(0.2, 0.5, 0.7, 1.0)
    obj.setName(name)
    return obj
Пример #19
0
def retract(robot,gripper,amount,local=True):
    """Retracts the robot's gripper by a vector `amount`.

    if local=True, amount is given in local coordinates.  Otherwise, its given in
    world coordinates.
    """
    if not isinstance(gripper,(int,str)):
        gripper = gripper.base_link
    link = robot.link(gripper)
    Tcur = link.getTransform()
    if local:
        amount = so3.apply(Tcur[0],amount)
    obj = ik.objective(link,R=Tcur[0],t=vectorops.add(Tcur[1],amount))
    res = ik.solve(obj)
    if not res:
        return None
    return robot.getConfig()
Пример #20
0
 def control_loop(self):
     #Calculate the desired velocity for each robot by adding up all
     #commands
     rvels = [[0]*self.world.robot(r).numLinks() for r in range(self.world.numRobots())]
     for (c,(r,v)) in self.current_velocities.iteritems():
         rvels[r] = vectorops.add(rvels[r],v)
     #print rvels
     #send to the robot(s)
     for r in range(self.world.numRobots()):
         robotController = self.sim.controller(r)
         qdes = robotController.getCommandedConfig()
         qdes = vectorops.madd(qdes,rvels[r],self.dt)
         #clamp to joint limits
         (qmin,qmax) = self.world.robot(r).getJointLimits()
         for i in xrange(len(qdes)):
             qdes[i] = min(qmax[i],max(qdes[i],qmin[i]))
         robotController.setPIDCommand(qdes,rvels[r])
     return
Пример #21
0
    def getDesiredCartesianPose(self,limb,device):
        """Returns a pair (R,t) of the desired EE pose if the limb should have
        a cartesian pose message, or None if it should not.

        - limb: either 'left' or 'right'
        - device: an index of the haptic device

        Implementation-wise, this reads from self.startTransforms and the deviceState
        to determine the correct desired end effector transform.  The delta
        from devices[device]['deviceCurrentTransform'] to devices[device]['deviceInitialTransform']
        is scaled, then offset by self.startTransforms[device].  (self.startTransforms is
        the end effector transform when deviceInitialTransform is set)
        """
        if limb=='left':
            T = self.serviceThread.eeGetter_left.get()
        else:
            T = self.serviceThread.eeGetter_right.get()
        if T is  None:
            T = se3.identity()
        R,t=T
        deviceState = self.haptic_client.deviceState
        if deviceState == None: return T
        dstate = deviceState[device]

        if dstate.widgetInitialTransform[0] == None or self.startTransforms[device] == None: return T
        Tcur = dstate.widgetCurrentTransform
        T0 = dstate.widgetInitialTransform[0]
        if T0 == None:
            T0 = Tcur
        #print "Button is down and mode is",dstate['mode']
        #print dstate
        assert T0 != None,"T0 is null"
        assert Tcur != None,"Tcur is null"
        relRot = so3.mul(Tcur[0],so3.inv(T0[0]))
        relTrans = vectorops.sub(Tcur[1],T0[1])

        #print "Rotation moment",so3.moment(relRot)
        desRot = so3.mul(relRot,self.startTransforms[device][0])
        desPos = vectorops.add(vectorops.mul(relTrans,hapticArmTranslationScaling),self.startTransforms[device][1])
        #TEST: just use start rotation
        #desRot = self.startTransforms[i][0]
        return (desRot,desPos)
Пример #22
0
 def next_state(self,x,u):
     assert len(x) == 3
     assert len(u) == 2
     pos = [x[0],x[1]]
     fwd = [math.cos(x[2]),math.sin(x[2])]
     right = [-fwd[1],fwd[0]]
     phi = u[1]
     d = u[0]
     if abs(phi)<1e-8:
         newpos = vectorops.madd(pos,fwd,d)
         return newpos + [x[2]]
     else:
         #rotate about a center of rotation, with radius 1/phi
         cor = vectorops.madd(pos,right,1.0/phi)
         sign = cmp(d*phi,0)
         d = abs(d)
         phi = abs(phi)
         theta=0
         thetaMax=d*phi
         newpos = vectorops.add(so2.apply(sign*thetaMax,vectorops.sub(pos,cor)),cor)
         return newpos + [so2.normalize(x[2]+sign*thetaMax)]
Пример #23
0
def calculate_workspace_axis(robot,obstacles,end_effector,point_local,axis_local,axis_world):
    global lower_corner,upper_corner
    resolution = (15,15,15)
    cellsize = vectorops.div(vectorops.sub(upper_corner,lower_corner),resolution)
    invcellsize = vectorops.div(resolution,vectorops.sub(upper_corner,lower_corner))
    
    reachable = np.zeros(resolution)
    #TODO: your code here
    for i in range(resolution[0]):
        for j in range(resolution[1]):
            for k in range(resolution[2]):
                orig_config = robot.getConfig()
                point = vectorops.add(vectorops.mul([i,j,k], cellsize), lower_corner)
                world_constraint = ik.fixed_rotation_objective(end_effector, world_axis=axis_world)
                local_constraint = ik.fixed_rotation_objective(end_effector, local_axis=axis_local)
                point_goal = ik.objective(end_effector, local=point_local, world=point)
                if ik.solve_global([point_goal, local_constraint, world_constraint], iters=10):
                    reachable[i,j,k] = 1.0
                robot.setConfig(orig_config)

    return reachable
Пример #24
0
def make_ycb_object(objectname, world, textured=True):
    """Adds an object to the world using its geometry / mass properties
    and places it in a default location (x,y)=(0,0) and resting on plane."""
    if objectname == 'random':
        objectname = random.choice(ycb_objects)
    if isinstance(objectname, int):
        objectname = ycb_objects[objectname]

    objmass = ycb_masses.get(objectname, DEFAULT_OBJECT_MASS)
    if textured:
        fn = os.path.join(YCB_DIR, objectname, 'textured.obj')
    else:
        fn = os.path.join(YCB_DIR, objectname, 'nontextured.ply')

    obj = world.makeRigidObject(objectname)
    if not obj.geometry().loadFile(fn):
        raise IOError("Unable to read geometry from file", fn)
    obj.setTransform(*se3.identity())

    #set mass automatically
    mass = obj.getMass()
    surfaceFraction = 0.5
    mass.estimate(obj.geometry(), objmass, surfaceFraction)
    obj.setMass(mass)

    bmin, bmax = obj.geometry().getBB()
    T = obj.getTransform()
    spacing = 0.006
    T = (T[0],
         vectorops.add(T[1], (-(bmin[0] + bmax[0]) * 0.5,
                              -(bmin[1] + bmax[1]) * 0.5, -bmin[2] + spacing)))
    obj.setTransform(*T)
    if textured:
        obj.appearance().setColor(1, 1, 1, 1.0)
    else:
        obj.appearance().setColor(random.random(), random.random(),
                                  random.random(), 1.0)
    obj.setName(objectname)
    return obj
Пример #25
0
def transform_average(Ts):
    t = vectorops.div(vectorops.add(*[T[1] for T in Ts]), len(Ts))
    qs = [so3.quaternion(T[0]) for T in Ts]
    q = vectorops.div(vectorops.add(*qs), len(Ts))
    return (so3.from_quaternion(q), t)
Пример #26
0
 def makeHapticCartesianPoseMsg(self):
     deviceState = self.haptic_client.deviceState
     if len(deviceState)==0: 
         print "No device state"
         return None
     transforms = [self.serviceThread.eeGetter_left.get(),self.serviceThread.eeGetter_right.get()]
     update = False
     commanding_arm=[0,0]
     for i,dstate in enumerate(deviceState):
         if dstate.buttonDown[0]:
             commanding_arm[i]=1
             if self.startTransforms[i] == None:
                 self.startTransforms[i] = transforms[i]
                 #RESET THE HAPTIC FORCE FEEDBACK CENTER
                 #self.serviceThread.hapticupdater.activateSpring(kP=hapticArmSpringStrength,kD=0,center=dstate.position,device=i)
                 
             #UPDATE THE HAPTIC FORCE FEEDBACK CENTER FROM ROBOT EE POSITION
             #need to invert world coordinates to widget coordinates to haptic device coordinates
             #widget and world translations are the same
             dx = vectorops.sub(transforms[i][1],self.startTransforms[i][1]);
             dxwidget = vectorops.div(dx,hapticArmTranslationScaling)
             R,device_center = widgetToDeviceTransform(so3.identity(),vectorops.add(dxwidget,dstate.widgetInitialTransform[0][1]))
             #print "Device position error",vectorops.sub(dstate.position,device_center)
             if vectorops.distance(dstate.position,device_center) > 0.03:
                 c = vectorops.madd(device_center,vectorops.unit(vectorops.sub(dstate.position,device_center)),0.025)
                 self.serviceThread.hapticupdater.activateSpring(kP=hapticArmSpringStrength,kD=0,center=c,device=i)
             else:
                 #deactivate
                 self.serviceThread.hapticupdater.activateSpring(kP=0,kD=0,device=i)
             if dstate.newupdate:
                 update = True
         else:
             if self.startTransforms[i] != None:
                 self.serviceThread.hapticupdater.deactivateHapticFeedback(device=i)
             self.startTransforms[i] = None
         dstate.newupdate = False
     if update:
         msg = {}
         msg['type'] = 'CartesianPose'
  
         T1 = self.getDesiredCartesianPose('left',0)
         R1,t1=T1
         T2 = self.getDesiredCartesianPose('right',1)
         R2,t2=T2
         transforms = [(R1,t1),(R2,t2)]
         if commanding_arm[0] and commanding_arm[1]:
             msg['limb'] = 'both'
             msg['position'] = t1+t2
             msg['rotation'] = R1+R2
             msg['maxJointDeviation']=0.5
             msg['safe'] = int(CollisionDetectionEnabled)
             self.CartesianPoseControl = True
             return msg
         elif commanding_arm[0] ==0:
             msg['limb'] = 'right'
             msg['position'] = t2
             msg['rotation'] = R2
             msg['maxJointDeviation']=0.5
             msg['safe'] = int(CollisionDetectionEnabled)
             self.CartesianPoseControl = True
             return msg
         else:
             msg['limb'] = 'left'
             msg['position'] = t1
             msg['rotation'] = R1
             msg['maxJointDeviation']=0.5
             msg['safe'] = int(CollisionDetectionEnabled)
             self.CartesianPoseControl = True
             return msg
     else:
         return None
    def get_contact_forces_and_jacobians(self):
        """
        Returns a force contact vector 1x(6*n_contacts)
        and a contact jacobian matrix 6*n_contactsxn.
        Contact forces are considered to be applied at the link origin
        """
        n_contacts = 0  # one contact per link
        maxid = self.world.numIDs()
        J_l = dict()
        f_l = dict()
        t_l = dict()
        for l_id in self.u_to_l:
            l_index = self.l_to_i[l_id]
            link_in_contact = self.robot.link(l_index)
            contacts_per_link = 0
            for j in xrange(maxid):  # TODO compute just one contact per link
                contacts_l_id_j = len(self.sim.getContacts(l_id, j))
                contacts_per_link += contacts_l_id_j
                if contacts_l_id_j > 0:
                    if not f_l.has_key(l_id):
                        f_l[l_id] = self.sim.contactForce(l_id, j)
                        t_l[l_id] = self.sim.contactTorque(l_id, j)
                    else:
                        f_l[l_id] = vectorops.add(f_l[l_id], self.sim.contactForce(l_id, j))
                        t_l[l_id] = vectorops.add(t_l[l_id], self.sim.contactTorque(l_id, j))
                    ### debugging ###
                    # print "link", link_in_contact.getName(), """
                    #      in contact with obj""", self.world.getName(j), """
                    #      (""", len(self.sim.getContacts(l_id, j)), """
                    #      contacts)\n f=""",self.sim.contactForce(l_id, j), """
                    #      t=""", self.sim.contactTorque(l_id, j)
            if self.virtual_contacts.has_key(l_id):
                b = self.sim.body(link_in_contact)

                f_v = se3.apply_rotation(b.getTransform(),self.virtual_wrenches[l_id][0:3])
                t_v = se3.apply_rotation(b.getTransform(),self.virtual_wrenches[l_id][3:6])
                if not f_l.has_key(l_id):
                    f_l[l_id] = f_v
                    t_l[l_id] = t_v
                else:
                    f_l[l_id] = f_v
                    t_l[l_id] = t_v


            ### debugging ###
            """
            if contacts_per_link == 0:
                print "link", link_in_contact.getName(), "not in contact"
            """
            if contacts_per_link > 0 or self.virtual_contacts.has_key(l_id):
                n_contacts += 1
                J_l[l_id] = np.array(link_in_contact.getJacobian(
                    (0, 0, 0)))
                self.robot.setConfig(self.sim.getActualConfig(self.robotindex))
                #print "J_l[l_id]:\n",J_l[l_id]
                #print "J_l shape", J_l[l_id].shape
        f_c = np.array(6 * n_contacts * [0.0])
        J_c = np.zeros((6 * n_contacts, self.u_dofs))

        for l_in_contact in xrange(len(J_l.keys())):
            f_c[l_in_contact * 6:l_in_contact * 6 + 3
            ] = t_l.values()[l_in_contact] # Jacobian has angular velocity first, then linear
            f_c[l_in_contact * 6 + 3:l_in_contact * 6 + 6
            ] = f_l.values()[l_in_contact] # Jacobian has angular velocity first, then linear
            J_c[l_in_contact * 6:l_in_contact * 6 + 6,
            :] = np.array(
                J_l.values()[l_in_contact])[:, [self.q_to_t[u_id] for u_id in self.u_to_n]]
        #print f_c, J_c
        return (f_c, J_c)
Пример #28
0
    def get_contact_forces_and_jacobians(self):
        """
        Returns a force contact vector 1x(6*n_contacts)
        and a contact jacobian matrix 6*n_contactsxn.
        Contact forces are considered to be applied at the link origin
        """
        n_contacts = 0  # one contact per link
        maxid = self.world.numIDs()
        J_l = dict()
        f_l = dict()
        t_l = dict()
        for l_id in self.u_to_l:
            l_index = self.l_to_i[l_id]
            link_in_contact = self.robot.link(l_index)
            contacts_per_link = 0
            for j in xrange(maxid):  # TODO compute just one contact per link
                contacts_l_id_j = len(self.sim.getContacts(l_id, j))
                contacts_per_link += contacts_l_id_j
                if contacts_l_id_j > 0:
                    if not f_l.has_key(l_id):
                        f_l[l_id] = self.sim.contactForce(l_id, j)
                        t_l[l_id] = self.sim.contactTorque(l_id, j)
                    else:
                        f_l[l_id] = vectorops.add(f_l[l_id], self.sim.contactForce(l_id, j))
                        t_l[l_id] = vectorops.add(t_l[l_id], self.sim.contactTorque(l_id, j))
                    ### debugging ###
                    # print "link", link_in_contact.getName(), """
                    #      in contact with obj""", self.world.getName(j), """
                    #      (""", len(self.sim.getContacts(l_id, j)), """
                    #      contacts)\n f=""",self.sim.contactForce(l_id, j), """
                    #      t=""", self.sim.contactTorque(l_id, j)
            if self.virtual_contacts.has_key(l_id):
                b = self.sim.body(link_in_contact)

                f_v = se3.apply_rotation(b.getTransform(),self.virtual_wrenches[l_id][0:3])
                t_v = se3.apply_rotation(b.getTransform(),self.virtual_wrenches[l_id][3:6])
                if not f_l.has_key(l_id):
                    f_l[l_id] = f_v
                    t_l[l_id] = t_v
                else:
                    f_l[l_id] += f_v
                    t_l[l_id] += t_v


            ### debugging ###
            """
            if contacts_per_link == 0:
                print "link", link_in_contact.getName(), "not in contact"
            """
            if contacts_per_link > 0 or self.virtual_contacts.has_key(l_id):
                n_contacts += 1
                J_l[l_id] = np.array(link_in_contact.getJacobian(
                    (0, 0, 0)))
                self.robot.setConfig(self.sim.getActualConfig(self.robotindex))
                #print "J_l[l_id]:\n",J_l[l_id]
                #print "J_l shape", J_l[l_id].shape
        f_c = np.array(6 * n_contacts * [0.0])
        J_c = np.zeros((6 * n_contacts, self.u_dofs))

        for l_in_contact in xrange(len(J_l.keys())):
            f_c[l_in_contact * 6:l_in_contact * 6 + 3
            ] = t_l.values()[l_in_contact] # Jacobian has angular velocity first, then linear
            f_c[l_in_contact * 6 + 3:l_in_contact * 6 + 6
            ] = f_l.values()[l_in_contact] # Jacobian has angular velocity first, then linear
            J_c[l_in_contact * 6:l_in_contact * 6 + 6,
            :] = np.array(
                J_l.values()[l_in_contact])[:, [self.q_to_t[u_id] for u_id in self.u_to_n]]
        #print f_c, J_c
        return (f_c, J_c)
Пример #29
0
def to_povray(vis, world, properties={}):
    """Convert a frame in klampt visualization to a povray script (or render
    to an image)

    Args:
        vis: sub-class of GLProgram
        world: sub-class of WorldModel
        properties: some additional information that povray can take but does
            not map to anything in klampt.
    
    Note::
        Do not modify properties, use the convenience functions that I provide 
        below (after this function).  These take the form ``render_to_x`` and
        ``add_x``.
    """
    #patch on vapory
    patch_vapory()

    #camera
    mat = vis.view.camera.matrix()
    pos = mat[1]
    right = mat[0][0:3]
    up = mat[0][3:6]
    dir = op.mul(mat[0][6:9], -1)
    tgt = op.add(mat[1], dir)
    #scale
    fovy = vis.view.fov * vis.view.h / vis.view.w
    fovx = math.atan(vis.view.w * math.tan(fovy * math.pi / 360.) /
                     vis.view.h) * 360. / math.pi
    right = op.mul(right, -float(vis.view.w) / vis.view.h)
    #camera
    camera_params = [
        'orthographic' if vis.view.orthogonal else 'perspective', 'location',
        [pos[0], pos[1], pos[2]], 'look_at', [tgt[0], tgt[1], tgt[2]], 'right',
        [right[0], right[1], right[2]], 'up', [up[0], up[1], up[2]], 'angle',
        fovx, 'sky',
        get_property(properties, [], "sky", [0., 0., 1.])
    ]
    camera = vp.Camera(*camera_params)

    #tempfile
    tempfile = get_property(properties, [], "tempfile", None)
    tempfile_path = os.path.dirname(tempfile) if tempfile is not None else '.'
    if not os.path.exists(tempfile_path):
        os.mkdir(tempfile_path)

    #objects
    objects = []
    objs = [o for o in properties["visualObjects"]
            ] if "visualObjects" in properties else []
    objs += [world.terrain(i) for i in range(world.numTerrains())]
    objs += [world.rigidObject(i) for i in range(world.numRigidObjects())]
    for r in range(world.numRobots()):
        objs += [
            world.robot(r).link(i) for i in range(world.robot(r).numLinks())
        ]
    for obj in objs:
        transient = get_property(properties, [obj], "transient", default=True)
        if transient:
            objects += geometry_to_povray(obj.appearance(),
                                          obj.geometry(),
                                          obj,
                                          None,
                                          properties=properties)
        else:
            path = tempfile_path + '/' + obj.getName() + '.pov'
            if not os.path.exists(path):
                R, t = obj.geometry().getCurrentTransform()
                obj.geometry().setCurrentTransform([1, 0, 0, 0, 1, 0, 0, 0, 1],
                                                   [0, 0, 0])
                geom = geometry_to_povray(obj.appearance(),
                                          obj.geometry(),
                                          obj,
                                          None,
                                          properties=properties)
                if len(geom) > 1:
                    file_content = vp.Union(*geom)
                elif len(geom) > 0:
                    file_content = vp.Object(*geom)
                else:
                    file_content = None
                if file_content is not None:
                    f = open(path, 'w')
                    f.write(str(file_content))
                    f.close()
                    obj.geometry().setCurrentTransform(R, t)
                else:
                    path = None
            #include
            if path is not None:
                R, t = obj.geometry().getCurrentTransform()
                objects.append(
                    vp.Object('#include "%s"' % path, "matrix", R + t))

    #light
    if "lights" in properties:
        objects += properties["lights"]

    #scene
    gsettings = []
    scene = vp.Scene(camera=camera,
                     objects=objects,
                     included=get_property(properties, [], "included", []),
                     global_settings=get_property(properties, [],
                                                  "global_settings", []))
    try:
        #this works with later version of vapory
        return  \
        render_povstring(str(scene),   \
                     outfile=get_property(properties,[],"outfile",None),  \
                     width=vis.view.w,height=vis.view.h,    \
                     quality=get_property(properties,[],"quality",None),    \
                     antialiasing=get_property(properties,[],"antialiasing",0.3),    \
                     remove_temp=get_property(properties,[],"remove_temp",False),    \
                     show_window=get_property(properties,[],"show_window",False),     \
                     tempfile=tempfile, \
                     includedirs=get_property(properties,[],"includedirs",None),    \
                     output_alpha=get_property(properties,[],"output_alpha",True))
    except:
        #this works with earlier version of vapory
        return  \
        render_povstring(str(scene),   \
                     outfile=get_property(properties,[],"outfile",None),  \
                     width=vis.view.w,height=vis.view.h,    \
                     quality=get_property(properties,[],"quality",None),    \
                     antialiasing=get_property(properties,[],"antialiasing",0.3),    \
                     remove_temp=get_property(properties,[],"remove_temp",False))
Пример #30
0
#visualize(world, robot, start=start,goal=goal)

qmin, qmax = robot.getJointLimits()
qmin[2] = -math.pi / 2
qmax[2] = 0
qmin[3] = 0
qmax[3] = math.pi
robot.setJointLimits(qmin, qmax)

config = robot.getConfig()
config[:] = q0[:len(config)].tolist()
robot.setConfig(config)
end_link = robot.link(6)  # for redundancy
end_link_pos = end_link.getWorldPosition([0, 0, 0])
object_pos = vo.add(end_link_pos, [0, 0.0, 0.18])
print('object at ', object_pos)
box = create.primitives.box(0.1,
                            0.1,
                            0.1,
                            object_pos,
                            world=world,
                            name='box',
                            mass=3)
print(type(box))
print(robot.getConfig())

path = np.zeros((plan.shape[0], len(config)))
path[:] = plan[:, :len(config)]
path = path.tolist()
Пример #31
0
    def find_target(self):
        self.target_prep_pos = (so3.identity(), [0, 10, -1])
        count = 0
        # print self.waiting_list
        for idx in self.waiting_list:
            # print 'i',idx
            bb = self.sim.world.rigidObject(idx).geometry().getBB()
            #decide the hand facing and finger configuration
            z_limit = 0.65
            ratio = 1.0
            if bb[1][2] > z_limit:
                hand_facing = 'face_toward_shelf'
                count += 1
            else:
                hand_facing = 'face_down'
                count += 1
            if bb[1][2] < 0.54 and self.hand_facing != 'sweep':
                hand_facing = 'sweep'

            if hand_facing == 'face_toward_shelf':
                max_limit = forward_max
                min_limit = forward_min
                face = face_toward_shelf
                hand_mode = 'power'
            elif hand_facing == 'face_down':
                max_limit = face_down_max
                min_limit = face_down_min
                x_diff = bb[1][0] - bb[0][0]
                y_diff = bb[1][1] - bb[0][1]
                if y_diff > x_diff * ratio:
                    hand_mode = 'power'
                    face = face_down
                elif x_diff > y_diff * ratio:
                    hand_mode = 'power'
                    face = face_down_rot
                else:
                    hand_mode = 'precision'
                    face = face_down
            else:
                face = sweep_pos
                hand_mode = 'power'

            if hand_facing == 'face_down':
                target_prep_pos = (face,
                                   vectorops.add(
                                       vectorops.div(
                                           vectorops.add(bb[1], bb[0]), 2),
                                       [0, 0, 0.5]))
                top_bb = bb[1][2]
                target_pos = (face,
                              vectorops.div(vectorops.add(bb[1], bb[0]), 2))
                target_pos[1][2] = top_bb + 0.06
                for i in range(3):
                    target_prep_pos[1][i] = max(
                        min(target_prep_pos[1][i], max_limit[i]), min_limit[i])
                    target_pos[1][i] = max(min(target_pos[1][i], max_limit[i]),
                                           min_limit[i])
            elif hand_facing == 'face_toward_shelf':
                target_prep_pos = (face,
                                   vectorops.add(
                                       vectorops.div(
                                           vectorops.add(bb[1], bb[0]), 2),
                                       [0, 0, 0.02]))
                back_bb = bb[0][1]
                target_pos = (face,
                              vectorops.div(vectorops.add(bb[1], bb[0]), 2))
                target_prep_pos[1][1] = back_bb - 0.07
                target_pos[1][1] = back_bb - 0.04
                for i in range(3):
                    target_prep_pos[1][i] = max(
                        min(target_prep_pos[1][i], max_limit[i]), min_limit[i])
                    target_pos[1][i] = max(min(target_pos[1][i], max_limit[i]),
                                           min_limit[i])
            else:
                target_prep_pos = (face, [(bb[1][0] + bb[0][0]) * 0.5, 0.55,
                                          0.66])
                y_len = bb[1][1] - bb[0][1]
                target_pos = (face, [(bb[1][0] + bb[0][0]) * 0.5, 0.92 - y_len,
                                     0.66])
            if count > 0 and hand_facing == 'sweep':
                continue
            if target_prep_pos[1][
                    1] + self.num_pick[idx] * 0.01 < self.target_prep_pos[1][
                        1] or self.hand_facing == 'sweep':
                self.hand_facing = hand_facing
                self.hand_mode = hand_mode
                self.target_prep_pos = target_prep_pos
                self.target_pos = target_pos
                self.target_id = idx
        self.num_pick[self.target_id] += 1
Пример #32
0
 def drawRobotGL(self, q):
     glColor3f(0, 0, 1)
     newc = vectorops.add(self.robot.center, q)
     c = Circle(newc[0], newc[1], self.robot.radius)
     c.drawGL()
Пример #33
0
def make_object_pile(world,container,objects,container_wall_thickness=0.01,randomize_orientation=True,
    visualize=False,verbose=0):
    """For a given container and a list of objects in the world, drops the objects inside the container and simulates until stable.

    Args:
        world (WorldModel): the world containing the objects and obstacles
        container: the container RigidObject / Terrain in world into which
            objects should be spawned.  Assumed axis-aligned.
        objects (list of RigidObject): a list of RigidObjects in the world,
            at arbitrary locations.  They are placed in order.
        container_wall_thickness (float, optional): a margin subtracted from
            the container's outer dimensions into which the objects are spawned.
        randomize_orientation (bool or str, optional): if True, the orientation
            of the objects are completely randomized.  If 'z', only the z
            orientation is randomized.  If False or None, the orientation is
            unchanged
        visualize (bool, optional): if True, pops up a visualization window to
            show the progress of the pile
        verbose (int, optional): if > 0, prints progress of the pile.
    
    Side effect: the positions of objects in world are modified

    Returns:
        (tuple): (world,sim), containing

            - world (WorldModel): the original world
            - sim (Simulator): the Simulator instance at the state used to obtain
              the stable placement of the objects.

    Note:
        Since world is modified in-place, if you wish to make multiple worlds with
        piles of the same objects, you should use world.copy() to store the
        configuration of the objects. You may also wish to randomize the object
        ordering using random.shuffle(objects) between instances.
    """
    container_outer_bb = _get_bound(container)
    container_inner_bb = (vectorops.add(container_outer_bb[0],[container_wall_thickness]*3),vectorops.sub(container_outer_bb[1],[container_wall_thickness]*3))
    spawn_area = (container_inner_bb[0][:],container_inner_bb[1][:])
    collision_margin = 0.0025
    if visualize:
        from klampt import vis
        from klampt.model import config
        import time
        oldwindow = vis.getWindow()
        newwindow = vis.createWindow("make_object_pile dynamic visualization")
        vis.setWindow(newwindow)
        vis.show()
        visworld = world.copy()
        vis.add("world",visworld)

    sim = Simulator(world)
    sim.setSetting("maxContacts","20")
    sim.setSetting("adaptiveTimeStepping","0")
    Tfar = (so3.identity(),[0,0,-100000])
    for object in objects:
        R,t = object.getTransform()
        object.setTransform(R,Tfar[1])
        sim.body(object).setTransform(*Tfar)
        sim.body(object).enable(False)
    if verbose: 
        print("Spawn area",spawn_area)
    if visualize:
        vis.lock()
        config.setConfig(visworld,config.getConfig(world))
        vis.unlock()
    for index in range(len(objects)):
        #always spawn above the current height of the pile 
        if index > 0:
            objects_bound = _get_bound(objects[:index])
            if verbose: 
                print("Existing objects bound:",objects_bound)
            zshift = max(0.0,objects_bound[1][2] - spawn_area[0][2])
            spawn_area[0][2] += zshift
            spawn_area[1][2] += zshift
        object = objects[index]
        obb = _get_bound(object)
        zmin = obb[0][2]
        R0,t0 = object.getTransform()
        feasible = False
        for sample in range(1000):
            R,t = R0[:],t0[:]
            if randomize_orientation == True:
                R = so3.sample()
            t[2] = spawn_area[1][2] - zmin + t0[2] + collision_margin
            object.setTransform(R,t)
            xy_randomize(object,spawn_area[0],spawn_area[1])
            if verbose: 
                print("Sampled position of",object.getName(),object.getTransform()[1])
            if not randomize_orientation:
                _,t = object.getTransform()
                object.setTransform(R,t)

            #object spawned, now settle
            sobject = sim.body(object)
            sobject.enable(True)
            sobject.setTransform(*object.getTransform())
            res = sim.checkObjectOverlap()
            if len(res[0]) == 0:
                feasible = True
                #get it low as possible without overlapping
                R,t = object.getTransform()
                for lower in range(100):
                    sobject.setTransform(R,vectorops.add(t,[0,0,-(lower+1)*0.01]))
                    res = sim.checkObjectOverlap()
                    if len(res[0]) != 0:
                        if verbose: 
                            print("Terminated lowering at",lower,"cm lower")
                        sobject.setTransform(R,vectorops.add(t,[0,0,-lower*0.01]))
                        res = sim.checkObjectOverlap()
                        break
                sim.updateWorld()
                break
        if not feasible:
            if verbose: 
                print("Failed to place object",object.getName())
            return None
        if visualize:
            vis.lock()
            config.setConfig(visworld,config.getConfig(world))
            vis.unlock()
            time.sleep(0.1)
    
    if verbose: 
        print("Beginning to simulate")
    #start letting everything  fall
    for firstfall in range(10):
        sim.simulate(0.01)
        if visualize:
            vis.lock()
            config.setConfig(visworld,config.getConfig(world))
            vis.unlock()
            time.sleep(0.01)
    maxT = 5.0
    dt = 0.01
    t = 0.0
    wdamping = -0.01
    vdamping = -0.1
    while t < maxT:
        settled = True
        for object in objects:
            sobject = sim.body(object)
            w,v = sobject.getVelocity()
            sobject.applyWrench(vectorops.mul(v,vdamping),vectorops.mul(w,wdamping))
            if vectorops.norm(w) + vectorops.norm(v) > 1e-4:
                #settled
                settled=False
                break
        if settled:
            break
        if visualize:
            t0 = time.time()
        sim.simulate(dt)
        if visualize:
            vis.lock()
            config.setConfig(visworld,config.getConfig(world))
            vis.unlock()
            time.sleep(max(0.0,dt-(time.time()-t0)))
        t += dt
    if visualize:
        vis.show(False)
        vis.setWindow(oldwindow)
    return (world,sim)
def predict_line(lineStarts,lineEnds,lineNormals,lineTorqueAxes,pcd,param,discretization,num_iter,queryDList,vis,world):
    vision_task_1 = False#True means we are doing the collision detection.
    o3d = False
    #create a pcd in open3D
    equilibriumPcd = open3d.geometry.PointCloud()
    xyz = []
    rgb = []
    normals = []
    for ele in pcd:
        xyz.append(ele[0:3])
        rgb.append(ele[3:6])
        normals.append(ele[6:9])
    equilibriumPcd.points = open3d.utility.Vector3dVector(np.asarray(xyz,dtype=np.float32))
    equilibriumPcd.colors = open3d.utility.Vector3dVector(np.asarray(rgb,dtype=np.float32))
    equilibriumPcd.normals = open3d.utility.Vector3dVector(np.asarray(normals,dtype=np.float32))
    # equilibriumPcd,ind=statistical_outlier_removal(equilibriumPcd,nb_neighbors=20,std_ratio=0.75) 
    if o3d:
        vis3 = open3d.visualization.Visualizer()
        vis3.create_window()
        open3dPcd = open3d.geometry.PointCloud()
        vis3.add_geometry(open3dPcd)

    probe = world.rigidObject(0)
    klampt_pcd_object = world.rigidObject(1) #this is a rigid object
    klampt_pcd = klampt_pcd_object.geometry().getPointCloud() #this is now a PointCloud()
    N_pts = klampt_pcd.numPoints()
    dt = 0.1
   

    for pointNumber in num_iter:

        ####Preprocess the pcd ####
        lineStart0 = lineStarts[pointNumber]
        lineEnd0 =lineEnds[pointNumber]
        lineTorqueAxis = lineTorqueAxes[pointNumber]
        N = 1 + round(vo.norm(vo.sub(lineStart0,lineEnd0))/discretization)
        s = np.linspace(0,1,N)
        lineNormal = lineNormals[pointNumber]
        localXinW = vo.sub(lineEnd0,lineStart0)/np.linalg.norm(vo.sub(lineEnd0,lineStart0))
        localYinW = (lineTorqueAxis)/np.linalg.norm(lineTorqueAxis)
        lineStartinLocal = [0,0]
        lineEndinLocal = [np.dot(vo.sub(lineEnd0,lineStart0),localXinW),
                        np.dot(vo.sub(lineEnd0,lineStart0),localYinW)]
        #################first project the pcd to the plane of the line##############
        #The start point is the origin of the plane...
        projectedPcd = [] #Each point is R^10 
        projectedPcdLocal = [] #localXY coordinate
        #the projected Pcd is in local frame....
        for i in range(len(pcd)):
            p = pcd[i][0:3]
            projectedPt = vo.sub(p,vo.mul(lineNormal,vo.dot(vo.sub(p,lineStart0),lineNormal))) ##world origin
            projectedPt2D = vo.sub(projectedPt,lineStart0)#world origin
            projectedPt2DinLocal = [vo.dot(projectedPt2D,localXinW),vo.dot(projectedPt2D,localYinW)]
            #%make sure point is in the "box" defined by the line
            if ((projectedPt2DinLocal[0]<0.051) and (projectedPt2DinLocal[0] > -0.001)
                and (projectedPt2DinLocal[1]<0.001) and (projectedPt2DinLocal[1]>-0.001)):
                projectedPcdLocal.append(projectedPt2DinLocal)
                projectedPcd.append(pcd[i])
        #Create a KDTree for searching
        projectedPcdTree = spatial.KDTree(projectedPcdLocal)
        ###############Find the corresponding point on the surface to the line############
        surfacePtsAll = []# %These are the surface pts that will be displaced.
        #%part of the probe not in contact with the object...
        #average 3 neighbors
        NofN = 3
        #rigidPointsFinal = []   ##we have a potential bug here for not using rigidPointsFinal....      
        for i in range(int(N)):
            tmp =vo.mul(vo.sub(lineEnd0,lineStart0),s[i])#%the point on the line, projected 
            linePt = [vo.dot(tmp,localXinW),vo.dot(tmp,localYinW)]
            d,Idx = projectedPcdTree.query(linePt[0:2],k=NofN)
            #We might end up having duplicated pts...
            #We should make sure that the discretization is not too fine..
            #or should average a few neighbors
            if d[0] < 0.002:
                surfacePt = [0]*10
                for j in range(NofN):
                    surfacePt = vo.add(surfacePt,projectedPcd[Idx[j]][0:10])
                surfacePt = vo.div(surfacePt,NofN)
                surfacePtsAll.append(surfacePt) #position in the global frame..
                #rigidPointsFinal.append(linePts)

        N = len(surfacePtsAll)

        ##### Preprocesss done
        if not o3d:
            vis.show()
            time.sleep(15.0)
        ############# Go through a list of displacements
        totalFinNList = []
        #for queryD = -0.003:0.001:0.014
        for queryD in queryDList:
            lineStart = vo.sub(lineStart0,vo.mul(lineNormal,queryD))
            lineEnd = vo.sub(lineEnd0,vo.mul(lineNormal,queryD))
            lineCenter = vo.div(vo.add(lineStart,lineEnd),2)
            torqueCenter = vo.add(lineCenter,vo.mul(lineNormal,0.09))


            if vision_task_1:

                vis.lock()
                print(queryD)
                x_axis = vo.mul(vo.unit(vo.sub(lineEnd,lineStart)),-1.0)
                y_axis = [lineTorqueAxis[0],lineTorqueAxis[1],lineTorqueAxis[2]]
                z_axis = vo.cross(x_axis,y_axis)
                z_axis = [z_axis[0],z_axis[1],z_axis[2]]
                R = x_axis+y_axis+z_axis
                t = vo.add(lineCenter,vo.mul(lineNormal,0.002))
                
                print(R,t)
                probe.setTransform(R,t)
                vis.unlock()
                time.sleep(dt)
            else:
                if not o3d:
                    vis.lock()
                print(queryD)
                x_axis = vo.mul(vo.unit(vo.sub(lineEnd,lineStart)),-1.0)
                y_axis = [lineTorqueAxis[0],lineTorqueAxis[1],lineTorqueAxis[2]]
                z_axis = vo.cross(x_axis,y_axis)
                z_axis = [z_axis[0],z_axis[1],z_axis[2]]
                R = x_axis+y_axis+z_axis
                t = vo.add(lineCenter,vo.mul(lineNormal,0.003))
                probe.setTransform(R,t)
                

                ####calculate the nominal displacements
                surfacePts = [] #These are the surface pts that will be displaced...
                rigidPtsInContact = []
                nominalD = [] #Column Vector..
                for i in range(int(N)): ##we have a potential bug here for keep interating trhough N, since about, if d[0] < 0.002, the points is not added...
                    #weird no bug occured...
                    linePt = vo.add(vo.mul(vo.sub(lineEnd,lineStart),s[i]),lineStart)              
                    surfacePt = surfacePtsAll[i][0:3]
                    normal = surfacePtsAll[i][6:9]
                    nominalDisp = -vo.dot(vo.sub(linePt,surfacePt),normal)
                    if nominalDisp > 0:
                        surfacePts.append(surfacePtsAll[i][0:10])#position in the global frame..
                        rigidPtsInContact.append(linePt)
                        nominalD.append(nominalDisp)
                originalNominalD = deepcopy(nominalD)
                NofSurfacePts = len(surfacePts)
                if NofSurfacePts > 0:
                    negativeDisp = True
                    while negativeDisp:
                        NofSurfacePts = len(surfacePts)
                        K = np.zeros((NofSurfacePts,NofSurfacePts))
                        for i in range(NofSurfacePts):
                            for j in range(NofSurfacePts):
                                K[i][j] = invKernel(surfacePts[i][0:3],surfacePts[j][0:3],param)
                        #print K
                        #startTime = time.time()
                        actualD =  np.dot(np.linalg.inv(K),nominalD)
                        #print('Time spent inverting matrix',time.time()- startTime)
                        #print nominalD,actualD
                        negativeIndex = actualD < 0
                        if np.sum(negativeIndex) > 0:
                            actualD = actualD.tolist()
                            surfacePts = [surfacePts[i] for i in range(len(surfacePts)) if actualD[i]>=0]
                            nominalD = [nominalD[i] for i in range(len(nominalD)) if actualD[i]>=0]
                            rigidPtsInContact = [rigidPtsInContact[i] for i in range(len(rigidPtsInContact)) if actualD[i]>=0]
                        else:
                            negativeDisp = False
                    
                    
                    #hsv's  hue: 0.25 = 0.0002 displacement 1 == 10 displacement
                    #generate the entire displacement field
                    #surfacePts are the equlibrium pts that provide 
                    entireDisplacedPcd = []
                    colorThreshold = 0.0005
                    colorUpperBound = 0.012
                    forceColorUpperBound = 0.004
                    colorRange = colorUpperBound - colorThreshold
                    greyColor = 0.38
                    
                    xyz = []
                    rgb = []
                    xyzForce = []
                    rgbForce = []
                    maxDisp = 0
                    for pt,ptNormal in zip(equilibriumPcd.points,equilibriumPcd.normals):
                        shapeVector = []
                        for pt2 in surfacePts:
                            shapeVector.append(invKernel(pt[0:3],pt2[0:3],param))
                        nominalDisplacement = vo.dot(shapeVector,actualD)
                        if nominalDisplacement > maxDisp:
                            maxDisp = nominalDisplacement

                        color = colorsys.hsv_to_rgb(nominalDisplacement/colorRange*0.75+0.25,1,0.75)
                        color = [color[0],color[1],color[2]]
                        displacedDeformablePoint = vo.sub(pt[0:3],vo.mul(ptNormal,nominalDisplacement))
                        xyz.append(displacedDeformablePoint)
                        rgb.append(color)
                        

                    counter = 0 
                    for (p,c) in zip(xyz,equilibriumPcd.colors):#rgb):
                        klampt_pcd.setProperty(counter,'r',c[0])
                        klampt_pcd.setProperty(counter,'g',c[1])
                        klampt_pcd.setProperty(counter,'b',c[2])
                        klampt_pcd.setPoint(counter,p)
                        counter = counter + 1
                    klampt_pcd_object.geometry().setPointCloud(klampt_pcd)
                    if o3d:
                        open3dPcd.points = open3d.utility.Vector3dVector(np.asarray(xyz,dtype=np.float32))
                        open3dPcd.colors = open3d.utility.Vector3dVector(np.asarray(rgb,dtype=np.float32))
                        open3dPcd.estimate_normals(search_param = open3d.geometry.KDTreeSearchParamHybrid(radius = 0.1, max_nn = 30))
                        ###open3dPcd,ind=statistical_outlier_removal(open3dPcd,nb_neighbors=10,std_ratio=2) 
                        #open3d.visualization.draw_geometries([open3dPcd])#_box_bottom])
                        vis3.add_geometry(open3dPcd)
                        vis3.poll_events()
                        vis3.update_renderer()
                    if not o3d:
                        vis.unlock()
                    time.sleep(dt)
                else:
                    pass

        
        while vis.shown():
            time.sleep(0.1)
    return