OpenCRG.jl
ASAM OpenCRG (.crg) files describe road surfaces as a curved regular grid: a reference line (position and heading as a function of the distance u along the road) plus a regular grid of elevations z over the lateral offset v from that line. OpenCRG.jl is a pure-Julia reader for these files: it parses the header, decodes the ASCII and binary payloads, applies the $ROAD_CRG_MODS modifiers and integrates the reference line into world-frame (X, Y, Z) grids. No C library is needed.
using Pkg
Pkg.add("OpenCRG")
Pkg.add("DataInterpolationsND")Walkthrough
The examples use a sample file from the repository's test/data directory (ASAM's handmade_curved_banked_sloped.crg, a 22 m long, 3 m wide curved, banked and sloped road).
Load a file
read_crg parses a file and returns a CRGData holding all data from that file:
using OpenCRG
using DataInterpolationsND
path = joinpath(pkgdir(OpenCRG), "test", "data", "handmade_curved_banked_sloped.crg")
data = OpenCRG.read_crg(path)CRGData (stored data, before modifiers)
Grid: 23 × 7 points (u × v)
u: [0.0, 22.0] m; increment: 1.0 m
v: [-1.5, 1.5] m; increment: nonuniform
Channels: reference-line x/y (integrated from phi), phi; elevation z; banking; slope
z range (raw): [-0.0333333, 0.0333333] m
Reference line closed (coincident endpoints): no
Modifiers: none
Options: none
Comment: "CRG file example for road surface description (width: 3m, length: 22m)"Evaluate the surface on a grid
road_surface_grid applies the modifiers, integrates the reference line and returns a grid (u, v, X, Y, Z).
Here, u and v are vectors of along-track and across-track distance, respectively. X, Y, Z are matrices of size (length(u), length(v)) that together define Cartesian positions of the surface of the road.
Positive v points left and negative v right, looking in the direction of increasing u. Undefined cells are NaN.
u, v, X, Y, Z = OpenCRG.road_surface_grid(data)
size(Z)(23, 7)Interpolate with DataInterpolationsND.jl
OpenCRG.jl only provides the grid. To evaluate it between nodes, use an interpolation package, like Interpolations.jl or DataInterpolationsND.jl. Interpolate the complete surface directly over both road-frame axes:
dimensions = (LinearInterpolationDimension(u), LinearInterpolationDimension(v))
surface = NDInterpolation(cat(X, Y, Z; dims = 3), dimensions)
surface(10.5, 0.5) # Cartesian [x, y, z]3-element Vector{Float64}:
10.426222453337271
1.046569095709622
0.6216944249999999The same interpolant gives the centre-line position at u = 10.5 or a point across the road at u = 10:
surface(10.5, 0.0)3-element Vector{Float64}:
10.479744900340215
0.5494401000455738
0.5722221999999999surface(10.0, 0.5)3-element Vector{Float64}:
9.930611107774567
0.9918308919767347
0.56116665Evaluate inside the grid (u in extrema(u), v in extrema(v)).
Restrictions
REFPOINT_U, REFPOINT_V and their _FRACTION variants are not supported (an error is thrown), REFPOINT_X/Y/Z/PHI need an exact v = 0 long-section column, GRID_NAN_MODE/GRID_NAN_OFFSET are parsed but ignored (NaN cells are not filled), and $ROAD_CRG_OPTS/$ROAD_CRG_MPRO have no effect.