예제 #1
0
def stoch_descent(X, y, alpha, w):
    """
    Stochastic gradient descent
    :param X:
    :param y:
    :param alpha:
    :param w:
    :return:
    """
    global logs, logs_stoch
    logs = []
    logs_stoch = []
    random.seed(0)
    idx = list(range(len(X)))
    for epoch in range(1000):
        random.shuffle(idx)
        w_old = w
        for i in idx:
            loss = y[i] - vector.dot(X[i], w)
            gradient = vector.mul(loss, X[i])
            w = vector.add(w, vector.mul(alpha, gradient))
            logs_stoch += (w, alpha, sse(X, y, w))
        if vector.norm(vector.sub(w, w_old)) / vector.norm(w) < 1.0e-5:
            break
        logs += (w, alpha, sse(X, y, w))
    print("Epoch", epoch)
    return w
예제 #2
0
def cc_int(p1, r1, p2, r2):
    """
    Intersect circle (p1,r1) circle (p2,r2)
    where p1 and p2 are 2-vectors and r1 and r2 are scalars
    Returns a list of zero, one or two solution points.
    """
    d = vector.norm(p2-p1)
    if not tol_gt(d, 0):
        return []
    u = ((r1*r1 - r2*r2)/d + d)/2
    if tol_lt(r1*r1, u*u):
        return []
    elif r1*r1 < u*u:
        v = 0.0
    else:
        v = math.sqrt(r1*r1 - u*u)
    s = (p2-p1) * u / d
    if tol_eq(vector.norm(s),0):
        p3a = p1+vector.vector([p2[1]-p1[1],p1[0]-p2[0]])*r1/d
        if tol_eq(r1/d,0):
            return [p3a]
        else:
            p3b = p1+vector.vector([p1[1]-p2[1],p2[0]-p1[0]])*r1/d
            return [p3a,p3b]
    else:
        p3a = p1 + s + vector.vector([s[1], -s[0]]) * v / vector.norm(s) 
        if tol_eq(v / vector.norm(s),0):
            return [p3a]
        else:
            p3b = p1 + s + vector.vector([-s[1], s[0]]) * v / vector.norm(s)
            return [p3a,p3b]
예제 #3
0
def make_hcs_3d (a, b, c, righthanded=True):
    """build a 3D homogeneous coordiate system from three points. The origin is point a. The x-axis is
    b-a, the y axis is c-a, or as close as possible after orthogonormalisation."""
    # create orthonormal basis 
    u = normalised(b-a)
    v = normalised(c-a)
    nu = vector.norm(u)
    nv = vector.norm(v)
    if tol_eq(nu,0.0) and tol_eq(nv,0.0):
        # all points equal, no rotation
        u = vector.vector([1.0,0.0,0.0])
        v = vector.vector([0.0,1.0,0.0])
    elif tol_eq(nu, 0.0):
        # determine u perpendicular from v
        u,dummy = perp_3d(v)
    elif tol_eq(nv, 0.0):
        # determine v perpendicular from u
        dummy,v = perp_3d(u)
    # ensure that u and v are different
    if tol_eq(vector.norm(u-v),0.0):
        dummy,v = perp_3d(u)
    # make the basis vectors orthogonal
    w = vector.cross(u,v)
    v = vector.cross(w,u)
    # flip basis if lefthanded desired
    if righthanded==False:
        w = -w
    # create matix with basis vectors + translation as columns
    hcs = Mat([ 
        [u[0],v[0], w[0], a[0]], 
        [u[1],v[1], w[1], a[1]],
        [u[2],v[2], w[2], a[2]], 
        [0.0, 0.0, 0.0, 1.0]    ])
    return hcs 
예제 #4
0
def angle_3p(p1, p2, p3):
    """Returns the angle, in radians, rotating vector p2p1 to vector p2p3.
       arg keywords:
          p1 - a vector
          p2 - a vector
          p3 - a vector
       returns: a number
       In 2D, the angle is a signed angle, range [-pi,pi], corresponding
       to a clockwise rotation. If p1-p2-p3 is clockwise, then angle > 0.
       In 3D, the angle is unsigned, range [0,pi]
    """
    d21 = vector.norm(p2-p1)
    d23 = vector.norm(p3-p2)
    if tol_eq(d21,0) or tol_eq(d23,0):
        # degenerate, indeterminate angle
        return None
    v21 = (p1-p2) / d21
    v23 = (p3-p2) / d23
    t = vector.dot(v21,v23) # / (d21 * d23)
    if t > 1.0:             # check for floating point error
        t = 1.0
    elif t < -1.0:
        t = -1.0
    angle = math.acos(t)
    if len(p1) == 2:        # 2D case
        if is_counterclockwise(p1,p2,p3):
            angle = -angle
    return angle
예제 #5
0
def make_hcs_2d (a, b):
    """build a 2D homogeneus coordiate system from two points"""
    u = b-a
    if tol_eq(vector.norm(u), 0.0):
        u = vector.vector([0.0,0.0])
    else:
        u = u / vector.norm(u)
    v = vector.vector([-u[1], u[0]])
    hcs = Mat([ [u[0],v[0],a[0]] , [u[1],v[1],a[1]] , [0.0, 0.0, 1.0] ] )
    return hcs 
예제 #6
0
def test_perp_3d():
    for i in range(10):
        u = normalised(vector.randvec(3))
        v,w = perp_3d(u)
        print u, vector.norm(u)
        print v, vector.norm(v)
        print w, vector.norm(w)
        print tol_eq(vector.dot(u,v),0.0) 
        print tol_eq(vector.dot(v,w),0.0) 
        print tol_eq(vector.dot(w,u),0.0) 
예제 #7
0
def distance_point_line(p,l1,l2):
    """distance from point p to line l1-l2"""
    # v,w is p, l2 relative to l1
    v = p-l1
    w = l2-l1
    # x = projection v on w
    lw = vector.norm(w)
    if tol_eq(lw,0):
        x = 0*w
    else:
        x = w * vector.dot(v,w) / lw
    # result is distance x,v
    return vector.norm(x-v)
예제 #8
0
    def biCGsolve(self, x0, b, tol=1.0e-10, nmax=1000):

        """
		Solve self*x = b and return x using the bi-conjugate gradient method
		"""

        try:
            if not vector.isVector(b):
                raise TypeError, self.__class__, " in solve "
            else:
                if self.size()[0] != len(b) or self.size()[1] != len(b):
                    print("**Incompatible sizes in solve")
                    print("**size()=", self.size()[0], self.size()[1])
                    print("**len=", len(b))
                else:
                    kvec = diag(self)  # preconditionner
                    n = len(b)
                    x = x0  # initial guess
                    r = b - dot(self, x)
                    rbar = r
                    w = r / kvec
                    wbar = rbar / kvec
                    p = vector.zeros(n)
                    pbar = vector.zeros(n)
                    beta = 0.0
                    rho = vector.dot(rbar, w)
                    err = vector.norm(dot(self, x) - b)
                    k = 0
                    print(" bi-conjugate gradient convergence (log error)")
                    while abs(err) > tol and k < nmax:
                        p = w + beta * p
                        pbar = wbar + beta * pbar
                        z = dot(self, p)
                        alpha = rho / vector.dot(pbar, z)
                        r = r - alpha * z
                        rbar = rbar - alpha * dot(pbar, self)
                        w = r / kvec
                        wbar = rbar / kvec
                        rhoold = rho
                        rho = vector.dot(rbar, w)
                        x = x + alpha * p
                        beta = rho / rhoold
                        err = vector.norm(dot(self, x) - b)
                        print(k, " %5.1f " % math.log10(err))
                        k = k + 1
                    return x

        except:
            print("ERROR ", self.__class__, "::biCGsolve")
예제 #9
0
	def biCGsolve(self,x0, b, tol=1.0e-10, nmax = 1000):
		
		"""
		Solve self*x = b and return x using the bi-conjugate gradient method
		"""

		try:
			if not vector.isVector(b):
				raise TypeError, self.__class__,' in solve '
			else:
				if self.size()[0] != len(b) or self.size()[1] != len(b):
					print '**Incompatible sizes in solve'
					print '**size()=', self.size()[0], self.size()[1]
					print '**len=', len(b)
				else:
					kvec = diag(self) # preconditionner 
					n = len(b)
					x = x0 # initial guess
					r =  b - dot(self, x)
					rbar =  r
					w = r/kvec;
					wbar = rbar/kvec;
					p = vector.zeros(n);
					pbar = vector.zeros(n);
					beta = 0.0;
					rho = vector.dot(rbar, w);
					err = vector.norm(dot(self,x) - b);
					k = 0
					print " bi-conjugate gradient convergence (log error)"
					while abs(err) > tol and k < nmax:
						p = w + beta*p;
						pbar = wbar + beta*pbar;
						z = dot(self, p);
						alpha = rho/vector.dot(pbar, z);
						r = r - alpha*z;
						rbar = rbar - alpha* dot(pbar, self);
						w = r/kvec;
						wbar = rbar/kvec;
						rhoold = rho;
						rho = vector.dot(rbar, w);
						x = x + alpha*p;
						beta = rho/rhoold;
						err = vector.norm(dot(self, x) - b);
						print k,' %5.1f ' % math.log10(err)
						k = k+1
					return x
			
		except: print 'ERROR ',self.__class__,'::biCGsolve'
예제 #10
0
def distance_2p(p1, p2):
    """Returns the euclidean distance between two points
       arg keywords:
          p1 - a vector
          p2 - a vector
       returns: a number
    """
    return vector.norm(p2 - p1)
예제 #11
0
파일: main.py 프로젝트: dspivak/Matriarch
def circleArcAroundPivotClosestPieces(pivot, start, end, smoothingFactor):
    pivotToStart = vector.translate(vector.minus(pivot))(start)
    pivotToEnd = vector.translate(vector.minus(pivot))(end)
    smallerNorm = min(vector.norm(pivotToStart),vector.norm(pivotToEnd))
    def findActualEndPoint(vec):
        unitVec = vector.unit(vec)
        return vector.translate(pivot)(vector.scale(vector.unit(vec),smallerNorm*smoothingFactor))
    circularPart = circleArcAroundPivot(pivot,findActualEndPoint(pivotToStart),findActualEndPoint(pivotToEnd))
    
    #FIX!!
    if smallerNorm == vector.norm(pivotToStart):
        output = circularPart
        if smallerNorm != vector.norm(pivotToEnd):
            output.attachPartial(1, cutSegment(pivot, end, smallerNorm * smoothingFactor / vector.norm(pivotToEnd), smoothingFactor))
    else:
        output = cutSegment(start, pivot, 1 - smoothingFactor, 1 - smallerNorm * smoothingFactor / vector.norm(pivotToStart))
        output.attachPartial(1, circularPart)
    return output
예제 #12
0
def make_hcs_2d_scaled (a, b):
    """build a 2D homogeneus coordiate system from two points, but scale with distance between input point"""
    u = b-a
    if tol_eq(vector.norm(u), 0.0):     
        u = vector.vector([1.0,0.0])
    #else:
    #    u = u / vector.norm(u)
    v = vector.vector([-u[1], u[0]])
    hcs = Mat([ [u[0],v[0],a[0]] , [u[1],v[1],a[1]] , [0.0, 0.0, 1.0] ] )
    return hcs 
예제 #13
0
def sss_int(p1, r1, p2, r2, p3, r3):
    """Intersect three spheres, centered in p1, p2, p3 with radius r1,r2,r3 respectively. 
       Returns a list of zero, one or two solution points.
    """
    solutions = []
    # intersect circles in plane
    cp1 = vector.vector([0.0,0.0]) 
    cp2 = vector.vector([vector.norm(p2-p1), 0.0])
    cpxs = cc_int(cp1, r1, cp2, r2)
    if len(cpxs) == 0:
        return []
    # determine normal of plane though p1, p2, p3
    n = vector.cross(p2-p1, p3-p1)
    if not tol_eq(vector.norm(n),0.0):  
        n = n / vector.norm(n)
    else:
        # traingle p1, p2, p3 is degenerate
        # check for 2d solutions
        if len(cpxs) == 0:
            return []
        # project cpxs back to 3d and check radius r3 
        cp4 = cpxs[0]
        u = normalised(p2-p1)
        v,w = perp_3d(u)
        p4 = p1 + cp4[0] * u + cp4[1] * v
        if tol_eq(vector.norm(p4-p3), r3):
            return [p4]
        else:
            return []
    # px, rx, nx is circle 
    px = p1 + (p2-p1) * cpxs[0][0] / vector.norm(p2-p1)
    rx = abs(cpxs[0][1])
    nx = p2-p1
    nx = nx / vector.norm(nx)
    # py is projection of p3 on px,nx
    dy3 = vector.dot(p3-px, nx)
    py = p3 - (nx * dy3)
    if tol_gt(dy3, r3):
        return []
    # ry is radius of circle in py
    if tol_eq(r3,0.0):
        ry = 0.0 
    else:   
        ry = math.sin(math.acos(min(1.0,abs(dy3/r3))))*r3
    # determine intersection of circle px, rx and circle py, ry, projected relative to line py-px 
    cpx = vector.vector([0.0,0.0]) 
    cpy = vector.vector([vector.norm(py-px), 0.0])
    cp4s = cc_int(cpx, rx, cpy, ry)
    for cp4 in cp4s:
        p4 = px + (py-px) * cp4[0] / vector.norm(py-px) + n * cp4[1] 
        solutions.append(p4)  
    return solutions
예제 #14
0
    def CGsolve(self, x0, b, tol=1.0e-10, nmax=1000, verbose=1):
        """
		Solve self*x = b and return x using the conjugate gradient method
		"""
        if not vector.isVector(b):
            raise TypeError, self.__class__, " in solve "
        else:
            if self.size()[0] != len(b) or self.size()[1] != len(b):
                print("**Incompatible sizes in solve")
                print("**size()=", self.size()[0], self.size()[1])
                print("**len=", len(b))
            else:
                kvec = diag(self)  # preconditionner
                n = len(b)
                x = x0  # initial guess
                r = b - dot(self, x)
                try:
                    w = r / kvec
                except:
                    print("***singular kvec")
                p = vector.zeros(n)
                beta = 0.0
                rho = vector.dot(r, w)
                err = vector.norm(dot(self, x) - b)
                k = 0
                if verbose:
                    print(" conjugate gradient convergence (log error)")
                while abs(err) > tol and k < nmax:
                    p = w + beta * p
                    z = dot(self, p)
                    alpha = rho / vector.dot(p, z)
                    r = r - alpha * z
                    w = r / kvec
                    rhoold = rho
                    rho = vector.dot(r, w)
                    x = x + alpha * p
                    beta = rho / rhoold
                    err = vector.norm(dot(self, x) - b)
                    if verbose:
                        print(k, " %5.1f " % math.log10(err))
                    k = k + 1
                return x
예제 #15
0
파일: main.py 프로젝트: dspivak/Matriarch
def circleArc(center, start, end):
    radToStart = vector.translate(vector.minus(center))(start)
    radToEnd = vector.translate(vector.minus(center))(end)
    radiusSquared = vector.norm(radToStart)*vector.norm(radToEnd)
    radius = math.sqrt(radiusSquared)
    
    innerProductValue = vector.innerproduct(radToStart, radToEnd)
    angle = math.acos(innerProductValue/radiusSquared)
    
    firstUnitRadial = vector.unit(radToStart)
    secondUnitRadial = vector.unit(vector.translate(vector.scale(radToStart,-innerProductValue/radiusSquared))(radToEnd))
    
    def CN(t):
        point = vector.translate(center)(vector.translate(vector.scale(firstUnitRadial,radius*math.cos(t/radius)))(vector.scale(secondUnitRadial,radius*math.sin(t/radius))))
        tangent = vector.translate(vector.scale(firstUnitRadial,-math.sin(t/radius)))(vector.scale(secondUnitRadial,math.cos(t/radius)))
        output = [point,tangent]
        #output.append([math.cos(t/radius),math.sin(t/radius),0])
        return output

    return TwistingAxis(angle*radius,CN)
예제 #16
0
def test_cc_int():
    """Generates two random circles, computes the intersection,
       and verifies that the number of intersections and the 
       positions of the intersections are correct. 
       Returns True or False"""
    # gen two random circles p1,r2 and p2, r2
    p1 = vector.randvec(2, 0.0, 10.0,1.0)
    r1 = random.uniform(0, 10.0)
    p2 = vector.randvec(2, 0.0, 10.0,1.0)
    r2 = random.uniform(0, 10.0)
    # 33% change that r2=abs(r1-|p1-p2|)
    if random.random() < 0.33:
        r2 = abs(r1-vector.norm(p1-p2))
    # do interesection 
    diag_print("problem:"+str(p1)+","+str(r1)+","+str(p2)+","+str(r2),"test_cc_int")
    sols = cc_int(p1, r1, p2, r2)
    diag_print("solutions:"+str(map(str, sols)),"test_cc_int")
    # test number of intersections
    if len(sols) == 0:
        if not tol_gt(vector.norm(p2-p1),r1 + r2) and not tol_lt(vector.norm(p2-p1),abs(r1 - r2)) and not tol_eq(vector.norm(p1-p2),0):
            diag_print("number of solutions 0 is wrong","test_cc_int")
            return False
    elif len(sols) == 1: 
        if not tol_eq(vector.norm(p2-p1),r1 + r2) and not tol_eq(vector.norm(p2-p1),abs(r1-r2)):
            diag_print("number of solutions 1 is wrong","test_cc_int")
            return False
    elif len(sols) == 2:
        if not tol_lt(vector.norm(p2-p1),r1 + r2) and not tol_gt(vector.norm(p2-p1),abs(r1 - r2)):
            diag_prin("number of solutions 2 is wrong")
            return False
    else:
        diag_print("number of solutions > 2 is wrong","test_cc_int")
        return False

    # test intersection coords
    for p3 in sols:
        if not tol_eq(vector.norm(p3-p1), r1):
            diag_print("solution not on circle 1","test_cc_int")
            return False
        if not tol_eq(vector.norm(p3-p2), r2):
            diag_print("solution not on circle 2","test_cc_int")
            return False

    diag_print("OK","test_cc_int")
    return True
예제 #17
0
def make_hcs_3d_scaled (a, b, c):
    """build a 3D homogeneus coordiate system from three points, and derive scale from distance between points"""
     # create orthonormal basis 
    u = normalised(b-a)
    v = normalised(c-a)
    nu = vector.norm(u)
    nv = vector.norm(v)
    if tol_eq(nu,0) and tol_eq(nv,0):
        # all points equal, no rotation
        u = vector.vector([1.0,0.0,0.0])
        v = vector.vector([0.0,1.0,0.0])
    elif tol_eq(nu, 0):
        # determine u perpendicular from v
        u,dummy = perp_3d(v)[0]
    elif tol_eq(nv, 0):
        # determine v perpendicular from u
        dummy,v = perp_3d(u)[0]
    # make the basis vectors orthogonal
    w = vector.cross(u,v)
    v = vector.cross(w,u)
    # scale again
    if not tol_eq(vector.norm(b-a),0.0):
        u = u / vector.norm(b-a)
    if not tol_eq(vector.norm(c-a),0.0):
        v = v / vector.norm(c-a)
    # note: w is not scaled
    # create matix with basis vectors + translation as columns
    hcs = Mat([ 
        [u[0],v[0], w[0], a[0]], 
        [u[1],v[1], w[1], a[1]],
        [u[2],v[2], w[2], a[2]], 
        [0.0, 0.0, 0.0, 1.0]    ])
    return hcs 
예제 #18
0
파일: ik.py 프로젝트: Unalost/rss-2015
 def show_debug_info(self, itnum):
     conv_vect = array([vector.norm(task.f()) for task in self.tasks])
     conv_str = ["%10.8f" % x for x in conv_vect]
     print "   %4d: %s" % (itnum, ' '.join(conv_str))
     for task in self.tasks:
         if type(task) is COMTask:
             com = self.robot.compute_com(self.robot.rave.GetDOFValues())
             pymanoid_sage.rave.display_box(
                 self.robot.env, com, box_id="COM", color='g',
                 thickness=0.01)
             pymanoid_sage.rave.display_box(
                 self.robot.env, task.target, box_id='Target', color='b',
                 thickness=0.01)
예제 #19
0
def batch_descent(X, y, alpha, w):
    """
    Batch gradient descent
    :param X:
    :param y:
    :param alpha:
    :param w:
    :return:
    """
    global logs
    logs = []
    alpha /= len(X)
    for epoch in range(1, 1000):
        loss = vector.sub(y, vector.mul_mat_vec(X, w))
        gradient = vector.mul_mat_vec(vector.transpose(X), loss)
        w_old = w
        w = vector.add(w, vector.mul(alpha, gradient))
        logs += (w, alpha, sse(X, y, w))
        if vector.norm(vector.sub(w, w_old)) / vector.norm(w) < 1.0e-5:
            break
    print("Epoch", epoch)
    return w
예제 #20
0
def test_rr_int():
    """test random ray-ray intersection. returns True iff succesful"""
    # generate tree points A,B,C an two rays AC, BC. 
    # then calculate the intersection of the two rays
    # and check that it equals C
    p_a = vector.randvec(2, 0.0, 10.0,1.0)
    p_b = vector.randvec(2, 0.0, 10.0,1.0)
    p_c = vector.randvec(2, 0.0, 10.0,1.0)
    # print p_a, p_b, p_c
    if tol_eq(vector.norm(p_c - p_a),0) or tol_eq(vector.norm(p_c - p_b),0): 
        return True # ignore this case
    v_ac = (p_c - p_a) / vector.norm(p_c - p_a)
    v_bc = (p_c - p_b) / vector.norm(p_c - p_b)
    s = rr_int(p_a, v_ac, p_b, v_bc)
    if tol_eq(math.fabs(vector.dot(v_ac, v_bc)),1.0): 
        return len(s) == 0
    else:
        if len(s) > 0:
            p_s = s[0]
            return tol_eq(p_s[0],p_c[0]) and tol_eq(p_s[1],p_c[1])
        else:
            return False
예제 #21
0
def segment(start, end):
    startToEnd = vector.translate(vector.minus(start))(end)
    distance = vector.norm(startToEnd)
    try:
        tng = vector.unit(startToEnd)
        def CN(t):
            output = [vector.translate(start)(vector.scale(tng,t)),tng]
            #output.append(normal)
            return output
    except:
        def CN(t):
            output = [start, [0,0,0]]  
    
    return TwistingAxis(distance, CN)
예제 #22
0
    def f_new_sphere1(beta, x):
        bias = map(lambda x, n: x + beta[0] * n, initial[:3], norm)
        b = numpy.matrix(map(lambda a, b: a - b, x[:3], bias))
        m = list(numpy.array(b.transpose()))
        r0 = map(lambda y: beta[1] - vector.norm(y), m)
        g = list(numpy.array(numpy.matrix(x[3:]).transpose()))
        fac = 1  # weight deviation

        def dip(y, z):
            n = min(max(vector.dot(y, z) / vector.norm(y), -1), 1)
            return n

        r1 = map(lambda y, z: fac * beta[1] * (beta[2] - dip(y, z)), m, g)
        return r0 + r1
예제 #23
0
    def f_new_sphere2(beta, x):
        bias = map(lambda x, a, b: x + beta[0] * a + beta[1] * b, initial[:3],
                   u, v)
        b = numpy.matrix(map(lambda a, b: a - b, x[:3], bias))
        m = list(numpy.array(b.transpose()))
        r0 = map(lambda y: beta[2] - vector.norm(y), m)
        g = list(numpy.array(numpy.matrix(x[3:]).transpose()))
        fac = .03  # weight deviation as 1 degree ~ .03 mag

        def deg(y, z):
            n = min(max(vector.dot(y, z) / vector.norm(y), -1), 1)
            return math.degrees(math.asin(n))

        r1 = map(lambda y, z: fac * beta[2] * (beta[3] - deg(y, z)), m, g)
        return r0 + r1
예제 #24
0
    def f_new_sphere3(beta, x):
        b = numpy.matrix(lmap(lambda a, b: a - b, x[:3], beta[:3]))
        m = list(numpy.array(b.transpose()))
        r0 = lmap(lambda y: beta[3] - vector.norm(y), m)
        #r0 = lmap(lambda y : 1 - vector.norm(y)/beta[3], m)
        g = list(numpy.array(numpy.matrix(x[3:]).transpose()))
        fac = 1  # weight deviation

        def dip(y, z):
            n = min(max(vector.dot(y, z) / vector.norm(y), -1), 1)
            return n

        r1 = lmap(lambda y, z: fac * beta[3] * (beta[4] - dip(y, z)), m, g)

        return r0 + r1
예제 #25
0
    def _call(v):

        if len(hv) < 1:
            v_reduced = (0, 0, 0)
        else:
            # Compute the direction of average acceleration
            a_hat = vector.norm(vector.vector_mean(hv))
            # Remove the component parallel to average accleration
            v_parallel = vector.vector_multiply(vector.dot(v, a_hat), a_hat)
            v_reduced = vector.vector_subtract(v, v_parallel)
        # Update the histopy elements with the new vector
        hv.append(v)
        if len(hv) > history:
            hv.pop(0)
        return v_reduced
예제 #26
0
 def boundarycompute(self):
     try:
         return self.boundary
     except:
         if self[0].str2[6:9] != 'GLY':
             atoms = self.findatoms(["  N  ","  C  ","  CA ","  O  ","  OT1", "  CB "])
         else:
             atoms = self.findatoms(["  N  ","  C  ","  CA ","  O  ","  OT1", "  HA2"])
         atoms.remove(0)
         posterm = vector.Nlocation(atoms[1].coords(),atoms[2].coords(),atoms[3].coords())
         axis = vector.translate(vector.minus(atoms[0].coords()))(posterm)
         N1 = vector.unit(axis)
         length = vector.norm(axis)
         N2 = vector.unit(vector.translate(vector.minus(atoms[2].coords()))(atoms[4].coords()))
         self.boundary = [atoms[0].coords(), N1, N2, length]
         return self.boundary
예제 #27
0
def ComputeDeviation(points, fit):
    m, d  = 0, 0
    for p in points:
        v = vector.sub(p[:3], fit[:3])
        m += (1 - vector.dot(v, v) / fit[3]**2)**2

        if len(fit) > 4:
            n = vector.dot(v, p[3:]) / vector.norm(v)
            if abs(n) <= 1:
                ang = math.degrees(math.asin(n))
                d += (fit[4] - ang)**2
            else:
                d += 1e111
    m /= len(points)
    d /= len(points)
    return [m**.5, d**.5]
예제 #28
0
def make_hcs_3d_scaled(a, b, c):
    """build a 3D homogeneus coordiate system from three vectors"""
    # create orthnormal basis
    u = b - a
    u = u / vector.norm(u)
    v = c - a
    v = v / vector.norm(v)
    w = vector.cross(u, v)
    v = vector.cross(w, u)
    # scale
    u = u / vector.norm(u) / vector.norm(b - a)
    v = v / vector.norm(v) / vector.norm(c - a)
    hcs = Mat([[u[0], v[0], w[0], a[0]], [u[1], v[1], w[1], a[1]],
               [u[2], v[2], w[2], a[2]], [0.0, 0.0, 0.0, 1.0]])
    return hcs
예제 #29
0
 def boundarycompute(self):
     try:
         return self.boundary
     except:
         if self[0].str2[6:9] != 'GLY':
             atoms = self.findatoms(
                 ["  N  ", "  C  ", "  CA ", "  O  ", "  OT1", "  CB "])
         else:
             atoms = self.findatoms(
                 ["  N  ", "  C  ", "  CA ", "  O  ", "  OT1", "  HA2"])
         atoms.remove(0)
         posterm = vector.Nlocation(atoms[1].coords(), atoms[2].coords(),
                                    atoms[3].coords())
         axis = vector.translate(vector.minus(atoms[0].coords()))(posterm)
         N1 = vector.unit(axis)
         length = vector.norm(axis)
         N2 = vector.unit(
             vector.translate(vector.minus(atoms[2].coords()))(
                 atoms[4].coords()))
         self.boundary = [atoms[0].coords(), N1, N2, length]
         return self.boundary
예제 #30
0
def smoothedPieceWiseLinearFullFunctionality(points, mapFromSpaceToTime, Wnew, smoothingFactor = 0.33):
    if len(points) < 2:
        print("Error: only " + str(len(points)) + " points supplied to smoothedPieceWiseLinear")
        return
    
    currentPoints = copy.deepcopy(points)
    numPoints = len(currentPoints)
    
    attachElements = [cutSegment(points[0],points[1],0,smoothingFactor)]
    
    for i in range(0,numPoints - 2):
        lastToPivot = vector.translate(vector.minus(points[i]))(points[i+1])
        pivotToNext = vector.translate(vector.minus(points[i+1]))(points[i+2])
        angle = vector.innerproduct(lastToPivot, pivotToNext)/(vector.norm(lastToPivot)*vector.norm(pivotToNext))
        collinear = (abs(angle) < 0.001)
        if collinear:
            attachElements.append(cutSegment(points[i],points[i+1],smoothingFactor,1))
            attachElements.append(cutSegment(points[i+1],points[i+2],1,smoothingFactor))
        else:
            attachElements.append(cutSegment(points[i],points[i+1],smoothingFactor,1-smoothingFactor))
            attachElements.append(circleArcAroundPivotClosestPieces(points[i+1],points[i],points[i+2],smoothingFactor))
    
    attachElements.append(cutSegment(points[-2],points[-1],smoothingFactor,1))
    
    def iteratedAttach(start, end):
        if start < end:
            midpoint = (start + end)/2
            iteratedAttach(start, midpoint)
            iteratedAttach(midpoint + 1, end)
            attachElements[start].attachPartial(1, attachElements[midpoint + 1])
    iteratedAttach(0, len(attachElements)-1)
    Wmap = attachElements[0]
    
    produceN2 = lambda x : vector.unit(vector.orthogonalComponent(vector.translate(vector.minus(Wnew.ev(mapFromSpaceToTime(x[0]))[0]))(x[0]),x[1]))
    appendN2 = lambda x: [x[0],x[1],produceN2(x)]
    Wmap.CN = compose(appendN2,Wmap.CN)
    
    return [Wmap, Wnew, lambda t: mapFromSpaceToTime(Wmap.ev(t)[0])]
예제 #31
0
    def poll(self):
        msgs = self.client.receive()
        for name in msgs:
            value = msgs[name]
            if name == 'imu.accel.calibration':
                self.s.AccelCalValid = True
                b, t = value[0][:3], value[0][3]
                self.s.AccelCalMin = b[0] - t, b[1] - t, b[2] - t
                self.s.AccelCalMax = b[0] + t, b[1] + t, b[2] + t
            elif name == 'imu.compass.calibration':
                self.compass_calibration_updated = True
                self.s.CompassCalEllipsoidValid = True
                self.s.CompassCalEllipsoidOffset = tuple(value[0][:3])
                #rtimu.resetFusion()
            elif name == 'imu.rate':
                self.rate = value
                print('imu rate set to rate', value)

        if not self.lastdata:
            return
        gyro, compass = self.lastdata
        self.lastdata = False

        # see if gyro is out of range, sometimes the sensors read
        # very high gyro readings and the sensors need to be reset by software
        # this is probably a bug in the underlying driver with fifo misalignment
        d = .05 / self.rate  # filter constant
        for i in range(3):  # filter gyro vector
            self.avggyro[i] = (1 - d) * self.avggyro[i] + d * gyro[i]
        if vector.norm(self.avggyro) > .8:  # 55 degrees/s
            print('too high standing gyro bias, resetting sensors', gyro,
                  self.avggyro)
            self.init()

        # detects the problem even faster:
        if any(map(lambda x: abs(x) > 1000, compass)):
            print('compass out of range, resetting', compass)
            self.init()
예제 #32
0
    def check_diff(self, m=10, reltol=0.05):
        """Check differential constraints (e.g., dq = qd * dt).

        m -- number of random time instants to test
        reltol -- tolerance in relative error

        """
        tset = numpy.random.random(m) * self.duration
        q, qd, qdd, dt = self.q, self.qd, self.qdd, 1e-5
        for t in tset:
            q_dev = q(t + dt) - q(t) - dt * qd(t)
            qd_dev = qd(t + dt) - qd(t) - dt * qdd(t)
            if norm(q_dev) > reltol * dt * norm(qd(t)):
                raise TrajectoryError("bad velocity", self, t)
            if norm(qd_dev) > reltol * dt * norm(qdd(t)):
                kron = norm(qd_dev), reltol * dt * norm(qdd(t))
                msg = "bad acceleration (%e > %e)" % kron
                raise TrajectoryError(msg, self, t)
예제 #33
0
def fit_batch(X, y, alpha, w, epochs=500, epsilon=1.0e-5):
    """
    Batch gradient descent
    :param X:
    :param y:
    :param alpha:
    :param w:
    :param epochs:
    :param epsilon:
    :return:
    """
    global logs
    logs = []
    alpha /= len(X)
    for epoch in range(epochs):
        y_hat = predict(X, w)
        loss = vector.sub(y, y_hat)
        gradient = vector.mul_mat_vec(vector.transpose(X), loss)
        w = vector.add(w, vector.mul(alpha, gradient))
        logs += (w, alpha, sse(X, y, w))
        if vector.norm(gradient) < epsilon:
            break
    print("Epoch", epoch)
    return w
예제 #34
0
def test_sss_int():
    p1 = vector.randvec(3, 0.0, 10.0,1.0)
    p2 = vector.randvec(3, 0.0, 10.0,1.0)
    p3 = vector.randvec(3, 0.0, 10.0,1.0)
    p4 = vector.randvec(3, 0.0, 10.0,1.0)
    #p1 = vector.vector([0.0,0.0,0.0])
    #p2 = vector.vector([1.0,0.0,0.0])
    #p3 = vector.vector([0.0,1.0,0.0])
    #p4 = vector.vector([1.0,1.0,1.0])
    d14 = vector.norm(p4-p1)
    d24 = vector.norm(p4-p2)
    d34 = vector.norm(p4-p3)
    sols = sss_int(p1,d14,p2,d24,p3,d34)
    sat = True
    for sol in sols:
        # print sol
        d1s = vector.norm(sol-p1)
        d2s = vector.norm(sol-p2)
        d3s = vector.norm(sol-p3)
        sat = sat and tol_eq(d1s,d14)
        sat = sat and tol_eq(d2s,d24)
        sat = sat and tol_eq(d3s,d34)
        # print sat
    return sat
예제 #35
0
def test_sss_int():
    p1 = vector.randvec(3, 0.0, 10.0, 1.0)
    p2 = vector.randvec(3, 0.0, 10.0, 1.0)
    p3 = vector.randvec(3, 0.0, 10.0, 1.0)
    p4 = vector.randvec(3, 0.0, 10.0, 1.0)
    #p1 = vector.vector([0.0,0.0,0.0])
    #p2 = vector.vector([1.0,0.0,0.0])
    #p3 = vector.vector([0.0,1.0,0.0])
    #p4 = vector.vector([1.0,1.0,1.0])
    d14 = vector.norm(p4 - p1)
    d24 = vector.norm(p4 - p2)
    d34 = vector.norm(p4 - p3)
    sols = sss_int(p1, d14, p2, d24, p3, d34)
    sat = True
    for sol in sols:
        # print sol
        d1s = vector.norm(sol - p1)
        d2s = vector.norm(sol - p2)
        d3s = vector.norm(sol - p3)
        sat = sat and tol_eq(d1s, d14)
        sat = sat and tol_eq(d2s, d24)
        sat = sat and tol_eq(d3s, d34)
        # print sat
    return sat
예제 #36
0
def ExtraFit():
    ellipsoid_fit = False
    '''
    if len(points) >= 10:
        def f_ellipsoid3(beta, x):
            return (x[0]-beta[0])**2 + (beta[4]*(x[1]-beta[1]))**2 + (beta[5]*(x[2]-beta[2]))**2 - beta[3]**2
        ellipsoid_fit = FitLeastSq(sphere_fit + [1, 1], f_ellipsoid3, zpoints)
        print('ellipsoid_fit', ellipsoid_fit)
    '''

#        return [sphere_fit, 1, ellipsoid_fit]
    def f_rotellipsoid3(beta, x):
        return x[0]**2 + (beta[1]*x[1] + beta[3]*x[0])**2 + (beta[2]*x[2] + beta[4]*x[0] + beta[5]*x[1])**2 - beta[0]**2
        a = x[0]-beta[0]
        b = x[1]-beta[1]
        c = x[2]-beta[2]
        return (a)**2 + (beta[4]*b + beta[6]*a)**2 + (beta[5]*c + beta[7]*a + beta[8]*b)**2 - beta[3]**2
    def f_ellipsoid3_cr(beta, x, cr):
        a = x[0]-beta[0]
        b = x[1]-beta[1]
        c = x[2]-beta[2]
        return (a)**2 + (beta[4]*b + cr[0]*a)**2 + (beta[5]*c + cr[1]*a + cr[2]*b)**2 - beta[3]**2

        # if the ellipsoid fit is sane
    if abs(ellipsoid_fit[4]-1) < .2 and abs(ellipsoid_fit[5]-1) < .2:
        cpoints = lmap(lambda a, b : a - b, zpoints[:3], ellipsoid_fit[:3])
        rotellipsoid_fit = FitLeastSq(ellipsoid_fit[3:] + [0, 0, 0], f_rotellipsoid3, cpoints)
        #print('rotellipsoid_fit', rotellipsoid_fit)
        ellipsoid_fit2 = FitLeastSq(ellipsoid_fit[:3] + rotellipsoid_fit[:3], f_ellipsoid3_cr, (zpoints, rotellipsoid_fit[3:]))
        #print('ellipsoid_fit2', ellipsoid_fit2)

        cpoints = lmap(lambda a, b : a - b, zpoints[:3], ellipsoid_fit2[:3])
        rotellipsoid_fit2 = FitLeastSq(ellipsoid_fit[3:] + [0, 0, 0], f_rotellipsoid3, cpoints)
        print('rotellipsoid_fit2', rotellipsoid_fit2)
    else:
        ellipsoid_fit = False

    def f_uppermatrixfit(beta, x):
            b = numpy.matrix(lmap(lambda a, b : a - b, x[:3], beta[:3]))
            r = numpy.matrix([beta[3:6], [0]+list(beta[6:8]), [0, 0]+[beta[8]]])
            print('b', beta)

            m = r * b
            m = list(numpy.array(m.transpose()))
            r0 = lmap(lambda y : 1 - vector.dot(y, y), m)

            return r0

    def f_matrixfit(beta, x, efit):
            b = numpy.matrix(lmap(lambda a, b : a - b, x[:3], efit[:3]))
            r = numpy.matrix([[1,       beta[0], beta[1]],
                              [beta[2], efit[4], beta[3]],
                              [beta[4], beta[5], efit[5]]])

            m = r * b
            m = list(numpy.array(m.transpose()))
            r0 = lmap(lambda y : efit[3]**2 - vector.dot(y, y), m)
            #return r0

            g = list(numpy.array(numpy.matrix(x[3:]).transpose()))
            r1 = lmap(lambda y, z : beta[6] - vector.dot(y, z), m, g)

            return r0+r1

    def f_matrix2fit(beta, x, efit):
            b = numpy.matrix(lmap(lambda a, b : a - b, x[:3], beta[:3]))
            r = numpy.matrix([[1,       efit[0], efit[1]],
                              [efit[2], beta[4], efit[3]],
                              [efit[4], efit[5], beta[5]]])

            m = r * b
            m = list(numpy.array(m.transpose()))
            r0 = lmap(lambda y : beta[3]**2 - vector.dot(y, y), m)
            #return r0

            g = list(numpy.array(numpy.matrix(x[3:]).transpose()))
            r1 = lmap(lambda y, z : beta[6] - vector.dot(y, z), m, g)

            return r0+r1

    if False:
         matrix_fit = FitLeastSq([0, 0, 0, 0, 0, 0, 0], f_matrixfit, (zpoints, ellipsoid_fit))
         #print('matrix_fit', matrix_fit)

         matrix2_fit = FitLeastSq(ellipsoid_fit + [matrix_fit[6]], f_matrix2fit, (zpoints, matrix_fit))
         #print('matrix2_fit', matrix2_fit)

         matrix_fit2 = FitLeastSq(matrix_fit, f_matrixfit, (zpoints, matrix2_fit))
         print('matrix_fit2', matrix_fit2)

         matrix2_fit2 = FitLeastSq(matrix2_fit[:6] + [matrix_fit2[6]], f_matrix2fit, (zpoints, matrix_fit2))
         print('matrix2_fit2', matrix2_fit2)

    def rot(v, beta):
        sin, cos = math.sin, math.cos
        v = vector.normalize(v)
        #            q = angvec2quat(beta[0], [0, 1, 0])
        #            return rotvecquat(v, q)
        v1 = [v[0]*cos(beta[0]) + v[2]*sin(beta[0]),
              v[1],
              v[2]*cos(beta[0]) - v[0]*sin(beta[0])]

        v2 = [v1[0],
              v1[1]*cos(beta[1]) + v1[2]*sin(beta[1]),
              v1[2]*cos(beta[1]) - v1[1]*sin(beta[1])]

        v3 = [v2[0]*cos(beta[2]) + v2[1]*sin(beta[2]),
              v2[1]*cos(beta[2]) - v2[0]*sin(beta[1]),
              v2[2]]
            
        return v3

    def f_quat(beta, x, sphere_fit):
        sphere_fit = numpy.array(sphere_fit)
        n = [x[0]-sphere_fit[0], x[1]-sphere_fit[1], x[2]-sphere_fit[2]]
        q = [1 - vector.norm(beta[:3])] + list(beta[:3])
        q = angvec2quat(vector.norm(beta[:3]), beta[:3])
        m = lmap(lambda v : rotvecquat(vector.normalize(v), q), list(zip(n[0], n[1], n[2])))
#        m = lmap(lambda v : rot(v, beta), list(zip(n[0], n[1], n[2])))

        m = numpy.array(list(zip(*m)))
        d = m[0]*x[3] + m[1]*x[4] + m[2]*x[5]
        return beta[3] - d

    quat_fit = FitLeastSq([0, 0, 0, 0], f_quat, (zpoints, sphere_fit))
    #    q = [1 - vector.norm(quat_fit[:3])] + list(quat_fit[:3])
    q = angvec2quat(vector.norm(quat_fit[:3]), quat_fit[:3])

    print('quat fit', q, math.degrees(angle(q)), math.degrees(math.asin(quat_fit[3])))
    
    def f_rot(beta, x, sphere_fit):
        sphere_fit = numpy.array(sphere_fit)
        n = [x[0]-sphere_fit[0], x[1]-sphere_fit[1], x[2]-sphere_fit[2]]
        m = lmap(lambda v : rot(v, beta), zip(n[0], n[1], n[2]))
        m = numpy.array(list(zip(*m)))

        d = m[0]*x[3] + m[1]*x[4] + m[2]*x[5]
        return beta[3] - d

    rot_fit = FitLeastSq([0, 0, 0, 0], f_rot, (zpoints, sphere_fit))
    print('rot fit', rot_fit, math.degrees(rot_fit[0]), math.degrees(rot_fit[1]), math.degrees(rot_fit[2]), math.degrees(math.asin(min(1, max(-1, rot_fit[3])))))
예제 #37
0
def normalised(v):
    n = vector.norm(v)
    if tol_eq(n, 0.0):
        return v
    else:
        return v / n
예제 #38
0
 def dip(y, z):
     n = min(max(vector.dot(y, z)/vector.norm(y), -1), 1)
     return n
예제 #39
0
파일: ik.py 프로젝트: Unalost/rss-2015
 def converged(self):
     conv_norms = (vector.norm(task.f()) for task in self.tasks)
     return max(conv_norms) < CONV_THRES
예제 #40
0
 def f_sphere3(beta, x):
     bias = beta[:3]
     b = numpy.matrix(lmap(lambda a, b : a - b, x[:3], bias))
     m = list(numpy.array(b.transpose()))
     r0 = lmap(lambda y : beta[3] - vector.norm(y), m)
     return r0
예제 #41
0
def FitPointsCompass(debug, points, current, norm):
    # ensure current and norm are float
    current = lmap(float, current)
    norm = lmap(float, norm)

    zpoints = [[], [], [], [], [], []]
    for i in range(6):
        zpoints[i] = lmap(lambda x : x[i], points)
        
    # determine if we have 0D, 1D, 2D, or 3D set of points
    point_fit, point_dev, point_max_dev = PointFit(points)
    if point_max_dev < 9:
        debug('0d fit, insufficient data %.1f %.1f < 9' % (point_dev, point_max_dev))
        return False

    line, plane = LinearFit(points)
    line_fit, line_dev, line_max_dev = line
    plane_fit, plane_dev, plane_max_dev = plane

    # initial guess average min and max for bias, and average range for radius
    minc = [1000, 1000, 1000]
    maxc = [-1000, -1000, -1000]
    for p in points:
        minc = lmap(min, p[:3], minc)
        maxc = lmap(max, p[:3], maxc)

    guess = lmap(lambda a, b : (a+b)/2, minc, maxc)
    diff = lmap(lambda a, b : b-a, minc, maxc)
    guess.append((diff[0]+diff[1]+diff[2])/3)
    #debug('initial guess', guess)

    # initial is the closest to guess on the uv plane containing current
    initial = vector.add(current[:3], vector.project(vector.sub(guess[:3], current[:3]), norm))
    initial.append(current[3])
    #debug('initial 1d fit', initial)

    # attempt 'normal' fit along normal vector
    '''
    def f_sphere1(beta, x):
        bias = lmap(lambda x, n: x + beta[0]*n, initial[:3], norm)
        b = numpy.matrix(lmap(lambda a, b : a - b, x[:3], bias))
        m = list(numpy.array(b.transpose()))
        r0 = lmap(lambda y : beta[1] - vector.norm(y), m)
        return r0
    sphere1d_fit = FitLeastSq([0, initial[3]], f_sphere1, zpoints)
    if not sphere1d_fit or sphere1d_fit[1] < 0:
        print('FitLeastSq sphere1d failed!!!! ', len(points))
        return False
    sphere1d_fit = lmap(lambda x, n: x + sphere1d_fit[0]*n, initial[:3], norm) + [sphere1d_fit[1]]
    debug('sphere1 fit', sphere1d_fit, ComputeDeviation(points, sphere1d_fit))
    '''

    def f_new_sphere1(beta, x):
        bias = lmap(lambda x, n: x + beta[0]*n, initial[:3], norm)
        b = numpy.matrix(lmap(lambda a, b : a - b, x[:3], bias))
        m = list(numpy.array(b.transpose()))
        r0 = lmap(lambda y : beta[1] - vector.norm(y), m)
        g = list(numpy.array(numpy.matrix(x[3:]).transpose()))
        fac = 1 # weight deviation
        def dip(y, z):
            n = min(max(vector.dot(y, z)/vector.norm(y), -1), 1)
            return n
        r1 = lmap(lambda y, z : fac*beta[1]*(beta[2]-dip(y, z)), m, g)
        return r0 + r1
    new_sphere1d_fit = FitLeastSq([0, initial[3], 0], f_new_sphere1, zpoints, debug, 2)
    if not new_sphere1d_fit or new_sphere1d_fit[1] < 0 or abs(new_sphere1d_fit[2]) > 1:
        debug('FitLeastSq new_sphere1 failed!!!! ', len(points), new_sphere1d_fit)
        new_sphere1d_fit = current
    else:
        new_sphere1d_fit = lmap(lambda x, a: x + new_sphere1d_fit[0]*a, initial[:3], norm) + [new_sphere1d_fit[1], math.degrees(math.asin(new_sphere1d_fit[2]))]
    new_sphere1d_fit = [new_sphere1d_fit, ComputeDeviation(points, new_sphere1d_fit), 1]
        #print('new sphere1 fit', new_sphere1d_fit)

    if line_max_dev < 2:
        debug('line fit found, insufficient data %.1f %.1f' % (line_dev, line_max_dev))
        return False
    
    # 2d sphere fit across normal vector
    u = vector.cross(norm, [norm[1]-norm[2], norm[2]-norm[0], norm[0]-norm[1]])
    v = vector.cross(norm, u)
    u = vector.normalize(u)
    v = vector.normalize(v)

    # initial is the closest to guess on the uv plane containing current
    initial = vector.add(guess[:3], vector.project(vector.sub(current[:3], guess[:3]), norm))
    initial.append(current[3])
    #debug('initial 2d fit', initial)
    
    '''
    def f_sphere2(beta, x):
        bias = lmap(lambda x, a, b: x + beta[0]*a + beta[1]*b, initial[:3], u, v)
        b = numpy.matrix(lmap(lambda a, b : a - b, x[:3], bias))
        m = list(numpy.array(b.transpose()))
        r0 = lmap(lambda y : beta[2] - vector.norm(y), m)
        return r0
    sphere2d_fit = FitLeastSq([0, 0, initial[3]], f_sphere2, zpoints)
    if not sphere2d_fit or sphere2d_fit[2] < 0:
        print('FitLeastSq sphere2d failed!!!! ', len(points))
        new_sphere2d_fit = initial
    else:
        sphere2d_fit = lmap(lambda x, a, b: x + sphere2d_fit[0]*a + sphere2d_fit[1]*b, initial[:3], u, v) + [sphere2d_fit[2]]
    debug('sphere2 fit', sphere2d_fit, ComputeDeviation(points, sphere2d_fit))
    '''

    def f_new_sphere2(beta, x):
        bias = lmap(lambda x, a, b: x + beta[0]*a + beta[1]*b, initial[:3], u, v)
        b = numpy.matrix(lmap(lambda a, b : a - b, x[:3], bias))
        m = list(numpy.array(b.transpose()))
        r0 = lmap(lambda y : beta[2] - vector.norm(y), m)
        #r0 = lmap(lambda y : 1 - vector.norm(y)/beta[2], m)
        g = list(numpy.array(numpy.matrix(x[3:]).transpose()))
        fac = 1 # weight deviation
        def dip(y, z):
            n = min(max(vector.dot(y, z)/vector.norm(y), -1), 1)
            return n
        r1 = lmap(lambda y, z : fac*beta[2]*(beta[3]-dip(y, z)), m, g)
        return r0 + r1
    new_sphere2d_fit = FitLeastSq([0, 0, initial[3], 0], f_new_sphere2, zpoints, debug, 2)
    if not new_sphere2d_fit or new_sphere2d_fit[2] < 0 or abs(new_sphere2d_fit[3]) >= 1:
        debug('FitLeastSq sphere2 failed!!!! ', len(points), new_sphere2d_fit)
        return False
    new_sphere2d_fit = lmap(lambda x, a, b: x + new_sphere2d_fit[0]*a + new_sphere2d_fit[1]*b, initial[:3], u, v) + [new_sphere2d_fit[2], math.degrees(math.asin(new_sphere2d_fit[3]))]
    new_sphere2d_fit = [new_sphere2d_fit, ComputeDeviation(points, new_sphere2d_fit), 2]

    if plane_max_dev < 1.2:
        ang = math.degrees(math.asin(vector.norm(vector.cross(plane_fit[1], norm))))
        
        debug('plane fit found, 2D fit only', ang, plane_fit, plane_dev, plane_max_dev)
        if ang > 30:
            debug('angle of plane not aligned to normal: no 2d fit')
            new_sphere2d_fit = False

        return [new_sphere1d_fit, new_sphere2d_fit, False]

    # ok to use best guess for 3d fit
    initial = guess
    '''
    def f_sphere3(beta, x):
        bias = beta[:3]
        b = numpy.matrix(lmap(lambda a, b : a - b, x[:3], bias))
        m = list(numpy.array(b.transpose()))
        r0 = lmap(lambda y : beta[3] - vector.norm(y), m)
        return r0
    sphere3d_fit = FitLeastSq(initial[:4], f_sphere3, zpoints)
    if not sphere3d_fit or sphere3d_fit[3] < 0:
        print('FitLeastSq sphere failed!!!! ', len(points))
        return False
    debug('sphere3 fit', sphere3d_fit, ComputeDeviation(points, sphere3d_fit))
    '''
    def f_new_sphere3(beta, x):
        b = numpy.matrix(lmap(lambda a, b : a - b, x[:3], beta[:3]))
        m = list(numpy.array(b.transpose()))
        r0 = lmap(lambda y : beta[3] - vector.norm(y), m)
        #r0 = lmap(lambda y : 1 - vector.norm(y)/beta[3], m)
        g = list(numpy.array(numpy.matrix(x[3:]).transpose()))
        fac = 1 # weight deviation
        def dip(y, z):
            n = min(max(vector.dot(y, z)/vector.norm(y), -1), 1)
            return n
        r1 = lmap(lambda y, z : fac*beta[3]*(beta[4]-dip(y, z)), m, g)

        return r0 + r1
    new_sphere3d_fit = FitLeastSq(initial[:4] + [0], f_new_sphere3, zpoints, debug, 2)
    if not new_sphere3d_fit or new_sphere3d_fit[3] < 0 or abs(new_sphere3d_fit[4]) >= 1:
        debug('FitLeastSq sphere3 failed!!!! ', len(points))
        return False
    new_sphere3d_fit[4] = math.degrees(math.asin(new_sphere3d_fit[4]))
    new_sphere3d_fit = [new_sphere3d_fit, ComputeDeviation(points, new_sphere3d_fit), 3]
    #debug('new sphere3 fit', new_sphere3d_fit)
    
    return [new_sphere1d_fit, new_sphere2d_fit, new_sphere3d_fit]
예제 #42
0
파일: motion.py 프로젝트: ahmetech/breakout
 def isMoving(self):
     previous = vector.vector_mean(self.positions[:self.NCONTOURS])
     now = vector.vector_mean(self.positions[self.NCONTOURS:])
     dist = vector.norm(vector.vector_sub(previous, now))
     print 'dist: ', dist
     return dist > self.MOVING_DIST_THRESHOLD
예제 #43
0
def test_cl_int():
    """Generates random circle and line, computes the intersection,
       and verifies that the number of intersections and the 
       positions of the intersections are correct. 
       Returns True or False"""
    # 3 random points
    p1 = vector.randvec(2, 0.0, 10.0,1.0)
    p2 = vector.randvec(2, 0.0, 10.0,1.0)
    p3 = vector.randvec(2, 0.0, 10.0,1.0)
    # prevent div by zero / no line direction
    if tol_eq(vector.norm(p1-p2),0):
        p2 = p1 + p3 * 0.1
    # line (o,v): origin p1, direction p1-p2
    o = p1
    v = (p2 - p1) / vector.norm(p2 - p1)
    # cirlce (c, r): centered in p3, radius p3-p2 + rx
    c = p3
    r0 = vector.norm(p3-p2)
    # cases rx = 0, rx > 0, rx < 0
    case = random.choice([1,2,3])
    if case==1:
        r = r0      #should have one intersection (unles r0 = 0)
    elif case==2:
        r = random.random() * r0   # should have no ints (unless r0=0)
    elif case==3:
        r = r0 + random.random() * r0 # should have 2 ints (unless r0=0) 
    # do interesection 
    diag_print("problem:"+str(c)+","+str(r)+","+str(o)+","+str(v),"test_cl_int")
    sols = cl_int(c,r,o,v)
    diag_print("solutions:"+str(map(str, sols)),"test_cl_int")
    # distance from point on line closest to circle center
    l = vector.dot(c-o, v) / vector.norm(v)
    p = o + v * l / vector.norm(v)  
    d = vector.norm(p-c)
    diag_print("distance center to line="+str(d),"test_cl_int")
    # test number of intersections 
    if len(sols) == 0:
        if not tol_gt(d, r):
            diag_print("wrong number of solutions: 0", "test_cl_int")
            return False
    elif len(sols) == 1:
        if not tol_eq(d, r):
            diag_print("wrong number of solutions: 1", "test_cl_int")
            return False
    elif len(sols) == 2:
        if not tol_lt(d, r):
            diag_print("wrong number of solutions: 2", "test_cl_int")
            return False
    else:
            diag_print("wrong number of solutions: >2", "test_cl_int")

    # test coordinates of intersection 
    for s in sols:
        # s on line (o,v)
        if not is_colinear(s, o, o+v):
            diag_print("solution not on line", "test_cl_int")
            return False
        # s on circle c, r
        if not tol_eq(vector.norm(s-c), r):
            diag_print("solution not on circle", "test_cl_int")
            return False

    return True
예제 #44
0
 def isMoving(self):
     previous = vector.vector_mean( self.positions[:self.NCONTOURS])
     now = vector.vector_mean( self.positions[self.NCONTOURS:])
     dist = vector.norm(vector.vector_sub(previous, now)) 
     print 'dist: ', dist
     return dist > self.MOVING_DIST_THRESHOLD
예제 #45
0
    def IMURead(self):
        data = False

        while self.poller.poll(0):  # read all the data from the pipe
            data = self.imu_pipe.recv()

        if not data:
            if time.time() - self.last_imuread > 1 and self.loopfreq.value:
                print 'IMURead failed!'
                self.loopfreq.set(0)
                for name in self.SensorValues:
                    self.SensorValues[name].set(False)
                self.uptime.reset()
            return False

        if vector.norm(data['accel']) == 0:
            print 'vector n', data['accel']
            return False

        self.last_imuread = time.time()
        self.loopfreq.strobe()

        if not self.FirstTimeStamp:
            self.FirstTimeStamp = data['timestamp']

        data['timestamp'] -= self.FirstTimeStamp

        #data['accel_comp'] = quaternion.rotvecquat(vector.sub(data['accel'], down), self.alignmentQ.value)

        # apply alignment calibration
        gyro_q = quaternion.rotvecquat(data['gyro'], data['fusionQPose'])

        data['pitchrate'], data['rollrate'], data['headingrate'] = map(
            math.degrees, gyro_q)

        origfusionQPose = data['fusionQPose']
        aligned = quaternion.multiply(data['fusionQPose'],
                                      self.alignmentQ.value)
        data['fusionQPose'] = quaternion.normalize(
            aligned)  # floating point precision errors

        data['roll'], data['pitch'], data['heading'] = map(
            math.degrees, quaternion.toeuler(data['fusionQPose']))

        if data['heading'] < 0:
            data['heading'] += 360

        dt = data['timestamp'] - self.lasttimestamp
        self.lasttimestamp = data['timestamp']
        if dt > .02 and dt < .5:
            data['headingraterate'] = (data['headingrate'] -
                                       self.headingrate) / dt
        else:
            data['headingraterate'] = 0

        self.headingrate = data['headingrate']

        data['heel'] = self.heel = data['roll'] * .03 + self.heel * .97
        #data['roll'] -= data['heel']

        data['gyro'] = list(map(math.degrees, data['gyro']))
        data['gyrobias'] = list(map(math.degrees, data['gyrobias']))

        # lowpass heading and rate
        llp = self.heading_lowpass_constant.value
        data['heading_lowpass'] = heading_filter(
            llp, data['heading'], self.SensorValues['heading_lowpass'].value)

        llp = self.headingrate_lowpass_constant.value
        data['headingrate_lowpass'] = llp * data['headingrate'] + (
            1 - llp) * self.SensorValues['headingrate_lowpass'].value

        llp = self.headingraterate_lowpass_constant.value
        data['headingraterate_lowpass'] = llp * data['headingraterate'] + (
            1 - llp) * self.SensorValues['headingraterate_lowpass'].value

        # set sensors
        self.server.TimeStamp('imu', data['timestamp'])
        for name in self.SensorValues:
            self.SensorValues[name].set(data[name])

        compass, accel, down = False, False, False
        if not self.accel_calibration.locked.value:
            accel = list(data['accel'])
        if not self.compass_calibration.locked.value:
            down = quaternion.rotvecquat([0, 0, 1],
                                         quaternion.conjugate(origfusionQPose))
            compass = list(data['compass']) + down
        if accel or compass:
            self.auto_cal.AddPoint((accel, compass, down))

        self.uptime.update()

        # count down to alignment
        if self.alignmentCounter.value != self.last_alignmentCounter:
            self.alignmentPose = [0, 0, 0, 0]

        if self.alignmentCounter.value > 0:
            self.alignmentPose = list(
                map(lambda x, y: x + y, self.alignmentPose,
                    data['fusionQPose']))
            self.alignmentCounter.set(self.alignmentCounter.value - 1)

            if self.alignmentCounter.value == 0:
                self.alignmentPose = quaternion.normalize(self.alignmentPose)
                adown = quaternion.rotvecquat([0, 0, 1],
                                              quaternion.conjugate(
                                                  self.alignmentPose))
                alignment = []

                alignment = quaternion.vec2vec2quat([0, 0, 1], adown)
                alignment = quaternion.multiply(self.alignmentQ.value,
                                                alignment)

                if len(alignment):
                    self.update_alignment(alignment)

            self.last_alignmentCounter = self.alignmentCounter.value
        if self.heading_off.value != self.last_heading_off:
            self.update_alignment(self.alignmentQ.value)
            self.last_heading_off = self.heading_off.value

        result = self.auto_cal.UpdatedCalibration()

        if result:
            if result[0] == 'accel' and not self.accel_calibration.locked.value:
                #print '[boatimu] cal result', result[0]
                self.accel_calibration.sigmapoints.set(result[2])
                if result[1]:
                    self.accel_calibration.age.reset()
                    self.accel_calibration.set(result[1])
            elif result[
                    0] == 'compass' and not self.compass_calibration.locked.value:
                #print '[boatimu] cal result', result[0]
                self.compass_calibration.sigmapoints.set(result[2])
                if result[1]:
                    self.compass_calibration.age.reset()
                    self.compass_calibration.set(result[1])

        self.accel_calibration.age.update()
        self.compass_calibration.age.update()
        return data
예제 #46
0
    def __init__(self, camera_azimuth, camera_altitude, camera_distance,
                 camera_fov):
        self.camera_azimuth = camera_azimuth
        self.camera_altitude = camera_altitude
        self.camera_distance = camera_distance
        self.camera_fov = camera_fov

        near = -30
        far = -60
        fov = math.radians(camera_fov)
        ratio = 1.333
        lookat = numpy.array([0, 0, 0])

        #
        # Camera
        #

        camera = vector.norm(numpy.array([0, 0, 1])) * camera_distance

        alti = math.radians(-camera_altitude)
        c = math.cos(alti)
        s = math.sin(alti)
        cameraRotateAroundX = numpy.array([
            [1, 0, 0, 0],
            [0, c, -s, 0],
            [0, s, c, 0],
            [0, 0, 0, 1],
        ])

        azim = math.radians(camera_azimuth)
        c = math.cos(azim)
        s = math.sin(azim)
        cameraRotateAroundY = numpy.array([
            [c, 0, s, 0],
            [0, 1, 0, 0],
            [-s, 0, c, 0],
            [0, 0, 0, 1],
        ])

        self.cameraRotate = numpy.dot(cameraRotateAroundY, cameraRotateAroundX)
        self.camera = vector.affineTransform(camera, self.cameraRotate)
        #print "Camera", camera
        #print "Lookat", lookat

        #
        # Perspective transform
        #

        self.width = width = -2 * near * math.tan(fov / 2)
        self.height = height = width / ratio
        #print "Width", width
        #print "Height", height
        m11 = 2 * near / width
        m22 = 2 * near / height
        m33 = -(far + near) / (far - near)
        m34 = -2 * far * near / (far - near)
        self.perspectiveTransform = numpy.array([
            [m11, 0, 0, 0],
            [0, m22, 0, 0],
            [0, 0, m33, m34],
            [0, 0, -1, 0],
        ])
        #print perspectiveTransform

        #
        # Camera look transform
        #

        up = numpy.array([0, 1, 0])
        n = vector.norm(lookat - self.camera)
        u = vector.norm(numpy.cross(up, n))
        v = numpy.cross(n, u)
        ux, uy, uz = u
        vx, vy, vz = v
        nx, ny, nz = n
        self.cameraLookTransform = numpy.array([
            [ux, uy, uz, 0],
            [vx, vy, vz, 0],
            [nx, ny, nz, 0],
            [0, 0, 0, 1],
        ])
        #print cameraLookTransform

        #
        # Camera translation transform
        #

        tx, ty, tz = -self.camera
        self.cameraLocationTransform = numpy.array([
            [1, 0, 0, tx],
            [0, 1, 0, ty],
            [0, 0, 1, tz],
            [0, 0, 0, 1],
        ])
        #print cameraLocationTransform

        #
        # Final transform
        #

        self.transform = numpy.dot(
            numpy.dot(self.perspectiveTransform, self.cameraLookTransform),
            self.cameraLocationTransform)
예제 #47
0
def test_cl_int():
    """Generates random circle and line, computes the intersection,
       and verifies that the number of intersections and the 
       positions of the intersections are correct. 
       Returns True or False"""
    # 3 random points
    p1 = vector.randvec(2, 0.0, 10.0, 1.0)
    p2 = vector.randvec(2, 0.0, 10.0, 1.0)
    p3 = vector.randvec(2, 0.0, 10.0, 1.0)
    # prevent div by zero / no line direction
    if tol_eq(vector.norm(p1 - p2), 0):
        p2 = p1 + p3 * 0.1
    # line (o,v): origin p1, direction p1-p2
    o = p1
    v = (p2 - p1) / vector.norm(p2 - p1)
    # cirlce (c, r): centered in p3, radius p3-p2 + rx
    c = p3
    r0 = vector.norm(p3 - p2)
    # cases rx = 0, rx > 0, rx < 0
    case = random.choice([1, 2, 3])
    if case == 1:
        r = r0  #should have one intersection (unles r0 = 0)
    elif case == 2:
        r = random.random() * r0  # should have no ints (unless r0=0)
    elif case == 3:
        r = r0 + random.random() * r0  # should have 2 ints (unless r0=0)
    # do interesection
    diag_print(
        "problem:" + str(c) + "," + str(r) + "," + str(o) + "," + str(v),
        "test_cl_int")
    sols = cl_int(c, r, o, v)
    diag_print("solutions:" + str(map(str, sols)), "test_cl_int")
    # distance from point on line closest to circle center
    l = vector.dot(c - o, v) / vector.norm(v)
    p = o + v * l / vector.norm(v)
    d = vector.norm(p - c)
    diag_print("distance center to line=" + str(d), "test_cl_int")
    # test number of intersections
    if len(sols) == 0:
        if not tol_gt(d, r):
            diag_print("wrong number of solutions: 0", "test_cl_int")
            return False
    elif len(sols) == 1:
        if not tol_eq(d, r):
            diag_print("wrong number of solutions: 1", "test_cl_int")
            return False
    elif len(sols) == 2:
        if not tol_lt(d, r):
            diag_print("wrong number of solutions: 2", "test_cl_int")
            return False
    else:
        diag_print("wrong number of solutions: >2", "test_cl_int")

    # test coordinates of intersection
    for s in sols:
        # s on line (o,v)
        if not is_colinear(s, o, o + v):
            diag_print("solution not on line", "test_cl_int")
            return False
        # s on circle c, r
        if not tol_eq(vector.norm(s - c), r):
            diag_print("solution not on circle", "test_cl_int")
            return False

    return True
예제 #48
0
def imu_process(pipe, cal_pipe, accel_cal, compass_cal, gyrobias, period):
    if not RTIMU:
        while True:
            time.sleep(10)

    #print 'imu on', os.getpid()
    if os.system('sudo chrt -pf 99 %d 2>&1 > /dev/null' % os.getpid()):
        print('warning, failed to make imu process realtime')

    #os.system("sudo renice -10 %d" % os.getpid())
    SETTINGS_FILE = "RTIMULib"
    s = RTIMU.Settings(SETTINGS_FILE)
    s.FusionType = 1
    s.CompassCalValid = False

    s.CompassCalEllipsoidOffset = tuple(compass_cal[:3])
    s.CompassCalEllipsoidValid = True
    s.MPU925xAccelFsr = 0  # +- 2g
    s.MPU925xGyroFsr = 0  # +- 250 deg/s
    # compass noise by rate 10=.043, 20=.033, 40=.024, 80=.017, 100=.015
    rate = 100
    s.MPU925xGyroAccelSampleRate = rate
    s.MPU925xCompassSampleRate = rate

    s.AccelCalValid = True
    if accel_cal:
        s.AccelCalMin = tuple(map(lambda x: x - accel_cal[3], accel_cal[:3]))
        s.AccelCalMax = tuple(map(lambda x: x + accel_cal[3], accel_cal[:3]))
    else:
        s.AccelCalMin = (-1, -1, -1)
        s.AccelCalMax = (1, 1, 1)

    s.GyroBiasValid = True
    if gyrobias:
        s.GyroBias = tuple(map(math.radians, gyrobias))
    else:
        s.GyroBias = (0, 0, 0)

    s.KalmanRk, s.KalmanQ = .002, .001
    #    s.KalmanRk, s.KalmanQ = .0005, .001

    while True:
        print("Using settings file " + SETTINGS_FILE + ".ini")
        s.IMUType = 0  # always autodetect imu
        rtimu = RTIMU.RTIMU(s)
        if rtimu.IMUName() == 'Null IMU':
            print('no IMU detected... try again')
            time.sleep(1)
            continue

        print("IMU Name: " + rtimu.IMUName())

        if not rtimu.IMUInit():
            print("ERROR: IMU Init Failed, no inertial data available")
            time.sleep(1)
            continue

        # this is a good time to set any fusion parameters
        rtimu.setSlerpPower(.01)
        rtimu.setGyroEnable(True)
        rtimu.setAccelEnable(True)
        rtimu.setCompassEnable(True)

        poll_interval = rtimu.IMUGetPollInterval()
        time.sleep(.1)

        cal_poller = select.poll()
        cal_poller.register(cal_pipe, select.POLLIN)

        avggyro = [0, 0, 0]
        compass_calibration_updated = False

        while True:
            t0 = time.time()
            if not rtimu.IMURead():
                print('failed to read IMU!!!!!!!!!!!!!!')
                pipe.send(False)
                break  # reinitialize imu

            data = rtimu.getIMUData()
            data['accel.residuals'] = list(rtimu.getAccelResiduals())
            data['gyrobias'] = s.GyroBias
            #data['timestamp'] = t0 # imu timestamp is perfectly accurate

            if compass_calibration_updated:
                data['compass_calibration_updated'] = True
                compass_calibration_updated = False

            pipe.send(data, False)

            # see if gyro is out of range, sometimes the sensors read
            # very high gyro readings and the sensors need to be reset by software
            # this is probably a bug in the underlying driver with fifo misalignment
            d = .05 * period  # filter constant
            for i in range(3):  # filter gyro vector
                avggyro[i] = (1 - d) * avggyro[i] + d * data['gyro'][i]
            if vector.norm(avggyro) > .8:  # 55 degrees/s
                print('too high standing gyro bias, resetting sensors',
                      data['gyro'], avggyro)
                break
            # detects the problem even faster:
            if any(map(lambda x: abs(x) > 1000, data['compass'])):
                print('compass out of range, resetting', data['compass'])
                break

            if cal_poller.poll(0):
                r = cal_pipe.recv()

                #print('[imu process] new cal', new_cal)
                if r[0] == 'accel':
                    s.AccelCalValid = True
                    b, t = r[1][0][:3], r[1][0][3]
                    s.AccelCalMin = b[0] - t, b[1] - t, b[2] - t
                    s.AccelCalMax = b[0] + t, b[1] + t, b[2] + t
                elif r[0] == 'compass':
                    compass_calibration_updated = True
                    s.CompassCalEllipsoidValid = True
                    s.CompassCalEllipsoidOffset = tuple(r[1][0][:3])
                #rtimu.resetFusion()

            dt = time.time() - t0
            t = period - dt

            if t > 0 and t < period:
                time.sleep(t)
            else:
                print('imu process failed to keep time', t)
예제 #49
0
    def IMURead(self):
        data = False

        while self.poller.poll(0):  # read all the data from the pipe
            data = self.imu_pipe.recv()

        if not data:
            if time.time() - self.last_imuread > 1 and self.loopfreq.value:
                print('IMURead failed!')
                self.loopfreq.set(0)
                for name in self.SensorValues:
                    self.SensorValues[name].set(False)
                self.uptime.reset()
            return False

        if vector.norm(data['accel']) == 0:
            print('accel values invalid', data['accel'])
            return False

        t = time.time()
        self.timestamp.set(t - self.starttime)

        self.last_imuread = t
        self.loopfreq.strobe()

        # apply alignment calibration
        gyro_q = quaternion.rotvecquat(data['gyro'], data['fusionQPose'])

        data['pitchrate'], data['rollrate'], data['headingrate'] = map(
            math.degrees, gyro_q)
        origfusionQPose = data['fusionQPose']

        aligned = quaternion.multiply(data['fusionQPose'],
                                      self.alignmentQ.value)
        data['fusionQPose'] = quaternion.normalize(
            aligned)  # floating point precision errors

        data['roll'], data['pitch'], data['heading'] = map(
            math.degrees, quaternion.toeuler(data['fusionQPose']))

        if data['heading'] < 0:
            data['heading'] += 360

        dt = data['timestamp'] - self.lasttimestamp
        self.lasttimestamp = data['timestamp']
        if dt > .02 and dt < .5:
            data['headingraterate'] = (data['headingrate'] -
                                       self.headingrate) / dt
        else:
            data['headingraterate'] = 0

        self.headingrate = data['headingrate']

        data['heel'] = self.heel = data['roll'] * .03 + self.heel * .97
        #data['roll'] -= data['heel']

        data['gyro'] = list(map(math.degrees, data['gyro']))
        data['gyrobias'] = list(map(math.degrees, data['gyrobias']))

        # lowpass heading and rate
        llp = self.heading_lowpass_constant.value
        data['heading_lowpass'] = heading_filter(
            llp, data['heading'], self.SensorValues['heading_lowpass'].value)

        llp = self.headingrate_lowpass_constant.value
        data['headingrate_lowpass'] = llp * data['headingrate'] + (
            1 - llp) * self.SensorValues['headingrate_lowpass'].value

        llp = self.headingraterate_lowpass_constant.value
        data['headingraterate_lowpass'] = llp * data['headingraterate'] + (
            1 - llp) * self.SensorValues['headingraterate_lowpass'].value

        # set sensors
        for name in self.SensorValues:
            self.SensorValues[name].set(data[name])

        self.uptime.update()

        # count down to alignment
        if self.alignmentCounter.value != self.last_alignmentCounter:
            self.alignmentPose = [0, 0, 0, 0]

        if self.alignmentCounter.value > 0:
            self.alignmentPose = list(
                map(lambda x, y: x + y, self.alignmentPose,
                    data['fusionQPose']))
            self.alignmentCounter.set(self.alignmentCounter.value - 1)

            if self.alignmentCounter.value == 0:
                self.alignmentPose = quaternion.normalize(self.alignmentPose)
                adown = quaternion.rotvecquat([0, 0, 1],
                                              quaternion.conjugate(
                                                  self.alignmentPose))
                alignment = []
                alignment = quaternion.vec2vec2quat([0, 0, 1], adown)
                alignment = quaternion.multiply(self.alignmentQ.value,
                                                alignment)

                if len(alignment):
                    self.update_alignment(alignment)

            self.last_alignmentCounter = self.alignmentCounter.value

        # if alignment or heading offset changed:
        if self.heading_off.value != self.heading_off.last or self.alignmentQ.value != self.alignmentQ.last:
            self.update_alignment(self.alignmentQ.value)
            self.heading_off.last = self.heading_off.value
            self.alignmentQ.last = self.alignmentQ.value

        cal_data = {}
        if not self.accel_calibration.locked.value:
            cal_data['accel'] = list(data['accel'])
        if not self.compass_calibration.locked.value:
            cal_data['compass'] = list(data['compass'])
            cal_data['down'] = quaternion.rotvecquat(
                [0, 0, 1], quaternion.conjugate(origfusionQPose))

        if cal_data:
            self.auto_cal.cal_pipe.send(cal_data)

        self.accel_calibration.age.update()
        self.compass_calibration.age.update()
        return data
예제 #50
0
 def deg(y, z):
     n = min(max(vector.dot(y, z) / vector.norm(y), -1), 1)
     return math.degrees(math.asin(n))
예제 #51
0
    def read(self):
        data = self.IMUread()
        if not data:
            if time.monotonic(
            ) - self.last_imuread > 1 and self.frequency.value:
                print('IMURead failed!')
                self.frequency.set(False)
                for name in self.SensorValues:
                    self.SensorValues[name].set(False)
                self.uptime.reset()
            return False

        if vector.norm(data['accel']) == 0:
            print('accel values invalid', data['accel'])
            return False

        self.last_imuread = time.monotonic()
        self.frequency.strobe()

        # apply alignment calibration
        gyro_q = quaternion.rotvecquat(data['gyro'], data['fusionQPose'])

        data['pitchrate'], data['rollrate'], data['headingrate'] = map(
            math.degrees, gyro_q)

        aligned = quaternion.multiply(data['fusionQPose'],
                                      self.alignmentQ.value)
        aligned = quaternion.normalize(
            aligned)  # floating point precision errors

        data['roll'], data['pitch'], data['heading'] = map(
            math.degrees, quaternion.toeuler(aligned))

        if data['heading'] < 0:
            data['heading'] += 360

        dt = data['timestamp'] - self.lasttimestamp
        self.lasttimestamp = data['timestamp']
        if dt > .01 and dt < .2:
            data['headingraterate'] = (data['headingrate'] -
                                       self.headingrate) / dt
        else:
            data['headingraterate'] = 0

        self.headingrate = data['headingrate']

        data['heel'] = self.heel = data['roll'] * .03 + self.heel * .97
        #data['roll'] -= data['heel']

        data['gyro'] = list(map(math.degrees, data['gyro']))

        # lowpass heading and rate
        llp = self.heading_lowpass_constant.value
        data['heading_lowpass'] = heading_filter(
            llp, data['heading'], self.SensorValues['heading_lowpass'].value)

        llp = self.headingrate_lowpass_constant.value
        data['headingrate_lowpass'] = llp * data['headingrate'] + (
            1 - llp) * self.SensorValues['headingrate_lowpass'].value

        llp = self.headingraterate_lowpass_constant.value
        data['headingraterate_lowpass'] = llp * data['headingraterate'] + (
            1 - llp) * self.SensorValues['headingraterate_lowpass'].value

        # set sensors
        for name in self.SensorValues:
            self.SensorValues[name].set(data[name])

        self.uptime.update()

        # count down to alignment
        if self.alignmentCounter.value != self.last_alignmentCounter:
            self.alignmentPose = [0, 0, 0, 0]

        if self.alignmentCounter.value > 0:
            self.alignmentPose = list(
                map(lambda x, y: x + y, self.alignmentPose, aligned))
            self.alignmentCounter.set(self.alignmentCounter.value - 1)

            if self.alignmentCounter.value == 0:
                self.alignmentPose = quaternion.normalize(self.alignmentPose)
                adown = quaternion.rotvecquat([0, 0, 1],
                                              quaternion.conjugate(
                                                  self.alignmentPose))

                alignment = []
                alignment = quaternion.vec2vec2quat([0, 0, 1], adown)
                alignment = quaternion.multiply(self.alignmentQ.value,
                                                alignment)

                if len(alignment):
                    self.update_alignment(alignment)

            self.last_alignmentCounter = self.alignmentCounter.value

        # if alignment or heading offset changed:
        if self.heading_off.value != self.heading_off.last or \
           self.alignmentQ.value != self.alignmentQ.last:
            self.update_alignment(self.alignmentQ.value)
            self.heading_off.last = self.heading_off.value
            self.alignmentQ.last = self.alignmentQ.value

        if self.auto_cal.cal_pipe:
            #print('warning, cal pipe always sending despite locks')
            cal_data = {}
            #how to check this here??  if not 'imu.accel.calibration.locked'
            cal_data['accel'] = list(data['accel'])

            #how to check this here??  if not 'imu.compass.calibration.locked'
            cal_data['compass'] = list(data['compass'])
            cal_data['fusionQPose'] = list(data['fusionQPose'])

            if cal_data:
                #print('send', cal_data)
                self.auto_cal.cal_pipe.send(cal_data)

        return data
예제 #52
0
def normalised(v):
    n = vector.norm(v)
    if tol_eq(n, 0.0):
        return v
    else:
        return v / n