forked from RobotLocomotion/drake
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrotation.cc
97 lines (86 loc) · 3.06 KB
/
rotation.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include "drake/common/schema/rotation.h"
#include "drake/common/drake_throw.h"
#include "drake/math/random_rotation.h"
#include "drake/math/rotation_matrix.h"
namespace drake {
namespace schema {
using symbolic::Expression;
namespace {
// Boilerplate for std::visit.
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
} // namespace
Rotation::Rotation(const math::RotationMatrix<double>& arg)
: Rotation(math::RollPitchYaw<double>(arg)) {}
Rotation::Rotation(const math::RollPitchYaw<double>& arg) {
const Eigen::Vector3d rpy_rad = arg.vector();
set_rpy_deg(rpy_rad * 180 / M_PI);
}
bool Rotation::IsDeterministic() const {
using Result = bool;
return std::visit(overloaded{
[](const Identity&) -> Result {
return true;
},
[](const Rpy& rpy) -> Result {
return schema::IsDeterministic(rpy.deg);
},
[](const AngleAxis& aa) -> Result {
return schema::IsDeterministic(aa.angle_deg) &&
schema::IsDeterministic(aa.axis);
},
[](const Uniform&) -> Result {
return false;
},
}, value);
}
math::RotationMatrixd Rotation::GetDeterministicValue() const {
DRAKE_THROW_UNLESS(this->IsDeterministic());
const Matrix3<Expression> symbolic = this->ToSymbolic().matrix();
const Eigen::Matrix3d result = symbolic.unaryExpr([](const auto& e) {
return ExtractDoubleOrThrow(e);
});
return math::RotationMatrixd(result);
}
namespace {
// Converts a degree distribution to radians. Our symbolic representations do
// not yet handle gaussian angles correctly, so we forbid them for now.
Expression deg2rad(const DistributionVariant& deg_var) {
DRAKE_THROW_UNLESS(!std::holds_alternative<Gaussian>(deg_var));
const Expression deg_sym = schema::ToSymbolic(deg_var);
return deg_sym * (M_PI / 180.0);
}
template <int Size>
Vector<Expression, Size> deg2rad(
const DistributionVectorVariant<Size>& deg_var) {
DRAKE_THROW_UNLESS(!std::holds_alternative<GaussianVector<Size>>(deg_var));
const Vector<Expression, Size> deg_sym =
schema::ToDistributionVector(deg_var)->ToSymbolic();
return deg_sym * (M_PI / 180.0);
}
} // namespace
math::RotationMatrix<Expression> Rotation::ToSymbolic() const {
using Result = math::RotationMatrix<Expression>;
return std::visit(overloaded{
[](const Identity&) -> Result {
return Result{};
},
[](const Rpy& rpy) -> Result {
const Vector3<Expression> rpy_rad = deg2rad(rpy.deg);
return Result{math::RollPitchYaw<Expression>(rpy_rad)};
},
[](const AngleAxis& aa) -> Result {
const Expression angle_rad = deg2rad(aa.angle_deg);
const Vector3<Expression> axis =
schema::ToDistributionVector(aa.axis)->ToSymbolic().normalized();
const Eigen::AngleAxis<Expression> theta_lambda(angle_rad, axis);
return Result{theta_lambda};
},
[](const Uniform&) -> Result {
RandomGenerator generator;
return math::UniformlyRandomRotationMatrix<Expression>(&generator);
},
}, value);
}
} // namespace schema
} // namespace drake