Example #1
0
  def reset( self, pose = (0,0,0), offsetDeg=0 ):
    global g_weedReportEnabled
    g_weedReportEnabled = True
    print "RESET ROW (%0.2f, %0.2f, %0.1f), offset=" % (pose[0], pose[1], math.degrees(pose[2])), offsetDeg 
    viewlog.dumpBeacon( pose[:2], color=(128,128,128) )
    self.preference = None
    self.center = None
    if self.rowHeading:
      self.directionAngle = normalizeAnglePIPI(self.rowHeading-pose[2])
      if abs(self.directionAngle) > math.radians(90):
        self.directionAngle = normalizeAnglePIPI(self.rowHeading-pose[2]+math.radians(180))
      if self.verbose:
        print "RESET_DIFF %.1f" % math.degrees(self.directionAngle)
    else:
      self.directionAngle = 0.0 # if you do not know, go ahead
    goal = combinedPose( (pose[0], pose[1], pose[2]+self.directionAngle), (self.radius, 0, 0) )
    self.line = Line( pose, goal )
# self.line = Line( (0.0, 0.0), (1.0, 0.0) )
    self.newData = False
    self.endOfRow = False
    self.cornLeft = 10.0 # far
    self.cornRight = 10.0
    self.collisionAhead = 10.0,10.0,False,False # far (wide, narrow, override, danger)
    self.lastLeft, self.lastRight = None, None
    self.prevLR = None
    self.poseHistory = []
Example #2
0
    def testVFH(self, verbose=False):
        turnRadius = None  # 1.2
        vfh = VFH(
            self.robot, blockingDistance=0.35, safetyDistance=0.6, maxRange=1.4, turnRadius=turnRadius, verbose=verbose
        )
        self.robot.addExtension(vfh.updateExtension)

        TOLERATED_MISS = 0.2  # [m]
        ANGULAR_THRESHOLD = math.radians(20)  # [rad]
        ANGULAR_SPEED = math.radians(60)  # [rad/s]
        D = 20.0  # [m]
        waypoints = [(D, 0.0), (D, D), (0.0, D), (0.0, 0.0)]
        prevDir = 0.0  # [rad]

        while True:
            for (x, y) in waypoints:
                isThere = False
                while not isThere:
                    pose = self.robot.localisation.pose()
                    if vfh.laserMeasurements is None:
                        strategy = self.driver.stopG()
                        prevDir = 0.0
                    else:
                        phi = math.atan2(y - pose[1], x - pose[0])
                        goalDir = normalizeAnglePIPI(phi - pose[2])
                        dir = vfh.navigate(goalDir, prevDir)

                        if dir is None:
                            strategy = self.driver.stopG()
                            prevDir = 0.0
                        else:
                            goal = combinedPose((pose[0], pose[1], pose[2] + dir), (1.0, 0, 0))
                            strategy = self.driver.goToG(
                                goal, TOLERATED_MISS, angleThreshold=ANGULAR_THRESHOLD, angularSpeed=ANGULAR_SPEED
                            )
                            prevDir = dir

                        vfh.laserMeasurements = None

                    for (speed, angularSpeed) in strategy:
                        self.robot.setSpeedPxPa(speed, angularSpeed)
                        self.robot.update()

                        pose = self.robot.localisation.pose()
                        isThere = math.hypot(pose[0] - x, pose[1] - y) <= TOLERATED_MISS
                        if isThere or vfh.laserMeasurements is not None:
                            break
Example #3
0
 def compassCheck():
     return (self.robot.compass is not None and abs(
         normalizeAnglePIPI(backHeading - startHeading)) > math.pi / 2)
Example #4
0
 def waypoint2dir( self, pose, waypoint ):
   "return direction to waypoint for current pose"
   absAngle = math.atan2(waypoint[1]-pose[1], waypoint[0]-pose[0])
   relAngle = absAngle - pose[2]
   return normalizeAnglePIPI(relAngle)
Example #5
0
  def approachFeeder( self, timeout=60, digitHelper=None, verifyTarget=True ):
    "robot should be within 1m of the feeder"
    print "Approaching Feeder"
    verified = False
    desiredDist = 0.4 #0.2
    countOK = 0
    startTime = self.robot.time
    angularSpeed = 0
    prevPose = None
    prevName = None
    prevLaser = None
    target = None
    frontDist, minDistL, minDistR = None, None, None
    while startTime + timeout > self.robot.time:
      if self.robot.cameraData is not None and len(self.robot.cameraData)> 0 and self.robot.cameraData[0] is not None:
        if prevName != self.robot.cameraData[1]:
#          print prevName, self.robot.localisation.pose()
          prevName = self.robot.cameraData[1]
          if prevPose is None:
            prevPose = self.robot.localisation.pose()
            prevLaser = self.robot.laserData[:]
          arr = eval(self.robot.cameraData[0])
          angularSpeed = None
          for a in arr:
            for digit, (x,y,dx,dy) in a:
              if digit == 'X':
                verified = True
                angularSpeed = (320-(x+dx/2))/100.0
#                print "angularSpeed", math.degrees(angularSpeed), self.robot.cameraData[1], (x,y,dx,dy)
                centerX = 320
                angle = (centerX-(x+dx/2))*0.002454369260617026
                dist = prevLaser[int(angle/2.)+271]/1000.
                print "Target at", dist, self.robot.cameraData[1]
                t = combinedPose( (prevPose[0], prevPose[1], prevPose[2]+angle), (dist,0,0) )
                target = (t[0],t[1])
                viewlog.dumpBeacon( target, color=(255,128,0) )
                break
          if target is None and digitHelper is not None:
            # if you do not have goal try to re-search old number
            for a in arr:
              for digit, (x,y,dx,dy) in a:
                if digit == 'X':
                  angularSpeed = (320-(x+dx/2))/100.0
                  centerX = 320
                  angle = (centerX-(x+dx/2))*0.002454369260617026
                  dist = prevLaser[int(angle/2.)+271]/1000.
                  t = combinedPose( (prevPose[0], prevPose[1], prevPose[2]+angle), (dist,0,0) )
                  target = (t[0],t[1])
                  viewlog.dumpBeacon( target, color=(255,0,255) )
                  break

          prevPose = self.robot.localisation.pose()
          prevLaser = self.robot.laserData[:]
        if angularSpeed is None:
          angularSpeed = 0

      if target is None or distance( target, self.robot.localisation.pose() ) < 0.3:
        angularSpeed = 0.0
      else:
        pose = self.robot.localisation.pose()
        angularSpeed = normalizeAnglePIPI( angleTo( pose, target) - pose[2] )
#        print "target:", target, math.degrees(angularSpeed)


      if self.robot.laserData == None or len(self.robot.laserData) != 541:
        self.robot.setSpeedPxPa( 0, 0 )
      else:
        minDistR = min([10000]+[x for x in self.robot.laserData[180:541/2] if x > 0])/1000.
        minDistL = min([10000]+[x for x in self.robot.laserData[541/2:-180] if x > 0])/1000.
        minDist = min(minDistL, minDistR)
        frontDist = min([10000]+[x for x in self.robot.laserData[265:-265] if x > 0])/1000.
        self.robot.setSpeedPxPa( min(self.driver.maxSpeed, minDist - desiredDist), angularSpeed )
#        print min(self.driver.maxSpeed, minDist - desiredDist)
#        self.robot.setSpeedPxPa( 0, angularSpeed )
        if abs(minDist - desiredDist) < 0.01:
          countOK += 1
        else:
          countOK = 0
        if countOK >= 10:
          break
      self.robot.update()
    self.robot.setSpeedPxPa( 0, 0 )
    self.robot.update()
    print "done."

    if verifyTarget and not verified:
      print "TARGET not verified!"
      return False

    # compute proper rotation and backup distance
    toTurn, toBackup = computeLoadManeuver( minDistL, frontDist, minDistR )
    print "Suggestion: ", math.degrees(toTurn), toBackup
    self.driver.turn( toTurn, angularSpeed = math.radians(20), timeout=30, verbose=True )
    self.driver.goStraight( toBackup, timeout=30 )
    return True
Example #6
0
  def ver2( self, code, detectWeeds = True, detectBlockedRow = True ):
    print "Field Robot - LASER & CAMERA"

    try:
      # start GPS sooner to get position fix
#      self.robot.gps.start()
      self.robot.laser.start()
      self.waitForStart()
      if not self.robot.switchBlueSelected:
        print "RED -> mirroring code directions!!!"
        code = [-x for x in code]
        print code

      if self.robot.compass:
        self.rowHeading = compassHeading(self.robot.compass)
      self.robot.camera.start()
      laserRow = LaserRow( verbose = self.verbose, rowHeading = self.robot.localisation.pose()[2] )
      self.robot.addExtension( laserRow.updateExtension )
      cameraRow = CameraRow( verbose = self.verbose )
      self.robot.addExtension( cameraRow.updateExtension )
      angularSpeed = 0.0
      self.robot.maxSpeed = 0.2
      speed = 0 # wait for first camera image (maybe beep?? if no route to host)
      startTime = self.robot.time
      row = laserRow
      row.reset( offsetDeg=None ) # just for test, try to find the gap (kitchen test)
#      row = cameraRow
      for action in code:
        self.robot.insideFiled = True
        print "=================  ACTION ", action, "================="
        print "battery:", self.robot.battery
        while not row.endOfRow:
#          sprayer( self.robot, True, True )
          for (speed, angularSpeed) in self.driver.followLineG( row.line ):
#            print "TEST %.2f" % (math.degrees(normalizeAnglePIPI(row.line.angle - self.robot.localisation.pose()[2])))
            if abs(normalizeAnglePIPI(row.line.angle - self.robot.localisation.pose()[2])) > SLOW_DOWN_ANGLE:
              speed *= 0.9
            if self.robot.laserData:
              self.robot.toDisplay = 'OK'
            else:
               self.robot.toDisplay = '--'
               speed, angularSpeed = 0.0, 0.0            
#            if detectBlockedRow and row.collisionAhead[1] < 0.25:

            blockedCamCount = 0
            if detectBlockedRow and self.robot.cameraData:
              camDat, fileName = self.robot.cameraData
              if camDat:
                blockedCamCount = int(camDat.split()[0])
                if blockedCamCount > RED_ALERT:
                  print "CAMERA BLOCKED!!", blockedCamCount

#            print  self.robot.cameraData
#            if detectBlockedRow and row.collisionAhead[2]:
            if detectBlockedRow and row.collisionAhead[3] and blockedCamCount > RED_ALERT:
#            if detectBlockedRow and blocked:
              print "---------- COLLISON -> TURN 180 -------------"
              self.robot.beep = 1
              self.driver.stop()
#              self.driver.goStraight( -0.5 )
              self.driver.turn( math.radians(90), radius = 0.12, angularSpeed=math.radians(120), withStop=False )
              self.driver.turn( math.radians(90), radius = -0.12, angularSpeed=math.radians(120) )
              self.robot.beep = 0
#              self.driver.turn( math.radians(180), radius = 0.075 )
#              self.driver.turn( math.radians(180), radius = 0.0 )
#              self.driver.turn( math.radians(20), radius = 0.37, angularSpeed=math.radians(20) )
#              self.driver.turn( math.radians(70), radius = 0.08, angularSpeed=math.radians(20) )
#              self.driver.turn( math.radians(70), radius = -0.08, angularSpeed=math.radians(20) )
#              self.driver.turn( math.radians(20), radius = -0.37, angularSpeed=math.radians(20) )
              self.robot.setSpeedPxPa( 0.0, 0.0 )
              row.reset( self.robot.localisation.pose(), offsetDeg = None ) # instead of turning shift search
            else:
#              if detectBlockedRow and (row.collisionAhead[0] < 0.5 or row.collisionAhead[1] < 0.7):
#                if self.verbose:
#                  print "!!SLOW DOWN!!"
#                speed, angularSpeed = speed/2.0, angularSpeed/2.0 # slow down
              self.robot.setSpeedPxPa( speed, angularSpeed )
            self.robot.update()
            if row.newData:
              row.newData = False
              break
#          sprayer( self.robot, False, False )

        # handle action after row termination
        self.robot.insideField = False
        self.robot.beep = 1
        self.driver.stop()
        self.robot.beep = 0
        if action == 0:
          self.driver.goStraight( 0.2 )
          prevAngle = self.robot.localisation.pose()[2]
          if not self.driver.turn( math.radians(180), timeout=7.0 ):
            self.driver.goStraight( -0.2 )
            currAngle = self.robot.localisation.pose()[2]
            print "TIMEOUT", math.degrees(normalizeAnglePIPI(math.radians(180)-currAngle+prevAngle))
            if not self.driver.turn( normalizeAnglePIPI(math.radians(180)-currAngle+prevAngle), timeout=5.0 ):
              currAngle = self.robot.localisation.pose()[2]
              print "TIMEOUT2 - GIVING UP", math.degrees(normalizeAnglePIPI(math.radians(180)-currAngle-prevAngle))            
        elif action == -1:
          self.driver.turn( math.radians(160), radius = 0.75/2.0, angularSpeed=math.radians(40) )
        elif action == 1:
          self.driver.turn( math.radians(-160), radius = 0.75/2.0, angularSpeed=math.radians(40) )
        else:
          if action < 0:
            self.driver.turn( math.radians(90), radius = self.rowWidth/2.0, angularSpeed=math.radians(40) )
          else:
            self.driver.turn( math.radians(-90), radius = self.rowWidth/2.0, angularSpeed=math.radians(40) )
#          self.driver.goStraight( (math.fabs(action)-1) * (self.rowWidth+self.rowPotsWidth)+self.rowPotsWidth )
          self.crossRows( row, math.fabs(action)-1, rowsOnLeft = (action < 0) )
          self.driver.stop()
          if action < 0:
            self.driver.turn( math.radians(90), radius = self.rowWidth/2.0, angularSpeed=math.radians(40) )
#            self.driver.turn( math.radians(90), radius = 0.0, angularSpeed=math.radians(40) )
          else:
            self.driver.turn( math.radians(-90), radius = self.rowWidth/2.0, angularSpeed=math.radians(40) )
#            self.driver.turn( math.radians(-90), radius = 0.0, angularSpeed=math.radians(40) )

        # clear flag for detection
#        row.reset( self.robot.localisation.pose() )
        row.reset( self.robot.localisation.pose(), offsetDeg=None ) # init with search for center
      self.robot.setSpeedPxPa( 0.0, 0.0 )
      self.robot.update() 
    except EmergencyStopException, e:
      print "EmergencyStopException"
Example #7
0
  def updateExtension( self, robot, id, data ):
    global g_weedReportEnabled
    if id == 'remission' and len(data) > 0:
      pass # ignored for FRE 2014

    if id == 'laser' and len(data) > 0:
      self.poseHistory.append( robot.localisation.pose()[:2] )
      if len(self.poseHistory) > 20:
        self.poseHistory = self.poseHistory[-20:]
      step = 10
      data2 = [x == 0 and 10000 or x for x in data]
      arr = [min(i)/1000.0 for i in [itertools.islice(data2, start, start+step) for start in range(0,len(data2),step)]]
      arr.reverse()
      robot.preprocessedLaser = arr

      limit = self.radius
      danger = False
      prevCenter = self.center
      if self.center != None:
#        if center > 0 and center < len(arr)-1 and arr[center] < limit and arr[center-1] < limit and arr[center+1] < limit:
        if self.center > 0 and self.center < len(arr)-1 and arr[self.center] < limit:
          print "!!!DANGER!!! PATH BLOCKED!!!", self.center
          danger = True
      if self.center==None or danger:
        # offset is not set - find nearest
        if self.center == None:
          self.center = len(arr)/2
        if arr[self.center] < limit:
          i = 0
          while i < self.center:
            if arr[self.center - i] >= limit:
              break
            i += 1
          left = i
          i = 0
          while i + self.center < len(arr):
            if arr[self.center + i] >= limit:
              break
            i += 1
          right = i
          print "HACK", left, right
          if left < right:
            self.center += -left
          else:
            self.center += right

      i = 0
      if self.center < 0 or self.center >= len(arr):
        self.center = prevCenter
      if self.center == None:
        self.center = len(arr)/2
      while i <= self.center:
        if arr[self.center - i] < limit:
          break
        i += 1
      left = i # arr is already reversed
      i = 0
      while i + self.center < len(arr):
        if arr[self.center + i] < limit:
          break
        i += 1
      right = i

      p = robot.localisation.pose()
      if self.center-left >= 0:
        self.lastLeft = combinedPose( (p[0], p[1], p[2]+math.radians(135-5*(self.center-left)) ), (arr[self.center-left],0,0) )
#        viewlog.dumpBeacon(self.lastLeft[:2], color=(0,128,0))
      if self.center+right < len(arr):
        self.lastRight = combinedPose( (p[0], p[1], p[2]+math.radians(135-5*(self.center+right)) ), (arr[self.center+right],0,0) )
#        viewlog.dumpBeacon(self.lastRight[:2], color=(0,128,50))

      if self.verbose:
        if danger and left+right < MIN_GAP_SIZE:
          print "MIN GAP SIZE danger:", left+right
        s = ''
        for i in arr:
          s += (i < 0.5 and 'X' or (i<1.0 and 'x' or (i<1.5 and '.' or ' ')))
        s = "".join( list(s)[:self.center] + ['C'] + list(s)[self.center:] )
        print "'" + s + "'"      
#        print "LRLR\t%d\t%d\t%d" % (left, right, left+right)
#        if self.prevLR :
#          print "LRDIFF", left-self.prevLR[0], right-self.prevLR[1]

      self.line = None # can be defined inside
      if left+right <= MAX_GAP_SIZE: # TODO limit based on minSize, radius and sample angle
        self.center += (right-left)/2
        offset = self.center-len(arr)/2
        self.directionAngle = math.radians( -offset*step/2.0 )
        self.collisionAhead = min(arr[54/3:2*54/3]), min(arr[4*54/9:5*54/9]), (left+right < MIN_GAP_SIZE), danger
        if False: #self.verbose:
          if self.collisionAhead[0] < 0.25:
            print "!!! COLISSION AHEAD !!!", self.collisionAhead
          else:
            print "free space", self.collisionAhead
      elif left < 3 or right < 3:
        # wide row & collision ahead
        if self.verbose:
          print "NEAR", left, right, left+right
        offset = self.center-len(arr)/2
        if left < right:
          offset += 3
        else:
          offset -= 3
        self.directionAngle = math.radians( -offset*step/2.0 )
      else:
        if self.verbose:
          print "OFF", left, right #, left+right, robot.compass
        if False: # hacked, ignoring compass   self.rowHeading:
          self.directionAngle = normalizeAnglePIPI(self.rowHeading-robot.localisation.pose()[2])
          if abs(self.directionAngle) > math.radians(90):
            self.directionAngle = normalizeAnglePIPI(self.rowHeading-robot.localisation.pose()[2]+math.radians(180))
          if self.verbose:
            print "DIFF %.1f" % math.degrees(self.directionAngle)
        else:
          if self.verbose:
            print "PATH GAP"    
          A, B = self.poseHistory[0][:2], self.poseHistory[-1][:2]
          viewlog.dumpBeacon( A, color=(0,0,180) )
          viewlog.dumpBeacon( B, color=(0,30,255) )
          self.line = Line( B, (2*B[0]-A[0], 2*B[1]-A[1]) ) # B+(B-A)
          if self.line and self.line.length < 0.5:
            self.line = None
          else:
            self.center = len(arr)/2
            # reset center
          """if self.prevLR:
            if abs(left-self.prevLR[0]) > 4 and abs(right-self.prevLR[1]) < 3:
              left = self.prevLR[0]
              self.center += (right-left)/2
              offset = self.center-len(arr)/2
              self.directionAngle = math.radians( -offset*step/2.0 )
            elif abs(right-self.prevLR[1]) > 4 and abs(left-self.prevLR[0]) < 3:
              right = self.prevLR[1]
              self.center += (right-left)/2
              offset = self.center-len(arr)/2
              self.directionAngle = math.radians( -offset*step/2.0 )
            else:
              self.directionAngle = 0.0 # if you do not know, go ahead
          else:
            self.directionAngle = 0.0 # if you do not know, go ahead"""
          self.directionAngle = 0.0 # default
          
        if left >= 17 and right >= 17 or left+right >= 40:
          self.endOfRow = True
          g_weedReportEnabled = False
          if self.verbose and robot.insideField:
            print "laser: END OF ROW"
      self.prevLR = left, right

      pose = robot.localisation.pose()
      goal = combinedPose( (pose[0], pose[1], pose[2]+self.directionAngle), (self.radius, 0, 0) )
      if self.line == None:
        self.line = Line( pose, goal )
      self.newData = True
      self.cornLeft = min(arr[5:9])
      self.cornRight = min(arr[40:44])
Example #8
0
 def waypoint2dir(self, pose, waypoint):
     "return direction to waypoint for current pose"
     absAngle = math.atan2(waypoint[1] - pose[1], waypoint[0] - pose[0])
     relAngle = absAngle - pose[2]
     return normalizeAnglePIPI(relAngle)
Example #9
0
    def approachFeeder(self, timeout=60, digitHelper=None, verifyTarget=True):
        "robot should be within 1m of the feeder"
        print "Approaching Feeder"
        verified = False
        desiredDist = 0.4  #0.2
        countOK = 0
        startTime = self.robot.time
        angularSpeed = 0
        prevPose = None
        prevName = None
        prevLaser = None
        target = None
        frontDist, minDistL, minDistR = None, None, None
        while startTime + timeout > self.robot.time:
            if self.robot.cameraData is not None and len(
                    self.robot.cameraData
            ) > 0 and self.robot.cameraData[0] is not None:
                if prevName != self.robot.cameraData[1]:
                    #          print prevName, self.robot.localisation.pose()
                    prevName = self.robot.cameraData[1]
                    if prevPose is None:
                        prevPose = self.robot.localisation.pose()
                        prevLaser = self.robot.laserData[:]
                    arr = eval(self.robot.cameraData[0])
                    angularSpeed = None
                    for a in arr:
                        for digit, (x, y, dx, dy) in a:
                            if digit == 'X':
                                verified = True
                                angularSpeed = (320 - (x + dx / 2)) / 100.0
                                #                print "angularSpeed", math.degrees(angularSpeed), self.robot.cameraData[1], (x,y,dx,dy)
                                centerX = 320
                                angle = (centerX -
                                         (x + dx / 2)) * 0.002454369260617026
                                dist = prevLaser[int(angle / 2.) + 271] / 1000.
                                print "Target at", dist, self.robot.cameraData[
                                    1]
                                t = combinedPose((prevPose[0], prevPose[1],
                                                  prevPose[2] + angle),
                                                 (dist, 0, 0))
                                target = (t[0], t[1])
                                viewlog.dumpBeacon(target, color=(255, 128, 0))
                                break
                    if target is None and digitHelper is not None:
                        # if you do not have goal try to re-search old number
                        for a in arr:
                            for digit, (x, y, dx, dy) in a:
                                if digit == 'X':
                                    angularSpeed = (320 - (x + dx / 2)) / 100.0
                                    centerX = 320
                                    angle = (
                                        centerX -
                                        (x + dx / 2)) * 0.002454369260617026
                                    dist = prevLaser[int(angle / 2.) +
                                                     271] / 1000.
                                    t = combinedPose((prevPose[0], prevPose[1],
                                                      prevPose[2] + angle),
                                                     (dist, 0, 0))
                                    target = (t[0], t[1])
                                    viewlog.dumpBeacon(target,
                                                       color=(255, 0, 255))
                                    break

                    prevPose = self.robot.localisation.pose()
                    prevLaser = self.robot.laserData[:]
                if angularSpeed is None:
                    angularSpeed = 0

            if target is None or distance(
                    target, self.robot.localisation.pose()) < 0.3:
                angularSpeed = 0.0
            else:
                pose = self.robot.localisation.pose()
                angularSpeed = normalizeAnglePIPI(
                    angleTo(pose, target) - pose[2])


#        print "target:", target, math.degrees(angularSpeed)

            if self.robot.laserData == None or len(
                    self.robot.laserData) != 541:
                self.robot.setSpeedPxPa(0, 0)
            else:
                minDistR = min(
                    [10000] +
                    [x for x in self.robot.laserData[180:541 / 2]
                     if x > 0]) / 1000.
                minDistL = min(
                    [10000] +
                    [x for x in self.robot.laserData[541 / 2:-180]
                     if x > 0]) / 1000.
                minDist = min(minDistL, minDistR)
                frontDist = min(
                    [10000] +
                    [x
                     for x in self.robot.laserData[265:-265] if x > 0]) / 1000.
                self.robot.setSpeedPxPa(
                    min(self.driver.maxSpeed, minDist - desiredDist),
                    angularSpeed)
                #        print min(self.driver.maxSpeed, minDist - desiredDist)
                #        self.robot.setSpeedPxPa( 0, angularSpeed )
                if abs(minDist - desiredDist) < 0.01:
                    countOK += 1
                else:
                    countOK = 0
                if countOK >= 10:
                    break
            self.robot.update()
        self.robot.setSpeedPxPa(0, 0)
        self.robot.update()
        print "done."

        if verifyTarget and not verified:
            print "TARGET not verified!"
            return False

        # compute proper rotation and backup distance
        toTurn, toBackup = computeLoadManeuver(minDistL, frontDist, minDistR)
        print "Suggestion: ", math.degrees(toTurn), toBackup
        self.driver.turn(toTurn,
                         angularSpeed=math.radians(20),
                         timeout=30,
                         verbose=True)
        self.driver.goStraight(toBackup, timeout=30)
        return True
Example #10
0
 def compassCheck():
     return self.robot.compass is not None and abs(normalizeAnglePIPI(backHeading - startHeading)) > math.pi / 2
Example #11
0
File: fre.py Project: luciusb/eduro
    def ver2(self, code, detectWeeds=True, detectBlockedRow=True):
        print "Field Robot - LASER & CAMERA"

        try:
            # start GPS sooner to get position fix
            #      self.robot.gps.start()
            self.robot.laser.start()
            self.waitForStart()
            if not self.robot.switchBlueSelected:
                print "RED -> mirroring code directions!!!"
                code = [-x for x in code]
                print code

            if self.robot.compass:
                self.rowHeading = compassHeading(self.robot.compass)
            self.robot.camera.start()
            laserRow = LaserRow(verbose=self.verbose,
                                rowHeading=self.robot.localisation.pose()[2])
            self.robot.addExtension(laserRow.updateExtension)
            cameraRow = CameraRow(verbose=self.verbose)
            self.robot.addExtension(cameraRow.updateExtension)
            angularSpeed = 0.0
            self.robot.maxSpeed = 0.2
            speed = 0  # wait for first camera image (maybe beep?? if no route to host)
            startTime = self.robot.time
            row = laserRow
            row.reset(offsetDeg=None
                      )  # just for test, try to find the gap (kitchen test)
            #      row = cameraRow
            for action in code:
                self.robot.insideFiled = True
                print "=================  ACTION ", action, "================="
                print "battery:", self.robot.battery
                while not row.endOfRow:
                    #          sprayer( self.robot, True, True )
                    for (speed,
                         angularSpeed) in self.driver.followLineG(row.line):
                        #            print "TEST %.2f" % (math.degrees(normalizeAnglePIPI(row.line.angle - self.robot.localisation.pose()[2])))
                        if abs(
                                normalizeAnglePIPI(
                                    row.line.angle -
                                    self.robot.localisation.pose()[2])
                        ) > SLOW_DOWN_ANGLE:
                            speed *= 0.9
                        if self.robot.laserData:
                            self.robot.toDisplay = 'OK'
                        else:
                            self.robot.toDisplay = '--'
                            speed, angularSpeed = 0.0, 0.0
#            if detectBlockedRow and row.collisionAhead[1] < 0.25:

                        blockedCamCount = 0
                        if detectBlockedRow and self.robot.cameraData:
                            camDat, fileName = self.robot.cameraData
                            if camDat:
                                blockedCamCount = int(camDat.split()[0])
                                if blockedCamCount > RED_ALERT:
                                    print "CAMERA BLOCKED!!", blockedCamCount

#            print  self.robot.cameraData
#            if detectBlockedRow and row.collisionAhead[2]:
                        if detectBlockedRow and row.collisionAhead[
                                3] and blockedCamCount > RED_ALERT:
                            #            if detectBlockedRow and blocked:
                            print "---------- COLLISON -> TURN 180 -------------"
                            self.robot.beep = 1
                            self.driver.stop()
                            #              self.driver.goStraight( -0.5 )
                            self.driver.turn(math.radians(90),
                                             radius=0.12,
                                             angularSpeed=math.radians(120),
                                             withStop=False)
                            self.driver.turn(math.radians(90),
                                             radius=-0.12,
                                             angularSpeed=math.radians(120))
                            self.robot.beep = 0
                            #              self.driver.turn( math.radians(180), radius = 0.075 )
                            #              self.driver.turn( math.radians(180), radius = 0.0 )
                            #              self.driver.turn( math.radians(20), radius = 0.37, angularSpeed=math.radians(20) )
                            #              self.driver.turn( math.radians(70), radius = 0.08, angularSpeed=math.radians(20) )
                            #              self.driver.turn( math.radians(70), radius = -0.08, angularSpeed=math.radians(20) )
                            #              self.driver.turn( math.radians(20), radius = -0.37, angularSpeed=math.radians(20) )
                            self.robot.setSpeedPxPa(0.0, 0.0)
                            row.reset(self.robot.localisation.pose(),
                                      offsetDeg=None
                                      )  # instead of turning shift search
                        else:
                            #              if detectBlockedRow and (row.collisionAhead[0] < 0.5 or row.collisionAhead[1] < 0.7):
                            #                if self.verbose:
                            #                  print "!!SLOW DOWN!!"
                            #                speed, angularSpeed = speed/2.0, angularSpeed/2.0 # slow down
                            self.robot.setSpeedPxPa(speed, angularSpeed)
                        self.robot.update()
                        if row.newData:
                            row.newData = False
                            break
#          sprayer( self.robot, False, False )

# handle action after row termination
                self.robot.insideField = False
                self.robot.beep = 1
                self.driver.stop()
                self.robot.beep = 0
                if action == 0:
                    self.driver.goStraight(0.2)
                    prevAngle = self.robot.localisation.pose()[2]
                    if not self.driver.turn(math.radians(180), timeout=7.0):
                        self.driver.goStraight(-0.2)
                        currAngle = self.robot.localisation.pose()[2]
                        print "TIMEOUT", math.degrees(
                            normalizeAnglePIPI(
                                math.radians(180) - currAngle + prevAngle))
                        if not self.driver.turn(normalizeAnglePIPI(
                                math.radians(180) - currAngle + prevAngle),
                                                timeout=5.0):
                            currAngle = self.robot.localisation.pose()[2]
                            print "TIMEOUT2 - GIVING UP", math.degrees(
                                normalizeAnglePIPI(
                                    math.radians(180) - currAngle - prevAngle))
                elif action == -1:
                    self.driver.turn(math.radians(160),
                                     radius=0.75 / 2.0,
                                     angularSpeed=math.radians(40))
                elif action == 1:
                    self.driver.turn(math.radians(-160),
                                     radius=0.75 / 2.0,
                                     angularSpeed=math.radians(40))
                else:
                    if action < 0:
                        self.driver.turn(math.radians(90),
                                         radius=self.rowWidth / 2.0,
                                         angularSpeed=math.radians(40))
                    else:
                        self.driver.turn(math.radians(-90),
                                         radius=self.rowWidth / 2.0,
                                         angularSpeed=math.radians(40))
#          self.driver.goStraight( (math.fabs(action)-1) * (self.rowWidth+self.rowPotsWidth)+self.rowPotsWidth )
                    self.crossRows(row,
                                   math.fabs(action) - 1,
                                   rowsOnLeft=(action < 0))
                    self.driver.stop()
                    if action < 0:
                        self.driver.turn(math.radians(90),
                                         radius=self.rowWidth / 2.0,
                                         angularSpeed=math.radians(40))
#            self.driver.turn( math.radians(90), radius = 0.0, angularSpeed=math.radians(40) )
                    else:
                        self.driver.turn(math.radians(-90),
                                         radius=self.rowWidth / 2.0,
                                         angularSpeed=math.radians(40))
#            self.driver.turn( math.radians(-90), radius = 0.0, angularSpeed=math.radians(40) )

# clear flag for detection
#        row.reset( self.robot.localisation.pose() )
                row.reset(self.robot.localisation.pose(),
                          offsetDeg=None)  # init with search for center
            self.robot.setSpeedPxPa(0.0, 0.0)
            self.robot.update()
        except EmergencyStopException, e:
            print "EmergencyStopException"
Example #12
0
File: fre.py Project: luciusb/eduro
    def updateExtension(self, robot, id, data):
        global g_weedReportEnabled
        if id == 'remission' and len(data) > 0:
            pass  # ignored for FRE 2014

        if id == 'laser' and len(data) > 0:
            self.poseHistory.append(robot.localisation.pose()[:2])
            if len(self.poseHistory) > 20:
                self.poseHistory = self.poseHistory[-20:]
            step = 10
            data2 = [x == 0 and 10000 or x for x in data]
            arr = [
                min(i) / 1000.0 for i in [
                    itertools.islice(data2, start, start + step)
                    for start in range(0, len(data2), step)
                ]
            ]
            arr.reverse()
            robot.preprocessedLaser = arr

            limit = self.radius
            danger = False
            prevCenter = self.center
            if self.center != None:
                #        if center > 0 and center < len(arr)-1 and arr[center] < limit and arr[center-1] < limit and arr[center+1] < limit:
                if self.center > 0 and self.center < len(arr) - 1 and arr[
                        self.center] < limit:
                    print "!!!DANGER!!! PATH BLOCKED!!!", self.center
                    danger = True
            if self.center == None or danger:
                # offset is not set - find nearest
                if self.center == None:
                    self.center = len(arr) / 2
                if arr[self.center] < limit:
                    i = 0
                    while i < self.center:
                        if arr[self.center - i] >= limit:
                            break
                        i += 1
                    left = i
                    i = 0
                    while i + self.center < len(arr):
                        if arr[self.center + i] >= limit:
                            break
                        i += 1
                    right = i
                    print "HACK", left, right
                    if left < right:
                        self.center += -left
                    else:
                        self.center += right

            i = 0
            if self.center < 0 or self.center >= len(arr):
                self.center = prevCenter
            if self.center == None:
                self.center = len(arr) / 2
            while i <= self.center:
                if arr[self.center - i] < limit:
                    break
                i += 1
            left = i  # arr is already reversed
            i = 0
            while i + self.center < len(arr):
                if arr[self.center + i] < limit:
                    break
                i += 1
            right = i

            p = robot.localisation.pose()
            if self.center - left >= 0:
                self.lastLeft = combinedPose(
                    (p[0], p[1], p[2] + math.radians(135 - 5 *
                                                     (self.center - left))),
                    (arr[self.center - left], 0, 0))
#        viewlog.dumpBeacon(self.lastLeft[:2], color=(0,128,0))
            if self.center + right < len(arr):
                self.lastRight = combinedPose(
                    (p[0], p[1], p[2] + math.radians(135 - 5 *
                                                     (self.center + right))),
                    (arr[self.center + right], 0, 0))
#        viewlog.dumpBeacon(self.lastRight[:2], color=(0,128,50))

            if self.verbose:
                if danger and left + right < MIN_GAP_SIZE:
                    print "MIN GAP SIZE danger:", left + right
                s = ''
                for i in arr:
                    s += (i < 0.5 and 'X'
                          or (i < 1.0 and 'x' or (i < 1.5 and '.' or ' ')))
                s = "".join(
                    list(s)[:self.center] + ['C'] + list(s)[self.center:])
                print "'" + s + "'"
#        print "LRLR\t%d\t%d\t%d" % (left, right, left+right)
#        if self.prevLR :
#          print "LRDIFF", left-self.prevLR[0], right-self.prevLR[1]

            self.line = None  # can be defined inside
            if left + right <= MAX_GAP_SIZE:  # TODO limit based on minSize, radius and sample angle
                self.center += (right - left) / 2
                offset = self.center - len(arr) / 2
                self.directionAngle = math.radians(-offset * step / 2.0)
                self.collisionAhead = min(arr[54 / 3:2 * 54 / 3]), min(
                    arr[4 * 54 / 9:5 * 54 /
                        9]), (left + right < MIN_GAP_SIZE), danger
                if False:  #self.verbose:
                    if self.collisionAhead[0] < 0.25:
                        print "!!! COLISSION AHEAD !!!", self.collisionAhead
                    else:
                        print "free space", self.collisionAhead
            elif left < 3 or right < 3:
                # wide row & collision ahead
                if self.verbose:
                    print "NEAR", left, right, left + right
                offset = self.center - len(arr) / 2
                if left < right:
                    offset += 3
                else:
                    offset -= 3
                self.directionAngle = math.radians(-offset * step / 2.0)
            else:
                if self.verbose:
                    print "OFF", left, right  #, left+right, robot.compass
                if False:  # hacked, ignoring compass   self.rowHeading:
                    self.directionAngle = normalizeAnglePIPI(
                        self.rowHeading - robot.localisation.pose()[2])
                    if abs(self.directionAngle) > math.radians(90):
                        self.directionAngle = normalizeAnglePIPI(
                            self.rowHeading - robot.localisation.pose()[2] +
                            math.radians(180))
                    if self.verbose:
                        print "DIFF %.1f" % math.degrees(self.directionAngle)
                else:
                    if self.verbose:
                        print "PATH GAP"
                    A, B = self.poseHistory[0][:2], self.poseHistory[-1][:2]
                    viewlog.dumpBeacon(A, color=(0, 0, 180))
                    viewlog.dumpBeacon(B, color=(0, 30, 255))
                    self.line = Line(
                        B, (2 * B[0] - A[0], 2 * B[1] - A[1]))  # B+(B-A)
                    if self.line and self.line.length < 0.5:
                        self.line = None
                    else:
                        self.center = len(arr) / 2
                        # reset center
                    """if self.prevLR:
            if abs(left-self.prevLR[0]) > 4 and abs(right-self.prevLR[1]) < 3:
              left = self.prevLR[0]
              self.center += (right-left)/2
              offset = self.center-len(arr)/2
              self.directionAngle = math.radians( -offset*step/2.0 )
            elif abs(right-self.prevLR[1]) > 4 and abs(left-self.prevLR[0]) < 3:
              right = self.prevLR[1]
              self.center += (right-left)/2
              offset = self.center-len(arr)/2
              self.directionAngle = math.radians( -offset*step/2.0 )
            else:
              self.directionAngle = 0.0 # if you do not know, go ahead
          else:
            self.directionAngle = 0.0 # if you do not know, go ahead"""
                    self.directionAngle = 0.0  # default

                if left >= 17 and right >= 17 or left + right >= 40:
                    self.endOfRow = True
                    g_weedReportEnabled = False
                    if self.verbose and robot.insideField:
                        print "laser: END OF ROW"
            self.prevLR = left, right

            pose = robot.localisation.pose()
            goal = combinedPose(
                (pose[0], pose[1], pose[2] + self.directionAngle),
                (self.radius, 0, 0))
            if self.line == None:
                self.line = Line(pose, goal)
            self.newData = True
            self.cornLeft = min(arr[5:9])
            self.cornRight = min(arr[40:44])