Example #1
0
    def testCoulombForce(self):
        RC = -1
        OC = -1
        GC = 1
        r = [3,4]
        f = Util.coulombForce(r, OC, RC)

        self.assertEquals(True, f[0] < 0 and f[1] < 0)
        f = Util.coulombForce(r, GC, RC)
        self.assertEquals(True, f[0] > 0 and f[1] > 0)
Example #2
0
def callback(scan,odom):
    # the odometry parameter should be global
    global globalOdom
    global vx, spinning, moving, theta, Pd, Ld
    globalOdom = odom

    # make a new twist message
    command = Twist()

    # Fill in the fields.  Field values are unspecified 
    # until they are actually assigned. The Twist message 
    # holds linear and angular velocities.
    command.linear.x = 0.0
    command.linear.y = 0.0
    command.linear.z = 0.0
    command.angular.x = 0.0
    command.angular.y = 0.0
    command.angular.z = 0.0
    
    

    #get goal x and y locations from the launch file
    goalX = rospy.get_param('lab2/goalX',0.0)
    goalY = rospy.get_param('lab2/goalY',0.0)
    
    # find current (x,y) position of robot based on odometry
    currentX = globalOdom.pose.pose.position.x
    currentY = globalOdom.pose.pose.position.y
    if goalX != currentX and goalY != currentY:

        # find current orientation of robot based on odometry (quaternion coordinates)
        xOr = globalOdom.pose.pose.orientation.x
        yOr = globalOdom.pose.pose.orientation.y
        zOr = globalOdom.pose.pose.orientation.z
        wOr = globalOdom.pose.pose.orientation.w

        # find orientation of robot (Euler coordinates)
        (roll, pitch, yaw) = euler_from_quaternion([xOr, yOr, zOr, wOr])

        # find currentAngle of robot (equivalent to yaw)
        # now that you have yaw, the robot's pose is completely defined by (currentX, currentY, currentAngle)
        currentAngle = yaw

        # find laser scanner properties (min scan angle, max scan angle, scan angle increment)
        maxAngle = scan.angle_max
        minAngle = scan.angle_min
        angleIncrement = scan.angle_increment

        # find current laser angle, max scan length, distance array for all scans, and number of laser scans
        currentLaserTheta = minAngle
        maxScanLength = scan.range_max 
        distanceArray = scan.ranges
        numScans = len(distanceArray)
        
       
        # the code below (currently commented) shows how 
        # you can print variables to the terminal (may 
        # be useful for debugging)
        #print 'x: {0}'.format(currentX)
        #print 'y: {0}'.format(currentY)
        #print 'theta: {0}'.format(currentAngle)
        if not spinning and not moving:
        # for each laser scan
            fResult = [0,0]
            for curScan in range(0, numScans):
                d = distanceArray[curScan]
                if d != 30:
                    r = Util.cartFromPolar(d, currentLaserTheta)
                    globR = Util.rotZTheta(r, -currentAngle)
                    f = Util.coulombForce(globR, 
                        OBSTACLE_CHARGE * Util.scanAngleMod(currentLaserTheta), 
                        ROBOT_CHARGE)
                    fResult[0] += f[0]
                    fResult[1] += f[1]
                currentLaserTheta += angleIncrement

                

        	goal = [goalX-currentX , goalY-currentY]
            mGoal = math.pow(math.pow(goal[0],2) + math.pow(goal[1],2),0.5)
            unitGoal = [goal[0]/mGoal, goal[1]/mGoal]
            goalForce = Util.coulombForce(goal, GOAL_CHARGE, ROBOT_CHARGE)
            fResult[0] += goalForce[0]
            fResult[1] += goalForce[1]
            localF = Util.rotZTheta(fResult, currentAngle)
            m, theta = Util.polarFromCart(localF)
            

            print 'Force {}'.format(fResult)
            print 'U {}'.format(command.linear.x)
            global vx, vy, u, omega
            vx += fResult[0]*DT
            vy += fResult[1]*DT
            print "location: ({}, {})".format(currentX, currentY)
            print "Angle: {}".format(currentAngle)
            print "Goal: ({}, {})".format(goalX, goalY)
            print "GoalVector: {}".format(goal)
            print "ax: {}, ay: {}".format(fResult[0], fResult[1])
            print "vx: {}, vy: {}".format(vx, vy)
            Pd = [vx*DT, vy*DT]
            Ld = [currentX+Pd[0], currentY+Pd[1]]
            print "Desired Point: {} ".format(Pd)

            u, omega = Util.unicycleTracking(Pd, u, omega, currentAngle)
            if abs(currentAngle - theta) > .1:
                command.angular.z = omega
                spinning = True
            else:
                command.linear.x = u
            
        else:
            u, omega = Util.unicycleTracking(Pd, u, omega, currentAngle)
            if abs(currentAngle - theta) > .1:
                command.angular.z = omega/abs(omega)
                spinning = True
            elif abs(currentX - Ld[0]) < 0.1 and abs(currentY - Ld[1])< 0.1:
                print 'u: {}'.format(u)
                print 'location: ({}, {})'.format(currentX, currentY)
                command.linear.x = u/abs(u)
                spinning = False
                moving = True
            else:
                spinning = False
                moving = False
    else:
        pass
    pub.publish(command)