Coordinate Systems#
RadarSimPy places everything — radars, targets, antenna patterns, motion — in a single right-handed, z-up Cartesian frame. Angles are in degrees, distances in metres, and no part of the library uses a different convention internally.
This page defines that frame, the two angle pairs used to point directions inside it, and the Euler angles that orient objects within it.
At a Glance#
Quantity |
Symbol |
Unit |
Meaning |
|---|---|---|---|
position |
|
m |
Right-handed, z pointing up |
phi |
\(\phi\) |
° |
Azimuthal angle in the x–y plane, 0° at +x |
theta |
\(\theta\) |
° |
Polar angle from +z, 0° at zenith |
azimuth |
— |
° |
Same angle as \(\phi\), radar-centric name |
elevation |
— |
° |
Angle above the x–y plane, \(90° - \theta\) |
orientation |
|
° |
Rotation about z, −y and x respectively |
The Global Frame#
The axes carry no built-in geographic meaning — you choose what they represent — but the handedness is fixed:
x — forward, the boresight direction for a radar at zero orientation
y — to the left, when looking along +x
z — up
Any direction can be named either by a unit vector or by the spherical pair \((\phi, \theta)\):
\(\phi\) sweeps within the x–y plane starting from +x; \(\theta\) opens downward from +z. Both arrows show the direction of increase.#
phi (\(\phi\)) is the azimuthal angle in the x–y plane. It is 0° along +x and 90° along +y, increasing counter-clockwise when viewed from above, and spans 0°…360° (or equivalently −180°…180°).
theta (\(\theta\)) is the polar angle measured from +z. It is 0° at the zenith, 90° in the x–y plane, and 180° at the nadir, spanning 0°…180°.
Converting between the two descriptions:
import numpy as np
def to_spherical(v):
x, y, z = v
r = np.linalg.norm(v)
return r, np.degrees(np.arctan2(y, x)), np.degrees(np.arccos(z / r))
to_spherical([1, 1, 1]) # (1.732, 45.0, 54.74)
Radar-Centric Angles#
Antenna patterns and beam geometry are more naturally described relative to boresight than to the zenith, so the same directions get a second pair of names:
Boresight is +x, where azimuth and elevation are both zero. Azimuth turns within the x–y plane toward +y; elevation lifts out of that plane toward +z.#
azimuth is the horizontal angle in the x–y plane. It is 0° at +x — the boresight — and positive toward +y, which is to the left as seen from behind the radar looking forward. It is the same angle as \(\phi\).
elevation is the vertical angle away from the x–y plane, 0° at the horizon and positive toward +z.
The difference is only where zero sits and which way is positive; nothing is lost or gained by switching between the pairs.
Note
Transmit and receive channels default to patterns spanning [-90, 90] in
both cuts (azimuth_angle and elevation_angle). That is the default
extent of the pattern arrays, not a restriction on the angles themselves.
See Transmitter and Waveform and Receiver and Baseband for how patterns are specified,
including the convention that the azimuth cut carries the absolute gain.
Orientation#
Objects are oriented with three Euler angles given as [yaw, pitch, roll]:
Each arc is drawn in the colour of the axis it turns about. Pitch is the exception worth noting: it turns about −y, not +y.#
Angle |
About |
Positive sense |
Typical range |
|---|---|---|---|
|
+z |
Turns +x toward +y |
−180°…180° |
|
−y |
Turns +x toward +z |
−90°…90° |
|
+x |
Turns +y toward +z |
−180°…180° |
The composed rotation is
Important
Pitch is the odd one out. Yaw and roll are ordinary right-handed rotations about +z and +x. Pitch is not: a right-handed rotation about +y would turn +x toward −z, whereas positive pitch turns +x toward +z. That is the aerospace “nose up is positive” convention, and it is why the matrix above carries \(R_y(-\text{pitch})\) rather than \(R_y(\text{pitch})\). Expect a sign flip on pitch when importing orientations from a toolchain that uses the strict right-handed sense.
Order of application#
The three angles are an intrinsic yaw → pitch → roll sequence: yaw about the global z, then pitch about the already yawed y, then roll about the already yawed and pitched x. Written as a matrix acting on a column vector, that same sequence reads right to left — roll reaches the vector first.
Either way the order is not negotiable, because rotations do not commute:
import numpy as np
from radarsimpy.animation_kit import _rsx_euler_to_quat, _quat_rotate
def rotate(rotation_deg, vec):
q = _rsx_euler_to_quat(np.radians(rotation_deg))
return _quat_rotate(q, np.array(vec, dtype=float))
rotate([90, 0, 90], [0, 1, 0]) # -> [0, 0, 1]
# roll first, then yaw, about the fixed global axes: same answer
rotate([90, 0, 0], rotate([0, 0, 90], [0, 1, 0])) # -> [0, 0, 1]
# yaw first, then roll: a different direction entirely
rotate([0, 0, 90], rotate([90, 0, 0], [0, 1, 0])) # -> [-1, 0, 0]
Pointing the boresight#
One consequence is worth having to hand. Roll turns about the body’s own x axis, which is the boresight, so it never moves it. Yaw and pitch are then exactly the azimuth and elevation of the resulting boresight direction:
rotation = [azimuth, elevation, roll]
To aim a radar at 30° azimuth and 20° below the horizon, set
rotation=[30, -20, 0]; the third angle is free to spin the antenna pattern
about the beam without changing where it points.
Origin#
origin(m) is the point that rotation and translation act about.A radar’s origin is always
[0, 0, 0]— position it withlocationinstead.Targets may set an arbitrary
origin, which is what lets a mesh rotate about a hinge, an axle or its own centre of mass rather than about the model file’s zero.
Notes#
Angles are degrees and distances metres everywhere, including motion rates (°/s and m/s).
Right-handedness holds throughout;
pitchis a sign convention on top of it, not a departure from it.glTF assets arrive Y-up and are converted on import — see Animated Targets (glTF 2.0 / GLB).
See Also#
Radar System Model — where the radar sits in this frame, and its virtual array
Transmitter and Waveform — antenna pattern cuts and the gain convention
Receiver and Baseband — the receive array in the same frame
Ray-Tracing Simulation — placing and orienting 3D mesh targets
Animated Targets (glTF 2.0 / GLB) — frame conversion for glTF assets (Y-up to Z-up)
Doppler Sign Convention — the sign convention for radial velocity