Esempio n. 1
0
def saGoToTargetFacingHeading(targetX, targetY, targetH, \
        maxSpeed = Action.MAX_FORWARD, maxTurn = Action.MAX_TURN):

    # Variables relative to self localisation.
    selfPos = Global.selfLoc.getPos()
    selfH = Global.selfLoc.getHeading()
    cosSelf = math.cos(math.radians(selfH))
    sinSelf = math.sin(math.radians(selfH))

    relX = targetX - selfPos[0]
    relY = targetY - selfPos[1]
    relH = hMath.normalizeAngle_180(targetH - selfH)
    # now take into account that as we turn, the position of our head will change
    relX += Constant.DOG_LENGTH / 2.0 * (cosSelf -
                                         math.cos(math.radians(targetH)))
    relY += Constant.DOG_LENGTH / 2.0 * (sinSelf -
                                         math.sin(math.radians(targetH)))
    relD = hMath.getLength((relX, relY))

    # Calculate approximate coordinates of all the dog's legs
    legs = []
    for legNum in range(4):
        legPos = list(selfPos)

        if legNum >= 2:
            legPos[0] = legPos[0] - DOG_RECT_LENGTH * cosSelf
            legPos[1] = legPos[1] - DOG_RECT_LENGTH * sinSelf

        if (legNum % 2) == 0:
            legPos[0] = legPos[0] - DOG_RECT_WIDTH * sinSelf
            legPos[1] = legPos[1] + DOG_RECT_WIDTH * cosSelf
        else:
            legPos[0] = legPos[0] + DOG_RECT_WIDTH * sinSelf
            legPos[1] = legPos[1] - DOG_RECT_WIDTH * cosSelf

        legs.append(tuple(legPos))

    # If a leg coordinate lies within the rear wall, clip the Y movement
    clipMove = False
    for legPos in legs:
        if abs(legPos[0] - Constant.FIELD_WIDTH / 2) > Constant.GOAL_WIDTH and\
            legPos[1] < 2:
            clipMove = True

    if clipMove and (relY < 0):
        relY = 0

    if relX == 0 and relY == 0:
        #on the dog, math.atan2(0,0) give "Value Error: math domain error"
        relTheta = 0
    else:
        relTheta = hMath.normalizeAngle_180(
            hMath.RAD2DEG(math.atan2(relY, relX)) - selfH)

    forward = hMath.CLIP(relD, maxSpeed) * math.cos(hMath.DEG2RAD(relTheta))
    left = hMath.CLIP(relD, maxSpeed) * math.sin(hMath.DEG2RAD(relTheta))
    turnCCW = hMath.CLIP(relH, maxTurn)

    Action.walk(forward, left, turnCCW, minorWalkType=Action.SkeFastForwardMWT)
Esempio n. 2
0
def SmartSetBeacon(panLimit=90, distLimit=550):
    global localiseBeacon

    # Get shared variables from elsewhere.
    selfLoc = Global.selfLoc
    cov = VisionLink.getGPSSelfCovariance()

    # Calculate the direction of the larger axis of the self covariance
    b = -(cov[0][0] + cov[1][1])
    c = cov[0][0] * cov[1][1] - cov[1][0] * cov[1][0]
    det = b * b - 4 * c

    if (det < 0.00001):
        sol = -b / 2
    else:
        sol = (-b + math.sqrt(det)) / 2

    if abs(cov[0][0] - sol) < 0.01 and cov[0][1] < 0.01:
        # If self position variance is circular, all beacons are equally good
        # to localise off, and so choose the one closest to current heading.
        if abs(cov[1][1] - sol) < 0.01:
            head = selfLoc.getHeading()
        else:
            head = hMath.RAD2DEG(math.atan2(-cov[1][0], cov[1][1] - sol))
    else:
        head = hMath.RAD2DEG(math.atan2(sol - cov[0][0], cov[0][1]))

    # Find the beacon that is closest to the variance direction.
    beaconPos = VisionLink.getGPSCoordArray()
    curCompHead = 360
    localiseBeacon = 0

    for beacon in CHECK_BEACONS:
        relPos = map(lambda b, s: b - s, beaconPos[beacon], selfLoc.getPos())
        beaconHead = hMath.RAD2DEG(math.atan2(relPos[1], relPos[0]))
        beaconDist = hMath.getLength(relPos)
        localHead = hMath.normalizeAngle_180(beaconHead - selfLoc.getHeading())

        if abs(localHead) < panLimit and beaconDist < distLimit:
            compHead = abs(hMath.normalizeAngle_180(head - beaconHead))
            if compHead > 90:
                compHead = 180 - compHead

            if compHead < curCompHead:
                curCompHead = compHead
                localiseBeacon = beacon
Esempio n. 3
0
def saGoToTargetFacingHeading(targetX, targetY, targetH, \
                maxSpeed = Action.MAX_FORWARD, maxTurn = Action.MAX_TURN):

    # ariables relative to self localisation.
    selfX = Global.selfLoc.getX()
    selfY = Global.selfLoc.getY()
    selfH = Global.selfLoc.getHeading()
    relX = targetX - selfX
    relY = targetY - selfY
    relH = hMath.normalizeAngle_180(targetH - selfH)
    relX            += Constant.DOG_LENGTH/2.0/10.0*(math.cos(math.radians(selfH)) \
                            - math.cos(math.radians(targetH)))
    relY            += Constant.DOG_LENGTH/2.0/10.0*(math.sin(math.radians(selfH)) \
                            - math.sin(math.radians(targetH)))
    relD = hMath.getLength((relX, relY))
    distanceSquared = hMath.getDistSquaredBetween(targetX, targetY, selfX,
                                                  selfY)
    inCircle = distanceSquared <= hMath.SQUARE(40)
    faceH = hMath.getHeadingToFaceAt(Global.selfLoc, targetX, targetY)

    ##~     print "faceH: ", faceH

    if not inCircle:
        if abs(faceH) >= 30:
            Action.walk(0, 0, faceH)
        else:
            #if sStealthDog.stealthDog(True):
            #    hFWHead.compulsoryAction = hFWHead.mustSeeBall
            #    hTrack.trackVisualBall()
            #    return
            Action.walk(maxSpeed, 0, hMath.CLIP(faceH / 1.5, maxTurn))

    else:
        if relX == 0 and relY == 0:
            # On the dog, math.atan2(0,0) give "Value Error: math domain error".
            relTheta = 0
        else:
            relTheta = hMath.normalizeAngle_180(
                hMath.RAD2DEG(math.atan2(relY, relX)) - selfH)

        forward = hMath.CLIP(relD, maxSpeed) * math.cos(
            hMath.DEG2RAD(relTheta))
        left = hMath.CLIP(relD, maxSpeed) * math.sin(hMath.DEG2RAD(relTheta))
        turnCCW = hMath.CLIP(relH, maxTurn)
        Action.walk(forward, left, turnCCW)
Esempio n. 4
0
def AlternateSetBeacon(panLimit=90, distLimit=550):
    global localiseBeacon, lastBeacon

    selfLoc = Global.selfLoc
    beaconPos = getBeaconCoords()
    curCompHead = panLimit
    localiseBeacon = None

    for beacon in beaconPos:
        relPos = map(lambda b, s: b - s, beacon, selfLoc.getPos())
        beaconHead = hMath.RAD2DEG(math.atan2(relPos[1], relPos[0]))
        beaconDist = hMath.getLength(relPos)
        localHead = hMath.normalizeAngle_180(beaconHead - selfLoc.getHeading())

        if abs(localHead) < curCompHead and beaconDist < distLimit:
            curCompHead = localHead
            localiseBeacon = beacon

    lastBeacon = localiseBeacon
Esempio n. 5
0
def saGoToTarget(targetX, targetY, maxSpeed=None, maxTurn=None):

    if maxSpeed == None:
        maxSpeed = Action.MAX_FORWARD
    if maxTurn == None:
        maxTurn = Action.MAX_TURN

    selfPos = Global.selfLoc.getPos()
    selfH = Global.selfLoc.getHeading()
    relX = targetX - selfPos[0]
    relY = targetY - selfPos[1]
    relD = hMath.getLength((relX, relY))

    if relX == 0 and relY == 0:
        relH = 0
    else:
        relH = hMath.normalizeAngle_180(
            hMath.RAD2DEG(math.atan2(relY, relX)) - selfH)

    forward = 0
    left = 0
    turnccw = 0
    if relD < CLOSE_WALK_RANGE and abs(relH) > 50:
        forward = relY
        left = relX
        turnccw = relH * 0.8
#        print "close walk and turn",relY,left,turnccw
    else:
        if abs(relH) > 80:  # stop and turn
            turnccw = relH * 0.8
        elif abs(relH) > 25:  # walk and turn
            turnccw = relH * 0.8
            forward = hMath.CLIP(relD, maxSpeed) * math.cos(
                hMath.DEG2RAD(relH))
#            print "walk and turn",forward, 0, turnccw
        else:  # ellipticalwalk and turn
            turnccw = hMath.CLIP(relH * 0.8, 25)
            forward = hMath.CLIP(relD, maxSpeed) * math.cos(
                hMath.DEG2RAD(relH))
    # finally, we walk
    Action.walk(forward, left, turnccw, minorWalkType=Action.SkeFastForwardMWT)
Esempio n. 6
0
def saGoToTarget(targetX, targetY, maxSpeed = Action.MAX_FORWARD, \
                    maxTurn = Action.MAX_TURN):

    selfX, selfY = Global.selfLoc.getPos()
    selfH = Global.selfLoc.getHeading()
    relX = targetX - selfX
    relY = targetY - selfY
    relD = hMath.getLength((relX, relY))
    distanceSquared = hMath.getDistSquaredBetween(targetX, targetY, selfX,
                                                  selfY)
    inCircle = distanceSquared <= hMath.SQUARE(40)
    faceH = hMath.getHeadingToFaceAt(Global.selfLoc, targetX, targetY)

    if not inCircle and abs(faceH) >= 30:
        Action.walk(0, 0, hMath.CLIP(faceH, maxTurn))

    elif not inCircle:

        #if sStealthDog.stealthDog(True):
        #    hFWHead.compulsoryAction = hFWHead.mustSeeBall
        #    hTrack.trackVisualBall()
        #    return

        Action.walk(maxSpeed, 0, hMath.CLIP(faceH / 1.5, maxTurn))

    else:
        if relX == 0 and relY == 0:
            relTheta = 0
        else:
            relTheta = hMath.normalizeAngle_180(
                hMath.RAD2DEG(math.atan2(relY, relX)) - selfH)

        forward = hMath.CLIP(relD, maxSpeed) * math.cos(
            hMath.DEG2RAD(relTheta))
        left = hMath.CLIP(relD, maxSpeed) * math.sin(hMath.DEG2RAD(relTheta))
        turnCCW = hMath.CLIP(relTheta, maxTurn)
        Action.walk(forward, left, turnCCW)
Esempio n. 7
0
def walk(target, selfPos, selfH):
    relX    = target[0] - selfPos[0]
    relY    = target[1] - selfPos[1]
    relD     = hMath.getLength((relX, relY))
    
    if relX == 0 and relY == 0:
        relThetaRad = 0
    else:
        relThetaRad = hMath.DEG2RAD(hMath.normalizeAngle_180(hMath.RAD2DEG(math.atan2(relY, relX)) - selfH))

    sinTheta = math.sin(relThetaRad)
    cosTheta = math.cos(relThetaRad)
    
    leftSign = relD * sinTheta
    leftAbs1 = abs(leftSign)    #leftAbs1: the distance left component
    if cosTheta != 0:        #leftAbs2: the max capping due to max forward
        leftAbs2 = abs(maxFwd * (sinTheta / cosTheta))
    else:
        leftAbs2 = 100000 # huge number
    #print "left1:", leftAbs1, "left2:", leftAbs2
    leftAbs = min(leftAbs1, leftAbs2, maxLeft)        
    left = hMath.getSign(leftAbs, leftSign)

    if sinTheta != 0:
        forward = left * (cosTheta / sinTheta)
    else:
        fwdSign = relD
        fwdAbs = min(maxFwd, abs(relD))
        forward = hMath.getSign(fwdAbs, fwdSign)

    if turningLeft:
        turnCCW = maxTurn
    else:
        turnCCW = -maxTurn
        
    print __name__, forward, left, turnCCW  
    Action.walk(forward, left, turnCCW,walkType=Action.SkellipticalWalkWT)
Esempio n. 8
0
def saGoToTargetFacingHeading(targetX, targetY, targetH, \
                            maxSpeed = None, maxTurn = None):

    if maxSpeed == None:
        maxSpeed = Action.MAX_FORWARD
    if maxTurn == None:
        maxTurn = Action.MAX_TURN

    # Variables relative to self localisation.
    selfPos = Global.selfLoc.getPos()
    selfH = Global.selfLoc.getHeading()
    relX = targetX - selfPos[0]
    relY = targetY - selfPos[1]
    relH = hMath.normalizeAngle_180(targetH - selfH)

    # take into account that as we turn, the position of our head will change
    relX  += Constant.DOG_NECK_TO_BODY_CENTER_OFFSET * \
             (math.cos(math.radians(selfH)) - math.cos(math.radians(targetH)))
    relY  += Constant.DOG_NECK_TO_BODY_CENTER_OFFSET * \
             (math.sin(math.radians(selfH)) - math.sin(math.radians(targetH)))
    relD = hMath.getLength((relX, relY))

    if relX == 0 and relY == 0:
        relTheta = 0
    else:
        relTheta = hMath.normalizeAngle_180(
            hMath.RAD2DEG(math.atan2(relY, relX)) - selfH)

    forward = hMath.CLIP(relD, maxSpeed) * math.cos(hMath.DEG2RAD(relTheta))
    left = hMath.CLIP(relD, maxSpeed) * math.sin(hMath.DEG2RAD(relTheta))
    turnccw = hMath.CLIP(relH, maxTurn)

    Action.walk(forward,
                left,
                turnccw,
                "ssd",
                minorWalkType=Action.SkeFastForwardMWT)
Esempio n. 9
0
def perform(dkd = 90, side = None, bx = None, by = None):
    # This implementation is very similar to sGetBehindBall (based on 2003)
    # but the ball is on the bottom edge of the circle, not the centre.
    global onCircle

    if side != None:
        print "Warning: sGetBesideBall.perform: side is not yet implemented"

    if bx == None or by == None:
        (bx, by) = Global.gpsGlobalBall.getPos()
    (myx, myy) = Global.selfLoc.getPos()
    myh = Global.selfLoc.getHeading()

    # Determine the centre of the circle, which is CIRCLE_RADIUS towards
    # dkd from the ball. Global coords.
    cx = bx + math.cos(hMath.DEG2RAD(dkd)) * CIRCLE_RADIUS
    cy = by + math.sin(hMath.DEG2RAD(dkd)) * CIRCLE_RADIUS

    # If we are backward of the ball or really close just run at it
    ballRobotH = hMath.getHeadingToMe(bx, by, dkd, myx, myy)
    ballDSquared = hMath.getDistSquaredBetween(myx, myy, bx, by)
    if (abs(ballRobotH) > 90 or ballDSquared < hMath.SQUARE(20)):
        Indicator.showHeadColor(Indicator.RGB_PURPLE)
        ballH = hMath.getHeadingBetween(myx, myy, bx, by)
        hTrack.saGoToTargetFacingHeading(bx, by, ballH)
        return

    # Work out if we are left or right of the centre (relative to DKD as 0)
    robotH = hMath.getHeadingToMe(cx, cy, dkd, myx, myy)
    # FIXME: allow choice of direction
    if (robotH > 0):  # robot to the left
        #print "robot to left of ball",
        direction = Constant.dANTICLOCKWISE
    else:           # robot to the right
        #print "robot to right of ball",
        direction = Constant.dCLOCKWISE
    
    # The circling point can be calculated as looking from the centre
    # towards the robot at CIRCLE_DEGREES to the left/right, and distance
    # CIRCLE_RADIUS. CircleAng is from the centre facing the robot with
    # positive x at zero degrees.
    # There are two modes here. In the first we are well outside the and
    # running to make a tangent with the circle. In the second we are close
    # to or inside the circle and tracing the circumference
    centreDSquared = hMath.getDistSquaredBetween(myx, myy, cx, cy)
    if (centreDSquared > hMath.SQUARE(CIRCLE_RADIUS + 20)):
        #print "Outside circle, running to tangent"
        onCircle = False
        Indicator.showHeadColor(Indicator.RGB_GREEN)
        if direction == Constant.dANTICLOCKWISE:
            circleAng = 90 + CIRCLE_DEGREES
        else:
            circleAng = 90 - CIRCLE_DEGREES
        circleAng = hMath.normalizeAngle_180(circleAng)
    else:
        #print "On circle, tracing circumference"
        onCircle = True
        Indicator.showHeadColor(Indicator.RGB_YELLOW)
        if direction == Constant.dANTICLOCKWISE:
            circleAng = 110
        else:
            circleAng = 70
        
#    print "me", int(myx), int(myy), "ball", int(bx), int(by), \
#        "centre", int(cx), int(cy), "robotH", int(robotH),
    # relative to centre facing robot
    circleRelX = math.cos(hMath.DEG2RAD(circleAng)) * CIRCLE_RADIUS
    circleRelY = math.sin(hMath.DEG2RAD(circleAng)) * CIRCLE_RADIUS
    #print "circleAng", circleAng, "rel circle pos", circleRelX, circleRelY
    robotH = hMath.normalizeAngle_180(robotH + dkd) # now global
    (circleX, circleY) = hMath.getGlobalCoordinate(cx, cy, robotH, \
                                                    circleRelX, circleRelY)
#    print "gRobotH", robotH, "circle pos", int(circleX), int(circleY)
    # circleX/Y now is the global coords of the circle point, so walk there.

#    ballH = hMath.getHeadingBetween(myx, myy, bx, by)   # global
    
    if onCircle:
        # Calls the walk directly to ensure smoothness: no stopping to turn
        relX = circleX - myx
        relY = circleY - myy
        relD = hMath.getLength((relX, relY))
        relTheta = hMath.RAD2DEG(hMath.getHeadingToRelative(relX, relY))

        # Don't turn outwards much, even if we are inside the circle. Walking
        # forward will put us back on it. Nobu can you fix this?
#        print "relTheta", relTheta, "=>",
#        if direction == Constant.dANTICLOCKWISE and relTheta < 0:
#            #relTheta = hMath.CLIP(relTheta, 15)
#            relTheta = 0
#        elif direction == Constant.dCLOCKWISE and relTheta > 0:
#            #relTheta = hMath.CLIP(relTheta, 15)
#            relTheta = 0
#        print relTheta
        left = 0
        if abs(relTheta) < 30:
            Action.walk(Action.MAX_FORWARD, left, relTheta)
        else:
            Action.walk(Action.MAX_FORWARD, left, relTheta)
    else:
        hTrack.saGoToTarget(circleX, circleY)
Esempio n. 10
0
def SmartSetBeacon(panLimit=90, distLimit=550):
    global localiseBeacon, lastBeacon

    # Get shared variables from elsewhere.
    selfLoc = Global.selfLoc
    cov = VisionLink.getGPSSelfCovariance()

    # Calculate the direction of the larger axis of the self covariance
    b = -(cov[0][0] + cov[1][1])
    c = cov[0][0] * cov[1][1] - cov[1][0] * cov[1][0]
    det = b * b - 4 * c

    if (det < 0.00001):
        sol = -b / 2
    else:
        sol = (-b + math.sqrt(det)) / 2

#    chooseCov = False   # Are we choosing a beacon to reduce covariance?
    if abs(cov[0][0] - sol) < 0.01 and cov[0][1] < 0.01:
        # If self position variance is circular, all beacons are equally good
        # to localise off, and so choose the one closest to current heading.
        # dHead is global heading we desire to stay close to
        if abs(cov[1][1] - sol) < 0.01:
            dHead = selfLoc.getHeading()
        else:
            dHead = hMath.RAD2DEG(math.atan2(-cov[1][0], cov[1][1] - sol))

    else:
        #chooseCov = True
        dHead = hMath.RAD2DEG(math.atan2(sol - cov[0][0], cov[0][1]))

    # Find the beacon that is closest to the variance direction.
    beaconPos = getBeaconCoords()
    bestHead = nextBestHead = 360
    localiseBeacon = None  # a tuple (x, y)
    nextBestBeacon = None

    #print beaconPos

    for beacon in beaconPos:
        relPos = map(lambda b, s: b - s, beacon, selfLoc.getPos())
        beaconHead = hMath.RAD2DEG(math.atan2(relPos[1], relPos[0]))
        beaconDist = hMath.getLength(relPos)
        localHead = hMath.normalizeAngle_180(beaconHead - selfLoc.getHeading())

        if abs(localHead) < panLimit and beaconDist < distLimit:
            #print beacon, localHead, beaconHead, dHead
            compHead = abs(hMath.normalizeAngle_180(dHead - beaconHead))
            if compHead > 90:
                compHead = 180 - compHead

            if compHead < bestHead:
                nextBestBeacon = localiseBeacon
                nextBestHead = bestHead
                localiseBeacon = beacon
                bestHead = compHead
            elif compHead < nextBestHead:
                nextBestBeacon = beacon
                nextBestHead = compHead

    #print "sActiveLocalise best =", localiseBeacon, "next =", nextBestBeacon

    # Don't choose the same beacon twice to reduce covariance. If we chose it
    # last time based on covariance and the covariance is still large that way
    # we likely didn't see it, so choose the next best
    if localiseBeacon == lastBeacon and nextBestBeacon != None:
        # print "Choosing a different beacon to last time"
        localiseBeacon = nextBestBeacon
        nextBestBeacon = None

    # Prefer not to look at a really close beacon - we don't get good
    # information
    if nextBestBeacon != None and \
        hMath.getDistanceBetween(selfLoc.getX(), selfLoc.getY(),\
                localiseBeacon[0], localiseBeacon[1]) < MIN_BEACON_DIST:
        # print "Choosing not to use close beacon"
        localiseBeacon = nextBestBeacon

    #print "Choosing beacon at", localiseBeacon, "frame", Global.frame
    lastBeacon = localiseBeacon

    if localiseBeacon == None:
        return False
    else:
        return True