Example #1
0
def setup():
    """
    One time setup. Inialize pixy and set sigint handler
    """
    pixy_init_status = pixy.pixy_init()
    if pixy_init_status != 0:
        print 'Error: pixy_init() [%d] ' % pixy_init_status
        pixy.pixy_error(pixy_init_status)
        return
    else:
        print "Pixy setup OK"
    signal.signal(signal.SIGINT, handle_SIGINT)
    pixy.pixy_cam_set_brightness(BRIGHTNESS)
    pixy.pixy_rcs_set_position(PIXY_RCS_PAN_CHANNEL, PIXY_RCS_CENTER_POS)

    if chatty:
        sayNow("I may not be the fastest but I have style")
        #say("SLEEP 2")
        time.sleep(2)
Example #2
0
        panError = PIXY_X_CENTER - averageX
        #objectDist = refSize1 / (2 * math.tan(math.radians(target_block.width * pix2ang_factor)))
        pass
    throttle = 0.5
    #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
Example #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, 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
Example #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_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
Example #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, 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
Example #6
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
Example #7
0
def hailmary(block_count):
    global throttle, diffDrive, diffGain, bias, advance, turnError, currentTime, lastTime, objectDist, distError, panError_prev, distError_prev
    if len(block_count) == 0:
        print "can't do hailmary with no blocks"
        return

    print "Attempting to hail Mary with %d block history" % len(block_count)
    leftTotal = 0.0
    rightTotal = 0.0
    for (left, right) in block_count:
        leftTotal += left
        rightTotal += right
    avgLeft = leftTotal / len(block_count)
    avgRight = rightTotal / len(block_count)
    print "Past %d frames had avg red blocks on (left=%d, right=%d)" % (
        AVG_N, avgLeft, avgRight)
    # Turn towards the preponderance of red blocks
    lastTime = currentTime
    if avgLeft > avgRight:
        print "Executing blind left turn"
        bias = -1
    elif avgRight > avgLeft:
        print "Executing blind right turn"
        bias = 1
    else:
        bias = 0
    if bias != 0:
        # Slow forward turn
        advance = 1
        throttle = 0.5
        diffDrive = 1
        # Reset pixy's head
        pixy.pixy_rcs_set_position(PIXY_RCS_PAN_CHANNEL, PIXY_RCS_CENTER_POS)
        normalDrive = False
    #If hailmary didn't work, hold on to your rosary beads, we're going hunting!
    else:
        # Need some kind of hunting behavior here
        #This situation usally arises when we're on a curve in one direction and want to sharply turn in the other direction
        #pan the camera until we find a red block, then go straight toward it.
        print "Execute search and destroy"
        i = 0
        noRedBlocks = True
        advance = -1  #if we can't find it, retreat
        while (noRedBlocks == True and i <= PIXY_RCS_MAX_POS):
            #while redblock not found
            #pan for red block
            print "Panning for red block. i:%d" % (i)
            pixy.pixy_rcs_set_position(PIXY_RCS_PAN_CHANNEL, i)
            count = pixy.pixy_get_blocks(BLOCK_BUFFER_SIZE, blocks)
            largestBlock = blocks[0]
            #code stolen from earlier in file, maybe turn it into a function?
            if largestBlock.signature == 2:
                noRedBlocks = False
                panError = PIXY_X_CENTER - blocks[0].x
                p = panError / 40.0
                if p < 0:
                    p = -p
                if p > 0.8:
                    p = 0.8
                throttle = 0.9 - p
                diffDrive = 0.6
                print "p: %f, panError: %d, turnError: %d" % (p, panError,
                                                              turnError)
                advance = 1
            i = i + 10
Example #8
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
Example #9
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