コード例 #1
0
ファイル: fre.py プロジェクト: robotika/eduro
  def updateExtension( self, robot, id, data ):
    global g_weedReportEnabled
    if id == 0x80:
      self.counter += 1
      if len(self.lastCamera)> 0:
#        print self.counter, self.lastCamera
        cmd = self.lastCamera[0]
        if self.counter >= cmd[0]:
          self.lastCamera = self.lastCamera[1:]
          if cmd[1] or cmd[2]:
            robot.beep  = 1
          else:
            robot.beep  = 0
          sprayer( robot, cmd[1], cmd[2] )
    if id == 'camera':
      if self.verbose and len(data) > 1:
        print data[1]
      cc = [int(x) for x in data[0].split()]
      leftPip = (cc[0] > BALL_SIZE_LIMIT_MIN and cc[0] < BALL_SIZE_LIMIT_MAX)
      rightPip = (cc[1] > BALL_SIZE_LIMIT_MIN and cc[1] < BALL_SIZE_LIMIT_MAX)
      if leftPip or rightPip:
        print "WEED:", leftPip, rightPip, g_weedReportEnabled
        if leftPip and g_weedReportEnabled:
          xy = combinedPose(robot.localisation.pose(), (0,0.35,0))[:2]
#          reportBall( robot.gpsData )
          viewlog.dumpBeacon( xy, color=(255,255,0) )
        if rightPip and g_weedReportEnabled:
          xy = combinedPose(robot.localisation.pose(), (0,-0.35,0))[:2]
#          reportBall( robot.gpsData )
          viewlog.dumpBeacon( xy, color=(255,255,0) )
        if g_weedReportEnabled:
          self.lastCamera.append( (self.counter + 0, leftPip, rightPip ) )
      else:
        self.lastCamera.append( (self.counter + 0+4, False, False) )
コード例 #2
0
ファイル: sickday2016.py プロジェクト: robotika/eduro
    def ver0( self, verbose=False ):
        # Go straight for 2 meters
        print "ver0", self.robot.battery

        prevRFID = None
        self.load_cube()
        for cmd in self.driver.goStraightG(2.0):
            self.robot.setSpeedPxPa(*cmd)

            if prevRFID != self.robot.rfu620Data:
                prevRFID = self.robot.rfu620Data
                posXY = combinedPose(self.robot.localisation.pose(), (-0.35, 0.14, 0))[:2]
                for d in self.robot.rfu620Data[1]:
                    i = d[0]  # i.e. 0x1000 0206 0000
                    x, y, zone = (i >> 24)&0xFF, (i >> 16)&0xFF, i&0xFF
                    print hex(i), (x, y)
                    if x == 1:
                        viewlog.dumpBeacon(posXY, color=(0, 0, 255))
                    elif x == 2:
                        viewlog.dumpBeacon(posXY, color=(255, 0, 255))
                    else:
                        viewlog.dumpBeacon(posXY, color=(255, 255, 255))
            self.robot.update()
        self.place_cube()
        self.game_over()
コード例 #3
0
ファイル: sickday2016.py プロジェクト: robotika/eduro
 def place_cube(self):
     pos = combinedPose(self.robot.localisation.pose(), (0.2, 0, 0))[:2]  # TODO check proper offset
     print "place cube at ({:.2f}, {:.2f} (time = {:.1f}))".format(pos[0], pos[1], self.robot.time - self.start_time)
     viewlog.dumpBeacon(pos, color=(255, 255, 255))
     viewlog.dumpObstacles([[pos]])
     gripperOpen(self.robot)
     self.driver.goStraight(-0.4, timeout=30)
コード例 #4
0
 def reset(self, pose=(0, 0, 0), offsetDeg=0):
     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  # far (wide, narrow, override)
     self.lastLeft, self.lastRight = None, None
     self.prevLR = None
     self.poseHistory = []
コード例 #5
0
ファイル: fre.py プロジェクト: robotika/eduro
  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 = []
コード例 #6
0
ファイル: sickday2014.py プロジェクト: TeaPackCZ/eduro
 def reset( self, pose = (0,0,0) ):
   print "RESET ROW (%0.2f, %0.2f, %0.1f)" % (pose[0], pose[1], math.degrees(pose[2]) )
   self.preference = None
   self.directionAngle = 0.0
   self.offset = 0
   goal = combinedPose( (pose[0], pose[1], pose[2]+self.directionAngle), (1.0, 0, 0) ) # was radius
   self.line = Line( pose, goal )
   self.newData = False
   self.traversable = None
   self.obstacles = []
   self.step = 10 # how many neighboring measurements are merged together
   #TODO: get the laser parameters somewhere
   h = 310 # Height of the laser above ground. [mm]
   alpha = math.radians(81.0) # An angle between a vertical direction and a forward measurement beam.
   n = 541 # Number of values provided by the laser
   self.laserRight = math.radians(-135.0) # Left-most angle measured by the laser. [rad]
   self.laserLeft = math.radians(+135.0) # Right-most angle measured by the laser. [rad]
   self.expectation = [] # Expected distances to the ground plane. [mm]
   epsilon = 1.0e-3
   angle_threshold = math.pi / 3 #math.pi / 2.0 - epsilon
   for i in xrange(n):
     beta = self.laserRight + (self.laserLeft - self.laserRight) * i / float(n)
     if abs(beta) >= angle_threshold:
       beta = angle_threshold * (1 if beta > 0 else -1) # Making sure we always have an "intersection" in a reasonable
     x = h / (math.cos(alpha) * math.cos(beta))
     self.expectation.append(x)
   avg_decim = lambda sl: sum(sl) / self.step
   self.decimatedExpectation = self.__decimate(self.expectation, decimator = avg_decim)
コード例 #7
0
ファイル: sickday2014.py プロジェクト: TeaPackCZ/eduro
 def cam2waypoint( self, pose, camInfo ):
   "estimate from camera info (x,y,width,height) new waypoint"
   if camInfo is None:
     dir = 0
     dist = 10.0
   else:
     dir = math.radians(0.1* (640/2-(camInfo[1][0]+camInfo[1][2]/2.0)))
     dist = 20.0/float(camInfo[1][2]) # TODO calibrate 
   return combinedPose( (pose[0], pose[1], pose[2]+dir), (dist, 0, 0) )
コード例 #8
0
ファイル: sickday2016.py プロジェクト: robotika/eduro
def draw_cubes_extension(robot, id, data):
    if id == 'laser':
#        cd = CubeDetector(robot.laser.pose)
#        cubes = cd.detect_cubes_xy(data, limit=4)
        # Jakub's alternative
        cubes = cubesFromScan(data)
        for cube_x, cube_y in cubes:
            goal = combinedPose(robot.localisation.pose(), (cube_x, cube_y, 0))[:2]
            viewlog.dumpBeacon(goal, color=(128, 255, 128))
コード例 #9
0
ファイル: sickday2014.py プロジェクト: luciusb/eduro
 def cam2waypoint(self, pose, camInfo):
     "estimate from camera info (x,y,width,height) new waypoint"
     if camInfo is None:
         dir = 0
         dist = 10.0
     else:
         dir = math.radians(0.1 * (640 / 2 -
                                   (camInfo[1][0] + camInfo[1][2] / 2.0)))
         dist = 20.0 / float(camInfo[1][2])  # TODO calibrate
     return combinedPose((pose[0], pose[1], pose[2] + dir), (dist, 0, 0))
コード例 #10
0
ファイル: vfh.py プロジェクト: luciusb/eduro
    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
コード例 #11
0
ファイル: simulator.py プロジェクト: TeaPackCZ/eduro
  def updateData( self ):
    pose = (0,0,0)
    if self.robot and self.robot.localisation:
      pose = self.robot.localisation.pose()

    step = 10
    for i in xrange(0,541,step):
      angle = math.radians((i-270)/2.0)
      absPose = combinedPose( pose, (0,0,angle) ) # TODO shift of laser
      simulatedDist = rayTrace( absPose, self.obstacles ) 
      for j in xrange(step):
        if i + j < 541:
          self.data[i+j] = simulatedDist*1000
コード例 #12
0
ファイル: fre.py プロジェクト: luciusb/eduro
 def updateExtension(self, robot, id, data):
     global g_weedReportEnabled
     if id == 0x80:
         self.counter += 1
         if len(self.lastCamera) > 0:
             #        print self.counter, self.lastCamera
             cmd = self.lastCamera[0]
             if self.counter >= cmd[0]:
                 self.lastCamera = self.lastCamera[1:]
                 if cmd[1] or cmd[2]:
                     robot.beep = 1
                 else:
                     robot.beep = 0
                 sprayer(robot, cmd[1], cmd[2])
     if id == 'camera':
         if self.verbose and len(data) > 1:
             print data[1]
         cc = [int(x) for x in data[0].split()]
         leftPip = (cc[0] > BALL_SIZE_LIMIT_MIN
                    and cc[0] < BALL_SIZE_LIMIT_MAX)
         rightPip = (cc[1] > BALL_SIZE_LIMIT_MIN
                     and cc[1] < BALL_SIZE_LIMIT_MAX)
         if leftPip or rightPip:
             print "WEED:", leftPip, rightPip, g_weedReportEnabled
             if leftPip and g_weedReportEnabled:
                 xy = combinedPose(robot.localisation.pose(),
                                   (0, 0.35, 0))[:2]
                 #          reportBall( robot.gpsData )
                 viewlog.dumpBeacon(xy, color=(255, 255, 0))
             if rightPip and g_weedReportEnabled:
                 xy = combinedPose(robot.localisation.pose(),
                                   (0, -0.35, 0))[:2]
                 #          reportBall( robot.gpsData )
                 viewlog.dumpBeacon(xy, color=(255, 255, 0))
             if g_weedReportEnabled:
                 self.lastCamera.append(
                     (self.counter + 0, leftPip, rightPip))
         else:
             self.lastCamera.append((self.counter + 0 + 4, False, False))
コード例 #13
0
ファイル: simulator.py プロジェクト: luciusb/eduro
    def updateData(self):
        pose = (0, 0, 0)
        if self.robot and self.robot.localisation:
            pose = self.robot.localisation.pose()

        step = 10
        for i in xrange(0, 541, step):
            angle = math.radians((i - 270) / 2.0)
            absPose = combinedPose(pose, (0, 0, angle))  # TODO shift of laser
            simulatedDist = rayTrace(absPose, self.obstacles)
            for j in xrange(step):
                if i + j < 541:
                    self.data[i + j] = simulatedDist * 1000
コード例 #14
0
ファイル: vfh.py プロジェクト: robotika/eduro
    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
コード例 #15
0
ファイル: sickday2016.py プロジェクト: robotika/eduro
    def find_cube(self, timeout):
        print "find_cube-v1"
        prev = None
        cd = CubeDetector(self.robot.laser.pose)
        startTime = self.robot.time
        while self.robot.time < startTime + timeout:
            self.robot.update()
            if prev != self.robot.laserData:
                prev = self.robot.laserData
                cubes = cd.detect_cubes_xy(self.robot.laserData, limit=4)
                if len(cubes) > 0:
                    for i, (cube_x, cube_y) in enumerate(cubes):
                        goal = combinedPose(self.robot.localisation.pose(), (cube_x, cube_y, 0))[:2]
                        viewlog.dumpBeacon(goal, color=(200, 200, 0) if i > 0 else (255, 255, 0))
                    cube_x, cube_y = cubes[0]
                    cube_y += 0.05  # hack for bended(?) laser
                    print "{:.2f}\t{:.2f}".format(cube_x, cube_y)
                    speed = 0.0

                    tolerance = 0.01
                    if cube_x > 0.5:
                        tolerance = 0.05

                    angle = math.atan2(cube_y, cube_x)
                    turnStep = math.radians(10)
                    if abs(angle) > math.radians(10):
                        turnStep = math.radians(50)

                    if cube_y > tolerance:
                        angularSpeed = turnStep
                    elif cube_y < -tolerance:
                        angularSpeed = -turnStep
                    else:
                        angularSpeed = 0
                        speed = 0.1
                        if cube_x > 0.5:
                            speed = 0.3  # move faster toward further goals
                        if cube_x < 0.30:
                            return True
                    self.robot.setSpeedPxPa(speed, angularSpeed)
                else:
                    self.robot.setSpeedPxPa(0.0, 0.0)

        print "TIMEOUT"
        return False
コード例 #16
0
ファイル: sickday2016.py プロジェクト: robotika/eduro
def draw_rfu620_extension(robot, id, data):
    if id=='rfu620':
        posXY = combinedPose(robot.localisation.pose(), RFU620_POSE)[:2]
        for index, d in enumerate(data[1], start=1):
            robot.last_valid_rfid = d, posXY
            i, rssi = d[:2]  # i.e. 0x1000 0206 0000
            x, y, zone = (i >> 24)&0xFF, (i >> 16)&0xFF, i&0xFF
            print hex(i), (x, y), rssi, '({}/{})'.format(index, len(data[1]))
            if (x + y) % 2 == 0:
                if rssi > -60:
                    viewlog.dumpBeacon(posXY, color=(0, 0, 255))
                else:
                    viewlog.dumpBeacon(posXY, color=(0, 0, 128))
            else:
                if rssi > -60:
                    viewlog.dumpBeacon(posXY, color=(255, 0, 255))
                else:
                    viewlog.dumpBeacon(posXY, color=(128, 0, 128))
コード例 #17
0
ファイル: sickday2014.py プロジェクト: luciusb/eduro
 def reset(self, pose=(0, 0, 0)):
     print "RESET ROW (%0.2f, %0.2f, %0.1f)" % (pose[0], pose[1],
                                                math.degrees(pose[2]))
     self.preference = None
     self.directionAngle = 0.0
     self.offset = 0
     goal = combinedPose((pose[0], pose[1], pose[2] + self.directionAngle),
                         (1.0, 0, 0))  # was radius
     self.line = Line(pose, goal)
     self.newData = False
     self.traversable = None
     self.obstacles = []
     self.step = 10  # how many neighboring measurements are merged together
     #TODO: get the laser parameters somewhere
     h = 310  # Height of the laser above ground. [mm]
     alpha = math.radians(
         81.0
     )  # An angle between a vertical direction and a forward measurement beam.
     n = 541  # Number of values provided by the laser
     self.laserRight = math.radians(
         -135.0)  # Left-most angle measured by the laser. [rad]
     self.laserLeft = math.radians(
         +135.0)  # Right-most angle measured by the laser. [rad]
     self.expectation = []  # Expected distances to the ground plane. [mm]
     epsilon = 1.0e-3
     angle_threshold = math.pi / 3  #math.pi / 2.0 - epsilon
     for i in xrange(n):
         beta = self.laserRight + (self.laserLeft -
                                   self.laserRight) * i / float(n)
         if abs(beta) >= angle_threshold:
             beta = angle_threshold * (
                 1 if beta > 0 else -1
             )  # Making sure we always have an "intersection" in a reasonable
         x = h / (math.cos(alpha) * math.cos(beta))
         self.expectation.append(x)
     avg_decim = lambda sl: sum(sl) / self.step
     self.decimatedExpectation = self.__decimate(self.expectation,
                                                 decimator=avg_decim)
コード例 #18
0
ファイル: laseranalysis.py プロジェクト: TeaPackCZ/eduro
  def updateExtension( self, robot, id, data ):
    if id == 0x80:
      # virtual bumper
      if math.fabs((robot._rampLastLeft+robot._rampLastRight)/2) > 0.2 and math.fabs(robot.currentSpeed) < 0.01:
        self.virtualBumper += 1
        if self.virtualBumper > 40:
          print "VIRTUAL BUMPER", (robot._rampLastLeft+robot._rampLastRight)/2, robot.currentSpeed
          self.collision = True
      else:
        self.virtualBumper = 0

    if id == 'laser' and len(data) > 0:
      # handle 0 = timeout and find min
      near = 10.0
      for x in islice(data, 270-90, 270+90):
        if x != 0 and x < near*1000:
          near = x/1000.0
      # TODO for 1m, slow down and define alternative route
      if near < 0.5:
        self.collision = True

      step = 10
      data2 = [x == 0 and 10000 or x for x in data]
      arr = [min(i)/1000.0 for i in [islice(data2, start, start+step) for start in range(0,len(data2),step)]]
      arr.reverse()

      limit = self.radius
      center = len(arr)/2 + self.offset
      center = min(max(center, 0), len(arr)-1)
      i = 0
      while i < center:
        if arr[center - i] < limit:
          break
        i += 1
      left = i # arr is already reversed
      i = 0
      while i + center < len(arr):
        if arr[center + i] < limit:
          break
        i += 1
      right = i
      s = ''
      for i in arr:
        s += (i<1.0 and 'x' or ' ')
      s = "".join( list(s)[:center] + ['C'] + list(s)[center:] )
      if self.verbose:
        print "'" + s + "'"       
      
      if left < 5 or right < 5:
        # wide row & collision ahead
        if self.verbose:
          print left, right, left+right
        if left < right:
          self.offset += 5
        else:
          self.offset -= 5
        self.directionAngle = math.radians( -self.offset*step/2.0 ) 
        pose = robot.localisation.pose()
        goal = combinedPose( (pose[0], pose[1], pose[2]+self.directionAngle), (self.radius, 0, 0) )
        if not self.collision:
          self.generator = self.driver.followLineG( Line( pose, goal ) )
      elif left >= 10 or right > 10:
        self.offset = 0

    if id == 0x186: 
      assert( len(data) )
      sonar = (data[1]*256 + data[0])*340.0/2.0/1000000.0
      if sonar < 0.5:
        self.collision = True
#      if self.verbose:
#        print "sonar %.2f" % sonar

    if id == 'camera':
      if self.verbose:
        print data[1]
コード例 #19
0
ファイル: sickday2014.py プロジェクト: luciusb/eduro
    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
コード例 #20
0
ファイル: sickday2014.py プロジェクト: luciusb/eduro
    def updateExtension(self, robot, id, data):
        if id == 'laser' and len(data) > 0:
            # Is there an obstacle somewhere very close?
            lbound = len(robot.laserData) / 6
            rbound = len(robot.laserData) * 5 / 6
            # (lbound, rbound) should cover the space ahead of the robot.
            obstacle_threshold = 300  # [mm]
            for x in islice(robot.laserData, lbound, rbound):
                if x > 0 and x < obstacle_threshold:
                    self.line = None
                    self.newData = True
                    self.directionAngle = 0.0
                    if self.verbose:
                        s = ''
                        for start in xrange(0, len(robot.laserData),
                                            self.step):
                            too_close = False
                            for x in islice(robot.laserData, start,
                                            start + self.step):
                                if x > 0 and x < obstacle_threshold:
                                    too_close = True
                                    break
                            s += '!' if too_close else '-'
                        print "'" + s[::
                                      -1] + "'"  # The reverse is needed to match the printed traversability pattern.
                    self.traversable = None
                    self.obstacles = []
                    return

            # Preprocess the data, so that the computation is not repeated multiple times.
            prepData = [self.FAR_AWAY if x == 0 else x for x in data]
            backData = [
                self.expectation[i] - x for (i, x) in enumerate(prepData)
            ]  # distances measured from the expected ground distance

            # Traversability stemming from "there is no obstacle close there".
            decimatedPrepData = self.__decimate(prepData, decimator=min)
            decimatedBackData = self.__decimate(backData, decimator=max)
            trav_obs = self.obstacleTraversability(decimatedBackData)

            self.traversable = trav_obs

            self.obstacles = []
            for i in xrange(len(self.traversable)):
                if not self.traversable[i]:
                    phi = self.laserRight + (self.laserLeft -
                                             self.laserRight) * i / (
                                                 len(self.traversable) - 1)
                    dist = decimatedPrepData[i] / 1000.0
                    self.obstacles.append((phi, dist))

            center = len(self.traversable) / 2 + self.offset
            if center < 0: center = 0
            elif center >= len(self.traversable):
                center = len(self.traversable) - 1

            # Look for a traversable direction. The more in the expected direction, the better.
            for i in range(max(center, len(self.traversable) - center)):
                if center - i >= 0 and self.traversable[center - i]:
                    center -= i
                    break
                elif center + i < len(
                        self.traversable) and self.traversable[center + i]:
                    center += i
                    break

            #If the center is not traversable, we should better STOP!!!
            if not self.traversable[center]:
                self.line = None
                self.newData = True
                self.directionAngle = 0.0
                if self.verbose:
                    print '+' * len(self.traversable)
                self.traversable = None
                self.obstacles = []
                return

            # Find borders of the traversable gap.
            i = 0
            while i < center:
                if not self.traversable[center - i]:
                    break
                i += 1
            right = i
            i = 0
            while i + center < len(self.traversable):
                if not self.traversable[center + i]:
                    break
                i += 1
            left = i

            # Spit the information.
            s = ''
            for t in self.traversable:
                s += (' ' if t else 'x')
            s = "".join(list(s)[:center] + ['C'] + list(s)[center:])
            s = s[::-1]
            if self.verbose:
                print "'" + s + "'"


#      print center, left, right, left+right

# Update the belief.
            if left + right <= 10:  # TODO limit based on minSize, radius and sample angle
                self.offset += (left - right) / 2
                self.directionAngle = math.radians(self.offset * self.step /
                                                   2.0)
            elif left < 5 or right < 5:
                # wide row & collision ahead
                print left, right, left + right
                if right < left:
                    self.offset += 5
                else:
                    self.offset -= 5
                self.directionAngle = math.radians(self.offset * self.step /
                                                   2.0)
            else:
                #        print "OFF", left, right, left+right
                self.directionAngle = 0.0  # if you do not know, go ahead

            pose = robot.localisation.pose()
            goal = combinedPose(
                (pose[0], pose[1], pose[2] + self.directionAngle), (1.0, 0, 0))
            self.line = Line(pose, goal)
            self.newData = True
        if id == 'camera':
            if self.verbose:
                print data[1]
コード例 #21
0
ファイル: sickday2014.py プロジェクト: TeaPackCZ/eduro
  def goToVfhDigit( self, digit, timeout, info = None ):
    TOLERATED_MISS = 0.2 # [m]
    ANGULAR_THRESHOLD = math.radians(20) # [rad]
    ANGULAR_SPEED = math.radians(60) # [rad/s]

    ENDURANCE = 3 # Amount of time the robot remains blocked before timing out and moving backwards. [s]
    RETREAT = 0.2 # A retreated distance after endurance times out. [m]

    pathFinder = LaserPath( verbose=False )
    self.robot.addExtension( pathFinder.updateExtension, "PATH" )

    turnRadius = None #1.2
#    vfh = VFH(self.robot, blockingDistance = 0.35, safetyDistance = 0.6, maxRange = 1.4, turnRadius = turnRadius, verbose = False)
    vfh = VFH(self.robot, blockingDistance = 0.2, safetyDistance = 0.3, maxRange = 1.0, turnRadius = None, verbose = False)
    self.robot.addExtension(vfh.updateExtension, "VHF")
    # Navigate roughly in the suggested direction, avoiding obstacles.
    prevDir = 0.0

    waypoint = self.cam2waypoint( self.robot.localisation.pose(), info )
    goalDir = self.waypoint2dir( self.robot.localisation.pose(), waypoint )
    print "GOAL DIR", goalDir

    oldCam = self.robot.cameraData
    countImages = 0
    countVerified = 0

    startTime = self.robot.time
    happyTime = self.robot.time
    while self.robot.time < startTime + timeout:
      if oldCam != self.robot.cameraData:
        oldCam = self.robot.cameraData
        countImages += 1
        if self.robot.cameraData and self.robot.cameraData[0]:
          info = None
          for d in parseCameraData( self.robot.cameraData ):
            # TODO switch to goToDigit for large enough number
            if d[0] == digit:
              info = d
          if info != None:
            countVerified += 1
            waypoint = self.cam2waypoint( self.robot.localisation.pose(), info )
            goalDir = self.waypoint2dir( self.robot.localisation.pose(), waypoint )
            print "GOAL DIR", goalDir, oldCam, info, digit

      dir = vfh.navigate(goalDir, prevDir, pathFinder.obstacles)
      if dir is None or not pathFinder.isTraversable(dir):
        strategy = zeroCmd()
        prevDir = 0.0
        self.robot.toDisplay = 'HH'
      else:
        pose = self.robot.localisation.pose()
        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
        self.robot.toDisplay = 'OK'
        happyTime = self.robot.time

      if self.robot.time - happyTime > ENDURANCE:
        break # does not have sense to wait - try to turn somewhere else ...
        # We are stuck for too long. Let's try to retreat a bit:
        #    1) to show we are alive,
        #    2) to hope the robot gets out of the blocked state.
        # Note: p(bumping backward) <= p(being disqualified for not moving) == 1.0
        pose = self.robot.localisation.pose()
        goal = combinedPose( pose, (-(RETREAT + TOLERATED_MISS), 0, 0) )
        strategy = self.driver.goToG( goal , TOLERATED_MISS, backward = True, angleThreshold = ANGULAR_THRESHOLD,  angularSpeed = ANGULAR_SPEED)
        self.robot.toDisplay = '\/'
        for (speed, angularSpeed) in strategy:
          self.robot.setSpeedPxPa( speed, angularSpeed )
          self.robot.update()
        happyTime = self.robot.time
        continue # TODO maybe replace by return -> give up

      for (speed, angularSpeed) in strategy:
        self.robot.setSpeedPxPa( speed, angularSpeed )
        self.robot.update()
        pose = self.robot.localisation.pose()
#        isThere = math.hypot(pose[0] - lastX, pose[1] - lastY) <= TOLERATED_MISS
#        if isThere or pathFinder.newData:
        if pathFinder.newData:
          pathFinder.newData = False
          break

    self.robot.removeExtension( "VHF" )
    self.robot.removeExtension( "PATH" )
コード例 #22
0
ファイル: sickday2014.py プロジェクト: luciusb/eduro
    def goVfh(self, timeout, maxDist=None):
        print "goVfh", maxDist
        TOLERATED_MISS = 0.2  # [m]
        ANGULAR_THRESHOLD = math.radians(20)  # [rad]
        ANGULAR_SPEED = math.radians(60)  # [rad/s]

        ENDURANCE = 3  # Amount of time the robot remains blocked before timing out and moving backwards. [s]
        RETREAT = 0.2  # A retreated distance after endurance times out. [m]

        pathFinder = LaserPath(verbose=False)
        self.robot.addExtension(pathFinder.updateExtension, "PATH")

        turnRadius = None  #1.2
        #    vfh = VFH(self.robot, blockingDistance = 0.35, safetyDistance = 0.6, maxRange = 1.4, turnRadius = turnRadius, verbose = False)
        vfh = VFH(self.robot,
                  blockingDistance=0.2,
                  safetyDistance=0.3,
                  maxRange=1.0,
                  turnRadius=None,
                  verbose=False)
        self.robot.addExtension(vfh.updateExtension, "VHF")
        # Navigate roughly in the suggested direction, avoiding obstacles.
        prevDir = 0.0
        goalDir = 0.0

        startTime = self.robot.time
        happyTime = self.robot.time
        distTraveled = 0.0
        while self.robot.time < startTime + timeout:
            if maxDist is not None and distTraveled > maxDist:
                print "goVfh - maxDist reached"
                break
            dir = vfh.navigate(goalDir, prevDir, pathFinder.obstacles)
            if dir is None or not pathFinder.isTraversable(dir):
                strategy = zeroCmd()
                prevDir = 0.0
                self.robot.toDisplay = 'HH'
            else:
                pose = self.robot.localisation.pose()
                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
                self.robot.toDisplay = 'OK'
                happyTime = self.robot.time

            if self.robot.time - happyTime > ENDURANCE:
                print "ENDURANCE!"
                break  # does not have sense to wait - try to turn somewhere else ...
                # We are stuck for too long. Let's try to retreat a bit:
                #    1) to show we are alive,
                #    2) to hope the robot gets out of the blocked state.
                # Note: p(bumping backward) <= p(being disqualified for not moving) == 1.0
                pose = self.robot.localisation.pose()
                goal = combinedPose(pose, (-(RETREAT + TOLERATED_MISS), 0, 0))
                strategy = self.driver.goToG(goal,
                                             TOLERATED_MISS,
                                             backward=True,
                                             angleThreshold=ANGULAR_THRESHOLD,
                                             angularSpeed=ANGULAR_SPEED)
                self.robot.toDisplay = '\/'
                for (speed, angularSpeed) in strategy:
                    self.robot.setSpeedPxPa(speed, angularSpeed)
                    self.robot.update()
                    distTraveled += self.robot.lastDistStep
                happyTime = self.robot.time
                continue  # TODO maybe replace by return -> give up

            for (speed, angularSpeed) in strategy:
                self.robot.setSpeedPxPa(speed, angularSpeed)
                self.robot.update()
                distTraveled += self.robot.lastDistStep
                pose = self.robot.localisation.pose()
                if pathFinder.newData:
                    pathFinder.newData = False
                    break

        self.robot.removeExtension("VHF")
        self.robot.removeExtension("PATH")
        print "... traveled", distTraveled, "time", self.robot.time - startTime
コード例 #23
0
ファイル: sickday2014.py プロジェクト: TeaPackCZ/eduro
  def goVfh( self, timeout, maxDist=None ):
    print "goVfh", maxDist
    TOLERATED_MISS = 0.2 # [m]
    ANGULAR_THRESHOLD = math.radians(20) # [rad]
    ANGULAR_SPEED = math.radians(60) # [rad/s]

    ENDURANCE = 3 # Amount of time the robot remains blocked before timing out and moving backwards. [s]
    RETREAT = 0.2 # A retreated distance after endurance times out. [m]

    pathFinder = LaserPath( verbose=False )
    self.robot.addExtension( pathFinder.updateExtension, "PATH" )

    turnRadius = None #1.2
#    vfh = VFH(self.robot, blockingDistance = 0.35, safetyDistance = 0.6, maxRange = 1.4, turnRadius = turnRadius, verbose = False)
    vfh = VFH(self.robot, blockingDistance = 0.2, safetyDistance = 0.3, maxRange = 1.0, turnRadius = None, verbose = False)
    self.robot.addExtension(vfh.updateExtension, "VHF")
    # Navigate roughly in the suggested direction, avoiding obstacles.
    prevDir = 0.0
    goalDir = 0.0

    startTime = self.robot.time
    happyTime = self.robot.time
    distTraveled = 0.0
    while self.robot.time < startTime + timeout:
      if maxDist is not None and distTraveled > maxDist:
        print "goVfh - maxDist reached"
        break
      dir = vfh.navigate(goalDir, prevDir, pathFinder.obstacles)
      if dir is None or not pathFinder.isTraversable(dir):
        strategy = zeroCmd()
        prevDir = 0.0
        self.robot.toDisplay = 'HH'
      else:
        pose = self.robot.localisation.pose()
        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
        self.robot.toDisplay = 'OK'
        happyTime = self.robot.time

      if self.robot.time - happyTime > ENDURANCE:
        print "ENDURANCE!"
        break # does not have sense to wait - try to turn somewhere else ...
        # We are stuck for too long. Let's try to retreat a bit:
        #    1) to show we are alive,
        #    2) to hope the robot gets out of the blocked state.
        # Note: p(bumping backward) <= p(being disqualified for not moving) == 1.0
        pose = self.robot.localisation.pose()
        goal = combinedPose( pose, (-(RETREAT + TOLERATED_MISS), 0, 0) )
        strategy = self.driver.goToG( goal , TOLERATED_MISS, backward = True, angleThreshold = ANGULAR_THRESHOLD,  angularSpeed = ANGULAR_SPEED)
        self.robot.toDisplay = '\/'
        for (speed, angularSpeed) in strategy:
          self.robot.setSpeedPxPa( speed, angularSpeed )
          self.robot.update()
          distTraveled += self.robot.lastDistStep
        happyTime = self.robot.time
        continue # TODO maybe replace by return -> give up

      for (speed, angularSpeed) in strategy:
        self.robot.setSpeedPxPa( speed, angularSpeed )
        self.robot.update()
        distTraveled += self.robot.lastDistStep
        pose = self.robot.localisation.pose()
        if pathFinder.newData:
          pathFinder.newData = False
          break

    self.robot.removeExtension( "VHF" )
    self.robot.removeExtension( "PATH" )
    print "... traveled", distTraveled, "time", self.robot.time - startTime
コード例 #24
0
ファイル: sickday2014.py プロジェクト: luciusb/eduro
    def goToVfhDigit(self, digit, timeout, info=None):
        TOLERATED_MISS = 0.2  # [m]
        ANGULAR_THRESHOLD = math.radians(20)  # [rad]
        ANGULAR_SPEED = math.radians(60)  # [rad/s]

        ENDURANCE = 3  # Amount of time the robot remains blocked before timing out and moving backwards. [s]
        RETREAT = 0.2  # A retreated distance after endurance times out. [m]

        pathFinder = LaserPath(verbose=False)
        self.robot.addExtension(pathFinder.updateExtension, "PATH")

        turnRadius = None  #1.2
        #    vfh = VFH(self.robot, blockingDistance = 0.35, safetyDistance = 0.6, maxRange = 1.4, turnRadius = turnRadius, verbose = False)
        vfh = VFH(self.robot,
                  blockingDistance=0.2,
                  safetyDistance=0.3,
                  maxRange=1.0,
                  turnRadius=None,
                  verbose=False)
        self.robot.addExtension(vfh.updateExtension, "VHF")
        # Navigate roughly in the suggested direction, avoiding obstacles.
        prevDir = 0.0

        waypoint = self.cam2waypoint(self.robot.localisation.pose(), info)
        goalDir = self.waypoint2dir(self.robot.localisation.pose(), waypoint)
        print "GOAL DIR", goalDir

        oldCam = self.robot.cameraData
        countImages = 0
        countVerified = 0

        startTime = self.robot.time
        happyTime = self.robot.time
        while self.robot.time < startTime + timeout:
            if oldCam != self.robot.cameraData:
                oldCam = self.robot.cameraData
                countImages += 1
                if self.robot.cameraData and self.robot.cameraData[0]:
                    info = None
                    for d in parseCameraData(self.robot.cameraData):
                        # TODO switch to goToDigit for large enough number
                        if d[0] == digit:
                            info = d
                    if info != None:
                        countVerified += 1
                        waypoint = self.cam2waypoint(
                            self.robot.localisation.pose(), info)
                        goalDir = self.waypoint2dir(
                            self.robot.localisation.pose(), waypoint)
                        print "GOAL DIR", goalDir, oldCam, info, digit

            dir = vfh.navigate(goalDir, prevDir, pathFinder.obstacles)
            if dir is None or not pathFinder.isTraversable(dir):
                strategy = zeroCmd()
                prevDir = 0.0
                self.robot.toDisplay = 'HH'
            else:
                pose = self.robot.localisation.pose()
                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
                self.robot.toDisplay = 'OK'
                happyTime = self.robot.time

            if self.robot.time - happyTime > ENDURANCE:
                break  # does not have sense to wait - try to turn somewhere else ...
                # We are stuck for too long. Let's try to retreat a bit:
                #    1) to show we are alive,
                #    2) to hope the robot gets out of the blocked state.
                # Note: p(bumping backward) <= p(being disqualified for not moving) == 1.0
                pose = self.robot.localisation.pose()
                goal = combinedPose(pose, (-(RETREAT + TOLERATED_MISS), 0, 0))
                strategy = self.driver.goToG(goal,
                                             TOLERATED_MISS,
                                             backward=True,
                                             angleThreshold=ANGULAR_THRESHOLD,
                                             angularSpeed=ANGULAR_SPEED)
                self.robot.toDisplay = '\/'
                for (speed, angularSpeed) in strategy:
                    self.robot.setSpeedPxPa(speed, angularSpeed)
                    self.robot.update()
                happyTime = self.robot.time
                continue  # TODO maybe replace by return -> give up

            for (speed, angularSpeed) in strategy:
                self.robot.setSpeedPxPa(speed, angularSpeed)
                self.robot.update()
                pose = self.robot.localisation.pose()
                #        isThere = math.hypot(pose[0] - lastX, pose[1] - lastY) <= TOLERATED_MISS
                #        if isThere or pathFinder.newData:
                if pathFinder.newData:
                    pathFinder.newData = False
                    break

        self.robot.removeExtension("VHF")
        self.robot.removeExtension("PATH")
コード例 #25
0
ファイル: sickday2014.py プロジェクト: TeaPackCZ/eduro
  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
コード例 #26
0
ファイル: sickday2014.py プロジェクト: TeaPackCZ/eduro
  def updateExtension( self, robot, id, data ):
    if id == 'laser' and len(data) > 0:
      # Is there an obstacle somewhere very close?
      lbound = len(robot.laserData) / 6
      rbound = len(robot.laserData) * 5 / 6
      # (lbound, rbound) should cover the space ahead of the robot.
      obstacle_threshold = 300 # [mm]
      for x in islice(robot.laserData, lbound, rbound):
        if x > 0 and x < obstacle_threshold:
            self.line = None
            self.newData = True
            self.directionAngle = 0.0
            if self.verbose:
              s = ''
              for start in xrange(0, len(robot.laserData), self.step):
                too_close = False
                for x in islice(robot.laserData, start, start+self.step):
                  if x > 0 and x < obstacle_threshold:
                    too_close = True
                    break
                s += '!' if too_close else '-'
              print "'" + s[::-1] + "'" # The reverse is needed to match the printed traversability pattern.
            self.traversable = None
            self.obstacles = []
            return

      # Preprocess the data, so that the computation is not repeated multiple times.
      prepData = [ self.FAR_AWAY if x == 0 else x for x in data ]
      backData = [ self.expectation[i] - x for (i, x) in enumerate(prepData) ] # distances measured from the expected ground distance

      # Traversability stemming from "there is no obstacle close there".
      decimatedPrepData = self.__decimate(prepData, decimator = min)
      decimatedBackData = self.__decimate(backData, decimator = max)
      trav_obs = self.obstacleTraversability( decimatedBackData )

      self.traversable = trav_obs

      self.obstacles = []
      for i in xrange(len(self.traversable)):
        if not self.traversable[i]:
          phi = self.laserRight + (self.laserLeft - self.laserRight) * i / (len(self.traversable) - 1)
          dist = decimatedPrepData[i] / 1000.0
          self.obstacles.append( (phi, dist) )

      center = len(self.traversable)/2 + self.offset
      if center < 0: center = 0
      elif center >= len(self.traversable): center = len(self.traversable) - 1

      # Look for a traversable direction. The more in the expected direction, the better.
      for i in range(max(center, len(self.traversable) - center)):
        if center - i >= 0 and self.traversable[center - i]:
          center -= i
          break
        elif center + i < len(self.traversable) and self.traversable[center + i]:
          center += i
          break

      #If the center is not traversable, we should better STOP!!!
      if not self.traversable[center]:
        self.line = None
        self.newData = True
        self.directionAngle = 0.0
        if self.verbose:
          print '+' * len(self.traversable)
        self.traversable = None
        self.obstacles = []
        return

      # Find borders of the traversable gap.
      i = 0
      while i < center:
        if not self.traversable[center - i]:
          break
        i += 1
      right = i
      i = 0
      while i + center < len(self.traversable):
        if not self.traversable[center + i]:
          break
        i += 1
      left = i

      # Spit the information.
      s = ''
      for t in self.traversable:
        s += (' ' if t else 'x')
      s = "".join( list(s)[:center] + ['C'] + list(s)[center:] )
      s = s[::-1]
      if self.verbose:
        print "'" + s + "'"      
#      print center, left, right, left+right

      # Update the belief.
      if left+right <= 10: # TODO limit based on minSize, radius and sample angle
        self.offset += (left - right) / 2
        self.directionAngle = math.radians( self.offset * self.step / 2.0 )
      elif left < 5 or right < 5:
        # wide row & collision ahead
        print left, right, left+right
        if right < left:
          self.offset += 5
        else:
          self.offset -= 5
        self.directionAngle = math.radians( self.offset * self.step / 2.0 )
      else:
#        print "OFF", left, right, left+right
        self.directionAngle = 0.0 # if you do not know, go ahead

      pose = robot.localisation.pose()
      goal = combinedPose( (pose[0], pose[1], pose[2]+self.directionAngle), (1.0, 0, 0) )
      self.line = Line( pose, goal )
      self.newData = True
    if id == 'camera':
      if self.verbose:
        print data[1]
コード例 #27
0
ファイル: fre.py プロジェクト: robotika/eduro
  def crossRows2( self, row, num, rowsOnLeft ):
    IGNORE_NEIGHBORS = 2
    ROWS_OFFSET = 0.7 #0.5

#    if row.lastLeft:
#      viewlog.dumpBeacon(row.lastLeft[:2], color=(0,128,0))
#    if row.lastRight:
#      viewlog.dumpBeacon(row.lastRight[:2], color=(0,128,50))
    start = self.robot.localisation.pose()[:2]
    viewlog.dumpBeacon( start, color=(255,128,0))

    goal = combinedPose( self.robot.localisation.pose(), (1.0, 0, 0) )    
    line = Line( self.robot.localisation.pose(), goal )
    lastA, lastB = None, None
    ends = []
    while True:
      for cmd in self.driver.followLineG( line ):
        self.robot.setSpeedPxPa( *cmd ) 
        self.robot.update()
        if row.newData:
          row.newData = False
          break
      else:
        print "END OF LINE REACHED!"

      if self.robot.preprocessedLaser != None:
        tmp = self.robot.preprocessedLaser[:]
        tlen = len(tmp)
        if rowsOnLeft:
          tmp = tmp[:tlen/2] + [3.0]*(tlen-tlen/2)
        else:
          tmp = [3.0]*(tlen-tlen/2) + tmp[tlen/2:]
        sarr = sorted([(x,i) for (i,x) in enumerate(tmp)])[:5]
        ax,ai = sarr[0]
        for bx,bi in sarr[1:]:
          if abs(ai-bi) > IGNORE_NEIGHBORS:
            break
        else:
          print "NO 2nd suitable minimum"
        print (ax,ai), (bx,bi)
        if rowsOnLeft:
          offset = -ROWS_OFFSET
          if ai > bi:
            (ax,ai), (bx,bi) = (bx,bi), (ax,ai)
        else:
          offset = ROWS_OFFSET
          if ai < bi: # rows on right
            (ax,ai), (bx,bi) = (bx,bi), (ax,ai)
        p = self.robot.localisation.pose()
        A = combinedPose( (p[0], p[1], p[2]+math.radians(135-5*ai) ), (ax,0,0) )
        B = combinedPose( (p[0], p[1], p[2]+math.radians(135-5*bi) ), (bx,0,0) )
        if lastA == None:
          ends.extend( [A,B] )
          lastA, lastB = A, B
        if self.verbose:
          print "DIST", distance(lastA, A), distance(lastB, B), distance(lastB,A)
        if distance(lastB,A) < 0.2:
          dist = distance(start, self.robot.localisation.pose())
          print "NEXT ROW", dist
          if dist > 0.4:
            ends.append( B ) # new one
          lastA, lastB = A, B
        line = Line(A,B) # going through the ends of rows
        A2 = combinedPose( (A[0], A[1], line.angle), (0, offset, 0) )
        B2 = combinedPose( (B[0], B[1], line.angle), (2.0, offset, 0) )
        line = Line(A2, B2)
        viewlog.dumpBeacon( A[:2], color=(200,0,0) )
        viewlog.dumpBeacon( B[:2], color=(200,128,0) )
        viewlog.dumpBeacon( A2[:2], color=(255,0,0) )
        viewlog.dumpBeacon( B2[:2], color=(255,128,0) )
        if len(ends) > num + 1:
          break
      else:
        print "BACKUP solution!!!"
        goal = combinedPose( self.robot.localisation.pose(), (1.0, 0, 0) )    
        line = Line( self.robot.localisation.pose(), goal )
コード例 #28
0
    def updateExtension(self, robot, id, data):
        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)
                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
                    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])
コード例 #29
0
ファイル: fre.py プロジェクト: robotika/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])
コード例 #30
0
    def crossRows2(self, row, num, rowsOnLeft):
        IGNORE_NEIGHBORS = 2
        ROWS_OFFSET = 0.7  #0.5

        #    if row.lastLeft:
        #      viewlog.dumpBeacon(row.lastLeft[:2], color=(0,128,0))
        #    if row.lastRight:
        #      viewlog.dumpBeacon(row.lastRight[:2], color=(0,128,50))
        start = self.robot.localisation.pose()[:2]
        viewlog.dumpBeacon(start, color=(255, 128, 0))

        goal = combinedPose(self.robot.localisation.pose(), (1.0, 0, 0))
        line = Line(self.robot.localisation.pose(), goal)
        lastA, lastB = None, None
        ends = []
        while True:
            for cmd in self.driver.followLineG(line):
                self.robot.setSpeedPxPa(*cmd)
                self.robot.update()
                if row.newData:
                    row.newData = False
                    break
            else:
                print "END OF LINE REACHED!"

            if self.robot.preprocessedLaser != None:
                tmp = self.robot.preprocessedLaser[:]
                tlen = len(tmp)
                if rowsOnLeft:
                    tmp = tmp[:tlen / 2] + [3.0] * (tlen - tlen / 2)
                else:
                    tmp = [3.0] * (tlen - tlen / 2) + tmp[tlen / 2:]
                sarr = sorted([(x, i) for (i, x) in enumerate(tmp)])[:5]
                ax, ai = sarr[0]
                for bx, bi in sarr[1:]:
                    if abs(ai - bi) > IGNORE_NEIGHBORS:
                        break
                else:
                    print "NO 2nd suitable minimum"
                print(ax, ai), (bx, bi)
                if rowsOnLeft:
                    offset = -ROWS_OFFSET
                    if ai > bi:
                        (ax, ai), (bx, bi) = (bx, bi), (ax, ai)
                else:
                    offset = ROWS_OFFSET
                    if ai < bi:  # rows on right
                        (ax, ai), (bx, bi) = (bx, bi), (ax, ai)
                p = self.robot.localisation.pose()
                A = combinedPose(
                    (p[0], p[1], p[2] + math.radians(135 - 5 * ai)),
                    (ax, 0, 0))
                B = combinedPose(
                    (p[0], p[1], p[2] + math.radians(135 - 5 * bi)),
                    (bx, 0, 0))
                if lastA == None:
                    ends.extend([A, B])
                    lastA, lastB = A, B
                if self.verbose:
                    print "DIST", distance(lastA,
                                           A), distance(lastB,
                                                        B), distance(lastB, A)
                if distance(lastB, A) < 0.2:
                    dist = distance(start, self.robot.localisation.pose())
                    print "NEXT ROW", dist
                    if dist > 0.4:
                        ends.append(B)  # new one
                    lastA, lastB = A, B
                line = Line(A, B)  # going through the ends of rows
                A2 = combinedPose((A[0], A[1], line.angle), (0, offset, 0))
                B2 = combinedPose((B[0], B[1], line.angle), (2.0, offset, 0))
                line = Line(A2, B2)
                viewlog.dumpBeacon(A[:2], color=(200, 0, 0))
                viewlog.dumpBeacon(B[:2], color=(200, 128, 0))
                viewlog.dumpBeacon(A2[:2], color=(255, 0, 0))
                viewlog.dumpBeacon(B2[:2], color=(255, 128, 0))
                if len(ends) > num + 1:
                    break
            else:
                print "BACKUP solution!!!"
                goal = combinedPose(self.robot.localisation.pose(),
                                    (1.0, 0, 0))
                line = Line(self.robot.localisation.pose(), goal)
コード例 #31
0
ファイル: laseranalysis.py プロジェクト: luciusb/eduro
    def updateExtension(self, robot, id, data):
        if id == 0x80:
            # virtual bumper
            if math.fabs((robot._rampLastLeft + robot._rampLastRight) /
                         2) > 0.2 and math.fabs(robot.currentSpeed) < 0.01:
                self.virtualBumper += 1
                if self.virtualBumper > 40:
                    print "VIRTUAL BUMPER", (
                        robot._rampLastLeft +
                        robot._rampLastRight) / 2, robot.currentSpeed
                    self.collision = True
            else:
                self.virtualBumper = 0

        if id == 'laser' and len(data) > 0:
            # handle 0 = timeout and find min
            near = 10.0
            for x in islice(data, 270 - 90, 270 + 90):
                if x != 0 and x < near * 1000:
                    near = x / 1000.0
            # TODO for 1m, slow down and define alternative route
            if near < 0.5:
                self.collision = True

            step = 10
            data2 = [x == 0 and 10000 or x for x in data]
            arr = [
                min(i) / 1000.0 for i in [
                    islice(data2, start, start + step)
                    for start in range(0, len(data2), step)
                ]
            ]
            arr.reverse()

            limit = self.radius
            center = len(arr) / 2 + self.offset
            center = min(max(center, 0), len(arr) - 1)
            i = 0
            while i < center:
                if arr[center - i] < limit:
                    break
                i += 1
            left = i  # arr is already reversed
            i = 0
            while i + center < len(arr):
                if arr[center + i] < limit:
                    break
                i += 1
            right = i
            s = ''
            for i in arr:
                s += (i < 1.0 and 'x' or ' ')
            s = "".join(list(s)[:center] + ['C'] + list(s)[center:])
            if self.verbose:
                print "'" + s + "'"

            if left < 5 or right < 5:
                # wide row & collision ahead
                if self.verbose:
                    print left, right, left + right
                if left < right:
                    self.offset += 5
                else:
                    self.offset -= 5
                self.directionAngle = math.radians(-self.offset * step / 2.0)
                pose = robot.localisation.pose()
                goal = combinedPose(
                    (pose[0], pose[1], pose[2] + self.directionAngle),
                    (self.radius, 0, 0))
                if not self.collision:
                    self.generator = self.driver.followLineG(Line(pose, goal))
            elif left >= 10 or right > 10:
                self.offset = 0

        if id == 0x186:
            assert (len(data))
            sonar = (data[1] * 256 + data[0]) * 340.0 / 2.0 / 1000000.0
            if sonar < 0.5:
                self.collision = True
#      if self.verbose:
#        print "sonar %.2f" % sonar

        if id == 'camera':
            if self.verbose:
                print data[1]