Generated banner for Matlab Convert Aerospace Coordinates
Generated logo for Matlab Convert Aerospace Coordinates

Matlab Convert Aerospace Coordinates

MathWorksOfficialCreated by MathWorks

  • Skill
  • Tool integration
  • Science and research
  • BSD-2-Clause
  • No issues found

From the author

Perform aerospace unit conversions, time conversions, coordinate frame transformations, and rotation representations using Aerospace Toolbox. Use when converting units (length, velocity, angle, acceleration, angular velocity, force, mass, pressure, temperature, density), computing Julian dates or decimal years, transforming between coordinate frames (ECEF, ECI, LLA, flat Earth, geodetic/geocentric, NED, body, wind, stability), or working with rotation representations (Euler angles, DCM, quaternion, Rodrigues vector). Also use when the user asks about aerospace coordinate systems, reference frames, or rotation conventions.
— the description by MathWorks

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

This skill provides a comprehensive interface for aerospace-specific mathematical operations. It enables users to perform unit conversions for physical quantities, calculate time formats like Julian dates, transform positions between various coordinate frames (such as ECEF, ECI, LLA, and NED), and manage rotation representations including Euler angles, DCMs, and quaternions. It is designed to support aerospace engineering workflows by providing robust functions for coordinate system management and orientation math.

What it does

  • Converts between common aerospace units for length, velocity, force, mass, and more.
  • Calculates time formats including Julian dates, Modified Julian dates, and decimal years.
  • Transforms position and velocity data between ECEF, ECI, LLA, Flat Earth, and NED frames.
  • Handles rotation representations and conversions between Euler angles, DCMs, quaternions, and Rodrigues vectors.
  • Provides a quaternion object for advanced rotation math, interpolation, and composition.
  • Computes frame transformations for specialized aerospace frames like body, wind, and stability.

When to use it

  • When you need to convert physical units between SI, imperial, and nautical systems.
  • When working with orbital or terrestrial navigation data requiring ECI or ECEF frames.
  • When you need to transform vehicle attitude data between different rotation representations.
  • When performing aerodynamic analysis requiring body-to-wind or body-to-stability frame transformations.
  • When you need to interpolate between orientations using spherical linear interpolation (SLERP).

Advantages

  • Provides standardized, validated functions for complex aerospace coordinate transformations.
  • Simplifies rotation math by offering both array-based functions and a dedicated quaternion object.
  • Includes built-in support for handling gimbal lock and singularity issues in Euler angles.
  • Ensures consistency across aerospace-specific reference frames and time standards.
  • Supports round-trip verification for coordinate transformations to ensure numerical accuracy.

Usage examples

“Convert 35,000 feet to meters.”
The skill uses the convlength function to return 10,668.0 meters.
“Transform an LLA position [40, -74, 0] to ECEF coordinates.”
The skill uses the lla2ecef function to return the corresponding ECEF vector in meters.
“Convert Euler angles (30, 10, 5 degrees) to a DCM.”
The skill converts the degrees to radians and uses angle2dcm with the 'ZYX' sequence to produce the 3x3 rotation matrix.
“Create a quaternion from Euler angles and rotate a point.”
The skill initializes a quaternion object and uses the rotatepoint method to apply the active rotation to the specified point.

Install

  1. Download the skill as a ZIP:

    https://autogineer.com/agent-skills/matlab/matlab-convert-aerospace-coordinates/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip matlab-convert-aerospace-coordinates.zip -d .agents/skills

Documentation by MathWorks

Aerospace Fundamentals

Core Aerospace Toolbox functions for unit conversions, time conversions, coordinate transformations, and rotation representations.

When to Use

  • Converting between aerospace unit systems (SI, imperial, nautical)

  • Computing Julian dates, modified Julian dates, decimal years, or TDB time

  • Transforming positions between ECEF, ECI, LLA, or flat Earth frames

  • Converting between geodetic and geocentric latitude

  • Building DCMs for frame transformations (ECI↔ECEF, ECEF↔NED, body↔wind, body↔stability)

  • Converting between Euler angles, DCMs, quaternions, and Rodrigues vectors

  • Using the quaternion object for rotation math, interpolation, or composition

  • Identifying which coordinate frame data is expressed in

When NOT to Use

  • Atmosphere models (atmosisa, atmoscoesa) — use matlab-compute-aerospace-environment

  • Airspeed corrections (correctairspeed) — not covered here

  • Orbit propagation or satellite maneuvers — use Aerospace Toolbox, Aerospace Blockset or Satellite Communications Toolbox

  • Navigation-specific transforms (lla2enu, lla2ned) — use Navigation Toolbox

  • Simulink blocks — use /model-based-design-core:building-simulink-models with Aerospace Blockset

Workflow

  1. Identify the coordinate frame — Determine what frame your data is in and what frame you need. See references/coordinate-systems.md for frame definitions and decision guide.

  2. Convert units first — Ensure inputs match the function's expected units before calling transforms.

  3. Apply the transformation — Use the appropriate function with correct argument ordering.

  4. Verify — Round-trip the result back to the original frame; error should be < 1e-10.

Key Functions

Unit Conversions
FunctionConvertsUnits
convlengthLength'ft', 'm', 'km', 'in', 'mi', 'naut mi'
convvelVelocity'ft/s', 'm/s', 'km/s', 'in/s', 'km/h', 'mph', 'kts', 'ft/min'
convangAngle'deg', 'rad', 'rev'
convaccAcceleration'ft/s^2', 'm/s^2', 'km/s^2', 'in/s^2', 'km/h-s', 'mph/s', 'G''s'
convangaccAngular acceleration'deg/s^2', 'rad/s^2', 'rpm/s'
convangvelAngular velocity'deg/s', 'rad/s', 'rpm'
convforceForce'N', 'lbf'
convmassMass'kg', 'lbm', 'slug'
convpresPressure'Pa', 'psi', 'psf', 'atm'
convtempTemperature'K', 'R', 'F', 'C'
convdensityDensity'kg/m^3', 'slug/ft^3', 'lbm/ft^3', 'lbm/in^3'

All conversion functions use the same signature: output = convXXX(value, fromUnit, toUnit)

Time Conversions
FunctionPurposeSince
juliandateCalendar → Julian DateR2006b
mjuliandateCalendar → Modified Julian Date (JD − 2400000.5)R2006b
decyearCalendar → decimal yearR2006b
leapyearTest if year is leap yearR2006b
tdbjuliandateTerrestrial Time → TDB Julian DateR2015a
Coordinate Transformations
FunctionFromToSince
lla2ecefLLA (geodetic)ECEFR2006b
ecef2llaECEFLLA (geodetic)R2006b
lla2eciLLAECIR2014a
eci2llaECILLAR2014a
ecef2eciECEF (pos/vel/acc)ECIR2019a
eci2ecefECI (pos/vel/acc)ECEFR2019a
eci2aerECIAER (azimuth, elevation, range)R2015a
lla2flatLLAFlat EarthR2011a
flat2llaFlat EarthLLAR2011a
geod2geocGeodetic latitudeGeocentric latitudeR2006b
geoc2geodGeocentric latitudeGeodetic latitudeR2006b
ijk2keplerianECI position/velocityKeplerian elementsR2019a
keplerian2ijkKeplerian elementsECI position/velocityR2019a
siderealTimeUTC Julian dateGMST (deg) / GAST (s)R2021a
dcmeci2ecef—ECI-to-ECEF DCMR2013b
dcmecef2ned—ECEF-to-NED DCMR2006b
dcm2latlonECEF-to-NED DCMLat/LonR2006b
dcmbody2windAlpha, BetaBody-to-Wind DCMR2006b
dcm2alphabetaBody-to-Wind DCMAlpha, BetaR2006b
dcmbody2stabilityAlphaBody-to-Stability DCMR2022a
Rotation Representations
FunctionFromToSince
angle2dcmEuler anglesDCMR2006b
dcm2angleDCMEuler anglesR2006b
angle2quatEuler anglesQuaternion (1×4)R2006b
quat2angleQuaternion (1×4)Euler anglesR2007b
dcm2quatDCMQuaternion (1×4)R2006b
quat2dcmQuaternion (1×4)DCMR2006b
angle2rodEuler anglesRodrigues vectorR2017a
rod2angleRodrigues vectorEuler anglesR2017a
dcm2rodDCMRodrigues vectorR2017a
rod2dcmRodrigues vectorDCMR2017a
quat2rodQuaternion (1×4)Rodrigues vectorR2017a
rod2quatRodrigues vectorQuaternion (1×4)R2017a
Quaternion Object
MethodPurpose
quaternion(E,'eulerd',RS,PF)Create from Euler angles (degrees)
quaternion(E,'euler',RS,PF)Create from Euler angles (radians)
quaternion(RM,'rotmat',PF)Create from rotation matrix
quaternion(RV,'rotvec')Create from rotation vector (radians)
compact(q)Extract [w x y z] array
eulerd(q,RS,PF)Convert to Euler angles (degrees)
euler(q,RS,PF)Convert to Euler angles (radians)
rotmat(q,PF)Convert to rotation matrix
rotvec(q) / rotvecd(q)Convert to rotation vector (rad/deg)
rotatepoint(q,pts)Rotate points (active rotation)
rotateframe(q,pts)Rotate frame (passive rotation)
normalize(q)Normalize to unit quaternion
slerp(q1,q2,t)Spherical linear interpolation
meanrot(q)Mean rotation of array
dist(q1,q2)Angular distance (radians)
angvel(q,dt,PF)Angular velocity from quaternion array
randrot(n)Uniform random rotations
Quaternion Math (Array-Based)
FunctionPurposeSince
quatmultiply(q,r)Quaternion product (compose rotations)R2006b
quatconj(q)Conjugate (negate vector part)R2006b
quatinv(q)Inverse (conjugate / norm²)R2006b
quatnormalize(q)Normalize to unit quaternionR2006b
quatnorm(q)Squared norm (q·q)R2006b
quatmod(q)Modulus (sqrt of norm)R2006b
quatrotate(q,v)Rotate vector by quaternionR2006b
quatdivide(q,r)Divide quaternion by quaternionR2006b
quatinterp(p,q,f,method)Interpolate ('slerp', 'lerp', 'nlerp')R2016a
quatexp(q)Exponential of quaternionR2016a
quatlog(q)Natural logarithm of quaternionR2016a
quatpower(q,pow)Quaternion raised to a powerR2016a

Patterns

Unit Conversion
% Always: convXXX(value, 'from', 'to')
alt_m = convlength(35000, 'ft', 'm');        % 10668.0 m
speed_ms = convvel(250, 'kts', 'm/s');       % 128.61 m/s
angle_rad = convang(45, 'deg', 'rad');       % 0.7854 rad
accel_g = convacc(9.81, 'm/s^2', 'G''s');   % 1.0 G
omega_rpm = convangvel(360, 'deg/s', 'rpm'); % 60 rpm
Time Conversion
% Julian Date from components (year, month, day, hour, min, sec)
jd = juliandate(2024, 6, 15, 12, 0, 0);     % 2460477.0

% Modified Julian Date
mjd = mjuliandate(2024, 6, 15, 12, 0, 0);   % 60476.5

% From datetime objects
dt = datetime(2024, 6, 15, 12, 0, 0);
jd = juliandate(dt);

% Decimal year
dy = decyear(2024, 6, 15);                   % 2024.4536

% TDB Julian Date from Terrestrial Time [yr mo day hr min sec]
tt = [2024 6 15 12 0 0];
jdTDB = tdbjuliandate(tt);
LLA ↔ ECEF
% LLA is [latitude_deg, longitude_deg, altitude_m]
lla = [40, -74, 0];
ecef = lla2ecef(lla);           % [1348613.0, -4703172.4, 4077985.6] m

% Round-trip verification
lla_check = ecef2lla(ecef);     % [40.0, -74.0, 0.0]
LLA ↔ ECI (time-dependent)
% ECI transforms require UTC time
lla = [40, -74, 1000];
utc = [2024 6 15 12 0 0];
posECI = lla2eci(lla, utc);

% Back to LLA
lla_check = eci2lla(posECI, utc);
Keplerian Elements ↔ ECI (IJK)
% Convert ECI position/velocity to Keplerian orbital elements
rijk = [-2981784; 5207055; 3161595];   % ECI position (m), 3x1
vijk = [-3384; -4887; 4843];           % ECI velocity (m/s), 3x1
[a, ecc, incl, RAAN, argp, nu] = ijk2keplerian(rijk, vijk);
% a=m, angles in degrees

% Convert Keplerian elements back to ECI position/velocity
[rijk_back, vijk_back] = keplerian2ijk(a, ecc, incl, RAAN, argp, nu);

% For a different central body (e.g., Mars)
[a_mars, ecc_mars, incl_mars, RAAN_mars, argp_mars, nu_mars] = ...
    ijk2keplerian(rijk, vijk, CentralBody="Mars");
Sidereal Time
% Compute Greenwich Mean Sidereal Time (GMST) and Apparent (GAST)
utcJD = juliandate(2019, 1, 4, 12, 0, 0);  % UTC as Julian date
dUT1 = 0;    % UT1-UTC offset (seconds)
dAT  = 37;   % TAI-UTC offset (leap seconds)
[thGMST, thGAST] = siderealTime(utcJD, dUT1, dAT);
% thGMST in degrees, thGAST in seconds
Flat Earth Approximation
% Good for short-range simulations (< ~100 km from reference)
llo = [40, -74];    % reference lat/lon (deg)
psio = 0;           % angular direction of flat Earth x-axis (rad, 0=North)
href = 0;           % reference height (m)

lla_point = [40.01, -73.99, 100];
flatPos = lla2flat(lla_point, llo, psio, href);  % [x, y, z] in meters
lla_back = flat2lla(flatPos, llo, psio, href);
Euler Angles ↔ DCM
% CRITICAL: angle2dcm expects RADIANS, not degrees
yaw = deg2rad(30); pitch = deg2rad(10); roll = deg2rad(5);
dcm = angle2dcm(yaw, pitch, roll, 'ZYX');

% Extract angles back (returns radians)
[y, p, r] = dcm2angle(dcm, 'ZYX');
fprintf('Yaw=%.1f, Pitch=%.1f, Roll=%.1f deg\n', rad2deg(y), rad2deg(p), rad2deg(r));
DCM ↔ Quaternion (Aerospace Toolbox format)
% Aerospace Toolbox quaternion format: [q0 q1 q2 q3] = [scalar, vector]
q = dcm2quat(dcm);       % 1x4, scalar-first
dcm_back = quat2dcm(q);  % 3x3

% Verify orthogonality
err = max(abs(dcm' * dcm - eye(3)), [], 'all');
assert(err < 1e-14, 'DCM is not orthogonal');
Quaternion Object (Modern Approach)
% Create from Euler angles — specify sequence AND frame type
q = quaternion([30 10 5], 'eulerd', 'ZYX', 'frame');

% Rotate a point (active rotation)
pt = [1 0 0];
pt_rotated = rotatepoint(q, pt);   % [0.8529, 0.4924, -0.1736]

% Compose rotations by multiplication
q_total = q2 * q1;  % applies q1 first, then q2

% Always normalize after arithmetic accumulation
q = normalize(q);
Quaternion Interpolation (SLERP)
% Smooth interpolation between two orientations
q1 = quaternion([0 0 0], 'eulerd', 'ZYX', 'frame');
q2 = quaternion([90 0 0], 'eulerd', 'ZYX', 'frame');
t = linspace(0, 1, 5)';
q_interp = slerp(q1, q2, t);

% Verify: yaw progresses linearly for pure yaw rotation
e = eulerd(q_interp, 'ZYX', 'frame');
% e(:,1) = [0, 22.5, 45, 67.5, 90]
Quaternion Math (Array-Based Functions)
% Compose two rotations: q2 applied after q1
q1 = angle2quat(deg2rad(30), 0, 0, 'ZYX');
q2 = angle2quat(0, deg2rad(10), 0, 'ZYX');
q_total = quatmultiply(q2, q1);  % q2 * q1 (apply q1 first)

% Inverse rotation
q_inv = quatinv(q1);
q_identity = quatmultiply(q1, q_inv);  % [1 0 0 0]

% Rotate a vector
v = [1 0 0];
v_rot = quatrotate(q1, v);  % rotate v by q1

% Normalize after accumulation
q_accumulated = quatnormalize(q_total);

% Interpolation (slerp, lerp, nlerp)
q_mid = quatinterp(q1, q2, 0.5, 'slerp');

% Relative rotation: what rotation takes q1 to q2?
q_rel = quatdivide(q2, q1);  % q_rel such that q2 = q_rel * q1

% Exponential/logarithm (useful for angular velocity integration)
q_log = quatlog(q1);         % maps to tangent space
q_back = quatexp(q_log);     % back to quaternion

% Fractional rotation (half the rotation of q1)
q_half = quatpower(q1, 0.5);
Rodrigues Vector
% Compact 3-element representation (singular at 180 deg)
rod = dcm2rod(dcm);           % 1x3 vector
dcm_back = rod2dcm(rod);

% Convert between all representations
rod = quat2rod(q_array);      % q is M×4 (scalar-first)
q_back = rod2quat(rod);
Body-to-Wind and Stability Frames
% Body-to-wind DCM from angle of attack and sideslip
alpha = deg2rad(5);
beta = deg2rad(2);
dcm_bw = dcmbody2wind(alpha, beta);

% Extract alpha/beta from a DCM
[alpha_out, beta_out] = dcm2alphabeta(dcm_bw);

% Body-to-stability (alpha only, no sideslip)
dcm_bs = dcmbody2stability(alpha);
ECEF-to-NED Frame DCM
% Get the DCM to rotate vectors from ECEF to local NED
lat = deg2rad(40);
lon = deg2rad(-74);
dcm_ecef2ned = dcmecef2ned(lat, lon);

% Transform an ECEF velocity to NED
v_ecef = [10; 20; 30];
v_ned = dcm_ecef2ned * v_ecef;
ECI to AER (Azimuth, Elevation, Slant Range)
% Compute look angles from a ground station to a satellite in ECI
posECI = [-2981784, 5207055, 3161595];  % satellite ECI position (m)
utc = [2019 1 4 12 0 0];               % observation time
lla0 = [28.5, -80.5, 0];               % ground station [lat, lon, alt] (deg, deg, m)

aer = eci2aer(posECI, utc, lla0);
% aer = [azimuth_deg, elevation_deg, slant_range_m]

Conventions

  • angle2dcm and angle2quat expect radians — always convert with deg2rad() or convang first

  • Rotation sequence default is 'ZYX' (yaw-pitch-roll) — always specify explicitly for clarity

  • Aerospace Toolbox quaternion format is [scalar, i, j, k] — the 1×4 array functions use scalar-first

  • quaternion object also uses scalar-first (compact returns [w x y z])

  • rotatepoint vs rotateframe — rotatepoint rotates the point (active); rotateframe rotates the frame (passive). They are inverses.

  • LLA ordering is [lat, lon, alt] in degrees and meters

  • geod2geoc and geoc2geod expect radians for latitude, meters for height/radius

  • ECI functions require UTC time — results change with Earth's rotation

  • Normalize quaternions after arithmetic operations to prevent drift

  • Rodrigues vector is singular at 180° — use quaternions for arbitrary rotations

Common Mistakes

MistakeWhy It's WrongCorrect Approach
Pass degrees to angle2dcmFunction expects radiansUse deg2rad() or convang(val,'deg','rad')
Omit rotation sequenceDefault ZYX may not match your conventionAlways pass 'ZYX', 'XYZ', etc. explicitly
Assume quaternion is [x y z w]Aerospace Toolbox uses [w x y z] (scalar-first)Check format; use compact(q) to verify
Use rotatepoint when meaning rotateframeThey are inverses — wrong one flips the rotationActive rotation = rotatepoint; passive = rotateframe
Skip normalization after quaternion mathQuaternion drift causes non-unit norm, distorted rotationsCall normalize(q) after accumulating rotations
Pass degrees to geod2geocExpects radians for latitudeConvert: geod2geoc(deg2rad(lat), alt)
Forget UTC for ECI transformsECI position depends on Earth rotation at that instantAlways provide [yr mo day hr min sec]
Use Rodrigues near 180° rotationRodrigues vector has a singularity at πUse quaternion representation instead
Ignore gimbal lock near ±90° pitchEuler angle extraction loses a degree of freedomUse quaternion or DCM directly for computations

Gimbal Lock

Euler angle representations lose one degree of freedom when the second rotation reaches ±90° (for ZYX: pitch = ±90°). Symptoms:

  • dcm2angle returns unexpected yaw/roll values near pitch = ±90°

  • Interpolating Euler angles produces erratic paths near singularity

Solution: Use quaternions for computation and interpolation. Only convert to Euler angles for display or human interpretation.

% Detect gimbal lock risk
[~, pitch, ~] = dcm2angle(dcm, 'ZYX');
if abs(pitch) > deg2rad(85)
    warning('Near gimbal lock — use quaternion representation');
end

References

  • See references/coordinate-systems.md for detailed frame definitions (ECEF, ECI, NED, body, wind, stability), axis conventions, and a decision guide for choosing the right frame.

  • See references/rotation-conventions.md for detailed rotation math: DCM properties, quaternion algebra, gimbal lock theory, and conversion paths between all representations.

  • See references/unit-conversion-guide.md for complete unit string tables and chaining conversions.


Copyright 2026 The MathWorks, Inc.


Files

SKILL.md

Aerospace Fundamentals

Core Aerospace Toolbox functions for unit conversions, time conversions, coordinate transformations, and rotation representations.

When to Use

  • Converting between aerospace unit systems (SI, imperial, nautical)

  • Computing Julian dates, modified Julian dates, decimal years, or TDB time

  • Transforming positions between ECEF, ECI, LLA, or flat Earth frames

  • Converting between geodetic and geocentric latitude

  • Building DCMs for frame transformations (ECI↔ECEF, ECEF↔NED, body↔wind, body↔stability)

  • Converting between Euler angles, DCMs, quaternions, and Rodrigues vectors

  • Using the quaternion object for rotation math, interpolation, or composition

  • Identifying which coordinate frame data is expressed in

When NOT to Use

  • Atmosphere models (atmosisa, atmoscoesa) — use matlab-compute-aerospace-environment

  • Airspeed corrections (correctairspeed) — not covered here

  • Orbit propagation or satellite maneuvers — use Aerospace Toolbox, Aerospace Blockset or Satellite Communications Toolbox

  • Navigation-specific transforms (lla2enu, lla2ned) — use Navigation Toolbox

  • Simulink blocks — use /model-based-design-core:building-simulink-models with Aerospace Blockset

Workflow

  1. Identify the coordinate frame — Determine what frame your data is in and what frame you need. See references/coordinate-systems.md for frame definitions and decision guide.

  2. Convert units first — Ensure inputs match the function's expected units before calling transforms.

  3. Apply the transformation — Use the appropriate function with correct argument ordering.

  4. Verify — Round-trip the result back to the original frame; error should be < 1e-10.

Key Functions

Unit Conversions
FunctionConvertsUnits
convlengthLength'ft', 'm', 'km', 'in', 'mi', 'naut mi'
convvelVelocity'ft/s', 'm/s', 'km/s', 'in/s', 'km/h', 'mph', 'kts', 'ft/min'
convangAngle'deg', 'rad', 'rev'
convaccAcceleration'ft/s^2', 'm/s^2', 'km/s^2', 'in/s^2', 'km/h-s', 'mph/s', 'G''s'
convangaccAngular acceleration'deg/s^2', 'rad/s^2', 'rpm/s'
convangvelAngular velocity'deg/s', 'rad/s', 'rpm'
convforceForce'N', 'lbf'
convmassMass'kg', 'lbm', 'slug'
convpresPressure'Pa', 'psi', 'psf', 'atm'
convtempTemperature'K', 'R', 'F', 'C'
convdensityDensity'kg/m^3', 'slug/ft^3', 'lbm/ft^3', 'lbm/in^3'

All conversion functions use the same signature: output = convXXX(value, fromUnit, toUnit)

Time Conversions
FunctionPurposeSince
juliandateCalendar → Julian DateR2006b
mjuliandateCalendar → Modified Julian Date (JD − 2400000.5)R2006b
decyearCalendar → decimal yearR2006b
leapyearTest if year is leap yearR2006b
tdbjuliandateTerrestrial Time → TDB Julian DateR2015a
Coordinate Transformations
FunctionFromToSince
lla2ecefLLA (geodetic)ECEFR2006b
ecef2llaECEFLLA (geodetic)R2006b
lla2eciLLAECIR2014a
eci2llaECILLAR2014a
ecef2eciECEF (pos/vel/acc)ECIR2019a
eci2ecefECI (pos/vel/acc)ECEFR2019a
eci2aerECIAER (azimuth, elevation, range)R2015a
lla2flatLLAFlat EarthR2011a
flat2llaFlat EarthLLAR2011a
geod2geocGeodetic latitudeGeocentric latitudeR2006b
geoc2geodGeocentric latitudeGeodetic latitudeR2006b
ijk2keplerianECI position/velocityKeplerian elementsR2019a
keplerian2ijkKeplerian elementsECI position/velocityR2019a
siderealTimeUTC Julian dateGMST (deg) / GAST (s)R2021a
dcmeci2ecef—ECI-to-ECEF DCMR2013b
dcmecef2ned—ECEF-to-NED DCMR2006b
dcm2latlonECEF-to-NED DCMLat/LonR2006b
dcmbody2windAlpha, BetaBody-to-Wind DCMR2006b
dcm2alphabetaBody-to-Wind DCMAlpha, BetaR2006b
dcmbody2stabilityAlphaBody-to-Stability DCMR2022a
Rotation Representations
FunctionFromToSince
angle2dcmEuler anglesDCMR2006b
dcm2angleDCMEuler anglesR2006b
angle2quatEuler anglesQuaternion (1×4)R2006b
quat2angleQuaternion (1×4)Euler anglesR2007b
dcm2quatDCMQuaternion (1×4)R2006b
quat2dcmQuaternion (1×4)DCMR2006b
angle2rodEuler anglesRodrigues vectorR2017a
rod2angleRodrigues vectorEuler anglesR2017a
dcm2rodDCMRodrigues vectorR2017a
rod2dcmRodrigues vectorDCMR2017a
quat2rodQuaternion (1×4)Rodrigues vectorR2017a
rod2quatRodrigues vectorQuaternion (1×4)R2017a
Quaternion Object
MethodPurpose
quaternion(E,'eulerd',RS,PF)Create from Euler angles (degrees)
quaternion(E,'euler',RS,PF)Create from Euler angles (radians)
quaternion(RM,'rotmat',PF)Create from rotation matrix
quaternion(RV,'rotvec')Create from rotation vector (radians)
compact(q)Extract [w x y z] array
eulerd(q,RS,PF)Convert to Euler angles (degrees)
euler(q,RS,PF)Convert to Euler angles (radians)
rotmat(q,PF)Convert to rotation matrix
rotvec(q) / rotvecd(q)Convert to rotation vector (rad/deg)
rotatepoint(q,pts)Rotate points (active rotation)
rotateframe(q,pts)Rotate frame (passive rotation)
normalize(q)Normalize to unit quaternion
slerp(q1,q2,t)Spherical linear interpolation
meanrot(q)Mean rotation of array
dist(q1,q2)Angular distance (radians)
angvel(q,dt,PF)Angular velocity from quaternion array
randrot(n)Uniform random rotations
Quaternion Math (Array-Based)
FunctionPurposeSince
quatmultiply(q,r)Quaternion product (compose rotations)R2006b
quatconj(q)Conjugate (negate vector part)R2006b
quatinv(q)Inverse (conjugate / norm²)R2006b
quatnormalize(q)Normalize to unit quaternionR2006b
quatnorm(q)Squared norm (q·q)R2006b
quatmod(q)Modulus (sqrt of norm)R2006b
quatrotate(q,v)Rotate vector by quaternionR2006b
quatdivide(q,r)Divide quaternion by quaternionR2006b
quatinterp(p,q,f,method)Interpolate ('slerp', 'lerp', 'nlerp')R2016a
quatexp(q)Exponential of quaternionR2016a
quatlog(q)Natural logarithm of quaternionR2016a
quatpower(q,pow)Quaternion raised to a powerR2016a

Patterns

Unit Conversion
% Always: convXXX(value, 'from', 'to')
alt_m = convlength(35000, 'ft', 'm');        % 10668.0 m
speed_ms = convvel(250, 'kts', 'm/s');       % 128.61 m/s
angle_rad = convang(45, 'deg', 'rad');       % 0.7854 rad
accel_g = convacc(9.81, 'm/s^2', 'G''s');   % 1.0 G
omega_rpm = convangvel(360, 'deg/s', 'rpm'); % 60 rpm
Time Conversion
% Julian Date from components (year, month, day, hour, min, sec)
jd = juliandate(2024, 6, 15, 12, 0, 0);     % 2460477.0

% Modified Julian Date
mjd = mjuliandate(2024, 6, 15, 12, 0, 0);   % 60476.5

% From datetime objects
dt = datetime(2024, 6, 15, 12, 0, 0);
jd = juliandate(dt);

% Decimal year
dy = decyear(2024, 6, 15);                   % 2024.4536

% TDB Julian Date from Terrestrial Time [yr mo day hr min sec]
tt = [2024 6 15 12 0 0];
jdTDB = tdbjuliandate(tt);
LLA ↔ ECEF
% LLA is [latitude_deg, longitude_deg, altitude_m]
lla = [40, -74, 0];
ecef = lla2ecef(lla);           % [1348613.0, -4703172.4, 4077985.6] m

% Round-trip verification
lla_check = ecef2lla(ecef);     % [40.0, -74.0, 0.0]
LLA ↔ ECI (time-dependent)
% ECI transforms require UTC time
lla = [40, -74, 1000];
utc = [2024 6 15 12 0 0];
posECI = lla2eci(lla, utc);

% Back to LLA
lla_check = eci2lla(posECI, utc);
Keplerian Elements ↔ ECI (IJK)
% Convert ECI position/velocity to Keplerian orbital elements
rijk = [-2981784; 5207055; 3161595];   % ECI position (m), 3x1
vijk = [-3384; -4887; 4843];           % ECI velocity (m/s), 3x1
[a, ecc, incl, RAAN, argp, nu] = ijk2keplerian(rijk, vijk);
% a=m, angles in degrees

% Convert Keplerian elements back to ECI position/velocity
[rijk_back, vijk_back] = keplerian2ijk(a, ecc, incl, RAAN, argp, nu);

% For a different central body (e.g., Mars)
[a_mars, ecc_mars, incl_mars, RAAN_mars, argp_mars, nu_mars] = ...
    ijk2keplerian(rijk, vijk, CentralBody="Mars");
Sidereal Time
% Compute Greenwich Mean Sidereal Time (GMST) and Apparent (GAST)
utcJD = juliandate(2019, 1, 4, 12, 0, 0);  % UTC as Julian date
dUT1 = 0;    % UT1-UTC offset (seconds)
dAT  = 37;   % TAI-UTC offset (leap seconds)
[thGMST, thGAST] = siderealTime(utcJD, dUT1, dAT);
% thGMST in degrees, thGAST in seconds
Flat Earth Approximation
% Good for short-range simulations (< ~100 km from reference)
llo = [40, -74];    % reference lat/lon (deg)
psio = 0;           % angular direction of flat Earth x-axis (rad, 0=North)
href = 0;           % reference height (m)

lla_point = [40.01, -73.99, 100];
flatPos = lla2flat(lla_point, llo, psio, href);  % [x, y, z] in meters
lla_back = flat2lla(flatPos, llo, psio, href);
Euler Angles ↔ DCM
% CRITICAL: angle2dcm expects RADIANS, not degrees
yaw = deg2rad(30); pitch = deg2rad(10); roll = deg2rad(5);
dcm = angle2dcm(yaw, pitch, roll, 'ZYX');

% Extract angles back (returns radians)
[y, p, r] = dcm2angle(dcm, 'ZYX');
fprintf('Yaw=%.1f, Pitch=%.1f, Roll=%.1f deg\n', rad2deg(y), rad2deg(p), rad2deg(r));
DCM ↔ Quaternion (Aerospace Toolbox format)
% Aerospace Toolbox quaternion format: [q0 q1 q2 q3] = [scalar, vector]
q = dcm2quat(dcm);       % 1x4, scalar-first
dcm_back = quat2dcm(q);  % 3x3

% Verify orthogonality
err = max(abs(dcm' * dcm - eye(3)), [], 'all');
assert(err < 1e-14, 'DCM is not orthogonal');
Quaternion Object (Modern Approach)
% Create from Euler angles — specify sequence AND frame type
q = quaternion([30 10 5], 'eulerd', 'ZYX', 'frame');

% Rotate a point (active rotation)
pt = [1 0 0];
pt_rotated = rotatepoint(q, pt);   % [0.8529, 0.4924, -0.1736]

% Compose rotations by multiplication
q_total = q2 * q1;  % applies q1 first, then q2

% Always normalize after arithmetic accumulation
q = normalize(q);
Quaternion Interpolation (SLERP)
% Smooth interpolation between two orientations
q1 = quaternion([0 0 0], 'eulerd', 'ZYX', 'frame');
q2 = quaternion([90 0 0], 'eulerd', 'ZYX', 'frame');
t = linspace(0, 1, 5)';
q_interp = slerp(q1, q2, t);

% Verify: yaw progresses linearly for pure yaw rotation
e = eulerd(q_interp, 'ZYX', 'frame');
% e(:,1) = [0, 22.5, 45, 67.5, 90]
Quaternion Math (Array-Based Functions)
% Compose two rotations: q2 applied after q1
q1 = angle2quat(deg2rad(30), 0, 0, 'ZYX');
q2 = angle2quat(0, deg2rad(10), 0, 'ZYX');
q_total = quatmultiply(q2, q1);  % q2 * q1 (apply q1 first)

% Inverse rotation
q_inv = quatinv(q1);
q_identity = quatmultiply(q1, q_inv);  % [1 0 0 0]

% Rotate a vector
v = [1 0 0];
v_rot = quatrotate(q1, v);  % rotate v by q1

% Normalize after accumulation
q_accumulated = quatnormalize(q_total);

% Interpolation (slerp, lerp, nlerp)
q_mid = quatinterp(q1, q2, 0.5, 'slerp');

% Relative rotation: what rotation takes q1 to q2?
q_rel = quatdivide(q2, q1);  % q_rel such that q2 = q_rel * q1

% Exponential/logarithm (useful for angular velocity integration)
q_log = quatlog(q1);         % maps to tangent space
q_back = quatexp(q_log);     % back to quaternion

% Fractional rotation (half the rotation of q1)
q_half = quatpower(q1, 0.5);
Rodrigues Vector
% Compact 3-element representation (singular at 180 deg)
rod = dcm2rod(dcm);           % 1x3 vector
dcm_back = rod2dcm(rod);

% Convert between all representations
rod = quat2rod(q_array);      % q is M×4 (scalar-first)
q_back = rod2quat(rod);
Body-to-Wind and Stability Frames
% Body-to-wind DCM from angle of attack and sideslip
alpha = deg2rad(5);
beta = deg2rad(2);
dcm_bw = dcmbody2wind(alpha, beta);

% Extract alpha/beta from a DCM
[alpha_out, beta_out] = dcm2alphabeta(dcm_bw);

% Body-to-stability (alpha only, no sideslip)
dcm_bs = dcmbody2stability(alpha);
ECEF-to-NED Frame DCM
% Get the DCM to rotate vectors from ECEF to local NED
lat = deg2rad(40);
lon = deg2rad(-74);
dcm_ecef2ned = dcmecef2ned(lat, lon);

% Transform an ECEF velocity to NED
v_ecef = [10; 20; 30];
v_ned = dcm_ecef2ned * v_ecef;
ECI to AER (Azimuth, Elevation, Slant Range)
% Compute look angles from a ground station to a satellite in ECI
posECI = [-2981784, 5207055, 3161595];  % satellite ECI position (m)
utc = [2019 1 4 12 0 0];               % observation time
lla0 = [28.5, -80.5, 0];               % ground station [lat, lon, alt] (deg, deg, m)

aer = eci2aer(posECI, utc, lla0);
% aer = [azimuth_deg, elevation_deg, slant_range_m]

Conventions

  • angle2dcm and angle2quat expect radians — always convert with deg2rad() or convang first

  • Rotation sequence default is 'ZYX' (yaw-pitch-roll) — always specify explicitly for clarity

  • Aerospace Toolbox quaternion format is [scalar, i, j, k] — the 1×4 array functions use scalar-first

  • quaternion object also uses scalar-first (compact returns [w x y z])

  • rotatepoint vs rotateframe — rotatepoint rotates the point (active); rotateframe rotates the frame (passive). They are inverses.

  • LLA ordering is [lat, lon, alt] in degrees and meters

  • geod2geoc and geoc2geod expect radians for latitude, meters for height/radius

  • ECI functions require UTC time — results change with Earth's rotation

  • Normalize quaternions after arithmetic operations to prevent drift

  • Rodrigues vector is singular at 180° — use quaternions for arbitrary rotations

Common Mistakes

MistakeWhy It's WrongCorrect Approach
Pass degrees to angle2dcmFunction expects radiansUse deg2rad() or convang(val,'deg','rad')
Omit rotation sequenceDefault ZYX may not match your conventionAlways pass 'ZYX', 'XYZ', etc. explicitly
Assume quaternion is [x y z w]Aerospace Toolbox uses [w x y z] (scalar-first)Check format; use compact(q) to verify
Use rotatepoint when meaning rotateframeThey are inverses — wrong one flips the rotationActive rotation = rotatepoint; passive = rotateframe
Skip normalization after quaternion mathQuaternion drift causes non-unit norm, distorted rotationsCall normalize(q) after accumulating rotations
Pass degrees to geod2geocExpects radians for latitudeConvert: geod2geoc(deg2rad(lat), alt)
Forget UTC for ECI transformsECI position depends on Earth rotation at that instantAlways provide [yr mo day hr min sec]
Use Rodrigues near 180° rotationRodrigues vector has a singularity at πUse quaternion representation instead
Ignore gimbal lock near ±90° pitchEuler angle extraction loses a degree of freedomUse quaternion or DCM directly for computations

Gimbal Lock

Euler angle representations lose one degree of freedom when the second rotation reaches ±90° (for ZYX: pitch = ±90°). Symptoms:

  • dcm2angle returns unexpected yaw/roll values near pitch = ±90°

  • Interpolating Euler angles produces erratic paths near singularity

Solution: Use quaternions for computation and interpolation. Only convert to Euler angles for display or human interpretation.

% Detect gimbal lock risk
[~, pitch, ~] = dcm2angle(dcm, 'ZYX');
if abs(pitch) > deg2rad(85)
    warning('Near gimbal lock — use quaternion representation');
end

References

  • See references/coordinate-systems.md for detailed frame definitions (ECEF, ECI, NED, body, wind, stability), axis conventions, and a decision guide for choosing the right frame.

  • See references/rotation-conventions.md for detailed rotation math: DCM properties, quaternion algebra, gimbal lock theory, and conversion paths between all representations.

  • See references/unit-conversion-guide.md for complete unit string tables and chaining conversions.


Copyright 2026 The MathWorks, Inc.


Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Security

No issues found by our static scan· No issues found

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Created by
MathWorks
Publisher
MathWorks (Official)
Source
matlab/matlab-agentic-toolkit · skills-catalog/aerospace/matlab-convert-aerospace-coordinates · commit 2a7f215
Licence
BSD 2-Clause License (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE.md)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by MathWorks or MathWorks.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download matlab-convert-aerospace-coordinates.zip