CARLA
Loading...
Searching...
No Matches
Misc.cpp
Go to the documentation of this file.
1// Copyright (c) 2018-2020 CVC.
2//
3// This work is licensed under the terms of the MIT license.
4// For a copy, see <https://opensource.org/licenses/MIT>.
5
7
12#include "carla/client/World.h"
14#include "carla/geom/Location.h"
15#include "carla/geom/Math.h"
17#include "carla/geom/Vector3D.h"
18
19#include <algorithm>
20#include <cmath>
21#include <limits>
22
23namespace carla {
24namespace agents {
25namespace navigation {
26
27namespace {
28
29constexpr float kKmhPerMs = 3.6f;
30
31// Replicates numpy's `np.finfo(float).eps` regularisation used in the Python
32// helpers so we don't divide by zero on coincident points.
33constexpr float kNormEps = std::numeric_limits<float>::epsilon();
34
35} // namespace
36
38 if (!actor) {
39 return 0.0f;
40 }
41 const auto vel = actor->GetVelocity();
42 return kKmhPerMs * std::sqrt(vel.x * vel.x + vel.y * vel.y + vel.z * vel.z);
43}
44
46 SharedPtr<client::TrafficLight> traffic_light) {
47 // Local helper that mirrors the lambda in misc.py. The Python code rotates
48 // the (0, 0, extent.z) point by the traffic light's yaw angle and adds it
49 // back onto the trigger volume's transformed location.
50 auto rotate_point = [](const geom::Vector3D &point, float radians) {
51 const float rotated_x =
52 std::cos(radians) * point.x - std::sin(radians) * point.y;
53 const float rotated_y =
54 std::sin(radians) * point.x - std::cos(radians) * point.y;
55 return geom::Vector3D(rotated_x, rotated_y, point.z);
56 };
57
58 const geom::Transform base_transform = traffic_light->GetTransform();
59 const float base_rot = base_transform.rotation.yaw;
60 const geom::BoundingBox &trigger = traffic_light->GetTriggerVolume();
61
62 // Transform the trigger volume's local centre into world space.
63 geom::Vector3D area_loc(trigger.location.x, trigger.location.y,
64 trigger.location.z);
65 base_transform.TransformPoint(area_loc);
66
67 const geom::Vector3D &area_ext = trigger.extent;
68
69 const geom::Vector3D point = rotate_point(
70 geom::Vector3D(0.0f, 0.0f, area_ext.z),
71 geom::Math::ToRadians(base_rot));
72
73 return geom::Location(area_loc.x + point.x,
74 area_loc.y + point.y,
75 area_loc.z);
76}
77
79 const geom::Transform &target,
80 const geom::Transform &reference,
81 float max_distance,
82 std::optional<std::pair<float, float>> angle_interval) {
83 const float dx = target.location.x - reference.location.x;
84 const float dy = target.location.y - reference.location.y;
85 const float norm_target = std::sqrt(dx * dx + dy * dy);
86
87 // Match the early-out behaviour from misc.py.
88 if (norm_target < 0.001f) {
89 return true;
90 }
91 if (norm_target > max_distance) {
92 return false;
93 }
94 if (!angle_interval.has_value()) {
95 return true;
96 }
97
98 const float min_angle = angle_interval->first;
99 const float max_angle = angle_interval->second;
100
101 const auto fwd = reference.GetForwardVector();
102 const float dot = (fwd.x * dx + fwd.y * dy) / norm_target;
103 const float clamped = std::clamp(dot, -1.0f, 1.0f);
104 const float angle_deg = geom::Math::ToDegrees(std::acos(clamped));
105
106 return min_angle < angle_deg && angle_deg < max_angle;
107}
108
109std::pair<float, float> ComputeMagnitudeAngle(
110 const geom::Location &target,
111 const geom::Location &current,
112 float orientation_deg) {
113 const float dx = target.x - current.x;
114 const float dy = target.y - current.y;
115 const float norm_target = std::sqrt(dx * dx + dy * dy);
116
117 const float orientation_rad = geom::Math::ToRadians(orientation_deg);
118 const float fwd_x = std::cos(orientation_rad);
119 const float fwd_y = std::sin(orientation_rad);
120
121 // Avoid a divide-by-zero when target and current coincide.
122 const float denom = norm_target > 0.0f ? norm_target : kNormEps;
123 const float dot = (fwd_x * dx + fwd_y * dy) / denom;
124 const float clamped = std::clamp(dot, -1.0f, 1.0f);
125 const float angle_deg = geom::Math::ToDegrees(std::acos(clamped));
126
127 return {norm_target, angle_deg};
128}
129
132 const geom::Transform &vehicle_transform) {
133 const auto &wp_loc = waypoint->GetTransform().location;
134 const float dx = wp_loc.x - vehicle_transform.location.x;
135 const float dy = wp_loc.y - vehicle_transform.location.y;
136 return std::sqrt(dx * dx + dy * dy);
137}
138
139std::array<float, 3> UnitVector(
140 const geom::Location &a,
141 const geom::Location &b) {
142 const float x = b.x - a.x;
143 const float y = b.y - a.y;
144 const float z = b.z - a.z;
145 // Match Python's `np.linalg.norm(...) + np.finfo(float).eps`.
146 const float norm = std::sqrt(x * x + y * y + z * z) + kNormEps;
147 return {x / norm, y / norm, z / norm};
148}
149
151 const geom::Location &a,
152 const geom::Location &b) {
153 const float x = b.x - a.x;
154 const float y = b.y - a.y;
155 const float z = b.z - a.z;
156 return std::sqrt(x * x + y * y + z * z) + kNormEps;
157}
158
161 const std::vector<SharedPtr<client::Waypoint>> &waypoints,
162 float z) {
163 if (!world) {
164 return;
165 }
166 auto debug = world->MakeDebugHelper();
167 for (const auto &wpt : waypoints) {
168 if (!wpt) continue;
169 const auto wpt_t = wpt->GetTransform();
170 const geom::Location begin(
171 wpt_t.location.x,
172 wpt_t.location.y,
173 wpt_t.location.z + z);
174 const float angle = geom::Math::ToRadians(wpt_t.rotation.yaw);
175 const geom::Location end(
176 begin.x + std::cos(angle),
177 begin.y + std::sin(angle),
178 begin.z);
179 debug.DrawArrow(
180 begin,
181 end,
182 /*thickness=*/0.1f,
183 /*arrow_size=*/0.3f,
184 client::DebugHelper::Color{255u, 0u, 0u},
185 /*life_time=*/1.0f);
186 }
187}
188
189} // namespace navigation
190} // namespace agents
191} // namespace carla
float y
float x
float z
geom::Point point
Definition LaneGraph.cpp:41
Location location
Center of the BoundingBox in local space.
Vector3D extent
Half the size of the BoundingBox in local space.
static constexpr T ToRadians(T deg)
Definition Math.h:43
static constexpr T ToDegrees(T rad)
Definition Math.h:37
A rigid transform in CARLA's / Unreal's left-handed frame: x forward, y right, z up,...
void TransformPoint(Vector3D &in_point) const
Applies this transformation to in_point (first translation then rotation).
Vector3D GetForwardVector() const
bool IsWithinDistance(const geom::Transform &target, const geom::Transform &reference, float max_distance, std::optional< std::pair< float, float > > angle_interval)
Returns true when target is within max_distance of reference.
Definition Misc.cpp:78
float ComputeDistance(const geom::Location &a, const geom::Location &b)
Euclidean distance between two locations (matches numpy's regularised version that adds an epsilon to...
Definition Misc.cpp:150
void DrawWaypoints(SharedPtr< client::World > world, const std::vector< SharedPtr< client::Waypoint > > &waypoints, float z)
Draw the supplied waypoints in the world for a fixed lifetime.
Definition Misc.cpp:159
geom::Location GetTrafficLightTriggerLocation(SharedPtr< client::TrafficLight > traffic_light)
Compute the world-space trigger location of a traffic light, mirroring the helper in agents....
Definition Misc.cpp:45
float GetSpeed(SharedPtr< client::Actor > actor)
Compute speed of an actor in km/h.
Definition Misc.cpp:37
std::pair< float, float > ComputeMagnitudeAngle(const geom::Location &target, const geom::Location &current, float orientation_deg)
Returns the (distance, angle in degrees) from current to target relative to a forward orientation ori...
Definition Misc.cpp:109
float DistanceVehicle(SharedPtr< client::Waypoint > waypoint, const geom::Transform &vehicle_transform)
2-D distance between a waypoint and a vehicle transform.
Definition Misc.cpp:130
std::array< float, 3 > UnitVector(const geom::Location &a, const geom::Location &b)
Unit vector going from a to b, including the z component.
Definition Misc.cpp:139
This file contains definitions of common data structures used in traffic manager.
std::shared_ptr< T > SharedPtr
Definition Memory.h:15