CARLA
Loading...
Searching...
No Matches
geom/Transform.h
Go to the documentation of this file.
1// Copyright (c) 2026 Computer Vision Center (CVC) at the Universitat Autonoma
2// de Barcelona (UAB).
3//
4// This work is licensed under the terms of the MIT license.
5// For a copy, see <https://opensource.org/licenses/MIT>.
6
7#pragma once
8
9#include "carla/MsgPack.h"
10#include "carla/geom/Location.h"
11#include "carla/geom/Math.h"
13#include "carla/geom/Rotation.h"
14
15#ifdef LIBCARLA_INCLUDED_FROM_UE4
17#include "Math/Transform.h"
19#endif // LIBCARLA_INCLUDED_FROM_UE4
20
21namespace carla {
22namespace geom {
23
24 /// A rigid transform in **CARLA's / Unreal's left-handed frame**: x
25 /// forward, y right, z up, metres, with a `Rotation` in degrees.
26 ///
27 /// `GetMatrix()`, `GetForwardVector()` and friends are all in that frame --
28 /// they are *not* "uncorrected" right-handed math and must not be flipped.
29 /// To hand a pose to a ROS / REP-103 consumer, convert explicitly with
30 /// `ToRightHanded()`; see `RightHandedTransform` and
31 /// `Docs/coordinate_conventions.md`.
32 class Transform {
33 public:
34
35 // =========================================================================
36 // -- Public data members --------------------------------------------------
37 // =========================================================================
38
40
42
44
45 // =========================================================================
46 // -- Constructors ---------------------------------------------------------
47 // =========================================================================
48
49 Transform() = default;
50
51 Transform(const Location &in_location)
52 : location(in_location),
53 rotation() {}
54
55 constexpr Transform(const Location &in_location, const Rotation &in_rotation)
56 : location(in_location),
57 rotation(in_rotation) {}
58
59 // =========================================================================
60 // -- Other methods --------------------------------------------------------
61 // =========================================================================
62
66
68 return rotation.GetRightVector();
69 }
70
72 return rotation.GetUpVector();
73 }
74
75 /// Applies this transformation to @a in_point (first translation then rotation).
76 void TransformPoint(Vector3D &in_point) const {
77 auto out_point = in_point;
78 rotation.RotateVector(out_point); // First rotate
79 out_point += location; // Then translate
80 in_point = out_point;
81 }
82
83 /// Applies this transformation to @a in_vector (rotation only).
84 void TransformVector(Vector3D &in_vector) const {
85 auto out_vector = in_vector;
86 rotation.RotateVector(out_vector); // First rotate
87 in_vector = out_vector;
88 }
89
90 /// Applies the inverse of this transformation to @a in_point
91 void InverseTransformPoint(Vector3D &in_point) const {
92 auto out_point = in_point;
93 out_point -= location; // First translate inverse
94 rotation.InverseRotateVector(out_point); // Then rotate inverse
95 in_point = out_point;
96 }
97
98 /// Computes the 4-matrix form of the transformation. Sign convention
99 /// matches `Rotation::RotateVector` and the engine: `+pitch` puts
100 /// `+sin(pitch)` on row 2 column 0 (forward axis tilts up), `+roll`
101 /// puts `-cos(pitch) * sin(roll)` on row 2 column 1 (right axis tilts
102 /// down). Verified against rendered camera frames on UE5.8 (2026-08-27).
103 std::array<float, 16> GetMatrix() const {
104 const float yaw = rotation.yaw;
105 const float cy = std::cos(Math::ToRadians(yaw));
106 const float sy = std::sin(Math::ToRadians(yaw));
107
108 const float roll = rotation.roll;
109 const float cr = std::cos(Math::ToRadians(roll));
110 const float sr = std::sin(Math::ToRadians(roll));
111
112 const float pitch = rotation.pitch;
113 const float cp = std::cos(Math::ToRadians(pitch));
114 const float sp = std::sin(Math::ToRadians(pitch));
115
116 std::array<float, 16> transform = {
117 cp * cy, cy * sp * sr - sy * cr, -cy * sp * cr - sy * sr, location.x,
118 cp * sy, sy * sp * sr + cy * cr, -sy * sp * cr + cy * sr, location.y,
119 sp, -cp * sr, cp * cr, location.z,
120 0.0, 0.0, 0.0, 1.0};
121
122 return transform;
123 }
124
125 /// Computes the 4-matrix form of the inverse transformation. Rows are
126 /// the transpose of the forward rotation; translation component pulled
127 /// from `InverseTransformPoint(origin)` to keep both helpers consistent.
128 std::array<float, 16> GetInverseMatrix() const {
129 const float yaw = rotation.yaw;
130 const float cy = std::cos(Math::ToRadians(yaw));
131 const float sy = std::sin(Math::ToRadians(yaw));
132
133 const float roll = rotation.roll;
134 const float cr = std::cos(Math::ToRadians(roll));
135 const float sr = std::sin(Math::ToRadians(roll));
136
137 const float pitch = rotation.pitch;
138 const float cp = std::cos(Math::ToRadians(pitch));
139 const float sp = std::sin(Math::ToRadians(pitch));
140
141 Vector3D a = {0.0f, 0.0f, 0.0f};
143
144 std::array<float, 16> transform = {
145 cp * cy, cp * sy, sp, a.x,
146 cy * sp * sr - sy * cr, sy * sp * sr + cy * cr, -cp * sr, a.y,
147 -cy * sp * cr - sy * sr, -sy * sp * cr + cy * sr, cp * cr, a.z,
148 0.0f, 0.0f, 0.0f, 1.0};
149
150 return transform;
151 }
152
153 // =========================================================================
154 // -- Right-handed (ROS / FLU) boundary ------------------------------------
155 // =========================================================================
156
157 /// This transform expressed in a right-handed, x-forward / y-**left** /
158 /// z-up frame (ROS REP-103 "FLU").
159 ///
160 /// `location` becomes `(x, -y, z)` and `rotation` becomes
161 /// `(roll, -pitch, -yaw)`; equivalently the pose matrix becomes
162 /// `S * GetMatrix() * S` with `S = diag(1, -1, 1, 1)`.
168
169 /// Inverse of `ToRightHanded()`: reads a right-handed (FLU) pose back into
170 /// CARLA's left-handed frame. The mapping is an involution.
176
177 // =========================================================================
178 // -- Comparison operators -------------------------------------------------
179 // =========================================================================
180
181 bool operator==(const Transform &rhs) const {
182 return (location == rhs.location) && (rotation == rhs.rotation);
183 }
184
185 bool operator!=(const Transform &rhs) const {
186 return !(*this == rhs);
187 }
188
189 // =========================================================================
190 // -- Conversions to UE4 types ---------------------------------------------
191 // =========================================================================
192
193#ifdef LIBCARLA_INCLUDED_FROM_UE4
194
195 Transform(const FTransform &transform)
196 : Transform(Location(transform.GetLocation()), Rotation(transform.Rotator())) {}
197
198 operator FTransform() const {
199 const FVector scale{1.0f, 1.0f, 1.0f};
200 return FTransform{FRotator(rotation), FVector(location), scale};
201 }
202
203#endif // LIBCARLA_INCLUDED_FROM_UE4
204 };
205
206} // namespace geom
207} // namespace carla
static constexpr T ToRadians(T deg)
Definition Math.h:43
Euler angles of a rotation in CARLA's / Unreal's left-handed frame: x forward, y right,...
Definition Rotation.h:45
constexpr RightHandedRotation ToRightHanded() const
This rotation expressed in a right-handed, x-forward / y-**left** / z-up frame (ROS REP-103 "FLU"),...
Definition Rotation.h:206
static constexpr Rotation FromRightHanded(const RightHandedRotation &rhs)
Inverse of ToRightHanded().
Definition Rotation.h:212
Vector3D GetUpVector() const
Definition Rotation.h:83
Vector3D GetRightVector() const
Definition Rotation.h:79
void InverseRotateVector(Vector3D &in_point) const
Definition Rotation.h:131
void RotateVector(Vector3D &in_point) const
Definition Rotation.h:87
Vector3D GetForwardVector() const
Definition Rotation.h:75
A rigid transform in CARLA's / Unreal's left-handed frame: x forward, y right, z up,...
std::array< float, 16 > GetMatrix() const
Computes the 4-matrix form of the transformation.
MSGPACK_DEFINE_ARRAY(location, rotation)
void TransformVector(Vector3D &in_vector) const
Applies this transformation to in_vector (rotation only).
static constexpr Transform FromRightHanded(const RightHandedTransform &rhs)
Inverse of ToRightHanded(): reads a right-handed (FLU) pose back into CARLA's left-handed frame.
void TransformPoint(Vector3D &in_point) const
Applies this transformation to in_point (first translation then rotation).
Vector3D GetUpVector() const
std::array< float, 16 > GetInverseMatrix() const
Computes the 4-matrix form of the inverse transformation.
constexpr Transform(const Location &in_location, const Rotation &in_rotation)
void InverseTransformPoint(Vector3D &in_point) const
Applies the inverse of this transformation to in_point.
Transform(const FTransform &transform)
bool operator!=(const Transform &rhs) const
bool operator==(const Transform &rhs) const
Transform(const Location &in_location)
Vector3D GetRightVector() const
constexpr RightHandedTransform ToRightHanded() const
This transform expressed in a right-handed, x-forward / y-**left** / z-up frame (ROS REP-103 "FLU").
Vector3D GetForwardVector() const
This file contains definitions of common data structures used in traffic manager.
constexpr RightHandedVector3D ToRightHanded() const
This location expressed in a right-handed, x-forward / y-**left** / z-up frame (ROS REP-103 "FLU"): (...
static constexpr Location FromRightHanded(const RightHandedVector3D &rhs)
Inverse of ToRightHanded().
A rigid transform expressed in a right-handed frame: x forward, y left, z up (ROS REP-103 "FLU"),...
RightHandedVector3D location
Translation in the right-handed frame, metres.
RightHandedRotation rotation
Orientation in the right-handed frame: roll, pitch, yaw in degrees, right-hand rule,...