37 m_task_size = task_size;
39 m_jacobian.resize(task_size, dof);
45 m_nullspace.resize(dof, dof);
47 m_d_theta.resize(dof);
48 m_d_theta_tmp.resize(dof);
49 m_d_norm_weight.resize(dof);
54 m_beta.resize(task_size);
57 m_weight_sqrt.resize(dof);
59 m_weight_sqrt.setOnes();
61 if (task_size >= dof) {
64 m_jacobian_tmp.resize(task_size, dof);
66 m_svd_u.resize(task_size, dof);
67 m_svd_v.resize(dof, dof);
70 m_svd_u_beta.resize(dof);
77 m_jacobian_tmp.resize(dof, task_size);
79 m_svd_u.resize(task_size, task_size);
80 m_svd_v.resize(dof, task_size);
81 m_svd_w.resize(task_size);
83 m_svd_u_beta.resize(task_size);
89 m_beta[
id + 0] =
v.x();
90 m_beta[
id + 1] =
v.y();
91 m_beta[
id + 2] =
v.z();
96 m_jacobian(
id + 0, dof_id) =
v.x() * m_weight_sqrt[dof_id];
97 m_jacobian(
id + 1, dof_id) =
v.y() * m_weight_sqrt[dof_id];
98 m_jacobian(
id + 2, dof_id) =
v.z() * m_weight_sqrt[dof_id];
100 m_d_norm_weight[dof_id] = norm_weight;
108 Eigen::JacobiSVD<MatrixXd> svd(m_jacobian.transpose(),
109 Eigen::ComputeThinU | Eigen::ComputeThinV);
110 m_svd_u = svd.matrixV();
111 m_svd_w = svd.singularValues();
112 m_svd_v = svd.matrixU();
117 Eigen::JacobiSVD<MatrixXd> svd(m_jacobian, Eigen::ComputeThinU | Eigen::ComputeThinV);
118 m_svd_u = svd.matrixU();
119 m_svd_w = svd.singularValues();
120 m_svd_v = svd.matrixV();
135 for (i = 0; i < m_svd_w.size(); i++)
139 if (rank < m_task_size)
142 MatrixXd basis(m_svd_v.rows(), rank);
145 for (i = 0; i < m_svd_w.size(); i++)
147 for (j = 0; j < m_svd_v.rows(); j++)
148 basis(j, b) = m_svd_v(j, i);
152 m_nullspace = basis * basis.transpose();
154 for (i = 0; i < m_nullspace.rows(); i++)
155 for (j = 0; j < m_nullspace.cols(); j++)
157 m_nullspace(i, j) = 1.0 - m_nullspace(i, j);
159 m_nullspace(i, j) = -m_nullspace(i, j);
170 jacobian.
Restrict(m_d_theta, m_nullspace);
179 for (i = 0; i < m_d_theta.size(); i++)
180 m_d_theta[i] = m_d_theta[i] + jacobian.
AngleUpdate(i);
186 m_beta = m_beta - m_jacobian * d_theta;
191 m_jacobian = m_jacobian * nullspace;
194 void IK_QJacobian::InvertSDLS()
212 double max_angle_change =
M_PI / 4.0;
219 for (i = 0; i < m_dof; i++) {
221 for (j = 0; j < m_task_size; j += 3) {
223 n += m_jacobian(j, i) * m_jacobian(j, i);
224 n += m_jacobian(j + 1, i) * m_jacobian(j + 1, i);
225 n += m_jacobian(j + 2, i) * m_jacobian(j + 2, i);
226 m_norm[i] +=
sqrt(n);
230 for (i = 0; i < m_svd_w.size(); i++) {
234 double wInv = 1.0 / m_svd_w[i];
239 for (j = 0; j < m_svd_u.rows(); j += 3) {
240 alpha += m_svd_u(j, i) * m_beta[j];
241 alpha += m_svd_u(j + 1, i) * m_beta[j + 1];
242 alpha += m_svd_u(j + 2, i) * m_beta[j + 2];
247 tmp = m_svd_u(j, i) * m_svd_u(j, i);
248 tmp += m_svd_u(j + 1, i) * m_svd_u(j + 1, i);
249 tmp += m_svd_u(j + 2, i) * m_svd_u(j + 2, i);
256 double max_dtheta = 0.0, abs_dtheta;
258 for (j = 0; j < m_d_theta.size(); j++) {
259 double v = m_svd_v(j, i);
263 m_d_theta_tmp[j] =
v *
alpha;
267 abs_dtheta =
fabs(m_d_theta_tmp[j]) * m_weight_sqrt[j];
268 if (abs_dtheta > max_dtheta)
269 max_dtheta = abs_dtheta;
275 double gamma = max_angle_change;
279 double damp = (gamma < max_dtheta) ? gamma / max_dtheta : 1.0;
281 for (j = 0; j < m_d_theta.size(); j++) {
286 double dofdamp = damp / m_weight[j];
290 m_d_theta[j] += 0.80 * dofdamp * m_d_theta_tmp[j];
293 if (damp < m_min_damp)
298 double max_angle = 0.0, abs_angle;
300 for (j = 0; j < m_dof; j++) {
301 m_d_theta[j] *= m_weight[j];
303 abs_angle =
fabs(m_d_theta[j]);
305 if (abs_angle > max_angle)
306 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;
317 void IK_QJacobian::InvertDLS()
337 double max_angle_change = 0.1;
338 double x_length =
sqrt(m_beta.dot(m_beta));
343 for (i = 0; i < m_svd_w.size(); i++) {
344 if (m_svd_w[i] >
epsilon && m_svd_w[i] < w_min)
350 double d = x_length / max_angle_change;
356 lambda =
sqrt(w_min * (d - w_min));
369 m_svd_u_beta = m_svd_u.transpose() * m_beta;
373 for (i = 0; i < m_svd_w.size(); i++) {
375 double wInv = m_svd_w[i] / (m_svd_w[i] * m_svd_w[i] + lambda);
378 m_svd_u_beta[i] *= wInv;
380 for (j = 0; j < m_d_theta.size(); j++)
381 m_d_theta[j] += m_svd_v(j, i) * m_svd_u_beta[i];
385 for (j = 0; j < m_d_theta.size(); j++)
386 m_d_theta[j] *= m_weight[j];
393 for (i = 0; i < m_task_size; i++) {
394 m_beta[i] -= m_jacobian(i, dof_id) * delta;
395 m_jacobian(i, dof_id) = 0.0;
398 m_norm[dof_id] = 0.0;
399 m_d_theta[dof_id] = 0.0;
404 return m_d_theta[dof_id];
410 double mx = 0.0, dtheta_abs;
412 for (i = 0; i < m_d_theta.size(); i++) {
413 dtheta_abs =
fabs(m_d_theta[i] * m_d_norm_weight[i]);
423 m_weight[dof] = weight;
424 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()
static CCL_NAMESPACE_BEGIN const double alpha
ccl_device_inline float2 fabs(const float2 &a)