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 Quat<T> pre_wrist_orientation_t(pre_wrist_orientation);
69
70 QuaternionProduct<T>(pre_wrist_orientation_t, post_wrist_orientation, out.wrist_final_orientation);
71#endif
72
73#ifdef USE_EVERYTHING_ELSE
74
75 out.thumb.metacarpal.swing.x = LMToModel(in[acc_idx++], the_limit.thumb_mcp_swing_x);
76 out.thumb.metacarpal.swing.y = LMToModel(in[acc_idx++], the_limit.thumb_mcp_swing_y);
77 out.thumb.metacarpal.twist = LMToModel(in[acc_idx++], the_limit.thumb_mcp_twist);
78
79 out.thumb.rots[0] = LMToModel(in[acc_idx++], the_limit.thumb_curls[0]);
80 out.thumb.rots[1] = LMToModel(in[acc_idx++], the_limit.thumb_curls[1]);
81
82 for (int finger_idx = 0; finger_idx < 4; finger_idx++) {
83 // Note that we are not unpacking the metacarpal swing/twist as it is constant.
84 out.finger[finger_idx].proximal_swing.x =
85 LMToModel(in[acc_idx++], the_limit.fingers[finger_idx].pxm_swing_x);
86 out.finger[finger_idx].proximal_swing.y =
87 LMToModel(in[acc_idx++], the_limit.fingers[finger_idx].pxm_swing_y);
88
89 out.finger[finger_idx].rots[0] = LMToModel(in[acc_idx++], the_limit.fingers[finger_idx].curls[0]);
90 out.finger[finger_idx].rots[1] = LMToModel(in[acc_idx++], the_limit.fingers[finger_idx].curls[1]);
91 }
92#endif
93
94#ifdef USE_HAND_SIZE
95 if (state.optimize_hand_size) {
96 out.hand_size = LMToModel(in[acc_idx++], the_limit.hand_size);
97 } else {
98 out.hand_size = T(state.target_hand_size);
99 }
100#endif
101}
102
103template <typename T>
104void
105OptimizerHandPackIntoVector(OptimizerHand<T> &in, bool use_hand_size, T *out)
106{
107 size_t acc_idx = 0;
108
109#ifdef USE_HAND_TRANSLATION
110 out[acc_idx++] = in.wrist_post_location.x;
111 out[acc_idx++] = in.wrist_post_location.y;
112 out[acc_idx++] = in.wrist_post_location.z;
113#endif
114#ifdef USE_HAND_ORIENTATION
115 out[acc_idx++] = in.wrist_post_orientation_aax.x;
116 out[acc_idx++] = in.wrist_post_orientation_aax.y;
117 out[acc_idx++] = in.wrist_post_orientation_aax.z;
118#endif
119#ifdef USE_EVERYTHING_ELSE
120 out[acc_idx++] = ModelToLM(in.thumb.metacarpal.swing.x, the_limit.thumb_mcp_swing_x);
121 out[acc_idx++] = ModelToLM(in.thumb.metacarpal.swing.y, the_limit.thumb_mcp_swing_y);
122 out[acc_idx++] = ModelToLM(in.thumb.metacarpal.twist, the_limit.thumb_mcp_twist);
123
124 out[acc_idx++] = ModelToLM(in.thumb.rots[0], the_limit.thumb_curls[0]);
125 out[acc_idx++] = ModelToLM(in.thumb.rots[1], the_limit.thumb_curls[1]);
126
127 for (int finger_idx = 0; finger_idx < 4; finger_idx++) {
128 // Note that we are not packing the metacarpal swing/twist as it is constant.
129 out[acc_idx++] =
130 ModelToLM(in.finger[finger_idx].proximal_swing.x, the_limit.fingers[finger_idx].pxm_swing_x);
131 out[acc_idx++] =
132 ModelToLM(in.finger[finger_idx].proximal_swing.y, the_limit.fingers[finger_idx].pxm_swing_y);
133
134 out[acc_idx++] = ModelToLM(in.finger[finger_idx].rots[0], the_limit.fingers[finger_idx].curls[0]);
135 out[acc_idx++] = ModelToLM(in.finger[finger_idx].rots[1], the_limit.fingers[finger_idx].curls[1]);
136 }
137#endif
138
139#ifdef USE_HAND_SIZE
140 if (use_hand_size) {
141 out[acc_idx++] = ModelToLM(in.hand_size, the_limit.hand_size);
142 }
143#endif
144}
145
146template <typename T>
147void
149{
150 opt.hand_size = (T)STANDARD_HAND_SIZE;
151
152 opt.wrist_post_orientation_aax.x = (T)(0);
153 opt.wrist_post_orientation_aax.y = (T)(0);
154 opt.wrist_post_orientation_aax.z = (T)(0);
155
156
157 // opt.wrist_pre_orientation_quat = pre_rotation;
158
159 opt.wrist_post_location.x = (T)(0);
160 opt.wrist_post_location.y = (T)(0);
161 opt.wrist_post_location.z = (T)(0);
162
163
164 for (int i = 0; i < 4; i++) {
165 //!@todo needed?
166 opt.finger[i].metacarpal.swing.x = T(0);
167 opt.finger[i].metacarpal.twist = T(0);
168
169 opt.finger[i].proximal_swing.x = T(rad<HandScalar>(15.0f));
170 opt.finger[i].rots[0] = T(rad<HandScalar>(-5));
171 opt.finger[i].rots[1] = T(rad<HandScalar>(-5));
172 }
173
174 opt.thumb.metacarpal.swing.x = (T)(0);
175 opt.thumb.metacarpal.swing.y = (T)(0);
176 opt.thumb.metacarpal.twist = (T)(0);
177
178 opt.thumb.rots[0] = T(rad<HandScalar>(-5));
179 opt.thumb.rots[1] = T(rad<HandScalar>(-59));
180
181 opt.finger[0].metacarpal.swing.y = (T)(-0.19);
182 opt.finger[1].metacarpal.swing.y = (T)(0);
183 opt.finger[2].metacarpal.swing.y = (T)(0.19);
184 opt.finger[3].metacarpal.swing.y = (T)(0.38);
185
186 opt.finger[0].metacarpal.swing.x = (T)(-0.02);
187 opt.finger[1].metacarpal.swing.x = (T)(0);
188 opt.finger[2].metacarpal.swing.x = (T)(0.02);
189 opt.finger[3].metacarpal.swing.x = (T)(0.04);
190
191 opt.finger[0].proximal_swing.y = (T)(-0.01);
192 opt.finger[1].proximal_swing.y = (T)(0);
193 opt.finger[2].proximal_swing.y = (T)(0.01);
194 opt.finger[3].proximal_swing.y = (T)(0.02);
195}
196
197
198} // 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:148
Autodiff-safe rotations for Levenberg-Marquardt kinematic optimizer.
C interface to math library.
Definition lm_defines.hpp:215
Basic logging functionality.