def update(self, segment_list: SegmentList):
        """ Returns the likelihood """

        self.last_segments_used = segment_list.segments

        with dtu.timeit_clock("generating likelihood"):
            if not self.optimize:
                measurement_likelihood = self.generate_measurement_likelihood(segment_list.segments)
            else:
                measurement_likelihood = self.generate_measurement_likelihood_faster(segment_list.segments)
        check_no_nans(measurement_likelihood)
        with dtu.timeit_clock("multiply belief"):
            if measurement_likelihood is not None:
                s_m = np.sum(measurement_likelihood)
                if s_m == 0:
                    logger.warning("flat likelihood - not updating")
                else:

                    self.belief = np.multiply(self.belief, measurement_likelihood)
                    s = np.sum(self.belief)
                    if s == 0:
                        logger.warning("flat belief, just use likelihood")
                        self.belief = measurement_likelihood

                    alpha = 1.0 / s
                    self.belief = self.belief * alpha

        return measurement_likelihood
Esempio n. 2
0
    def setImage(self, bgr):

        with dtu.timeit_clock("np.copy"):
            self.bgr = np.copy(bgr)
        with dtu.timeit_clock("cvtColor COLOR_BGR2HSV"):
            self.hsv = cv2.cvtColor(bgr, cv2.COLOR_BGR2HSV)
        with dtu.timeit_clock("_findEdge"):
            self.edges = self._findEdge(self.bgr)
    def generate_measurement_likelihood(self, segments: List[Segment]):
        # initialize measurement likelihood to all zeros
        measurement_likelihood = self.grid_helper.create_new("float32")
        measurement_likelihood.fill(0)
        hit = miss = 0

        pose_weight = []

        num_by_color = defaultdict(lambda: 0)

        adjust_by_number = False  # add to configuration

        with dtu.timeit_clock(f"pose gen for {len(segments)} segs"):

            for segment in segments:
                num_by_color[segment.color] += 1

            for segment in segments:
                for pose, weight in self.generate_votes(segment, self.delta_segment):

                    if self.bounds_theta_deg is not None:
                        theta_deg = np.rad2deg(dtu.norm_angle(dtu.geo.angle_from_SE2(pose)))
                        m, M = self.bounds_theta_deg
                        if not (m <= theta_deg < M):
                            continue

                    if adjust_by_number:
                        n = num_by_color[segment.color]
                        weight_adjusted = weight * 1.0 / n
                    else:
                        weight_adjusted = weight
                    pose_weight.append((pose, weight_adjusted))

        values = []
        with dtu.timeit_clock(f"generating coords for {len(pose_weight)} votes"):
            for pose, weight in pose_weight:
                est = self._localization_template.coords_from_pose(pose)
                value = dict((k, float(est[k])) for k in self.variables)
                values.append((value, weight))

        with dtu.timeit_clock(f"add voting for {len(pose_weight)} votes"):
            for value, weight in values:
                #                 if value['dstop'] > 0.3:
                #                     print('value:%s' % value)
                #                 else:
                #                     continue
                added = self.grid_helper.add_vote(measurement_likelihood, value, weight, F=self.F)
                hit += added > 0
                miss += added == 0

        dtu.logger.debug(f"hit: {hit} miss : {miss}")
        if np.linalg.norm(measurement_likelihood) == 0:
            return None

        return measurement_likelihood
Esempio n. 4
0
 def detectLines(self, color):
     with dtu.timeit_clock("_colorFilter"):
         bw, edge_color = self._colorFilter(color)
     with dtu.timeit_clock("_HoughLine"):
         lines = self._HoughLine(edge_color)
     with dtu.timeit_clock("_findNormal"):
         centers, normals = self._findNormal(bw, lines)
     return Detections(lines=lines,
                       normals=normals,
                       area=bw,
                       centers=centers)
Esempio n. 5
0
    def phase(self, phase_name):
        with dtu.timeit_clock(phase_name):
            if not phase_name in self.phase_names:
                self.phase_names.append(phase_name)
            if self.last_msg_being_processed is None:
                msg = "Did not call decided_to_process() before?"
                raise ValueError(msg)

            #         t1 = rospy.get_time()
            t1 = time.time()
            c1 = time.process_time()

            try:
                yield
            finally:
                c2 = time.process_time()
                #             t2 = rospy.get_time()
                t2 = time.time()
                delta_clock = c2 - c1
                delta_wall = t2 - t1
                latency_from_acquisition = t2 - self.last_msg_being_processed

            self.stats[(phase_name, "clock")].sample(delta_clock)
            self.stats[(phase_name, "wall")].sample(delta_wall)
            self.stats[(phase_name,
                        "latency")].sample(latency_from_acquisition)
    def generate_measurement_likelihood_faster(self, segments: List[Segment]):
        with dtu.timeit_clock(f"get_compat_representation_obs ({len(segments)} segments)"):
            rep_obs = get_compat_representation_obs(segments)
            rep_map = self.rep_map

        with dtu.timeit_clock(
            f"generate_votes_faster (map: {len(rep_map.weight)}, obs: {len(rep_obs.weight)})"
        ):
            votes = generate_votes_faster(rep_map, rep_obs)

            if self.bounds_theta_deg is not None:
                weight = votes.weight.copy()
                theta_min = np.deg2rad(self.bounds_theta_deg[0])
                theta_max = np.deg2rad(self.bounds_theta_deg[1])
                num_outside = 0
                for i in range(weight.shape[0]):

                    theta = votes.theta[i]

                    if not (theta_min <= theta <= theta_max):
                        weight[i] = 0
                        num_outside += 1

                # print('Removed %d of %d because outside box' % (num_outside, len(weight)))
                votes = remove_zero_weight(votes._replace(weight=weight))

        with dtu.timeit_clock(f"compute pos iterative ({len(votes.weight)})"):
            locations = self._localization_template.coords_from_position_orientation(votes.p, votes.theta)

            num = len(locations)
            est = np.zeros((2, num))
            for i in range(2):
                v = list(self.variables)[i]
                est[i, :] = locations[v]

        F = self.F

        compare = False

        with dtu.timeit_clock(f"add voting faster ({len(votes.weight)})"):
            measurement_likelihood = self.grid_helper.create_new("float32")
            measurement_likelihood.fill(0)

            if compare:
                counts1 = np.zeros(measurement_likelihood.shape, dtype="int")
            else:
                counts1 = None

            added = self.grid_helper.add_vote_faster(
                measurement_likelihood, est, votes.weight, F=F, counts=counts1
            )

        #             print('Counts (new):\n'  + array_as_string(counts1, lambda x: ' %3d' % x))

        if compare:
            with dtu.timeit_clock("add voting (traditional)"):
                measurement_likelihood_classic = self.grid_helper.create_new("float32")
                measurement_likelihood_classic.fill(0)
                hit = miss = 0
                counts2 = np.zeros(measurement_likelihood.shape, dtype="int")
                for i in range(len(locations)):
                    loc = locations[i]
                    weight = votes.weight[i]
                    value = dict((k, loc[k]) for k in self.variables)

                    added = self.grid_helper.add_vote(
                        measurement_likelihood_classic, value, weight, F=F, counts=counts2
                    )

                    hit += added > 0
                    miss += added == 0

                #             dtu.logger.debug('tradoitional hit: %s miss : %s' % (hit, miss))
                #             print('Counts (old):\n'  + array_as_string(counts2, lambda x: ' %3d' % x))
                #
                diff = measurement_likelihood - measurement_likelihood_classic

                deviation = np.max(np.abs(diff))
                if deviation > 1e-6:
                    s = array_as_string_sign(diff)
                    print(f"max deviation: {deviation}")
                    print(s)

        return measurement_likelihood
Esempio n. 7
0
    def add_vote_faster(self, target, values, weights, F=1, counts=None):

        with dtu.timeit_clock(
                f"adding additional votes (orig: {values.shape[1]})"):
            _factor, values_ref, values, weights, group = self.multiply(
                values, weights, F)

        #         cells_in_group = np.zeros(len(group))
        #         for i in range(len(group)):
        #             cells_in_group[group[i]] += 1
        #         print('cells_in_group: %s' % cells_in_group)

        #         diff = values - values_ref
        #         for a in [0,1]:
        #             print('diff %s min %s max %s res %s' % (a, np.min(diff[a,:]), np.max(diff[a,:]),
        #                                                     self._specs[a].resolution))

        with dtu.timeit_clock(
                f"computing coordinates (nvalid = {values.shape[1]})"):

            nvalid = values.shape[1]

            coords = np.zeros((2, nvalid), dtype="int32")
            K = [self.K0, self.K1]

            for a in range(2):
                spec = self._specs[a]
                inv_resolution = 1.0 / spec.resolution
                x = (values[a, :] - spec.min) * inv_resolution

                #             print('values[%d] = %s' % (a, values[a, :]))
                #             print('x = %s' % x)
                coords[a, :] = np.floor(x)
                #             print('coords[%d] = %s' % (a, coords[a, :]))
                xr = (values_ref[a, :] - spec.min) * inv_resolution

                dc = xr - (coords[a, :] + 0.5)

                #             print('dc[%d] = %s' % (a, dc))
                dr = dc * spec.resolution

                k = 1
                k = K[a](dr)

                weights *= k

        if nvalid == 0:
            return 0

        with dtu.timeit_clock("normalizing weights"):

            ngroups = np.max(group) + 1

            weight_group = np.zeros(ngroups)
            if False:
                for i in range(len(weights)):
                    weight_group[group[i]] += weights[i]
            else:
                np.add.at(weight_group, group, weights)

            assert len(weights) == nvalid
            weights_normalized = weights / weight_group[group]

        with dtu.timeit_clock(f"selecting valid (using {values.shape[1]})"):
            AND = np.logical_and
            inside0 = AND(self._specs[0].min <= values[0, :],
                          values[0, :] <= self._specs[0].max)
            inside1 = AND(self._specs[1].min <= values[1, :],
                          values[1, :] <= self._specs[1].max)
            inside = AND(inside0, inside1)
            #         hits = np.sum(inside)
            #         misses = len(inside) - hits
            #         print('num hit: %s (eq %d)  misses %s (eq %d) ' % (hits, hits/_factor, misses,
            #         misses/_factor))

            # only consider inside
            values = values[:, inside]
            values_ref = values_ref[:, inside]
            weights = weights[inside]
            weights_normalized = weights_normalized[inside]
            group = group[inside]

            coords = coords[:, inside]

        with dtu.timeit_clock("using numpy.at"):
            np.add.at(target, tuple(coords), weights_normalized)

        if counts is not None:
            with dtu.timeit_clock("update counts"):
                for i in range(nvalid):
                    counts[coords[0, i], coords[1, i]] += 1

        return nvalid