Пример #1
0
def loop():
    """
    Main loop, Gets blocks from pixy, analyzes target location,
    chooses action for robot and sends instruction to motors
    """
    global blocks, throttle, diffDrive, diffGain, bias, advance, turnError, currentTime, lastTime, objectDist, distError, panError, panError_prev, distError_prev
    currentTime = datetime.now()
    # If no new blocks, don't do anything
    while not pixy.pixy_blocks_are_new() and run_flag:
        pass
    count = pixy.pixy_get_blocks(BLOCK_BUFFER_SIZE, blocks)
    # If negative blocks, something went wrong
    if count < 0:
        print 'Error: pixy_get_blocks() [%d] ' % count
        pixy.pixy_error(count)
        sys.exit(1)
    # if more than one block
    # Check which the largest block's signature and either do target chasing or
    # line following
    if count > 0:
        lastTime = currentTime
        print lastTime

    #print block
    numBlocks = 0
    print "new loop!"	
    greenBlocks = []
    for idx in range(count):
        block_ = blocks[idx]
        #print block_.signature
        if block_.signature == 3 :
            greenBlocks.append(block_)
            #print "X: " + str(block_.x) + " Y: " + str(block_.y) + " width: " + str(block_.width) + " height: " + str(block_.height) + " area: " + str(block_.height*block_.width)
        
    # let's first get the biggest first
    max_area = 0
    area_idx = 0
    furthest_idx = 0
    furthest = 600
    gb_idx = 0
    averageX = 0
    for gb in greenBlocks:
         
        block_area = gb.height*gb.width
        if block_area > max_area:
            max_area = block_area
            area_idx = gb_idx 

        if gb.y < furthest :
            furthest_idx = gb_idx
            furthest = gb.y
        
        averageX = averageX + gb.x 
        gb_idx = gb_idx + 1  



    if gb_idx > 0 : # we don't have green blocks
            
            averageX = averageX / gb_idx

            #print gb_idx
            #print greenBlocks[area_idx].x
          
            furthest_block = greenBlocks[furthest_idx] 
            closest_block = greenBlocks[area_idx]

            singleObjTrack = 0 

            # we select which object to track
            target_block = closest_block 
        #    target_block = furthest_block
            if singleObjTrack == 1:
                panError = PIXY_X_CENTER - target_block.x
                objectDist = refSize1 / (2 * math.tan(math.radians(target_block.width * pix2ang_factor)))
            else :
                #panError = PIXY_X_CENTER - averageX
                LPError_x.calculate(PIXY_X_CENTER - averageX)
                panError = LPError_x.currentValue
                objectDist = refSize1 / (2 * math.tan(math.radians(target_block.width * pix2ang_factor)))
                pass
            throttle = 0.3
            diffDrive = 1.5* diffGain * abs(float(panError)) / PIXY_X_CENTER
            #diffDrive = 0.6    
            #distError = objectDist - targetDist
            #advance = driveGain * float(distError) / refDist
            advance = 1

            print "panError: " + str(panError) + " objectDist: " + str(objectDist) + " diffDrive: " + str(diffDrive)
            #print objectDist

            panLoop.update(panError)
            # Update pixy's pan position
            #pixy.pixy_rcs_set_position(PIXY_RCS_PAN_CHANNEL, panLoop.m_pos)

            # if Pixy sees nothing recognizable, don't move.
            time_difference = currentTime - lastTime
            if time_difference.total_seconds() >= timeout:
                throttle = 0.0
                diffDrive = 1

            print "throttle is " + str(throttle)

            # this is turning to left
            print "panLoop.m_pos: " + str(panLoop.m_pos)
            if panLoop.m_pos > PIXY_RCS_CENTER_POS:
                # should be still int32_t
                turnError = panLoop.m_pos - PIXY_RCS_CENTER_POS
                # <0 is turning left; currently only p-control is implemented
                bias = - float(turnError) / float(PIXY_RCS_CENTER_POS) * h_pgain
            # this is turning to right
            elif panLoop.m_pos < PIXY_RCS_CENTER_POS:
                # should be still int32_t
                turnError = PIXY_RCS_CENTER_POS - panLoop.m_pos
                # >0 is turning left; currently only p-control is implemented
                bias = float(turnError) / float(PIXY_RCS_CENTER_POS) * h_pgain
            
            elapsedTime = currentTime - startTime 
            if elapsedTime.secs > waiTime:
                drive()
            else :
                # we only adjust the beginning
                pixy.pixy_rcs_set_position(PIXY_RCS_PAN_CHANNEL, panLoop.m_pos)

    else: # no green blocks
        pass






 
    return run_flag
Пример #2
0
def loop():
    """
    Main loop, Gets blocks from pixy, analyzes target location,
    chooses action for robot and sends instruction to motors
    """
    global blocks, throttle, diffDrive, diffGain, bias, advance, turnError, currentTime, lastTime, objectDist, distError, panError, panError_prev, distError_prev
    currentTime = datetime.now()
    # If no new blocks, don't do anything
    while not pixy.pixy_blocks_are_new() and run_flag:
        pass
    count = pixy.pixy_get_blocks(BLOCK_BUFFER_SIZE, blocks)
    # If negative blocks, something went wrong
    if count < 0:
        print 'Error: pixy_get_blocks() [%d] ' % count
        pixy.pixy_error(count)
        sys.exit(1)
    # if more than one block
    # Check which the largest block's signature and either do target chasing or
    # line following
    if count > 0:
        lastTime = currentTime
        print lastTime

    #print block
    numBlocks = 0
    print "new loop!"	
    greenBlocks = []
    sideLane = []

    for idx in range(count):
        block_ = blocks[idx]
        #print block_.signature
        if block_.signature == 3 :
            greenBlocks.append(block_)
            #print "X: " + str(block_.x) + " Y: " + str(block_.y) + " width: " + str(block_.width) + " height: " + str(block_.height) + " area: " + str(block_.height*block_.width)

        elif block_.signature == 1 or block_.signature == 2:
            sideLane.append(block_)

    	max_area = 0
    	area_idx = 0  
    	
    if greenBlocks <> []:
        # let's first get the biggest first

		furthest_idx = 0
		furthest = 600
		gb_idx = 0
		averageX = 0
		for gb in greenBlocks:
		 
			block_area = gb.height*gb.width
			if block_area > max_area:
				max_area = block_area
				area_idx = gb_idx 

			if gb.y < furthest :
				furthest_idx = gb_idx
				furthest = gb.y
		
			averageX = averageX + gb.x 
			gb_idx = gb_idx + 1 
	
		averageX = averageX / gb_idx
		#averageX = averageX + greenBlocks[area_idx].x / (gb_idx+1) # average weighted (a bit) w/ closest block

  		print "green block n# " + str(gb_idx) + ", X pos is " +  str(greenBlocks[area_idx].x) + ", averageX is " + str(averageX)

		#furthest_block = greenBlocks[furthest_idx] 
		#closest_block = greenBlocks[area_idx]

    elif sideLane <> []:
		sl_idx = 0
		for sl in sideLane:
	    		sidelane_area = sl.height*sl.width
	    		if sidelane_area > max_area:
				max_area = sidelane_area
				area_idx = sl_idx 
	
		averageX = abs(319-sideLane[area_idx].x)
		closest_block = sideLane[area_idx]            
	
		print "side lane n# " + str(area_idx) + ", X pos is " +  str(sideLane[area_idx].x) + ", averageX is " + str(averageX)
		
    else :
    		averageX = 50
    		print "no blocks, averageX is " + str(averageX)
    singleObjTrack = 0 
    
    #target_block  = closest_block
    		averageX = 50
Пример #3
0
def loop():
    """
    Main loop, Gets blocks from pixy, analyzes target location,
    chooses action for robot and sends instruction to motors
    """
    global blocks, throttle, diffDrive, diffGain, bias, advance, turnError, currentTime, lastTime, objectDist, distError, panError_prev, distError_prev
    currentTime = datetime.now()
    # If no new blocks, don't do anything
    while not pixy.pixy_blocks_are_new() and run_flag:
        pass
    count = pixy.pixy_get_blocks(BLOCK_BUFFER_SIZE, blocks)
    # If negative blocks, something went wrong
    if count < 0:
        print 'Error: pixy_get_blocks() [%d] ' % count
        pixy.pixy_error(count)
        sys.exit(1)
    # if more than one block
    # Check which the largest block's signature and either do target chasing or
    # line following
    if count > 0:
        lastTime = currentTime
        # if the largest block is the object to pursue, then prioritize this behavior
        if blocks[0].signature == 1:
            panError = PIXY_X_CENTER - blocks[0].x
            objectDist = refSize1 / (
                2 * math.tan(math.radians(blocks[0].width * pix2ang_factor)))
            throttle = 0.5
            # amount of steering depends on how much deviation is there
            diffDrive = diffGain * abs(float(panError)) / PIXY_X_CENTER
            distError = objectDist - targetDist
            # this is in float format with sign indicating advancing or retreating
            advance = driveGain * float(distError) / refDist
        # if Pixy sees a guideline, perform line following algorithm
        elif blocks[0].signature == 2:
            panError = PIXY_X_CENTER - blocks[0].x
            throttle = 1.0
            diffDrive = 0.6
            # amount of steering depends on how much deviation is there
            # diffDrive = diffGain * abs(float(turnError)) / PIXY_X_CENTER
            # use full available throttle for charging forward
            advance = 1
        # if none of the blocks make sense, just pause
        # else:
        #    panError = 0
        #    throttle = 0.0
        #    diffDrive = 1
        panLoop.update(panError)
    # Update pixy's pan position
    pixy.pixy_rcs_set_position(PIXY_RCS_PAN_CHANNEL, panLoop.m_pos)

    # if Pixy sees nothing recognizable, don't move.
    time_difference = currentTime - lastTime
    if time_difference.total_seconds() >= timeout:
        throttle = 0.0
        diffDrive = 1

    # this is turning to left
    if panLoop.m_pos > PIXY_RCS_CENTER_POS:
        # should be still int32_t
        turnError = panLoop.m_pos - PIXY_RCS_CENTER_POS
        # <0 is turning left; currently only p-control is implemented
        bias = -float(turnError) / float(PIXY_RCS_CENTER_POS) * h_pgain
    # this is turning to right
    elif panLoop.m_pos < PIXY_RCS_CENTER_POS:
        # should be still int32_t
        turnError = PIXY_RCS_CENTER_POS - panLoop.m_pos
        # >0 is turning left; currently only p-control is implemented
        bias = float(turnError) / float(PIXY_RCS_CENTER_POS) * h_pgain
    drive()
    return run_flag
Пример #4
0
def loop():
    """
    Main loop, Gets blocks from pixy, analyzes target location,
    chooses action for robot and sends instruction to motors
    """
    global blocks, throttle, diffDrive, diffGain, bias, advance, turnError, currentTime, lastTime, objectDist, distError, panError, panError_prev, distError_prev
    currentTime = datetime.now()
    # If no new blocks, don't do anything
    while not pixy.pixy_blocks_are_new() and run_flag:
        pass
    count = pixy.pixy_get_blocks(BLOCK_BUFFER_SIZE, blocks)
    # If negative blocks, something went wrong
    if count < 0:
        print 'Error: pixy_get_blocks() [%d] ' % count
        pixy.pixy_error(count)
        sys.exit(1)
    # if more than one block
    # Check which the largest block's signature and either do target chasing or
    # line following
    if count > 0:
        lastTime = currentTime
        print lastTime

    #print block
    numBlocks = 0
    print "new loop!"
    greenBlocks = []
    for idx in range(count):
        block_ = blocks[idx]
        #print block_.signature
        if block_.signature == 3:
            greenBlocks.append(block_)
            #print "X: " + str(block_.x) + " Y: " + str(block_.y) + " width: " + str(block_.width) + " height: " + str(block_.height) + " area: " + str(block_.height*block_.width)

    # let's first get the biggest first
    max_area = 0
    area_idx = 0
    furthest_idx = 0
    furthest = 600
    gb_idx = 0
    averageX = 0
    for gb in greenBlocks:

        block_area = gb.height * gb.width
        if block_area > max_area:
            max_area = block_area
            area_idx = gb_idx

        if gb.y < furthest:
            furthest_idx = gb_idx
            furthest = gb.y

        averageX = averageX + gb.x
        gb_idx = gb_idx + 1

    if gb_idx > 0:  # we don't have green blocks

        averageX = averageX / gb_idx

        #print gb_idx
        #print greenBlocks[area_idx].x

        furthest_block = greenBlocks[furthest_idx]
        closest_block = greenBlocks[area_idx]

        singleObjTrack = 0

        # we select which object to track
        target_block = closest_block
        #    target_block = furthest_block
        if singleObjTrack == 1:
            panError = PIXY_X_CENTER - target_block.x
            objectDist = refSize1 / (2 * math.tan(
                math.radians(target_block.width * pix2ang_factor)))
        else:
            panErrorRaw = PIXY_X_CENTER - averageX
            LPError_x.calculate(PIXY_X_CENTER - averageX)

            panError = LPError_x.currentValue
            objectDist = refSize1 / (2 * math.tan(
                math.radians(target_block.width * pix2ang_factor)))
            Grad_x.calculate(panError)
            pass
        throttle = 0.3
        diffDrive = 1.5 * diffGain * abs(float(panError)) / PIXY_X_CENTER
        #diffDrive = 0.6
        #distError = objectDist - targetDist
        #advance = driveGain * float(distError) / refDist
        advance = 1

        print "panError: " + str(panError) + " objectDist: " + str(
            objectDist) + " diffDrive: " + str(diffDrive)
        #print objectDist

        panLoop.update(panErrorRaw)
        # Update pixy's pan position
        #pixy.pixy_rcs_set_position(PIXY_RCS_PAN_CHANNEL, panLoop.m_pos)

        # if Pixy sees nothing recognizable, don't move.
        time_difference = currentTime - lastTime
        if time_difference.total_seconds() >= timeout:
            throttle = 0.0
            diffDrive = 1

        print "throttle is " + str(throttle)

        drive_original = False

        elapsedTime = currentTime - startTime
        if elapsedTime.seconds > waitTime:

            advance = 1
            if drive_original == True:
                # this is turning to left
                # print "panLoop.m_pos: " + str(panLoop.m_pos)
                if panLoop.m_pos > PIXY_RCS_CENTER_POS:
                    # should be still int32_t
                    turnError = panLoop.m_pos - PIXY_RCS_CENTER_POS
                    # <0 is turning left; currently only p-control is implemented
                    bias = -float(turnError) / float(
                        PIXY_RCS_CENTER_POS) * h_pgain
                # this is turning to right
                elif panLoop.m_pos < PIXY_RCS_CENTER_POS:
                    # should be still int32_t
                    turnError = PIXY_RCS_CENTER_POS - panLoop.m_pos
                    # >0 is turning left; currently only p-control is implemented
                    bias = float(turnError) / float(
                        PIXY_RCS_CENTER_POS) * h_pgain
                drive()
            else:  # we use our new way

                turnError = Grad_x.uOut
                h_pgain = 1  # for now we don't do anything
                bias = float(turnError) * h_pgain
                drive_new()
        else:
            # we only adjust the beginning
            advance = 0
            pixy.pixy_rcs_set_position(PIXY_RCS_PAN_CHANNEL, panLoop.m_pos)

            drive()
            drive_new()

    else:  # no green blocks
        pass

    return run_flag
Пример #5
0
def loop():
    """
    Main loop, Gets blocks from pixy, analyzes target location,
    chooses action for robot and sends instruction to motors
    """
    global blocks, throttle, diffDrive, diffGain, bias, advance, turnError, currentTime, lastTime, objectDist, distError, panError_prev, distError_prev
    currentTime = datetime.now()
    # If no new blocks, don't do anything
    while not pixy.pixy_blocks_are_new() and run_flag:
        pass
    count = pixy.pixy_get_blocks(BLOCK_BUFFER_SIZE, blocks)
    # If negative blocks, something went wrong
    if count < 0:
        print 'Error: pixy_get_blocks() [%d] ' % count
        pixy.pixy_error(count)
        sys.exit(1)
    # if more than one block
    # Check which the largest block's signature and either do target chasing or
    # line following
    if count > 0:
        lastTime = currentTime
        # if the largest block is the object to pursue, then prioritize this behavior
        if blocks[0].signature == 1:
            panError = PIXY_X_CENTER - blocks[0].x
            objectDist = refSize1 / (2 * math.tan(math.radians(blocks[0].width * pix2ang_factor)))
            throttle = 0.5
            # amount of steering depends on how much deviation is there
            diffDrive = diffGain * abs(float(panError)) / PIXY_X_CENTER
            distError = objectDist - targetDist
            # this is in float format with sign indicating advancing or retreating
            advance = driveGain * float(distError) / refDist
        # if Pixy sees a guideline, perform line following algorithm
        elif blocks[0].signature == 2:
            panError = PIXY_X_CENTER-blocks[0].x
            throttle = 1.0
            diffDrive = 0.6
            # amount of steering depends on how much deviation is there
            # diffDrive = diffGain * abs(float(turnError)) / PIXY_X_CENTER
            # use full available throttle for charging forward
            advance = 1            
        # if none of the blocks make sense, just pause
        # else:
        #    panError = 0
        #    throttle = 0.0
        #    diffDrive = 1
        panLoop.update(panError)
    # Update pixy's pan position
    pixy.pixy_rcs_set_position(PIXY_RCS_PAN_CHANNEL, panLoop.m_pos)

    # if Pixy sees nothing recognizable, don't move.
    time_difference = currentTime - lastTime
    if time_difference.total_seconds() >= timeout:
        throttle = 0.0
        diffDrive = 1

    # this is turning to left
    if panLoop.m_pos > PIXY_RCS_CENTER_POS:
        # should be still int32_t
        turnError = panLoop.m_pos - PIXY_RCS_CENTER_POS
        # <0 is turning left; currently only p-control is implemented
        bias = - float(turnError) / float(PIXY_RCS_CENTER_POS) * h_pgain
    # this is turning to right
    elif panLoop.m_pos < PIXY_RCS_CENTER_POS:
        # should be still int32_t
        turnError = PIXY_RCS_CENTER_POS - panLoop.m_pos
        # >0 is turning left; currently only p-control is implemented
        bias = float(turnError) / float(PIXY_RCS_CENTER_POS) * h_pgain
    drive_rr()
    return run_flag
Пример #6
0
def loop():
    """
    Main loop, Gets blocks from pixy, analyzes target location,
    chooses action for robot and sends instruction to motors
    """
    global startTime, throttle, diffDrive, diffGain, bias, advance, turnError, currentTime, lastTime, objectDist, distError, panError_prev, distError_prev, firstPass, pid_bias, last_turn

    currentTime = datetime.now()
    # If no new blocks, don't do anything
    while not pixy.pixy_blocks_are_new() and run_flag:
        pass

    if firstPass:
        say("Here goes")
        startTime = time.time()
        firstPass = False

    scene.get_frame()
    if scene.blocksSeen():
        lastTime = currentTime

    if finale:
        refuseToPlay()
        return False

    p = scene.panError
    if p < 0:
        p = -p
    incr = p / 300.0
    #print "panError: %f, incr: %f" % (scene.panError, incr)
    #if incr > 0.65:
    #    incr = 0.65
    throttle = initThrottle  # - incr / 1.5
    diffDrive = diffDriveStraight + incr

    # amount of steering depends on how much deviation is there
    #diffDrive = diffGain * abs(float(turnError)) / PIXY_X_CENTER
    # use full available throttle for charging forward
    advance = 1

    panLoop.update(scene.panError)

    # Update pixy's pan position
    pixy.pixy_rcs_set_position(PIXY_RCS_PAN_CHANNEL, panLoop.m_pos)

    # if Pixy sees nothing recognizable, don't move.
    # time_difference = currentTime - lastTime
    if not scene.seeCenter():  #time_difference.total_seconds() >= timeout:
        print "Stopping since see nothing"
        throttle = 0.0
        diffDrive = 1

    turn = 0

    # this is turning to left
    if panLoop.m_pos > PIXY_RCS_CENTER_POS:
        # should be still int32_t
        turnError = panLoop.m_pos - PIXY_RCS_CENTER_POS
        # <0 is turning left; currently only p-control is implemented
        turn = float(turnError) / float(PIXY_RCS_CENTER_POS)

    # this is turning to right
    elif panLoop.m_pos < PIXY_RCS_CENTER_POS:
        # should be still int32_t
        turnError = PIXY_RCS_CENTER_POS - panLoop.m_pos
        # >0 is turning left; currently only p-control is implemented
        turn = -float(turnError) / float(PIXY_RCS_CENTER_POS)

    pid.setPoint(0)
    pid_bias = pid.update(turn)
    #print "PID controller: SP=%2.2f PV=%2.2f -> OP=%2.2f" % (0, turn, pid_bias)
    last_turn = turn
    bias = pid_bias  # use PID controller on turn bias
    # TODO: parameterize drive()

    if bias < -0.3:
        say("Going left")
    if bias > 0.3:
        say("Going right")

    drive()
    return run_flag
Пример #7
0
def loop():
        global blocks, throttle, diffGain, bias, currentTime, lastTime
	# TODO python equivilant?
	currentTime = datetime.now()
	while not pixy.pixy_blocks_are_new() and run_flag:
		pass
	count = pixy.pixy_get_blocks(BLOCK_BUFFER_SIZE, blocks)
	if count < 0:
              print 'Error: pixy_get_blocks() [%d] ' % count
              pixy.pixy_error(count)
              sys.exit(1)
	if count > 0:
                lastTime = currentTime
		# if the largest block is the object to pursue, then prioritize this behavior
		if (blocks[0].signature == 1):
			panError = PIXY_X_CENTER - blocks[0].x
			tiltError = blocks[0].y - PIXY_Y_CENTER
			# the target is far and we must advance
			if (blocks[0].width < targetSize):
				# charge forward
				throttle = 100  # charge forward
				distError = targetSize - blocks[0].width
				# this is in float format
				diffGain = 1 - driveGain * float(distError) / targetSize

			# the target is too close and we must back off
			elif (blocks[0].width > targetSize):
				# retreat
				throttle = -100
				distError = blocks[0].width - targetSize
				# this is in float format
				diffGain = 1 - float(distError) / targetSize

		# this is line following algorithm
		elif (blocks[0].signature == 2):
			panError = PIXY_X_CENTER-blocks[0].x
			tiltError = blocks[0].y-PIXY_Y_CENTER
			# charge forward
			throttle = 100
			diffGain = 0.3
		# if none of the blocks make sense, just pause
		else:
			panError = 0
			tiltError = 0
			throttle = 0
			diffGain = 1

		panLoop.update(panError)
		tiltLoop.update(tiltError)

	
	set_position_result = pixy.pixy_rcs_set_position(PIXY_RCS_PAN_CHANNEL, panLoop.m_pos)
	set_position_result = pixy.pixy_rcs_set_position(PIXY_RCS_TILT_CHANNEL, tiltLoop.m_pos)	

    # TODO implement this?
	# if Pixy sees nothing recognizable, don't move.
	time_difference = currentTime - lastTime
	if (time_difference.total_seconds() >= timeout) :
                print time_difference.total_seconds(), timeout
		throttle = 0
		diffGain = 1


	# this is turning to left
	if (panLoop.m_pos > PIXY_RCS_CENTER_POS) : 
		# should be still int32_t
		turnError = panLoop.m_pos - PIXY_RCS_CENTER_POS 
		# <0.5 is turning left 
		bias = - float(turnError) / float(PIXY_RCS_CENTER_POS) * h_pgain
	# this is turning to right
	elif (panLoop.m_pos < PIXY_RCS_CENTER_POS):
		# should be still int32_t
		turnError = PIXY_RCS_CENTER_POS - panLoop.m_pos 
		# <0.5 is turning left 
		bias = float(turnError) / float(PIXY_RCS_CENTER_POS) * h_pgain
	drive()
	return run_flag