20 m_task_size = task_size;
22 m_jacobian.resize(task_size, dof);
28 m_nullspace.resize(dof, dof);
30 m_d_theta.resize(dof);
31 m_d_theta_tmp.resize(dof);
32 m_d_norm_weight.resize(dof);
37 m_beta.resize(task_size);
40 m_weight_sqrt.resize(dof);
42 m_weight_sqrt.setOnes();
44 if (task_size >= dof) {
47 m_jacobian_tmp.resize(task_size, dof);
49 m_svd_u.resize(task_size, dof);
50 m_svd_v.resize(dof, dof);
53 m_svd_u_beta.resize(dof);
60 m_jacobian_tmp.resize(dof, task_size);
62 m_svd_u.resize(task_size, task_size);
63 m_svd_v.resize(dof, task_size);
64 m_svd_w.resize(task_size);
66 m_svd_u_beta.resize(task_size);
72 m_beta[
id + 0] =
v.x();
73 m_beta[
id + 1] =
v.y();
74 m_beta[
id + 2] =
v.z();
79 m_jacobian(
id + 0, dof_id) =
v.x() * m_weight_sqrt[dof_id];
80 m_jacobian(
id + 1, dof_id) =
v.y() * m_weight_sqrt[dof_id];
81 m_jacobian(
id + 2, dof_id) =
v.z() * m_weight_sqrt[dof_id];
83 m_d_norm_weight[dof_id] = norm_weight;
91 Eigen::JacobiSVD<MatrixXd> svd(m_jacobian.transpose(),
92 Eigen::ComputeThinU | Eigen::ComputeThinV);
93 m_svd_u = svd.matrixV();
94 m_svd_w = svd.singularValues();
95 m_svd_v = svd.matrixU();
100 Eigen::JacobiSVD<MatrixXd> svd(m_jacobian, Eigen::ComputeThinU | Eigen::ComputeThinV);
101 m_svd_u = svd.matrixU();
102 m_svd_w = svd.singularValues();
103 m_svd_v = svd.matrixV();
116 double epsilon = 1
e-10;
120 for (
i = 0;
i < m_svd_w.size();
i++) {
121 if (m_svd_w[
i] > epsilon) {
126 if (rank < m_task_size) {
130 MatrixXd basis(m_svd_v.rows(), rank);
133 for (
i = 0;
i < m_svd_w.size();
i++) {
134 if (m_svd_w[
i] > epsilon) {
135 for (j = 0; j < m_svd_v.rows(); j++) {
136 basis(j,
b) = m_svd_v(j,
i);
142 m_nullspace = basis * basis.transpose();
144 for (
i = 0;
i < m_nullspace.rows();
i++) {
145 for (j = 0; j < m_nullspace.cols(); j++) {
147 m_nullspace(
i, j) = 1.0 - m_nullspace(
i, j);
150 m_nullspace(
i, j) = -m_nullspace(
i, j);
165 jacobian.
Restrict(m_d_theta, m_nullspace);
174 for (
i = 0;
i < m_d_theta.size();
i++) {
182 m_beta = m_beta - m_jacobian * d_theta;
187 m_jacobian = m_jacobian * nullspace;
190void IK_QJacobian::InvertSDLS()
208 double max_angle_change =
M_PI_4;
209 double epsilon = 1
e-10;
215 for (
i = 0;
i < m_dof;
i++) {
217 for (j = 0; j < m_task_size; j += 3) {
219 n += m_jacobian(j,
i) * m_jacobian(j,
i);
220 n += m_jacobian(j + 1,
i) * m_jacobian(j + 1,
i);
221 n += m_jacobian(j + 2,
i) * m_jacobian(j + 2,
i);
222 m_norm[
i] +=
sqrt(n);
226 for (
i = 0;
i < m_svd_w.size();
i++) {
227 if (m_svd_w[
i] <= epsilon) {
231 double wInv = 1.0 / m_svd_w[
i];
236 for (j = 0; j < m_svd_u.rows(); j += 3) {
237 alpha += m_svd_u(j,
i) * m_beta[j];
238 alpha += m_svd_u(j + 1,
i) * m_beta[j + 1];
239 alpha += m_svd_u(j + 2,
i) * m_beta[j + 2];
244 tmp = m_svd_u(j,
i) * m_svd_u(j,
i);
245 tmp += m_svd_u(j + 1,
i) * m_svd_u(j + 1,
i);
246 tmp += m_svd_u(j + 2,
i) * m_svd_u(j + 2,
i);
253 double max_dtheta = 0.0, abs_dtheta;
255 for (j = 0; j < m_d_theta.size(); j++) {
256 double v = m_svd_v(j,
i);
260 m_d_theta_tmp[j] =
v * alpha;
264 abs_dtheta =
fabs(m_d_theta_tmp[j]) * m_weight_sqrt[j];
265 max_dtheta = std::max(abs_dtheta, max_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];
284 dofdamp = std::min(dofdamp, 1.0);
286 m_d_theta[j] += 0.80 * dofdamp * m_d_theta_tmp[j];
289 m_min_damp = std::min(damp, m_min_damp);
293 double max_angle = 0.0, abs_angle;
295 for (j = 0; j < m_dof; j++) {
296 m_d_theta[j] *= m_weight[j];
298 abs_angle =
fabs(m_d_theta[j]);
300 max_angle = std::max(abs_angle, max_angle);
303 if (max_angle > max_angle_change) {
304 double damp = (max_angle_change) / (max_angle_change + max_angle);
306 for (j = 0; j < m_dof; j++) {
307 m_d_theta[j] *= damp;
312void IK_QJacobian::InvertDLS()
332 double max_angle_change = 0.1;
333 double x_length =
sqrt(m_beta.dot(m_beta));
336 double w_min = std::numeric_limits<double>::max();
338 for (
i = 0;
i < m_svd_w.size();
i++) {
339 if (m_svd_w[
i] > epsilon && m_svd_w[
i] < w_min) {
346 double d = x_length / max_angle_change;
349 if (w_min <= d / 2) {
352 else if (w_min < d) {
353 lambda =
sqrt(w_min * (d - w_min));
361 lambda = std::min<double>(lambda, 10);
367 m_svd_u_beta = m_svd_u.transpose() * m_beta;
371 for (
i = 0;
i < m_svd_w.size();
i++) {
372 if (m_svd_w[
i] > epsilon) {
373 double wInv = m_svd_w[
i] / (m_svd_w[
i] * m_svd_w[
i] + lambda);
376 m_svd_u_beta[
i] *= wInv;
378 for (j = 0; j < m_d_theta.size(); j++) {
379 m_d_theta[j] += m_svd_v(j,
i) * m_svd_u_beta[
i];
384 for (j = 0; j < m_d_theta.size(); j++) {
385 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]);
414 mx = std::max(dtheta_abs, mx);
422 m_weight[dof] = weight;
423 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()
ccl_device_inline float2 fabs(const float2 a)
double epsilon
default precision while comparing with Equal(..,..) functions. Initialized at 0.0000001.