18 m_task_size = task_size;
20 m_jacobian.resize(task_size, dof);
26 m_nullspace.resize(dof, dof);
28 m_d_theta.resize(dof);
29 m_d_theta_tmp.resize(dof);
30 m_d_norm_weight.resize(dof);
35 m_beta.resize(task_size);
38 m_weight_sqrt.resize(dof);
40 m_weight_sqrt.setOnes();
42 if (task_size >= dof) {
45 m_jacobian_tmp.resize(task_size, dof);
47 m_svd_u.resize(task_size, dof);
48 m_svd_v.resize(dof, dof);
51 m_svd_u_beta.resize(dof);
58 m_jacobian_tmp.resize(dof, task_size);
60 m_svd_u.resize(task_size, task_size);
61 m_svd_v.resize(dof, task_size);
62 m_svd_w.resize(task_size);
64 m_svd_u_beta.resize(task_size);
70 m_beta[
id + 0] =
v.x();
71 m_beta[
id + 1] =
v.y();
72 m_beta[
id + 2] =
v.z();
77 m_jacobian(
id + 0, dof_id) =
v.x() * m_weight_sqrt[dof_id];
78 m_jacobian(
id + 1, dof_id) =
v.y() * m_weight_sqrt[dof_id];
79 m_jacobian(
id + 2, dof_id) =
v.z() * m_weight_sqrt[dof_id];
81 m_d_norm_weight[dof_id] = norm_weight;
89 Eigen::JacobiSVD<MatrixXd> svd(m_jacobian.transpose(),
90 Eigen::ComputeThinU | Eigen::ComputeThinV);
91 m_svd_u = svd.matrixV();
92 m_svd_w = svd.singularValues();
93 m_svd_v = svd.matrixU();
98 Eigen::JacobiSVD<MatrixXd> svd(m_jacobian, Eigen::ComputeThinU | Eigen::ComputeThinV);
99 m_svd_u = svd.matrixU();
100 m_svd_w = svd.singularValues();
101 m_svd_v = svd.matrixV();
114 double epsilon = 1
e-10;
118 for (i = 0; i < m_svd_w.size(); i++) {
119 if (m_svd_w[i] > epsilon) {
124 if (rank < m_task_size) {
128 MatrixXd basis(m_svd_v.rows(), rank);
131 for (i = 0; i < m_svd_w.size(); i++) {
132 if (m_svd_w[i] > epsilon) {
133 for (j = 0; j < m_svd_v.rows(); j++) {
134 basis(j,
b) = m_svd_v(j, i);
140 m_nullspace = basis * basis.transpose();
142 for (i = 0; i < m_nullspace.rows(); i++) {
143 for (j = 0; j < m_nullspace.cols(); j++) {
145 m_nullspace(i, j) = 1.0 - m_nullspace(i, j);
148 m_nullspace(i, j) = -m_nullspace(i, j);
163 jacobian.
Restrict(m_d_theta, m_nullspace);
172 for (i = 0; i < m_d_theta.size(); i++) {
173 m_d_theta[i] = m_d_theta[i] + jacobian.
AngleUpdate(i);
180 m_beta = m_beta - m_jacobian * d_theta;
185 m_jacobian = m_jacobian * nullspace;
188void IK_QJacobian::InvertSDLS()
206 double max_angle_change =
M_PI_4;
207 double epsilon = 1
e-10;
213 for (i = 0; i < m_dof; i++) {
215 for (j = 0; j < m_task_size; j += 3) {
217 n += m_jacobian(j, i) * m_jacobian(j, i);
218 n += m_jacobian(j + 1, i) * m_jacobian(j + 1, i);
219 n += m_jacobian(j + 2, i) * m_jacobian(j + 2, i);
220 m_norm[i] +=
sqrt(n);
224 for (i = 0; i < m_svd_w.size(); i++) {
225 if (m_svd_w[i] <= epsilon) {
229 double wInv = 1.0 / m_svd_w[i];
234 for (j = 0; j < m_svd_u.rows(); j += 3) {
235 alpha += m_svd_u(j, i) * m_beta[j];
236 alpha += m_svd_u(j + 1, i) * m_beta[j + 1];
237 alpha += m_svd_u(j + 2, i) * m_beta[j + 2];
242 tmp = m_svd_u(j, i) * m_svd_u(j, i);
243 tmp += m_svd_u(j + 1, i) * m_svd_u(j + 1, i);
244 tmp += m_svd_u(j + 2, i) * m_svd_u(j + 2, i);
251 double max_dtheta = 0.0, abs_dtheta;
253 for (j = 0; j < m_d_theta.size(); j++) {
254 double v = m_svd_v(j, i);
258 m_d_theta_tmp[j] =
v * alpha;
262 abs_dtheta =
fabs(m_d_theta_tmp[j]) * m_weight_sqrt[j];
263 if (abs_dtheta > max_dtheta) {
264 max_dtheta = abs_dtheta;
271 double gamma = max_angle_change;
276 double damp = (gamma < max_dtheta) ? gamma / max_dtheta : 1.0;
278 for (j = 0; j < m_d_theta.size(); j++) {
283 double dofdamp = damp / m_weight[j];
288 m_d_theta[j] += 0.80 * dofdamp * m_d_theta_tmp[j];
291 if (damp < m_min_damp) {
297 double max_angle = 0.0, abs_angle;
299 for (j = 0; j < m_dof; j++) {
300 m_d_theta[j] *= m_weight[j];
302 abs_angle =
fabs(m_d_theta[j]);
304 if (abs_angle > max_angle) {
305 max_angle = abs_angle;
309 if (max_angle > max_angle_change) {
310 double damp = (max_angle_change) / (max_angle_change + max_angle);
312 for (j = 0; j < m_dof; j++) {
313 m_d_theta[j] *= damp;
318void IK_QJacobian::InvertDLS()
338 double max_angle_change = 0.1;
339 double x_length =
sqrt(m_beta.dot(m_beta));
342 double w_min = std::numeric_limits<double>::max();
344 for (i = 0; i < m_svd_w.size(); i++) {
345 if (m_svd_w[i] > epsilon && m_svd_w[i] < w_min) {
352 double d = x_length / max_angle_change;
355 if (w_min <= d / 2) {
358 else if (w_min < d) {
359 lambda =
sqrt(w_min * (d - w_min));
375 m_svd_u_beta = m_svd_u.transpose() * m_beta;
379 for (i = 0; i < m_svd_w.size(); i++) {
380 if (m_svd_w[i] > epsilon) {
381 double wInv = m_svd_w[i] / (m_svd_w[i] * m_svd_w[i] + lambda);
384 m_svd_u_beta[i] *= wInv;
386 for (j = 0; j < m_d_theta.size(); j++) {
387 m_d_theta[j] += m_svd_v(j, i) * m_svd_u_beta[i];
392 for (j = 0; j < m_d_theta.size(); j++) {
393 m_d_theta[j] *= m_weight[j];
401 for (i = 0; i < m_task_size; i++) {
402 m_beta[i] -= m_jacobian(i, dof_id) * delta;
403 m_jacobian(i, dof_id) = 0.0;
406 m_norm[dof_id] = 0.0;
407 m_d_theta[dof_id] = 0.0;
412 return m_d_theta[dof_id];
418 double mx = 0.0, dtheta_abs;
420 for (i = 0; i < m_d_theta.size(); i++) {
421 dtheta_abs =
fabs(m_d_theta[i] * m_d_norm_weight[i]);
422 if (dtheta_abs > mx) {
432 m_weight[dof] = weight;
433 m_weight_sqrt[dof] =
sqrt(weight);
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
void Lock(int dof_id, double delta)
void SetDerivatives(int id, int dof_id, const Vector3d &v, double norm_weight)
void SetDoFWeight(int dof, double weight)
void Restrict(VectorXd &d_theta, MatrixXd &nullspace)
void SubTask(IK_QJacobian &jacobian)
double AngleUpdateNorm() const
void SetBetas(int id, int size, const Vector3d &v)
double AngleUpdate(int dof_id) const
void ArmMatrices(int dof, int task_size)
bool ComputeNullProjection()
local_group_size(16, 16) .push_constant(Type b
ccl_device_inline float2 fabs(const float2 a)
double epsilon
default precision while comparing with Equal(..,..) functions. Initialized at 0.0000001.