.. _road_sections: Road Sections ============= Roads are nothing more than a sequence of modular sections placed one after another. This simple fact allows to create a large variety of roads using just a few different :py:mod:`simulation.utils.road.sections`. While :ref:`roads` provides a general introductions to roads, this page aims to highlight the different available road sections. Required and optional arguments are not explained in detail for every road section. However, all arguments can always be found by checking out the implementation of each section. (*Simply click on the link!*) **Please note that all angles must be specified in radians!** .. onboarding_start StraightRoad ------------ The :py:class:`simulation.utils.road.sections.straight_road.StraightRoad` is a straight road. This is an example on how to create a *StraightRoad* with length of two meters: .. literalinclude:: ../tutorials/road_examples/example.py :language: python :linenos: :start-after: # - Beginning sphinx straight_road - :end-before: # - Ending sphinx straight_road - ParkingArea ---------------- .. figure:: ../tutorials/resources/example_parking_area.jpg The :py:class:`simulation.utils.road.sections.parking_area.ParkingArea` is a straight road with parking lots on the left and right side. The arguments :py:attr:`left_lots` and :py:attr:`right_lots` each define a list of :py:class:`simulation.utils.road.sections.parking_area.ParkingLot`. Each parking lot can contain multiple :py:class:`simulation.utils.road.sections.parking_area.ParkingSpot`\s. This is an example on how to create a *ParkingArea*: .. literalinclude:: ../tutorials/road_examples/example.py :language: python :linenos: :start-after: # - Beginning sphinx parking_area - :end-before: # - Ending sphinx parking_area - The *ParkingArea* takes three optional arguments, which are :py:attr:`start_line`, :py:attr:`left_lots`, and :py:attr:`right_lots`. In the example, :py:attr:`start_line` is set to :py:func:`StartLine`. This creates a *StartLine* at the beginning of the *ParkingArea*. If you do not want a StartLine, remove :py:attr:`start_line=StartLine()`. By default, :py:attr:`start_line` is :py:attr:`None`. You can also discover this if you take a closer look at :py:class:`simulation.utils.road.sections.parking_area`. If you want to take this one step further, it is also possible to create a ParkingArea without any children; practically a StraightRoad. The arguments :py:attr:`left_lots` and :py:attr:`right_lots` expect a list of *ParkingLots*. In this example two lots are created on the left and one is on the right side. In the first lot on the left side, two *ParkingSpots* are placed. As you already know, *ParkingSpots* can have three different types. The first spot in this example is occupied by a *ParkingObstacle*, the second is blocked, i.e. it looks like an X. The second lot on the left looks different. You can also specify a :py:attr:`length` and an :py:attr:`opening_angle` for a *ParkingLot*. Here, the start is set to two meters from the beginning of the *ParkingArea*. If you do not specify the start argument (like in the first lot) it is set to zero. The opening angle is set to 40 degrees; the default is 60 degrees. For the first spot in this lot, no arguments are given and thus it's kind is ParkingSpot.FREE and there's no obstacle placed inside. This is the default behavior for a *ParkingSpot*. .. Caution:: Be careful: it is possible to place an obstacle on a free spot. The rendered road will look perfectly fine but it can cause problems in automatic driving tests because on a free spot no obstacle is expected. Moving to the single lot on the right side, you can see the third optional argument for a *ParkingLot*. It is called :py:attr:`depth` and controls the depth (along the y-axis) of a lot. There is no length parameter because the length (along the x-axis) is calculated as the sum of all spots in one lot. To change the size of a spot along the x-axis, simply specify a :py:attr:`width` parameter. You can not set the depth of a spot because it is derived from the parent lot. Intersection ------------ .. figure:: ../tutorials/resources/example_intersection.jpg .. literalinclude:: ../tutorials/road_examples/example.py :language: python :linenos: :start-after: # - Beginning sphinx intersection - :end-before: # - Ending sphinx intersection - Use :py:class:`simulation.utils.road.sections.intersection.Intersection` to create a *Intersection*. In this example, the crossing roads intersect at a 110-degree angle. The :py:attr:`simulation.utils.road.sections.intersection.Intersection.turn` parameter indicates in which direction the road continues after the intersection. The possible turn values are :py:attr:`simulation.utils.road.sections.intersection.Intersection.RIGHT`, :py:attr:`simulation.utils.road.sections.intersection.Intersection.LEFT` and :py:attr:`simulation.utils.road.sections.intersection.Intersection.STRAIGHT`, the latter is the default. The default size is 1.8 m and represents the length of each of the crossing roads. Using the :py:attr:`simulation.utils.road.sections.intersection.Intersection.rule` parameter it is possible to generate intersections with different priority rules. The possible turn values are: - :py:attr:`simulation.utils.road.sections.intersection.Intersection.EQUAL` - :py:attr:`simulation.utils.road.sections.intersection.Intersection.YIELD` - :py:attr:`simulation.utils.road.sections.intersection.Intersection.STOP` - :py:attr:`simulation.utils.road.sections.intersection.Intersection.PRIORITY_YIELD` - :py:attr:`simulation.utils.road.sections.intersection.Intersection.PRIORITY_STOP` The first is the default. T-Intersection ^^^^^^^^^^^^^^ .. figure:: ../tutorials/resources/example_intersection_closed.jpg .. literalinclude:: ../tutorials/road_examples/example.py :language: python :linenos: :start-after: # - Beginning sphinx t_intersection - :end-before: # - Ending sphinx t_intersection - This generates a three-way intersection. One arm of the intersection has to be removed. The :py:attr:`simulation.utils.road.sections.intersection.Intersection.closing` parameter accepts the same options as the :py:attr:`simulation.utils.road.sections.intersection.Intersection.turn` parameter and the given direction is closed of. Closed Loop at Intersection ^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. figure:: ../tutorials/resources/example_intersection_loop.jpg .. literalinclude:: ../tutorials/road_examples/example.py :language: python :linenos: :start-after: # - Beginning sphinx loop_intersection - :end-before: # - Ending sphinx loop_intersection - To generate a closed loop at an Intersection and thus driving two times across it :py:meth:`simulation.utils.road.road.Road.close_to_section` has to be used. After crossing the intersection in a straight direction, a *RightCircularArc* is added. The end of this arc is then automatically connected to the right arm of the initial intersection. When crossing the intersection a second time, the direction is set to straight. ZebraCrossing ------------- .. figure:: ../tutorials/resources/example_zebra_crossing.jpg The zebra crossing spans the entire length of this section. If no length argument is given, it defaults to 0.45 m. .. literalinclude:: ../tutorials/road_examples/example.py :language: python :linenos: :start-after: # - Beginning sphinx zebra_crossing - :end-before: # - Ending sphinx zebra_crossing - Pedestrian ^^^^^^^^^^ .. figure:: ../tutorials/resources/example_zebra_crossing_pedestrian.jpg A :py:class:`simulation.utils.road.sections.obstacle.pedestrian` is added in the same way as any other obstacle. The :py:attr:`arc_length` attribute specifies where along the road the pedestrian is placed. .. literalinclude:: ../tutorials/road_examples/example.py :language: python :linenos: :start-after: # - Beginning sphinx zebra_crossing_pedestrian - :end-before: # - Ending sphinx zebra_crossing_pedestrian - CircularArc ----------- .. figure:: ../tutorials/resources/example_arc.jpg This section creates a circular arc pointing to the left (*LeftCircularArc*) and right (*RightCircularArc*). This means instead of creating an arc with a negative radius to make it turn right the radius is always positive. The two **required** parametes for an arc are :py:attr:`radius` and :py:attr:`angle`. .. literalinclude:: ../tutorials/road_examples/example.py :language: python :linenos: :start-after: # - Beginning sphinx left_arc - :end-before: # - Ending sphinx left_arc - This example creates a circular arc to the left resulting in a 90-degree turn. BlockedArea ------------ .. figure:: ../tutorials/resources/example_blocked_area.jpg The :py:class:`simulation.utils.road.sections.blocked_area.BlockedArea` is a straight road, but the car is not allowed to drive on the blocked area which is marked by parallel white lines. By default the section is 1 m in length and the blocked area is 0.2 m wide, starting on the right line. This is an example on how to create a *BlockedArea* with a length of 1 m and a blocked area which is 0.2 m in width: .. literalinclude:: ../tutorials/road_examples/example.py :language: python :linenos: :start-after: # - Beginning sphinx blocked_area - :end-before: # - Ending sphinx blocked_area - TrafficIsland ------------- .. figure:: ../tutorials/resources/example_traffic_island.jpg The :py:class:`simulation.utils.road.sections.traffic_island.TrafficIsland` consists of a visible traffic island in the center of the road and a crosswalk or just dashed lines connecting the island with both sides of the road. B *Pedestrians are coming soon!* The parameters in the following example are also the default parameters: .. literalinclude:: ../tutorials/road_examples/example.py :language: python :linenos: :start-after: # - Beginning sphinx traffic_island - :end-before: # - Ending sphinx traffic_island - .. onboarding_end StaticObstacle -------------- .. figure:: ../tutorials/resources/example_straight_road_obs.jpg Static Obstacles can be placed on any road section. In this example a :py:class:`simulation.utils.road.sections.obstacle.StaticObstacle` is placed on a *StraightRoad* using the :py:meth:`simulation.utils.road.sections.road_section.RoadSection.add_obstacle` method. The generated obstacle is aligned along the middle line of the current section. In this case the obstacle is placed after one meter (:py:attr:`arc_length`) from the beginning of the current sections middle line and with a negative :py:attr:`y_offset`, thus ending up in the middle of the *StraightRoad* on the right lane. The :py:attr:`width` and :py:attr:`height` of the obstacle are defined by parameters of the same name. For rotating the obstacle an :py:attr:`angle` can be specified. The example shows an obstacle rotated by 45 degrees. .. literalinclude:: ../tutorials/road_examples/example.py :language: python :linenos: :start-after: # - Beginning sphinx straight_road_obs - :end-before: # - Ending sphinx straight_road_obs - It is also possible to place obstacles during creation of a *RoadSection* object. A list of obstacles can be passed to any road section. .. literalinclude:: ../tutorials/road_examples/example.py :language: python :linenos: :start-after: # - Beginning sphinx straight_road_obs_ - :end-before: # - Ending sphinx straight_road_obs_ - DynamicObstacle --------------- Dynamic Obstacles can be placed on any road section. In the following example a :py:class:`simulation.utils.road.sections.obstacle.DynamicObstacle` is placed on the opposite side of the road. The obstacle is moved from the end of the road to the start. .. Caution:: Be careful: On the opposite side of the road the path points have to be specified in reverse order! .. literalinclude:: ../tutorials/road_examples/example.py :language: python :linenos: :start-after: # - Beginning sphinx straight_road_dyn_obs - :end-before: # - Ending sphinx straight_road_dyn_obs -