Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 537683f

Browse files
committedJul 4, 2018
Added DepthNav
1 parent d094d1e commit 537683f

File tree

5 files changed

+218
-9
lines changed

5 files changed

+218
-9
lines changed
 

‎AirLib/include/common/VectorMath.hpp

+112-8
Original file line numberDiff line numberDiff line change
@@ -188,17 +188,25 @@ class VectorMathT {
188188
return rotateVectorReverse(v_world, q, assume_unit_quat);
189189
}
190190

191+
static Vector3T transformToBodyFrame(const Vector3T& v_world, const Pose& body_pose, bool assume_unit_quat = true)
192+
{
193+
//translate
194+
Vector3T translated = v_world - body_pose.position;
195+
//rotate
196+
return transformToBodyFrame(translated, body_pose.orientation, assume_unit_quat);
197+
}
198+
191199
static Vector3T transformToWorldFrame(const Vector3T& v_body, const QuaternionT& q, bool assume_unit_quat = true)
192200
{
193201
return rotateVector(v_body, q, assume_unit_quat);
194202
}
195203

196-
static Vector3T transformToWorldFrame(const Vector3T& v_body, const Pose& pose, bool assume_unit_quat = true)
204+
static Vector3T transformToWorldFrame(const Vector3T& v_body, const Pose& body_pose, bool assume_unit_quat = true)
197205
{
198206
//translate
199-
Vector3T translated = v_body + pose.position;
207+
Vector3T translated = v_body + body_pose.position;
200208
//rotate
201-
return transformToWorldFrame(translated, pose.orientation, assume_unit_quat);
209+
return transformToWorldFrame(translated, body_pose.orientation, assume_unit_quat);
202210
}
203211

204212
static QuaternionT negate(const QuaternionT& q)
@@ -226,6 +234,9 @@ class VectorMathT {
226234
static void toEulerianAngle(const QuaternionT& q
227235
, RealT& pitch, RealT& roll, RealT& yaw)
228236
{
237+
//z-y-x rotation convention (Tait-Bryan angles)
238+
//http://www.sedris.org/wg8home/Documents/WG80485.pdf
239+
229240
RealT ysqr = q.y() * q.y();
230241

231242
// roll (x-axis rotation)
@@ -300,6 +311,9 @@ class VectorMathT {
300311
//all angles in radians
301312
static QuaternionT toQuaternion(RealT pitch, RealT roll, RealT yaw)
302313
{
314+
//z-y-x rotation convention (Tait-Bryan angles)
315+
//http://www.sedris.org/wg8home/Documents/WG80485.pdf
316+
303317
QuaternionT q;
304318
RealT t0 = std::cos(yaw * 0.5f);
305319
RealT t1 = std::sin(yaw * 0.5f);
@@ -413,32 +427,122 @@ class VectorMathT {
413427
* RPY rotates about the fixed axes in the order x-y-z,
414428
* which is the same as euler angles in the order z-y'-x''.
415429
*/
416-
static RealT yawFromQuaternion(const QuaternionT& q) {
430+
static RealT yawFromQuaternion(const QuaternionT& q)
431+
{
417432
return atan2(2.0 * (q.w() * q.z() + q.x() * q.y()),
418433
1.0 - 2.0 * (q.y() * q.y() + q.z() * q.z()));
419434
}
420435

421-
static QuaternionT quaternionFromYaw(RealT yaw) {
422-
return QuaternionT(Eigen::AngleAxisd(yaw, Vector3T::UnitZ()));
436+
static QuaternionT quaternionFromYaw(RealT yaw)
437+
{
438+
return QuaternionT(Eigen::AngleAxis<RealT>(yaw, Vector3T::UnitZ()));
439+
}
440+
441+
static QuaternionT toQuaternion(const Vector3T& axis, RealT angle)
442+
{
443+
//Alternative:
444+
//auto s = std::sinf(angle / 2);
445+
//auto u = axis.normalized();
446+
//return Quaternionr(std::cosf(angle / 2), u.x() * s, u.y() * s, u.z() * s);
447+
448+
return QuaternionT(Eigen::AngleAxis<RealT>(angle, axis));
449+
}
450+
451+
//linear interpolate
452+
static QuaternionT lerp(const QuaternionT& from, const QuaternionT& to, RealT alpha)
453+
{
454+
QuaternionT r;
455+
RealT n_alpha = 1 - alpha;
456+
r.x = n_alpha * from.x + alpha * to.x;
457+
r.y = n_alpha * from.y + alpha * to.y;
458+
r.z = n_alpha * from.z + alpha * to.z;
459+
r.w = n_alpha * from.w + alpha * to.w;
460+
return r.normalized();
461+
}
462+
463+
//spherical lerp
464+
static QuaternionT slerp(const QuaternionT& from, const QuaternionT& to, RealT alpha)
465+
{
466+
QuaternionT r;
467+
RealT n_alpha = 1 - alpha;
468+
RealT Wa, Wb;
469+
RealT theta = acos(from.x*to.x + from.y*to.y + from.z*to.z + from.w*to.w);
470+
RealT sn = sin(theta);
471+
Wa = sin(n_alpha*theta) / sn;
472+
Wb = sin(alpha*theta) / sn;
473+
r.x = Wa * from.x + Wb * to.x;
474+
r.y = Wa * from.y + Wb * to.y;
475+
r.z = Wa * from.z + Wb * to.z;
476+
r.w = Wa * from.w + Wb * to.w;
477+
return r.normalized();
478+
}
479+
480+
Vector3T lerp(const Vector3T& from, const Vector3T& to, RealT alpha)
481+
{
482+
return (from + alpha * (to - from));
483+
}
484+
485+
Vector3T slerp(const Vector3T& from, const Vector3T& to, RealT alpha)
486+
{
487+
RealT dot = from.dot(to);
488+
dot = Utils::clip<RealT>(dot, -1, 1);
489+
RealT theta = std::acos(dot)*alpha;
490+
Vector3T relative = (to - from * dot).normalized();
491+
return from * std::cos(theta) + relative * std::sin(theta);
492+
}
493+
494+
Vector3T nlerp(const Vector3T& from, const Vector3T& to, float alpha)
495+
{
496+
return lerp(from, to, alpha).normalized();
497+
}
498+
499+
static QuaternionT lookAt(Vector3T sourcePoint, Vector3T destPoint)
500+
{
501+
Vector3T toVector = (destPoint - sourcePoint);
502+
503+
RealT dot = VectorMath::front().dot(toVector);
504+
dot = Utils::clip<RealT>(dot, -1, 1);
505+
RealT ang = std::acosf(dot);
506+
507+
Vector3T axis = VectorMath::front().cross(toVector);
508+
if (axis == Vector3T::Zero())
509+
axis = VectorMath::up();
510+
else
511+
axis = axis.normalized();
512+
513+
return VectorMath::toQuaternion(axis, ang);
423514
}
424515

425516
static const Vector3T front()
426517
{
427518
static Vector3T v(1, 0, 0);
428519
return v;
429520
}
430-
521+
static const Vector3T back()
522+
{
523+
static Vector3T v(-1, 0, 0);
524+
return v;
525+
}
431526
static const Vector3T down()
432527
{
433528
static Vector3T v(0, 0, 1);
434529
return v;
435530
}
436-
531+
static const Vector3T up()
532+
{
533+
static Vector3T v(0, 0, -1);
534+
return v;
535+
}
437536
static const Vector3T right()
438537
{
439538
static Vector3T v(0, 1, 0);
440539
return v;
441540
}
541+
static const Vector3T left()
542+
{
543+
static Vector3T v(0, -1, 0);
544+
return v;
545+
}
442546
};
443547
typedef VectorMathT<Eigen::Vector3d, Eigen::Quaternion<double,Eigen::DontAlign>, double> VectorMathd;
444548
typedef VectorMathT<Eigen::Vector3f, Eigen::Quaternion<float,Eigen::DontAlign>, float> VectorMathf;

‎AirLibUnitTests/QuaternionTest.hpp

+42-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,47 @@ class QuaternionTest : public TestBase
1010
{
1111
public:
1212
virtual void run() override
13+
{
14+
//eulerAngleTest();
15+
lookAtTest();
16+
}
17+
18+
private:
19+
Quaternionr lookAt(Vector3r sourcePoint, Vector3r destPoint)
20+
{
21+
Vector3r toVector = (destPoint - sourcePoint).normalized();
22+
23+
Vector3r rotAxis = VectorMath::front().cross(toVector).normalized();
24+
if (rotAxis.squaredNorm() == 0)
25+
rotAxis = VectorMath::up();
26+
float dot = VectorMath::front().dot(toVector);
27+
float ang = std::acosf(dot);
28+
29+
return VectorMath::toQuaternion(rotAxis, ang);
30+
}
31+
32+
Quaternionr toQuaternion(const Vector3r& axis, float angle) {
33+
auto s = std::sinf(angle / 2);
34+
auto u = axis.normalized();
35+
return Quaternionr(std::cosf(angle / 2), u.x() * s, u.y() * s, u.z() * s);
36+
}
37+
38+
void lookAtTest()
39+
{
40+
auto q = lookAt(Vector3r::Zero(), Vector3r(-1.f, 0, 0));
41+
std::cout << VectorMath::toString(q) << std::endl;
42+
43+
float pitch, roll, yaw;
44+
VectorMath::toEulerianAngle(q, pitch, roll, yaw);
45+
std::cout << pitch << "\t" << roll << "\t" << yaw << "\t" << std::endl;
46+
47+
//q = VectorMath::toQuaternion(0, 0, Utils::degreesToRadians(180.0f));
48+
//std::cout << VectorMath::toString(q) << std::endl;
49+
//VectorMath::toEulerianAngle(q, pitch, roll, yaw);
50+
//std::cout << pitch << "\t" << roll << "\t" << yaw << "\t" << std::endl;
51+
}
52+
53+
void eulerAngleTest()
1354
{
1455
RandomGeneratorR r(-1000.0f, 1000.0f);
1556
RandomGeneratorR rw(-1000.0f, 1000.0f);
@@ -22,7 +63,7 @@ class QuaternionTest : public TestBase
2263

2364
Quaternionr qd = VectorMath::toQuaternion(pitch, roll, yaw);
2465
if (std::signbit(qd.w()) != std::signbit(q.w())) {
25-
qd.coeffs() = - qd.coeffs();
66+
qd.coeffs() = -qd.coeffs();
2667
}
2768

2869
auto dw = std::abs(qd.w() - q.w());

‎Examples/DepthNav.hpp

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
#pragma once
5+
6+
// includes needed to call RPC APIs
7+
#include "common/common_utils/StrictMode.hpp"
8+
STRICT_MODE_OFF
9+
#ifndef RPCLIB_MSGPACK
10+
#define RPCLIB_MSGPACK clmdep_msgpack
11+
#endif // !RPCLIB_MSGPACK
12+
#include "rpc/rpc_error.h"
13+
STRICT_MODE_ON
14+
15+
//includes for vector math and other common types
16+
#include "common/Common.hpp"
17+
18+
namespace msr { namespace airlib {
19+
20+
class DepthNav {
21+
public: //types
22+
struct Params {
23+
//Camera FOV
24+
float fov = Utils::degreesToRadians(90.0f);
25+
//min dot product required for goal vector to be
26+
//considered so goal is inside frustum
27+
float min_frustrum_alighment = (1.0f + 0.75f) / 2;
28+
};
29+
30+
public:
31+
DepthNav(const Params& params = Params())
32+
: params_(params)
33+
{
34+
}
35+
36+
//goal is specified in world frame and typically provided by the global planner
37+
//current_pose is current pose of the vehicle in world frame
38+
//return next pose that vehicle should be in
39+
Pose getNextPose(const Vector3r& goal, const Pose& current_pose)
40+
{
41+
//get goal in body frame
42+
auto goal_body = VectorMath::transformToBodyFrame(goal, current_pose);
43+
44+
//is goal inside frustum?
45+
float frustrum_alighment = std::fabsf(goal_body.dot(VectorMath::front()));
46+
if (frustrum_alighment >= params_.min_frustrum_alighment) {
47+
48+
}
49+
else {
50+
//goal is not in the frustum. Let's rotate ourselves until we get
51+
//goal in the frustum
52+
53+
}
54+
}
55+
56+
private:
57+
Params params_;
58+
};
59+
60+
}}

‎Examples/Examples.vcxproj

+1
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@
185185
<ClCompile Include="main.cpp" />
186186
</ItemGroup>
187187
<ItemGroup>
188+
<ClInclude Include="DepthNav.hpp" />
188189
<ClInclude Include="GaussianMarkovTest.hpp" />
189190
<ClInclude Include="RandomPointPoseGenerator.hpp" />
190191
<ClInclude Include="StandAlonePhysics.hpp" />

‎Examples/Examples.vcxproj.filters

+3
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,8 @@
3535
<ClInclude Include="GaussianMarkovTest.hpp">
3636
<Filter>Header Files</Filter>
3737
</ClInclude>
38+
<ClInclude Include="DepthNav.hpp">
39+
<Filter>Header Files</Filter>
40+
</ClInclude>
3841
</ItemGroup>
3942
</Project>

0 commit comments

Comments
 (0)
Please sign in to comment.