15#include "../kine_common.hpp"
17namespace xrt::tracking::hand::mercury::lm {
19#define LM_TRACE(lmh, ...) U_LOG_IFL_T(lmh.log_level, __VA_ARGS__)
20#define LM_DEBUG(lmh, ...) U_LOG_IFL_D(lmh.log_level, __VA_ARGS__)
21#define LM_INFO(lmh, ...) U_LOG_IFL_I(lmh.log_level, __VA_ARGS__)
22#define LM_WARN(lmh, ...) U_LOG_IFL_W(lmh.log_level, __VA_ARGS__)
23#define LM_ERROR(lmh, ...) U_LOG_IFL_E(lmh.log_level, __VA_ARGS__)
30 return degrees * T(M_PI / 180.f);
34static constexpr size_t kNumNNJoints = 21;
36static constexpr size_t kNumFingers = 5;
39static constexpr size_t kNumJointsInFinger = 5;
41static constexpr size_t kNumOrientationsInFinger = 4;
45#define USE_HAND_TRANSLATION
46#define USE_HAND_ORIENTATION
47#define USE_EVERYTHING_ELSE
50#undef USE_HAND_PLAUSIBILITY
54#undef RESIDUALS_HACKING
56static constexpr size_t kMetacarpalBoneDim = 3;
57static constexpr size_t kProximalBoneDim = 2;
58static constexpr size_t kFingerDim = kProximalBoneDim + 2;
59static constexpr size_t kThumbDim = kMetacarpalBoneDim + 2;
60static constexpr size_t kHandSizeDim = 1;
61static constexpr size_t kHandTranslationDim = 3;
62static constexpr size_t kHandOrientationDim = 3;
66static constexpr size_t kHRTC_HandSize = 1;
67static constexpr size_t kHRTC_RootBoneTranslation = 3;
68static constexpr size_t kHRTC_RootBoneOrientation = 3;
71static constexpr size_t kHRTC_ThumbMCPSwingTwist = 3;
72static constexpr size_t kHRTC_ThumbCurls = 2;
74static constexpr size_t kHRTC_ProximalSimilarity = 2;
76static constexpr size_t kHRTC_FingerMCPSwingTwist = 0;
77static constexpr size_t kHRTC_FingerPXMSwing = 2;
78static constexpr size_t kHRTC_FingerCurls = 2;
79static constexpr size_t kHRTC_CurlSimilarity = 1;
82static constexpr size_t kHandResidualOneSideXY = (kNumNNJoints * 2);
83static constexpr size_t kHandResidualOneSideDepth = 20;
85static constexpr size_t kHandResidualOneSideMatchCurls = 4;
87static constexpr size_t kHandResidualOneSideMatchCurls = 0;
89static constexpr size_t kHandResidualOneSideSize =
90 kHandResidualOneSideXY + kHandResidualOneSideDepth + kHandResidualOneSideMatchCurls;
92static constexpr size_t kHandResidualTemporalConsistencyOneFingerSize =
93 kHRTC_FingerMCPSwingTwist +
94 kHRTC_FingerPXMSwing +
96#ifdef USE_HAND_PLAUSIBILITY
97 kHRTC_CurlSimilarity +
101static constexpr size_t kHandResidualTemporalConsistencySize =
102 kHRTC_RootBoneTranslation +
103 kHRTC_RootBoneOrientation +
104 kHRTC_ThumbMCPSwingTwist +
106#ifdef USE_HAND_PLAUSIBILITY
107 kHRTC_ProximalSimilarity +
109 (kHandResidualTemporalConsistencyOneFingerSize * 4) +
116 HandScalar stabilityRoot;
117 HandScalar stabilityCurlRoot;
118 HandScalar stabilityOtherRoot;
120 HandScalar stabilityThumbMCPSwing;
121 HandScalar stabilityThumbMCPTwist;
123 HandScalar stabilityFingerMCPSwing;
124 HandScalar stabilityFingerMCPTwist;
126 HandScalar stabilityFingerPXMSwingX;
127 HandScalar stabilityFingerPXMSwingY;
129 HandScalar stabilityRootPosition;
130 HandScalar stabilityHandSize;
132 HandScalar stabilityHandOrientationZ;
133 HandScalar stabilityHandOrientationXY;
136 this->stabilityRoot = root;
137 this->stabilityCurlRoot = this->stabilityRoot * 0.03f;
138 this->stabilityOtherRoot = this->stabilityRoot * 0.03f;
140 this->stabilityThumbMCPSwing = this->stabilityCurlRoot * 1.5f;
141 this->stabilityThumbMCPTwist = this->stabilityCurlRoot * 1.5f;
143 this->stabilityFingerMCPSwing = this->stabilityCurlRoot * 3.0f;
144 this->stabilityFingerMCPTwist = this->stabilityCurlRoot * 3.0f;
146 this->stabilityFingerPXMSwingX = this->stabilityCurlRoot * 0.6f;
147 this->stabilityFingerPXMSwingY = this->stabilityCurlRoot * 1.6f;
149 this->stabilityRootPosition = this->stabilityOtherRoot * 25;
150 this->stabilityHandSize = this->stabilityOtherRoot * 1000;
152 this->stabilityHandOrientationZ = this->stabilityOtherRoot * 0.5;
153 this->stabilityHandOrientationXY = this->stabilityOtherRoot * 0.8;
158static constexpr HandScalar kPlausibilityRoot = 1.0;
159static constexpr HandScalar kPlausibilityProximalSimilarity = 0.05f * kPlausibilityRoot;
161static constexpr HandScalar kPlausibilityCurlSimilarityHard = 0.10f * kPlausibilityRoot;
162static constexpr HandScalar kPlausibilityCurlSimilaritySoft = 0.05f * kPlausibilityRoot;
166calc_input_size(
bool optimize_hand_size)
170#ifdef USE_HAND_TRANSLATION
171 out += kHandTranslationDim;
174#ifdef USE_HAND_ORIENTATION
175 out += kHandOrientationDim;
178#ifdef USE_EVERYTHING_ELSE
180 out += (kFingerDim * 4);
184 if (optimize_hand_size) {
193calc_residual_size(
bool stability,
bool optimize_hand_size,
int num_views)
196 for (
int i = 0; i < num_views; i++) {
197 out += kHandResidualOneSideSize;
201 out += kHandResidualTemporalConsistencySize;
204 if (optimize_hand_size) {
205 out += kHRTC_HandSize;
214template <
typename Scalar>
struct Quat
225 constexpr Quat(
Quat const &)
noexcept(std::is_nothrow_copy_constructible_v<Scalar>) =
default;
232 operator=(
Quat const &) = default;
236 operator=(
Quat &&) noexcept = default;
239 template <typename Other>
240 constexpr
Quat(Other x, Other y, Other z, Other w) noexcept
250 return Quat(0.f, 0.f, 0.f, 1.f);
254template <
typename Scalar>
struct Vec3
265 constexpr Vec3(
Vec3 const &other)
noexcept(std::is_nothrow_copy_constructible_v<Scalar>) =
default;
272 operator=(
Vec3 const &) = default;
276 operator=(
Vec3 &&) noexcept = default;
279 template <typename Other>
280 constexpr
Vec3(Other x, Other y, Other z) noexcept
284 template <
typename Other>
Vec3(Vec3<Other>
const &other) :
Vec3(other.x, other.y, other.z) {}
289 return Vec3(0.f, 0.f, 0.f);
297 len_sqrd += this->x * this->x;
298 len_sqrd += this->y * this->y;
299 len_sqrd += this->z * this->z;
311 Scalar len_sqrd = this->norm_sqrd();
313 return sqrt(len_sqrd);
321 Scalar norm = this->norm();
324 retval.x = this->x / norm;
325 retval.y = this->y / norm;
326 retval.z = this->z / norm;
331template <
typename Scalar>
struct Vec2
340 constexpr Vec2(
Vec2 const &)
noexcept(std::is_nothrow_copy_constructible_v<Scalar>) =
default;
343 constexpr Vec2(
Vec2 &&) noexcept(std::is_nothrow_move_constructible_v<
Scalar>) = default;
347 operator=(
Vec2 const &) = default;
351 operator=(
Vec2 &&) noexcept = default;
354 template <typename Other>
356 noexcept(std::is_nothrow_constructible_v<
Scalar, Other>)
360 template <
typename Other>
361 Vec2(Vec2<Other>
const &other)
noexcept(std::is_nothrow_constructible_v<Scalar, Other>) :
Vec2(other.x, other.y)
364 static constexpr Vec2
367 return Vec2(0.f, 0.f);
373 T *out_residual =
nullptr;
374 size_t out_residual_idx = 0;
378 out_residual_idx = 0;
382 AddValue(T
const &value)
384 this->out_residual[out_residual_idx++] = value;
413 Vec3<T> wrist_post_location = {};
414 Vec3<T> wrist_post_orientation_aax = {};
416 Vec3<T> wrist_final_location = {};
417 Quat<T> wrist_final_orientation = {};
448 minmax thumb_mcp_swing_x = {};
449 minmax thumb_mcp_swing_y = {};
450 minmax thumb_mcp_twist = {};
451 minmax thumb_curls[2] = {};
459 thumb_mcp_swing_x = {rad<HandScalar>(-60), rad<HandScalar>(60)};
460 thumb_mcp_swing_y = {rad<HandScalar>(-60), rad<HandScalar>(60)};
461 thumb_mcp_twist = {rad<HandScalar>(-35), rad<HandScalar>(35)};
463 for (
int i = 0; i < 2; i++) {
464 thumb_curls[i] = {rad<HandScalar>(-90), rad<HandScalar>(40)};
468 HandScalar margin = 0.0001;
470 fingers[0].mcp_swing_y = {HandScalar(-0.19) - margin, HandScalar(-0.19) + margin};
471 fingers[1].mcp_swing_y = {HandScalar(0.00) - margin, HandScalar(0.00) + margin};
472 fingers[2].mcp_swing_y = {HandScalar(0.19) - margin, HandScalar(0.19) + margin};
473 fingers[3].mcp_swing_y = {HandScalar(0.38) - margin, HandScalar(0.38) + margin};
476 fingers[0].mcp_swing_x = {HandScalar(-0.02) - margin, HandScalar(-0.02) + margin};
477 fingers[1].mcp_swing_x = {HandScalar(0.00) - margin, HandScalar(0.00) + margin};
478 fingers[2].mcp_swing_x = {HandScalar(0.02) - margin, HandScalar(0.02) + margin};
479 fingers[3].mcp_swing_x = {HandScalar(0.04) - margin, HandScalar(0.04) + margin};
482 for (
int finger_idx = 0; finger_idx < 4; finger_idx++) {
486 finger.mcp_twist = {rad<HandScalar>(-4), rad<HandScalar>(4)};
488 finger.pxm_swing_x = {rad<HandScalar>(-100), rad<HandScalar>(20)};
489 finger.pxm_swing_y = {rad<HandScalar>(-20), rad<HandScalar>(20)};
491 for (
int i = 0; i < 2; i++) {
492 finger.curls[i] = {rad<HandScalar>(-90), rad<HandScalar>(0)};
498static const class HandLimit the_limit = {};
509 T depth_value[kNumNNJoints];
514 T *out_residual =
nullptr;
515 size_t out_residual_idx = {};
520 AddValue(T
const &value)
522 this->out_residual[out_residual_idx++] = value;
529 bool first_frame =
true;
530 bool use_stability =
false;
531 bool optimize_hand_size =
true;
532 bool is_right =
false;
533 float smoothing_factor;
534 int num_observation_views = 0;
537 HandScalar target_hand_size = {};
538 HandScalar hand_size_err_mul = {};
539 HandScalar depth_err_mul = {};
560 Eigen::Matrix<HandScalar, calc_input_size(
true), 1> TinyOptimizerInput = {};
565 Vec3<T> t[kNumFingers][kNumJointsInFinger] = {};
570 Quat<T> q[kNumFingers][kNumJointsInFinger] = {};
576 size_t num_residuals_;
578 template <
typename T>
580 operator()(
const T *
const x, T *residual)
const;
583 : parent(in_last_hand), num_residuals_(num_residuals)
589 return num_residuals_;
Definition: lm_defines.hpp:431
Definition: lm_defines.hpp:444
Definition: lm_defines.hpp:114
u_logging_level
Logging level enum.
Definition: u_logging.h:43
@ U_LOGGING_INFO
Info messages: not very verbose, not indicating a problem.
Definition: u_logging.h:46
constexpr HandScalar MIN_HAND_SIZE
Definition: kine_common.hpp:90
Interoperability helpers connecting internal math types and Eigen.
Wrapper header for <math.h> to ensure pi-related math constants are defined.
Definition: lm_defines.hpp:574
Definition: lm_defines.hpp:508
Definition: lm_defines.hpp:528
Definition: lm_defines.hpp:396
Definition: lm_defines.hpp:411
Definition: lm_defines.hpp:404
Definition: lm_defines.hpp:569
Definition: lm_defines.hpp:215
Quat(Quat< Other > const &other)
So that we can copy a regular Vec2 into the real part of a Jet Vec2.
Definition: lm_defines.hpp:245
constexpr Quat(Quat const &) noexcept(std::is_nothrow_copy_constructible_v< Scalar >)=default
Copy constructor.
Quat(Quat &&) noexcept(std::is_nothrow_move_constructible_v< Scalar >)=default
Move constructor.
constexpr Quat()
Default constructor - DOES NOT INITIALIZE VALUES.
Definition: lm_defines.hpp:222
Definition: lm_defines.hpp:372
Definition: lm_defines.hpp:513
Definition: lm_defines.hpp:502
Definition: lm_defines.hpp:564
Definition: lm_defines.hpp:332
constexpr Vec2(Vec2 &&) noexcept(std::is_nothrow_move_constructible_v< Scalar >)=default
Move constructor.
constexpr Vec2(Vec2 const &) noexcept(std::is_nothrow_copy_constructible_v< Scalar >)=default
Copy constructor.
constexpr Vec2() noexcept
Default constructor - DOES NOT INITIALIZE VALUES.
Definition: lm_defines.hpp:337
Definition: lm_defines.hpp:255
Vec3(Vec3 &&) noexcept(std::is_nothrow_move_constructible_v< Scalar >)=default
Move constructor.
constexpr Vec3(Vec3 const &other) noexcept(std::is_nothrow_copy_constructible_v< Scalar >)=default
Copy constructor.
constexpr Vec3()
Default constructor - DOES NOT INITIALIZE VALUES.
Definition: lm_defines.hpp:263
Definition: lm_defines.hpp:425
A pose composed of a position and orientation.
Definition: xrt_defines.h:465
Basic logging functionality.