예제 #1
0
    def split_by(self,
                 sections: List[Tuple[int, RoadSection]],
                 x_buffer=1) -> List[RoadSection]:
        """Add a number of other sections along this section.

        Args:
            sections: Road sections and arc lengths at which they should be added.
            x_buffer: Buffer after a road section to improve the adjustment of the end
                pose.

        Return:
            New road sections that replace this section.
        """
        if len(sections) == 0:
            return [self]
        assert 0 < sections[0][0] < self.middle_line.length
        x_beginning, section = sections[0]

        x_end = x_beginning + section.middle_line.length
        x_buffered_end = x_end + x_buffer
        start_pose = self.middle_line.interpolate_pose(x_beginning)
        end_pose = self.middle_line.interpolate_pose(x_buffered_end)

        beginning = CustomSection(middle_line_points=Line.cut(
            self.middle_line, x_beginning)[0].get_points())

        intermediate_section = RoadSection.fit_ending(
            Transform(start_pose.position, start_pose.orientation) *
            (section.get_ending()[0]),
            end_pose,
        )

        tf = Transform(end_pose.position, end_pose.orientation).inverse
        remaining_custom_section = CustomSection(middle_line_points=[
            tf * p for p in Line.cut(self.middle_line, x_buffered_end)
            [1].get_points()
        ])

        def distribute_objects(attribute_name: str):
            """Distribute objects (traffic signs, obstacles, surface_markings, ...) to
            resulting sections."""
            for obj in self.__getattribute__(attribute_name):
                x = self.middle_line.project(obj.center)
                if x < x_beginning:
                    x_shift = 0
                    beginning.__getattribute__(attribute_name).append(obj)
                elif x_beginning < x < x_end:
                    x_shift = -x_beginning
                    section.__getattribute__(attribute_name).append(obj)
                elif x_end < x < x_buffered_end:
                    x_shift = -x_end
                    intermediate_section.__getattribute__(
                        attribute_name).append(obj)
                else:
                    x_shift = -x_buffered_end
                    remaining_custom_section.__getattribute__(
                        attribute_name).append(obj)
                obj._frame = Transform([x_shift, 0], 0) * obj._frame

        distribute_objects("obstacles")
        distribute_objects("surface_markings")
        distribute_objects("traffic_signs")

        return [
            beginning,
            section,
            intermediate_section,
        ] + remaining_custom_section.split_by(
            sections=[(x - x_buffered_end, section)
                      for x, section in sections[1:]])
예제 #2
0
    def driving_line(self) -> Tuple[Line, List[List[float]]]:
        """Tuple[Line, List[List[float]]]: Line where car drives.

        And points to stop at.
        """

        path = Line()
        stops = []

        def append(offset, segment, stop):
            nonlocal path

            if offset > 0:
                segment = segment.parallel_offset(offset, "left")
            elif offset < 0:
                segment = segment.parallel_offset(-offset, "right")

            path += segment
            if stop > 0:
                stops.append([path.length, stop])

        if self.param.randomize_path:
            # Stitch a line together from varied offsets along the middle line
            length = self.middle_line.length
            x = 0
            offset = 0
            max_step = 4
            road_width = 0.4
            while x < length:
                offset = max(
                    min((0.5 - random.random()) * 2 * road_width, road_width),
                    -road_width,
                )

                p = self.middle_line.interpolate_pose(x)
                orth = Vector(1, 0, 0).rotated(p.get_angle() + math.pi / 2)
                path += Line([p.position + offset * orth, p.position + offset * orth])

                x += max_step * random.random()
        else:
            param_path: List[Dict[str, float]] = self.param.path
            param_path = [obj for obj in param_path if "offset" in obj]

            current_start = param_path[0]["start"]
            current_offset = param_path[0]["offset"]
            current_stop = 0

            param_path.remove(param_path[0])

            # Read the path from the parameters
            for obj in param_path:
                end_arc_length = obj["start"]
                before_end_line = Line.cut(self.middle_line, end_arc_length)[0]
                current_segment = Line.cut(before_end_line, current_start)[1]

                append(current_offset, current_segment, current_stop)

                current_offset = obj["offset"]
                current_start = obj["start"]
                current_stop = obj.get("stop", 0)

            current_segment = Line.cut(self.middle_line, current_start)[1]

            append(current_offset, current_segment, 0)

        return path.simplify(0.05).smooth(0.1), stops