コード例 #1
0
    def __init__(self, use_machine=True):
        if use_machine:
            self.machine = Machine(CONTROL_HOSTNAME)
        else:
            self.machine = None

        self.map = StoneMap('stonemap')
        # shortcuts for convenience

        if self.machine:
            self.m = self.machine
            self.c = self.machine.control
            self.c.reset()
            self.c.home()
コード例 #2
0
ファイル: brain.py プロジェクト: allesblinkt/riverbed-vision
    def __init__(self, use_machine=True):
        if use_machine:
            self.machine = Machine(CONTROL_HOSTNAME)
        else:
            self.machine = None

        self.map = StoneMap('stonemap')
        # shortcuts for convenience

        if self.machine:
            self.m = self.machine
            self.c = self.machine.control
            self.c.reset()
            self.c.home()
コード例 #3
0
class Brain(object):
    def __init__(self, use_machine=True):
        if use_machine:
            self.machine = Machine(CONTROL_HOSTNAME)
        else:
            self.machine = None

        self.map = StoneMap('stonemap')
        # shortcuts for convenience

        if self.machine:
            self.m = self.machine
            self.c = self.machine.control
            self.c.reset()
            self.c.home()

            # go home (also test if the machine is initialized and working)
            # self.c.home()

    def start(self):
        pass

    def run(self, prgname):
        f = getattr(self, prgname)
        f()

    def scan(self, startx=0, starty=0, analyze=True):
        log.debug('Begin scanning')
        self.c.pickup_top()
        self.z = self.c.get_pickup_z()
        self.m.go(e=90)
        self.c.block()

        stones = []
        x, y = self.map.size
        stepx = int(self.machine.cam.viewx / 2.0)
        stepy = int(self.machine.cam.viewy / 2.0)
        for i in range(int(startx), x + 1, stepx):
            for j in range(int(starty), y + 1, stepy):
                self.m.go(x=i, y=j)
                self.c.block()
                if analyze:
                    st = self.machine.cam.grab_extract(i, j, save=True)
                    for s in st:
                        s.center = self.machine.cam.pos_to_mm(s.center,
                                                              offset=(i, j))
                        s.size = self.machine.cam.size_to_mm(s.size)
                        s.rank = 0.0
                        stones.append(s)
                else:
                    self.machine.cam.grab(save=True)
        log.debug('End scanning')
        if analyze:
            # select correct stones
            log.debug('Begin selecting/reducing stones')
            for i in range(len(stones)):
                for j in range(i + 1, len(stones)):
                    s = stones[i].similarity(stones[j])
                    stones[i].rank += s
                    stones[j].rank -= s
            log.debug('End selecting/reducing stones')
            # copy selected stones to storage
            self.map.stones = [s for s in stones if s.rank >= 1.5]
            self.map.save()

    def scan_from_files(self, analyze=True):
        import re
        import os
        import fnmatch
        import pickle as serialization

        log.debug('Begin scanning')

        cam = Camera(None)

        stones = []
        p = "map_offline/"  # looks here for pngs...

        pngfiles = []

        bins = []

        for file in os.listdir(p):
            if fnmatch.fnmatch(file, 'grab*.jpg'):
                pngfiles.append(file)

        for fn in pngfiles:
            m = re.search('\w+_(\d+)_(\d+)', fn)

            image = cv2.imread(os.path.join(p, fn), -1)
            (h, w) = image.shape[:2]

            xp, yp = float(m.group(1)), float(m.group(2))

            log.info('Reading file at {} {}'.format(xp, yp))

            localstones = []

            st = cam.grab_extract(xp, yp, img=image, save=False)
            for s in st:
                s.center = cam.pos_to_mm(s.center, offset=(xp, yp))
                s.size = cam.size_to_mm(s.size)
                s.rank = 0.0
                stones.append(s)
                localstones.append(s)

            bin = {'x': xp, 'y': yp, 'stones': localstones}
            bins.append(bin)

        with open('map/intermediate.data', 'wb') as f:
            serialization.dump(bins, f)

        log.debug('Found {} stones in {} bins'.format(len(stones), len(bins)))

        log.debug('End scanning')
        chosen_stones = []
        if analyze:
            # select correct stones
            log.debug('Begin selecting/reducing stones')
            for bi in range(len(bins)):
                bin_a = bins[bi]
                stones_a = bin_a['stones']

                other_stones = []

                for bj in range(bi + 1, len(bins)):
                    bin_b = bins[bj]
                    stones_b = bin_b['stones']

                    d_x = abs(bin_b['x'] - bin_a['x'])
                    d_y = abs(bin_b['y'] - bin_a['y'])

                    if d_x > cam.viewx * 2.0 or d_y > cam.viewy * 2.0:
                        continue

                    other_stones += stones_b

                for this_stone in stones_a:
                    for other_stone in other_stones:
                        if this_stone.coincides(other_stone):
                            other_stone.bogus = True

                    if not this_stone.bogus:
                        chosen_stones.append(this_stone)

            log.debug('End selecting/reducing stones')
            # copy selected stones to storage
            self.map.stones = [s for s in chosen_stones]
            self.map.stage = (0, 2, None, None)

            log.debug('Reduced from {} to {} stones'.format(
                len(stones), len(self.map.stones)))

            self.map.save(meta=True)

    def demo1(self):
        # demo program which moves stone back and forth
        while True:
            self._move_stone_absolute((3500, 1000), 0, (3500, 1250), 90)
            self._move_stone_absolute((3500, 1250), 90, (3500, 1000), 0)

    def demo2(self):
        while True:
            self._move_stone((3500, 1000), 30, (3500, 1000), 120)
            self._move_stone((3500, 1000), 120, (3500, 1000), 30)

    def demo3(self):
        while True:
            self._move_stone((3700, 1000), 30, (3700, 1000), 120)
            self._move_stone((3700, 1000), 120, (3700, 1000), 30)

    def _move_stone_absolute(self, c1, a1, c2, a2):
        log.debug('Abs moving stone center %s angle %s to center %s angle %s',
                  str(c1), str(a1), str(c2), str(a2))

        if not self.m.check_movement(x=c1[0], y=c1[1], e=a1):
            log.warn('Invalid pickup position {},{}. Aborting move.'.format(
                c1[0], c1[1]))
            return False

        if not self.m.check_movement(x=c2[0], y=c2[1], e=a2):
            log.warn('Invalid placement position {},{}. Aborting move.'.format(
                c2[0], c2[1]))
            return False

        self.m.go(x=c1[0], y=c1[1], e=a1)
        ret = self.m.lift_up(x=c1[0], y=c1[1])

        if ret:
            self.m.go(x=c2[0], y=c2[1], e=a2)
            self.m.lift_down()
            return True
        else:
            return False

    def _turn_stone_calc(self, c1, sa, c2, ea):
        h1 = self.machine.head_delta(angle=sa)
        c1 = c1[0] - h1[0], c1[1] - h1[1]
        h2 = self.machine.head_delta(angle=ea)
        c2 = c2[0] - h2[0], c2[1] - h2[1]

        off = (0.0, 0.0)  # was 6.0, 0
        return (c1[0] + off[0],
                c1[1] + off[1]), (c2[0] + off[0], c2[1] + off[1]
                                  )  # FIXME: Offseted

    def _move_stone(self, c1, a1, c2, a2):
        log.debug('Moving stone center %s angle %s to center %s angle %s',
                  str(c1), str(a1), str(c2), str(a2))
        da = a1 - a2
        if da < 0.0:
            da = 360.0 + da
        da = da % 180

        # Case 1
        nc1, nc2 = self._turn_stone_calc(c1, 0.0, c2, da)

        max_y = self.map.size[1]
        if c1[1] >= 0 and c2[1] >= 0 and c1[1] <= max_y and c2[1] <= max_y:
            return self._move_stone_absolute(nc1, 0, nc2, da)
        else:  # Case 2
            nc1, nc2 = self._turn_stone_calc(c1, 180.0, c2, da)
            return self._move_stone_absolute(nc1, 180.0, nc2, da)
        # TODO: save map here ?

    def save_map(self):
        log.debug('Saving map...')
        self.map.save()
        log.debug('Saving map. Done.')

    def performance(self):
        saving_thread = threading.Thread(target=save_map, args=(self.map, ))

        while True:
            log.debug('Thinking...')
            i, nc, na, stage, force = art_step(self.map)

            if i is not None:
                s = self.map.stones[i]

                if nc is None:
                    nc = s.center

                if na is None:
                    na = s.angle

                log.debug('Placing stone {} from {} to {}'.format(
                    i, s.center, nc))

                if self._move_stone(s.center, s.angle, nc,
                                    na):  # Pickup worked
                    if saving_thread.is_alive():
                        saving_thread.join(
                        )  # wait until save is completed if still being done
                    s.center = nc
                    s.angle = na
                    self.map.stage = stage  # Commit stage
                    log.info('Placement worked')
                else:  # Fail, flag
                    if saving_thread.is_alive():
                        saving_thread.join(
                        )  # wait until save is completed if still being done
                    s.flag = True
                    log.info('Placement failed')

                saving_thread = threading.Thread(target=save_map,
                                                 args=(self.map, ))
                saving_thread.start()  # async call of self.save_map

            elif force:  # Art wants us to advance anyhow
                if saving_thread.is_alive():
                    saving_thread.join(
                    )  # wait until save is completed if still being done
                self.map.stage = stage  # Commit stage

                saving_thread = threading.Thread(target=save_map,
                                                 args=(self.map, ))
                saving_thread.start()  # async call of self.save_map
            else:
                if saving_thread.is_alive():
                    saving_thread.join(
                    )  # wait until save is completed if still being done
                time.sleep(1)

        if saving_thread.is_alive():
            saving_thread.join(
            )  # wait until save is completed if still being done
コード例 #4
0
ファイル: brain.py プロジェクト: allesblinkt/riverbed-vision
class Brain(object):

    def __init__(self, use_machine=True):
        if use_machine:
            self.machine = Machine(CONTROL_HOSTNAME)
        else:
            self.machine = None

        self.map = StoneMap('stonemap')
        # shortcuts for convenience

        if self.machine:
            self.m = self.machine
            self.c = self.machine.control
            self.c.reset()
            self.c.home()

            # go home (also test if the machine is initialized and working)
            # self.c.home()

    def start(self):
        pass

    def run(self, prgname):
        f = getattr(self, prgname)
        f()

    def scan(self, startx=0, starty=0, analyze=True):
        log.debug('Begin scanning')
        self.c.pickup_top()
        self.z = self.c.get_pickup_z()
        self.m.go(e=90)
        self.c.block()

        stones = []
        x, y = self.map.size
        stepx = int(self.machine.cam.viewx / 2.0)
        stepy = int(self.machine.cam.viewy / 2.0)
        for i in range(int(startx), x + 1, stepx):
            for j in range(int(starty), y + 1, stepy):
                self.m.go(x=i, y=j)
                self.c.block()
                if analyze:
                    st = self.machine.cam.grab_extract(i, j, save=True)
                    for s in st:
                        s.center = self.machine.cam.pos_to_mm(s.center, offset=(i, j))
                        s.size = self.machine.cam.size_to_mm(s.size)
                        s.rank = 0.0
                        stones.append(s)
                else:
                    self.machine.cam.grab(save=True)
        log.debug('End scanning')
        if analyze:
            # select correct stones
            log.debug('Begin selecting/reducing stones')
            for i in range(len(stones)):
                for j in range(i + 1, len(stones)):
                    s = stones[i].similarity(stones[j])
                    stones[i].rank += s
                    stones[j].rank -= s
            log.debug('End selecting/reducing stones')
            # copy selected stones to storage
            self.map.stones = [s for s in stones if s.rank >= 1.5]
            self.map.save()

    def scan_from_files(self, analyze=True):
        import re
        import os
        import fnmatch
        import pickle as serialization

        log.debug('Begin scanning')

        cam = Camera(None)

        stones = []
        p = "map_offline/"   # looks here for pngs...

        pngfiles = []

        bins = []

        for file in os.listdir(p):
            if fnmatch.fnmatch(file, 'grab*.jpg'):
                pngfiles.append(file)

        for fn in pngfiles:
            m = re.search('\w+_(\d+)_(\d+)', fn)

            image = cv2.imread(os.path.join(p, fn), -1)
            (h, w) = image.shape[:2]

            xp, yp = float(m.group(1)), float(m.group(2))

            log.info('Reading file at {} {}'.format(xp, yp))

            localstones = []

            st = cam.grab_extract(xp, yp, img=image, save=False)
            for s in st:
                s.center = cam.pos_to_mm(s.center, offset=(xp, yp))
                s.size = cam.size_to_mm(s.size)
                s.rank = 0.0
                stones.append(s)
                localstones.append(s)

            bin = {'x': xp, 'y': yp, 'stones': localstones}
            bins.append(bin)

        with open('map/intermediate.data', 'wb') as f:
            serialization.dump(bins, f)

        log.debug('Found {} stones in {} bins'.format(len(stones), len(bins)))

        log.debug('End scanning')
        chosen_stones = []
        if analyze:
            # select correct stones
            log.debug('Begin selecting/reducing stones')
            for bi in range(len(bins)):
                bin_a = bins[bi]
                stones_a = bin_a['stones']

                other_stones = []

                for bj in range(bi + 1, len(bins)):
                    bin_b = bins[bj]
                    stones_b = bin_b['stones']

                    d_x = abs(bin_b['x'] - bin_a['x'])
                    d_y = abs(bin_b['y'] - bin_a['y'])

                    if d_x > cam.viewx * 2.0 or d_y > cam.viewy * 2.0:
                        continue

                    other_stones += stones_b

                for this_stone in stones_a:
                    for other_stone in other_stones:
                        if this_stone.coincides(other_stone):
                            other_stone.bogus = True

                    if not this_stone.bogus:
                        chosen_stones.append(this_stone)

            log.debug('End selecting/reducing stones')
            # copy selected stones to storage
            self.map.stones = [s for s in chosen_stones]
            self.map.stage = (0, 2, None, None)

            log.debug('Reduced from {} to {} stones'.format(len(stones), len(self.map.stones)))

            self.map.save(meta=True)

    def demo1(self):
        # demo program which moves stone back and forth
        while True:
            self._move_stone_absolute((3500, 1000),  0, (3500, 1250), 90)
            self._move_stone_absolute((3500, 1250), 90, (3500, 1000),  0)

    def demo2(self):
        while True:
            self._move_stone((3500, 1000),  30, (3500, 1000), 120)
            self._move_stone((3500, 1000), 120, (3500, 1000),  30)

    def demo3(self):
        while True:
            self._move_stone((3700, 1000),  30, (3700, 1000), 120)
            self._move_stone((3700, 1000), 120, (3700, 1000),  30)

    def _move_stone_absolute(self, c1, a1, c2, a2):
        log.debug('Abs moving stone center %s angle %s to center %s angle %s', str(c1), str(a1), str(c2), str(a2))

        if not self.m.check_movement(x=c1[0], y=c1[1], e=a1):
            log.warn('Invalid pickup position {},{}. Aborting move.'.format(c1[0], c1[1]))
            return False

        if not self.m.check_movement(x=c2[0], y=c2[1], e=a2):
            log.warn('Invalid placement position {},{}. Aborting move.'.format(c2[0], c2[1]))
            return False

        self.m.go(x=c1[0], y=c1[1], e=a1)
        ret = self.m.lift_up(x=c1[0], y=c1[1])

        if ret:
            self.m.go(x=c2[0], y=c2[1], e=a2)
            self.m.lift_down()
            return True
        else:
            return False

    def _turn_stone_calc(self, c1, sa, c2, ea):
        h1 = self.machine.head_delta(angle=sa)
        c1 = c1[0] - h1[0], c1[1] - h1[1]
        h2 = self.machine.head_delta(angle=ea)
        c2 = c2[0] - h2[0], c2[1] - h2[1]

        off = (0.0, 0.0)   # was 6.0, 0
        return (c1[0] + off[0], c1[1] + off[1]), (c2[0] + off[0], c2[1] + off[1])  # FIXME: Offseted

    def _move_stone(self, c1, a1, c2, a2):
        log.debug('Moving stone center %s angle %s to center %s angle %s', str(c1), str(a1), str(c2), str(a2))
        da = a1 - a2
        if da < 0.0:
            da = 360.0 + da
        da = da % 180

        # Case 1
        nc1, nc2 = self._turn_stone_calc(c1, 0.0, c2, da)

        max_y = self.map.size[1]
        if c1[1] >= 0 and c2[1] >= 0 and c1[1] <= max_y and c2[1] <= max_y:
            return self._move_stone_absolute(nc1, 0, nc2, da)
        else:   # Case 2
            nc1, nc2 = self._turn_stone_calc(c1, 180.0, c2, da)
            return self._move_stone_absolute(nc1, 180.0, nc2, da)
        # TODO: save map here ?

    def save_map(self):
        log.debug('Saving map...')
        self.map.save()
        log.debug('Saving map. Done.')

    def performance(self):
        saving_thread = threading.Thread(target=save_map, args=(self.map, ))

        while True:
            log.debug('Thinking...')
            i, nc, na, stage, force = art_step(self.map)

            if i is not None:
                s = self.map.stones[i]

                if nc is None:
                    nc = s.center

                if na is None:
                    na = s.angle

                log.debug('Placing stone {} from {} to {}'.format(i, s.center, nc))

                if self._move_stone(s.center, s.angle, nc, na):   # Pickup worked
                    if saving_thread.is_alive(): saving_thread.join() # wait until save is completed if still being done
                    s.center = nc
                    s.angle = na
                    self.map.stage = stage  # Commit stage
                    log.info('Placement worked')
                else:  # Fail, flag
                    if saving_thread.is_alive(): saving_thread.join() # wait until save is completed if still being done
                    s.flag = True
                    log.info('Placement failed')

                saving_thread = threading.Thread(target=save_map, args=(self.map, ))
                saving_thread.start() # async call of self.save_map

            elif force:  # Art wants us to advance anyhow
                if saving_thread.is_alive(): saving_thread.join() # wait until save is completed if still being done
                self.map.stage = stage  # Commit stage

                saving_thread = threading.Thread(target=save_map, args=(self.map, ))
                saving_thread.start() # async call of self.save_map
            else:
                if saving_thread.is_alive(): saving_thread.join() # wait until save is completed if still being done
                time.sleep(1)

        if saving_thread.is_alive(): saving_thread.join() # wait until save is completed if still being done