Extended functionality of point transforms
This commit is contained in:
parent
3b8507d18d
commit
7a163c2320
|
@ -252,6 +252,8 @@ Static presets
|
||||||
- `rotation`
|
- `rotation`
|
||||||
- `__eq__(other)`
|
- `__eq__(other)`
|
||||||
- `__ne__(other)`
|
- `__ne__(other)`
|
||||||
|
- `transform_point`
|
||||||
|
- `transform_point_list`
|
||||||
|
|
||||||
## `carla.BoundingBox`
|
## `carla.BoundingBox`
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,6 @@ namespace geom {
|
||||||
|
|
||||||
class Math {
|
class Math {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static constexpr auto pi() {
|
static constexpr auto pi() {
|
||||||
return 3.14159265358979323846264338327950288;
|
return 3.14159265358979323846264338327950288;
|
||||||
}
|
}
|
||||||
|
@ -34,6 +33,10 @@ namespace geom {
|
||||||
return rad * (180.0 / pi());
|
return rad * (180.0 / pi());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static constexpr auto to_radians(double deg) {
|
||||||
|
return deg * (pi() / 180.0);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static T clamp(
|
static T clamp(
|
||||||
const T &a,
|
const T &a,
|
||||||
|
|
|
@ -9,11 +9,13 @@
|
||||||
#include "carla/MsgPack.h"
|
#include "carla/MsgPack.h"
|
||||||
#include "carla/geom/Location.h"
|
#include "carla/geom/Location.h"
|
||||||
#include "carla/geom/Rotation.h"
|
#include "carla/geom/Rotation.h"
|
||||||
|
#include "carla/geom/Math.h"
|
||||||
|
|
||||||
#ifdef LIBCARLA_INCLUDED_FROM_UE4
|
#ifdef LIBCARLA_INCLUDED_FROM_UE4
|
||||||
# include "Math/Transform.h"
|
#include "Math/Transform.h"
|
||||||
#endif // LIBCARLA_INCLUDED_FROM_UE4
|
#endif // LIBCARLA_INCLUDED_FROM_UE4
|
||||||
|
|
||||||
|
|
||||||
namespace carla {
|
namespace carla {
|
||||||
namespace geom {
|
namespace geom {
|
||||||
|
|
||||||
|
@ -24,7 +26,8 @@ namespace geom {
|
||||||
|
|
||||||
Transform(const Location &in_location, const Rotation &in_rotation)
|
Transform(const Location &in_location, const Rotation &in_rotation)
|
||||||
: location(in_location),
|
: location(in_location),
|
||||||
rotation(in_rotation) {}
|
rotation(in_rotation) {
|
||||||
|
}
|
||||||
|
|
||||||
Location location;
|
Location location;
|
||||||
Rotation rotation;
|
Rotation rotation;
|
||||||
|
@ -37,6 +40,50 @@ namespace geom {
|
||||||
return !(*this == rhs);
|
return !(*this == rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Location GetLocation() const {
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rotation GetRotation() const {
|
||||||
|
return rotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline void TransformPointList(std::vector<T> &in_point_list) const {
|
||||||
|
for (T in_point : in_point_list) {
|
||||||
|
TransformPoint(in_point);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void TransformPoint (Location &in_point) const {
|
||||||
|
|
||||||
|
// Rotate
|
||||||
|
double cy = cos(Math::to_radians(rotation.yaw));
|
||||||
|
double sy = sin(Math::to_radians(rotation.yaw));
|
||||||
|
double cr = cos(Math::to_radians(rotation.roll));
|
||||||
|
double sr = sin(Math::to_radians(rotation.roll));
|
||||||
|
double cp = cos(Math::to_radians(rotation.pitch));
|
||||||
|
double sp = sin(Math::to_radians(rotation.pitch));
|
||||||
|
|
||||||
|
Location out_point;
|
||||||
|
out_point.x = in_point.x * ( cp * cy )
|
||||||
|
+ in_point.y * ( cy * sp * sr - sy * cr)
|
||||||
|
+ in_point.z * (-cy * sp * cr - sy * sr);
|
||||||
|
out_point.y = in_point.x * ( cp * sy)
|
||||||
|
+ in_point.y * ( sy * sp * sr + cy * cr)
|
||||||
|
+ in_point.z * (-sy * sp * cr + cy * sr);
|
||||||
|
|
||||||
|
out_point.z = in_point.x * (sp)
|
||||||
|
+ in_point.y * -(cp * sr)
|
||||||
|
+ in_point.z * (cp * cr);
|
||||||
|
|
||||||
|
// Translate
|
||||||
|
out_point += location;
|
||||||
|
|
||||||
|
in_point = out_point;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef LIBCARLA_INCLUDED_FROM_UE4
|
#ifdef LIBCARLA_INCLUDED_FROM_UE4
|
||||||
|
|
||||||
Transform(const FTransform &transform)
|
Transform(const FTransform &transform)
|
||||||
|
|
|
@ -8,11 +8,75 @@
|
||||||
|
|
||||||
#include <carla/geom/Vector3D.h>
|
#include <carla/geom/Vector3D.h>
|
||||||
#include <carla/geom/Math.h>
|
#include <carla/geom/Math.h>
|
||||||
|
#include <carla/geom/Transform.h>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
using namespace carla::geom;
|
using namespace carla::geom;
|
||||||
|
|
||||||
|
TEST(geom, single_point_no_transform) {
|
||||||
|
constexpr double error = 0.001;
|
||||||
|
|
||||||
|
Location translation (0.0, 0.0, 0.0);
|
||||||
|
Rotation rotation(0.0, 0.0, 0.0);
|
||||||
|
Transform transform (translation, rotation);
|
||||||
|
|
||||||
|
Location point (1.0,1.0,1.0);
|
||||||
|
transform.TransformPoint(point);
|
||||||
|
Location result_point(1.0, 1.0, 1.0);
|
||||||
|
|
||||||
|
ASSERT_NEAR(point.x, result_point.x, error);
|
||||||
|
ASSERT_NEAR(point.y, result_point.y, error);
|
||||||
|
ASSERT_NEAR(point.z, result_point.z, error);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(geom, single_point_translation) {
|
||||||
|
constexpr double error = 0.001;
|
||||||
|
|
||||||
|
Location translation (2.0,5.0,7.0);
|
||||||
|
Rotation rotation (0.0, 0.0, 0.0);
|
||||||
|
Transform transform (translation, rotation);
|
||||||
|
|
||||||
|
Location point (0.0, 0.0, 0.0);
|
||||||
|
transform.TransformPoint(point);
|
||||||
|
Location result_point(2.0, 5.0, 7.0);
|
||||||
|
|
||||||
|
ASSERT_NEAR(point.x, result_point.x, error);
|
||||||
|
ASSERT_NEAR(point.y, result_point.y, error);
|
||||||
|
ASSERT_NEAR(point.z, result_point.z, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(geom, single_point_rotation) {
|
||||||
|
constexpr double error = 0.001;
|
||||||
|
|
||||||
|
Location translation (0.0,0.0,0.0);
|
||||||
|
Rotation rotation (0.0,180.0,0.0); // y z x
|
||||||
|
Transform transform (translation, rotation);
|
||||||
|
|
||||||
|
Location point (0.0, 0.0, 1.0);
|
||||||
|
transform.TransformPoint(point);
|
||||||
|
Location result_point(0.0, 0.0, 1.0);
|
||||||
|
ASSERT_NEAR(point.x, result_point.x, error);
|
||||||
|
ASSERT_NEAR(point.y, result_point.y, error);
|
||||||
|
ASSERT_NEAR(point.z, result_point.z, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(geom, single_point_translation_and_rotation) {
|
||||||
|
constexpr double error = 0.001;
|
||||||
|
|
||||||
|
Location translation (0.0,0.0,-1.0); // x y z
|
||||||
|
Rotation rotation (90.0,0.0,0.0); // y z x
|
||||||
|
Transform transform (translation, rotation);
|
||||||
|
|
||||||
|
Location point (0.0, 0.0, 2.0);
|
||||||
|
transform.TransformPoint(point);
|
||||||
|
Location result_point(-2.0, 0.0, -1.0);
|
||||||
|
ASSERT_NEAR(point.x, result_point.x, error);
|
||||||
|
ASSERT_NEAR(point.y, result_point.y, error);
|
||||||
|
ASSERT_NEAR(point.z, result_point.z, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
TEST(geom, distance) {
|
TEST(geom, distance) {
|
||||||
constexpr double error = .01;
|
constexpr double error = .01;
|
||||||
ASSERT_NEAR(Math::Distance({0, 0, 0}, {0, 0, 0}), 0.0, error);
|
ASSERT_NEAR(Math::Distance({0, 0, 0}, {0, 0, 0}), 0.0, error);
|
||||||
|
|
|
@ -98,13 +98,30 @@ void export_geom() {
|
||||||
.def(self_ns::str(self_ns::self))
|
.def(self_ns::str(self_ns::self))
|
||||||
;
|
;
|
||||||
|
|
||||||
|
class_<std::vector<cg::Location> >("vector_of_locations")
|
||||||
|
.def(vector_indexing_suite<std::vector<cg::Location>>())
|
||||||
|
.def(self_ns::str(self_ns::self))
|
||||||
|
;
|
||||||
|
|
||||||
class_<cg::Transform>("Transform")
|
class_<cg::Transform>("Transform")
|
||||||
|
|
||||||
.def(init<cg::Location, cg::Rotation>(
|
.def(init<cg::Location, cg::Rotation>(
|
||||||
(arg("location")=cg::Location(), arg("rotation")=cg::Rotation())))
|
(arg("location")=cg::Location(), arg("rotation")=cg::Rotation())))
|
||||||
.def_readwrite("location", &cg::Transform::location)
|
.def_readwrite("location", &cg::Transform::location)
|
||||||
.def_readwrite("rotation", &cg::Transform::rotation)
|
.def_readwrite("rotation", &cg::Transform::rotation)
|
||||||
.def("__eq__", &cg::Transform::operator==)
|
.def("__eq__", &cg::Transform::operator==)
|
||||||
.def("__ne__", &cg::Transform::operator!=)
|
.def("__ne__", &cg::Transform::operator!=)
|
||||||
|
.def("transform_point", +[](const cg::Transform &self, cg::Location &location) {
|
||||||
|
self.TransformPoint(location);
|
||||||
|
return location;
|
||||||
|
}, arg("in_point"))
|
||||||
|
|
||||||
|
.def("transform_point_list", +[](const cg::Transform &self, std::vector<cg::Location> &location_list) {
|
||||||
|
for (cg::Location &location : location_list) {
|
||||||
|
self.TransformPoint(location);
|
||||||
|
}
|
||||||
|
return location_list;
|
||||||
|
})
|
||||||
.def(self_ns::str(self_ns::self))
|
.def(self_ns::str(self_ns::self))
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@ import carla
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
|
||||||
class testLocation(unittest.TestCase):
|
class testLocation(unittest.TestCase):
|
||||||
def test_default_values(self):
|
def test_default_values(self):
|
||||||
location = carla.Location()
|
location = carla.Location()
|
||||||
|
@ -115,3 +114,64 @@ class testTransform(unittest.TestCase):
|
||||||
carla.Rotation(pitch=4.0, yaw=5.0, roll=6.0))
|
carla.Rotation(pitch=4.0, yaw=5.0, roll=6.0))
|
||||||
s = 'Transform(Location(x=1, y=2, z=3), Rotation(pitch=4, yaw=5, roll=6))'
|
s = 'Transform(Location(x=1, y=2, z=3), Rotation(pitch=4, yaw=5, roll=6))'
|
||||||
self.assertEqual(str(t), s)
|
self.assertEqual(str(t), s)
|
||||||
|
|
||||||
|
def test_translation(self):
|
||||||
|
error = .001
|
||||||
|
t = carla.Transform(
|
||||||
|
carla.Location(x=8.0, y=19.0, z=20.0),
|
||||||
|
carla.Rotation(pitch=0.0, yaw=0.0, roll=0.0))
|
||||||
|
point = carla.Location(x=0.0, y=0.0, z=0.0)
|
||||||
|
t.transform_point(point)
|
||||||
|
self.assertTrue(abs(point.x - 8.0) <= error)
|
||||||
|
self.assertTrue(abs(point.y - 19.0) <= error)
|
||||||
|
self.assertTrue(abs(point.z - 20.0) <= error)
|
||||||
|
|
||||||
|
def test_rotation(self):
|
||||||
|
error = .001
|
||||||
|
t = carla.Transform(
|
||||||
|
carla.Location(x=0.0, y=0.0, z=0.0),
|
||||||
|
carla.Rotation(pitch=180.0, yaw=0.0, roll=0.0))
|
||||||
|
point = carla.Location(x=0.0, y=0.0, z=1.0)
|
||||||
|
t.transform_point(point)
|
||||||
|
|
||||||
|
self.assertTrue(abs(point.x - 0.0) <= error)
|
||||||
|
self.assertTrue(abs(point.y - 0.0) <= error)
|
||||||
|
self.assertTrue(abs(point.z - (-1.0)) <= error)
|
||||||
|
|
||||||
|
def test_rotation_and_translation(self):
|
||||||
|
error = .001
|
||||||
|
t = carla.Transform(
|
||||||
|
carla.Location(x=0.0, y=0.0, z=-1.0),
|
||||||
|
carla.Rotation(pitch=90.0, yaw=0.0, roll=0.0))
|
||||||
|
point = carla.Location(x=0.0, y=0.0, z=2.0)
|
||||||
|
t.transform_point(point)
|
||||||
|
|
||||||
|
self.assertTrue(abs(point.x - (-2.0)) <= error)
|
||||||
|
self.assertTrue(abs(point.y - 0.0) <= error)
|
||||||
|
self.assertTrue(abs(point.z - (-1.0)) <= error)
|
||||||
|
|
||||||
|
def test_list_rotation_and_translation(self):
|
||||||
|
error = .001
|
||||||
|
t = carla.Transform(
|
||||||
|
carla.Location(x=0.0, y=0.0, z=-1.0),
|
||||||
|
carla.Rotation(pitch=90.0, yaw=0.0, roll=0.0))
|
||||||
|
|
||||||
|
point_list = carla.vector_of_locations()
|
||||||
|
point_list.append(carla.Location(x=0.0, y=0.0, z=2.0))
|
||||||
|
point_list.append(carla.Location(x=0.0, y=10.0, z=1.0))
|
||||||
|
point_list.append(carla.Location(x=0.0, y=18.0, z=2.0))
|
||||||
|
|
||||||
|
t.transform_point_list(point_list)
|
||||||
|
|
||||||
|
solution_list = carla.vector_of_locations()
|
||||||
|
solution_list.append(carla.Location(x=-2.0, y=0.0, z=-1.0))
|
||||||
|
solution_list.append(carla.Location(x=-1.0, y=10.0, z=-1.0))
|
||||||
|
solution_list.append(carla.Location(x=-2.0, y=18.0, z=-1.0))
|
||||||
|
|
||||||
|
for i in range(len(point_list)):
|
||||||
|
self.assertTrue(abs(point_list[i].x - solution_list[i].x) <= error)
|
||||||
|
self.assertTrue(abs(point_list[i].y - solution_list[i].y) <= error)
|
||||||
|
self.assertTrue(abs(point_list[i].z - solution_list[i].z) <= error)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue