ROMP icon indicating copy to clipboard operation
ROMP copied to clipboard

global rotation problem

Open ldincredible opened this issue 2 years ago • 2 comments

Hi, when I input the output['smpl_thetas'] into smpl.pose and then visualize it, I find the global rotation is upside down. I rotated the quaternion by -180 degrees about the X-axis and -90 degrees about the z-axis, but it was still wrong, what rotation do I need to do about those axes? image image

ldincredible avatar Jan 10 '23 04:01 ldincredible

Here is an example to convert to a blender 3D view: https://github.com/Arthur151/ROMP/blob/a349c6bf4d6229b8fba2e900d38ef210888937d0/simple_romp/tools/convert2fbx.py#L192

Arthur151 avatar Jan 11 '23 16:01 Arthur151

I see. Thank you. I would like to know if the smpl is a left-handed coordinate system? Is the root joint of the smpl rotated around the (1, 0, 0) unit vector? I was recently thinking of converting the smpl axis Angle to a global right-handed xyz coordinate system quaternion, but the rotation of the conversion was incorrect, and I used the following code: first

def local_to_global(poses, parents, output_format='aa', input_format='aa'):
    """
    Convert relative joint angles to global ones by unrolling the kinematic chain.
    :param poses: A tensor of shape (N, N_JOINTS*3) defining the relative poses in angle-axis format.
    :param parents: A list of parents for each joint j, i.e. parent[j] is the parent of joint j.
    :param output_format: 'aa' or 'rotmat'.
    :param input_format: 'aa' or 'rotmat'
    :return: The global joint angles as a tensor of shape (N, N_JOINTS*DOF).
    """
    assert output_format in ['aa', 'rotmat']
    assert input_format in ['aa', 'rotmat']
    dof = 3 if input_format == 'aa' else 9
    n_joints = poses.shape[-1] // dof
    if input_format == 'aa':
        local_oris = aa2rot_torch(poses.reshape((-1, 3)))
    else:
        local_oris = poses
    local_oris = local_oris.reshape((-1, n_joints, 3, 3))
    global_oris = torch.zeros_like(local_oris)

    for j in range(n_joints):
        if parents[j] < 0:
            # root rotation
            global_oris[..., j, :, :] = local_oris[..., j, :, :]
        else:
            parent_rot = global_oris[..., parents[j], :, :]
            local_rot = local_oris[..., j, :, :]
            global_oris[..., j, :, :] = torch.matmul(parent_rot, local_rot)

    if output_format == 'aa':
        global_oris = rot2aa_torch(global_oris.reshape((-1, 3, 3)))
        res = global_oris.reshape((-1, n_joints * 3))
    else:
        res = global_oris.reshape((-1, n_joints * 3 * 3))
    return res

then

def transform_rot_representation(rot, input_type='mat',out_type='quat',input_is_degrees=True):
    '''
    make transformation between different representation of 3D rotation
    input_type / out_type (np.array):
        'mat': rotation matrix (3*3)
        'quat': quaternion (4)
        'vec': rotation vector (3)
        'euler': Euler degrees in x,y,z (3)
    '''
    if input_type=='mat':
        r = R.from_matrix(rot)
    elif input_type=='quat':
        r = R.from_quat(rot)
    elif input_type =='vec':
        r = R.from_rotvec(rot)
    elif input_type =='euler':
        r = R.from_euler('xyz',rot, degrees=input_is_degrees)
    
    if out_type=='mat':
        out = r.as_matrix()
    elif out_type=='quat':
        out = r.as_quat()
    elif out_type =='vec':
        out = r.as_rotvec()
    elif out_type =='euler':
        out = r.as_euler('xyz', degrees=False)
    return out

Can you help me see what's wrong?

ldincredible avatar Jan 12 '23 02:01 ldincredible