Open yang2640 opened 4 years ago
Yep, this part is necessary. If I remember correctly, that's what happens if you take an analytical derivative of the Forward Kinematics. The derivation is a bit lengthy, so forgive me for not putting it here. I could also suggest removing that line and watching some funny results of optimization =)
Intuitively, we could think that every model vertex that is transformed by a particular joint is transformed w.r.t. to that joint rotation AND global position. A derivative of the vertex w.r.t. to joint angles essentially describes how this vertex position will change when the joint is rotated a bit. And this change will be notably different for different locations of the joint even if the amount of rotation is the same. Thus derivative has to reflect the joint location somehow. If you put zeros in this local_transform_jac_out
, then the position info will be lost entirely.
Hope this helps =)
@maria-korosteleva , rotation theta for joint i should only cause translation change to child joints of joint i, but not for joint i, if we look into the formula T(i) = R(global) * (Resting(i) - Resting(i_parent)) + T(global), local rotation didn't appear in the formula. Could you help look into this part again, because I seem to be pretty sure to the formula.
@yang2640, let me extend my attempt of "intuitive" explanation
Here the dynamic programming thing also comes into play. The derivative for the local transformation of each joint is computed once per full-pose jacobian computation and then is reused to compute derivatives of global transformation matrices for all the subsequent joints.
lines 928-929 of SMPLWrapper.cpp:
fk_derivatives_[joint_id][joint_id * SMPLWrapper::SPACE_DIM + dim] =
fk_transforms_[joints_parents_[joint_id]] * localTransformJac[dim];
Here we update fk_derivatives_
for the current joint w.r.t. current joint's parameters
lines 939-940 of SMPLWrapper.cpp:
fk_derivatives_[joint_id][j] =
fk_derivatives_[joints_parents_[joint_id]][j] * localTransform;
we reuse the fk_derivatives
from the joints higher in the hierarchy to get fk_derivatives_
for the current joint w.r.t. parameters of previous joints. If we set zeros localTransformJac[dim]
translation part when working with those previous joints, this multiplicative chain will get broken.
Regarding the formula you are giving, T(i) = R(global) * (Resting(i) - Resting(i_parent)) + T(global)
-- I don't quite understand the notation and cannot recognize it. What are you trying to depict here?
I can comment, however, on the note "local rotation didn't appear in the formula". Whenever we are talking about pose parameters for this model, we are talking about specifying the local transform of each joint w.r.t. its a parent (this is actually a common practice). Skinning ( in our case, LBS) requires global transformation, so in order to get a global transformation for the joint w.r.t. to the world, one needs to perform Forward Kinematics. FK formula derivative thus requires getting a derivative of local transform at some point =))
In "void SMPLWrapper::get3DLocalTransformJac_(const E::Vector3d & jointAxisAngleRotation, const E::MatrixXd & transform_mat, E::MatrixXd* local_transform_jac_out)"
" for (int i = 0; i < SPACE_DIM; ++i) { local_transform_jac_out[i].setZero(4, 4); local_transform_jac_out[i].col(SPACE_DIM) = transform_mat.col(SPACE_DIM);
} " Is " local_transform_jac_out[i].col(SPACE_DIM) = transform_mat.col(SPACE_DIM); " necessary ? I am thinking this column on translation should be all 0s, because the axis-angle rotation on current jointID will have not any influence on the current translation, though it should be have influence on the translation of the child.