Monado OpenXR Runtime
Loading...
Searching...
No Matches
lm_optimizer_params_packer.inl
Go to the documentation of this file.
1// Copyright 2022, Collabora, Ltd.
2// SPDX-License-Identifier: BSL-1.0
3/*!
4 * @file
5 * @brief Util to reinterpret Ceres parameter vectors as hand model parameters
6 * @author Moshi Turner <moshiturner@protonmail.com>
7 * @author Charlton Rodda <charlton.rodda@collabora.com>
8 * @ingroup tracking
9 */
10
11// #include <iostream>
12// #include <cmath>
13#include "util/u_logging.h"
14#include "math/m_api.h"
15
16#include "lm_interface.hpp"
17#include "lm_defines.hpp"
18#include "lm_rotations.inl"
19
20namespace xrt::tracking::hand::mercury::lm {
21
22
23
24template <typename T>
25inline T
26LMToModel(T lm, minmax mm)
27{
28 return mm.min + ((sin(lm) + T(1)) * ((mm.max - mm.min) * T(.5)));
29}
30
31template <typename T>
32inline T
33ModelToLM(T model, minmax mm)
34{
35 return asin((2 * (model - mm.min) / (mm.max - mm.min)) - 1);
36}
37
38// Input vector,
39template <typename T>
40void
41OptimizerHandUnpackFromVector(const T *in, const KinematicHandLM &state, OptimizerHand<T> &out)
42{
43
44 const Quat<T> pre_wrist_orientation(state.this_frame_pre_rotation);
45 const Vec3<T> pre_wrist_position(state.this_frame_pre_position);
46
47 size_t acc_idx = 0;
48#ifdef USE_HAND_TRANSLATION
49 out.wrist_post_location.x = in[acc_idx++];
50 out.wrist_post_location.y = in[acc_idx++];
51 out.wrist_post_location.z = in[acc_idx++];
52
53 out.wrist_final_location.x = out.wrist_post_location.x + T(pre_wrist_position.x);
54 out.wrist_final_location.y = out.wrist_post_location.y + T(pre_wrist_position.y);
55 out.wrist_final_location.z = out.wrist_post_location.z + T(pre_wrist_position.z);
56
57#endif
58
59#ifdef USE_HAND_ORIENTATION
60 out.wrist_post_orientation_aax.x = in[acc_idx++];
61 out.wrist_post_orientation_aax.y = in[acc_idx++];
62 out.wrist_post_orientation_aax.z = in[acc_idx++];
63
64 Quat<T> post_wrist_orientation = {};
65
66 AngleAxisToQuaternion<T>(out.wrist_post_orientation_aax, post_wrist_orientation);
67
68 QuaternionProduct<T>(pre_wrist_orientation, post_wrist_orientation, out.wrist_final_orientation);
69#endif
70
71#ifdef USE_EVERYTHING_ELSE
72
73 out.thumb.metacarpal.swing.x = LMToModel(in[acc_idx++], the_limit.thumb_mcp_swing_x);
74 out.thumb.metacarpal.swing.y = LMToModel(in[acc_idx++], the_limit.thumb_mcp_swing_y);
75 out.thumb.metacarpal.twist = LMToModel(in[acc_idx++], the_limit.thumb_mcp_twist);
76
77 out.thumb.rots[0] = LMToModel(in[acc_idx++], the_limit.thumb_curls[0]);
78 out.thumb.rots[1] = LMToModel(in[acc_idx++], the_limit.thumb_curls[1]);
79
80 for (int finger_idx = 0; finger_idx < 4; finger_idx++) {
81 // Note that we are not unpacking the metacarpal swing/twist as it is constant.
82 out.finger[finger_idx].proximal_swing.x =
83 LMToModel(in[acc_idx++], the_limit.fingers[finger_idx].pxm_swing_x);
84 out.finger[finger_idx].proximal_swing.y =
85 LMToModel(in[acc_idx++], the_limit.fingers[finger_idx].pxm_swing_y);
86
87 out.finger[finger_idx].rots[0] = LMToModel(in[acc_idx++], the_limit.fingers[finger_idx].curls[0]);
88 out.finger[finger_idx].rots[1] = LMToModel(in[acc_idx++], the_limit.fingers[finger_idx].curls[1]);
89 }
90#endif
91
92#ifdef USE_HAND_SIZE
93 if (state.optimize_hand_size) {
94 out.hand_size = LMToModel(in[acc_idx++], the_limit.hand_size);
95 } else {
96 out.hand_size = T(state.target_hand_size);
97 }
98#endif
99}
100
101template <typename T>
102void
103OptimizerHandPackIntoVector(OptimizerHand<T> &in, bool use_hand_size, T *out)
104{
105 size_t acc_idx = 0;
106
107#ifdef USE_HAND_TRANSLATION
108 out[acc_idx++] = in.wrist_post_location.x;
109 out[acc_idx++] = in.wrist_post_location.y;
110 out[acc_idx++] = in.wrist_post_location.z;
111#endif
112#ifdef USE_HAND_ORIENTATION
113 out[acc_idx++] = in.wrist_post_orientation_aax.x;
114 out[acc_idx++] = in.wrist_post_orientation_aax.y;
115 out[acc_idx++] = in.wrist_post_orientation_aax.z;
116#endif
117#ifdef USE_EVERYTHING_ELSE
118 out[acc_idx++] = ModelToLM(in.thumb.metacarpal.swing.x, the_limit.thumb_mcp_swing_x);
119 out[acc_idx++] = ModelToLM(in.thumb.metacarpal.swing.y, the_limit.thumb_mcp_swing_y);
120 out[acc_idx++] = ModelToLM(in.thumb.metacarpal.twist, the_limit.thumb_mcp_twist);
121
122 out[acc_idx++] = ModelToLM(in.thumb.rots[0], the_limit.thumb_curls[0]);
123 out[acc_idx++] = ModelToLM(in.thumb.rots[1], the_limit.thumb_curls[1]);
124
125 for (int finger_idx = 0; finger_idx < 4; finger_idx++) {
126 // Note that we are not packing the metacarpal swing/twist as it is constant.
127 out[acc_idx++] =
128 ModelToLM(in.finger[finger_idx].proximal_swing.x, the_limit.fingers[finger_idx].pxm_swing_x);
129 out[acc_idx++] =
130 ModelToLM(in.finger[finger_idx].proximal_swing.y, the_limit.fingers[finger_idx].pxm_swing_y);
131
132 out[acc_idx++] = ModelToLM(in.finger[finger_idx].rots[0], the_limit.fingers[finger_idx].curls[0]);
133 out[acc_idx++] = ModelToLM(in.finger[finger_idx].rots[1], the_limit.fingers[finger_idx].curls[1]);
134 }
135#endif
136
137#ifdef USE_HAND_SIZE
138 if (use_hand_size) {
139 out[acc_idx++] = ModelToLM(in.hand_size, the_limit.hand_size);
140 }
141#endif
142}
143
144template <typename T>
145void
147{
148 opt.hand_size = (T)STANDARD_HAND_SIZE;
149
150 opt.wrist_post_orientation_aax.x = (T)(0);
151 opt.wrist_post_orientation_aax.y = (T)(0);
152 opt.wrist_post_orientation_aax.z = (T)(0);
153
154
155 // opt.wrist_pre_orientation_quat = pre_rotation;
156
157 opt.wrist_post_location.x = (T)(0);
158 opt.wrist_post_location.y = (T)(0);
159 opt.wrist_post_location.z = (T)(0);
160
161
162 for (int i = 0; i < 4; i++) {
163 //!@todo needed?
164 opt.finger[i].metacarpal.swing.x = T(0);
165 opt.finger[i].metacarpal.twist = T(0);
166
167 opt.finger[i].proximal_swing.x = T(rad<HandScalar>(15.0f));
168 opt.finger[i].rots[0] = T(rad<HandScalar>(-5));
169 opt.finger[i].rots[1] = T(rad<HandScalar>(-5));
170 }
171
172 opt.thumb.metacarpal.swing.x = (T)(0);
173 opt.thumb.metacarpal.swing.y = (T)(0);
174 opt.thumb.metacarpal.twist = (T)(0);
175
176 opt.thumb.rots[0] = T(rad<HandScalar>(-5));
177 opt.thumb.rots[1] = T(rad<HandScalar>(-59));
178
179 opt.finger[0].metacarpal.swing.y = (T)(-0.19);
180 opt.finger[1].metacarpal.swing.y = (T)(0);
181 opt.finger[2].metacarpal.swing.y = (T)(0.19);
182 opt.finger[3].metacarpal.swing.y = (T)(0.38);
183
184 opt.finger[0].metacarpal.swing.x = (T)(-0.02);
185 opt.finger[1].metacarpal.swing.x = (T)(0);
186 opt.finger[2].metacarpal.swing.x = (T)(0.02);
187 opt.finger[3].metacarpal.swing.x = (T)(0.04);
188
189 opt.finger[0].proximal_swing.y = (T)(-0.01);
190 opt.finger[1].proximal_swing.y = (T)(0);
191 opt.finger[2].proximal_swing.y = (T)(0.01);
192 opt.finger[3].proximal_swing.y = (T)(0.02);
193}
194
195
196} // namespace xrt::tracking::hand::mercury::lm
Defines for Levenberg-Marquardt kinematic optimizer.
Interface for Levenberg-Marquardt kinematic optimizer.
void OptimizerHandInit(OptimizerHand< T > &opt, Quat< T > &pre_rotation)
Definition lm_optimizer_params_packer.inl:146
Autodiff-safe rotations for Levenberg-Marquardt kinematic optimizer.
C interface to math library.
Definition lm_defines.hpp:215
Basic logging functionality.