Repository navigation
CARLA lane orientation
A known waypoint faces along its evaluated lane centerline. Road.lane_transform
and Map.compute_transform use its geometric tangent for yaw and pitch.
They keep the existing center-coordinate arithmetic and zero roll.
This is an engineering correction to CARLA 1360bb9, not exact output parity.
The correction covers line, arc, spiral, poly3 and paramPoly3 references. It includes the lane-offset polynomial, each full inner-lane width, and half of the selected lane width. Lane 0 uses the lane offset without a width. Each width and offset contributes both its value and its derivative. Elevation contributes its derivative to the vertical tangent.
The derivative is taken from the selected position expression before its Float32 conversions. The canonical center retains Float64 lateral offsets and elevation. The public transform narrows the final position to Float32 coordinates. A finite difference of rounded positions is meaningful only when its step resolves that storage precision. For example, rounding can collapse a very small offset circle to one stored point while its unrounded tangent still has a direction.
The OpenDRIVE reader turns border-only lanes into width records, so this correction covers them through their widths. See CARLA lane borders. Superelevation, crossfall, shape and lane-height geometry remain outside this centerline model. Nearest-waypoint stations on offset and widening lanes are a separate correction. See Differences from CARLA and issue #302.
Let P(s) be the reference position, theta(s) its offset-frame heading, and t(s) the signed lane-center offset. Positive t points right in the OpenDRIVE frame. The lane center in that frame is:
C(s) = P(s) + t(s) * (sin(theta), -cos(theta))
C'(s) = P'(s)
+ t'(s) * (sin(theta), -cos(theta))
+ t(s) * theta'(s) * (cos(theta), sin(theta))
The returned frame negates the y coordinate and y derivative. Its forward
vector follows (C'.x, -C'.y, elevation'). The yaw correction is measured
relative to the reference heading. This retains its existing whole turns.
Pitch is the negative arctangent of vertical speed over horizontal speed. The norm calculation scales all components first to avoid squared overflow and underflow. It does not assume that horizontal speed is one.
A lane traveling against increasing s gains 180 degrees of yaw. Its pitch
becomes 360 - pitch. This retains the established CARLA angle convention.
Right lanes travel with s under RHT. Left lanes travel with s under LHT.
Lane 0 always travels with s.
- A line has a constant heading and unit reference speed
- An arc includes its curvature in the offset derivative. A center can stop or reverse when an offset reaches or passes the circle center
- A spiral differentiates its existing Gauss-Legendre position expression, including the moving quadrature nodes and weights. It uses the selected partition, with no change to reference positions
- Poly3 and paramPoly3 differentiate their sampled position chords and their interpolated heading separately. The chord direction can differ from that heading. Both normalized and arc-length parameter ranges keep the existing sample tables and extrapolated final interval
At a geometry, width, offset or elevation record start, the new record
applies. A supplied lane section keeps its own lane records. At an internal
sample knot, the interval ending at that knot applies, as in pos_at.
A spiral partition switch uses the partition selected at the exact s.
These are one-sided derivative conventions. A discontinuous position has no two-sided tangent. The method does not smooth or join such positions. A clamped reference outside its geometry record has zero reference speed and heading derivative; any active lateral or elevation derivative remains.
Zero horizontal speed keeps the reference yaw. A stationary center has zero pitch before traffic reversal. A vertical tangent has a pitch of minus or plus 90 degrees, according to its vertical direction. No small-speed tolerance changes a moving center into a stationary one.
The method raises an error for a nonfinite s or missing required records.
An undefined sampled offset frame or nonfinite derivative arithmetic also
raises an error. The center and yaw must fit in their public Float32
representations.
A paramPoly3 whose interpolated (u', v') is zero has no offset-frame
heading and raises an error. A selected sample span must be finite and
positive. Required geometry lengths and curvatures must be finite.
This is not a complete OpenDRIVE model validator.
The pinned CARLA lane transform
subtracts the lateral slope directly from its heading as an angle.
A straight road with lane offset t = s has tangent (1, -1) in the
returned frame. Its yaw must be -45 degrees. The inherited calculation
returned about -57.2958 degrees. Curved offsets also change horizontal
speed, so elevation grade alone does not give the lane pitch.
Existing callers keep their waypoint identity and center coordinates. Orientation changes can affect steering, trigger direction, lane-crossing classification, crosswalk placement, and scenario replay. The current Map index subdivides lanes using heading differences. Corrected headings can therefore change its segmentation and approximate query results. This does not claim to fix its separate global-search limitations. Fixed-s nearest-lane queries are unchanged.
tests/test_carla_lane_orientation.mojo combines analytic direction controls
with independent finite differences of public positions. It covers both
lane signs, lane 0, inner widths, positive and negative slopes, RHT and LHT,
and all five geometries. It checks record boundaries, sample knots, partition
switches, stationary and vertical centers, winding, and numerical failures.
tools/generate_carla_lane_orientation_controls.mojo independently reads the
hand-authored town XML. It reconstructs the polynomial samples and analytic
geometry tangents without reading Mojo output. It derives the corrected
map fixture angles and the 230-segment count. Its 292 heading decisions
stay at least 0.000112 radians from the subdivision threshold.
The map tests retain their
original tolerances and workloads.
The tool imports no CARLA module of the port. It rounds each product
separately. It uses the C library's trigonometry and CPython's
math.hypot. Its report thus matches the replaced Python script digit
for digit. tests/test_carla_control_replay_tool.mojo compares the full
report.
bench/carla_lane_orientation_bench.mojo compares the old and corrected
orientation calculations in one build. Both use the current canonical
lane-center calculation. The baseline retains the slope-as-angle formula
from 0f58bc1; it does not retain that revision's Float32 center arithmetic.
The benchmark alternates timing order for each geometry and checks that
all sampled center positions remain exactly equal. It measures orientation
cost on shared centers, not the performance of a historical binary.
Tutorials
How-to
Reference
- Scene graph
- Rotations
- Cameras
- Geometry
- Geometry addons
- Lofts and clipping groups
- Sculptor
- Procedural generators
- Meshes and assets
- Lines
- Points and sprites
- Helpers
- Scene objects
- Animated objects
- Raycasting
- Curves and paths
- Animation
- Skinning
- Materials
- Node materials
- TSL functions
- Lights
- Lighting addons
- Fog
- Textures
- Renderer
- Renderer hooks and material flags
- Rasterization
- GPU backend
- Render target
- Post-processing
- GPU computation
- Compute nodes
- Progressive light map
- Gaussian splats
- Voxel global illumination
- SVG renderer
- Image files
- Image decode queue
- Model files
- More model files
- Exporters
- Scene JSON
- Windowing and controls
- Math
- Norm consumers
- Math addons
- Units
- Coverage tool
- Commands
- Examples
- Benchmarks
- Extensions
- Shared physics
- Physics query snapshots
- Continuous collision
- Tick force restoration
- Water
- Animals
- Buildings
- CARLA
- Femur
- Tibia
- Fibula
- Patella
- Knee
- Muscles
- Vessels
- Lymph
- Nerves
- Integument
- Leg
- Foot
- Pelvis
- Torso
- Arm
- Hand
- Head
- Genome
- Game humanoid
- Humanoid fidelity
- Audio-aligned game faces
- Converted assets
- Mesh quality
- Segment inertia
Explanation
- Software rasterizer
- Scene graph as an array
- Linear color
- Normals are not colors
- Perspective correction
- Fixed-point coverage
- Per-fragment shading
- Mipmaps
- Sorted transparency
- Types and checks
- Render hooks as a trait
- Shared CPU and GPU code
- Bands and threads
- PNG structure
- Extensions beside the port
- CUDA teardown hang
- Mojo compiler hang