예제 #1
0
def test_conversions_between_exponential_coordinates_and_transform():
    A2B = np.eye(4)
    Stheta = exponential_coordinates_from_transform(A2B)
    assert_array_almost_equal(Stheta, [0.0, 0.0, 0.0, 0.0, 0.0, 0.0])
    A2B2 = transform_from_exponential_coordinates(Stheta)
    assert_array_almost_equal(A2B, A2B2)

    A2B = translate_transform(np.eye(4), [1.0, 5.0, 0.0])
    Stheta = exponential_coordinates_from_transform(A2B)
    assert_array_almost_equal(Stheta, [0.0, 0.0, 0.0, 1.0, 5.0, 0.0])
    A2B2 = transform_from_exponential_coordinates(Stheta)
    assert_array_almost_equal(A2B, A2B2)

    A2B = rotate_transform(np.eye(4), active_matrix_from_angle(2, 0.5 * np.pi))
    Stheta = exponential_coordinates_from_transform(A2B)
    assert_array_almost_equal(Stheta, [0.0, 0.0, 0.5 * np.pi, 0.0, 0.0, 0.0])
    A2B2 = transform_from_exponential_coordinates(Stheta)
    assert_array_almost_equal(A2B, A2B2)

    random_state = np.random.RandomState(52)
    for _ in range(5):
        A2B = random_transform(random_state)
        Stheta = exponential_coordinates_from_transform(A2B)
        A2B2 = transform_from_exponential_coordinates(Stheta)
        assert_array_almost_equal(A2B, A2B2)
예제 #2
0
def test_norm_exponential_coordinates():
    Stheta_only_translation = np.array([0.0, 0.0, 0.0, 100.0, 25.0, -23.0])
    Stheta_only_translation2 = norm_exponential_coordinates(
        Stheta_only_translation)
    assert_array_almost_equal(Stheta_only_translation,
                              Stheta_only_translation2)

    random_state = np.random.RandomState(381)

    # 180 degree rotation ambiguity
    for _ in range(10):
        q = random_state.randn(3)
        s = norm_vector(random_state.randn(3))
        h = random_state.randn()
        Stheta = screw_axis_from_screw_parameters(q, s, h) * np.pi
        Stheta2 = screw_axis_from_screw_parameters(q, -s, -h) * np.pi
        assert_array_almost_equal(
            transform_from_exponential_coordinates(Stheta),
            transform_from_exponential_coordinates(Stheta2))
        assert_array_almost_equal(norm_exponential_coordinates(Stheta),
                                  norm_exponential_coordinates(Stheta2))

    for _ in range(10):
        Stheta = random_state.randn(6)
        # ensure that theta is not within [-pi, pi]
        Stheta[random_state.randint(0, 3)] += np.pi + random_state.rand()
        Stheta_norm = norm_exponential_coordinates(Stheta)
        assert_false(np.all(Stheta == Stheta_norm))

        A2B = transform_from_exponential_coordinates(Stheta)
        Stheta2 = exponential_coordinates_from_transform(A2B)
        assert_array_almost_equal(Stheta2, Stheta_norm)
예제 #3
0
def test_dual_quaternion_sclerp():
    random_state = np.random.RandomState(22)
    pose1 = random_transform(random_state)
    pose2 = random_transform(random_state)
    dq1 = dual_quaternion_from_transform(pose1)
    dq2 = dual_quaternion_from_transform(pose2)

    n_steps = 100

    # Ground truth: screw linear interpolation
    pose12pose2 = concat(pose2, invert_transform(pose1))
    screw_axis, theta = screw_axis_from_exponential_coordinates(
        exponential_coordinates_from_transform(pose12pose2))
    offsets = np.array([
        transform_from_exponential_coordinates(screw_axis * t * theta)
        for t in np.linspace(0, 1, n_steps)
    ])
    interpolated_poses = np.array(
        [concat(offset, pose1) for offset in offsets])

    # Dual quaternion ScLERP
    sclerp_interpolated_dqs = np.vstack([
        dual_quaternion_sclerp(dq1, dq2, t)
        for t in np.linspace(0, 1, n_steps)
    ])
    sclerp_interpolated_poses_from_dqs = np.array(
        [transform_from_dual_quaternion(dq) for dq in sclerp_interpolated_dqs])

    for t in range(n_steps):
        assert_array_almost_equal(interpolated_poses[t],
                                  sclerp_interpolated_poses_from_dqs[t])
def animation_callback(step, cylinder, cylinder_frame, prev_cylinder2world,
                       Stheta_dot, inertia_inv):
    if step == 0:  # Reset cylinder state
        prev_cylinder2world[:, :] = np.eye(4)
        Stheta_dot[:] = 0.0

    # Apply constant wrench
    wrench_in_cylinder = np.array([0.1, 0.001, 0.001, 0.01, 1.0, 1.0])
    dt = 0.0005

    Stheta_ddot = np.dot(inertia_inv, wrench_in_cylinder)
    Stheta_dot += dt * Stheta_ddot
    cylinder2world = transform_from_exponential_coordinates(
        dt * Stheta_dot).dot(prev_cylinder2world)

    # Update visualization
    cylinder_frame.set_data(cylinder2world)
    cylinder.set_data(cylinder2world)

    prev_cylinder2world[:, :] = cylinder2world

    return cylinder_frame, cylinder
예제 #5
0
import numpy as np
import matplotlib.pyplot as plt
from pytransform3d.rotations import active_matrix_from_extrinsic_roll_pitch_yaw
from pytransform3d.transformations import (
    plot_transform, plot_screw, screw_axis_from_screw_parameters,
    transform_from_exponential_coordinates, concat, transform_from)

# Screw parameters
q = np.array([-0.2, -0.1, -0.5])
s_axis = np.array([0, 0, 1])
h = 0.05
theta = 5.5 * np.pi

Stheta = screw_axis_from_screw_parameters(q, s_axis, h) * theta
A2B = transform_from_exponential_coordinates(Stheta)

origin = transform_from(
    active_matrix_from_extrinsic_roll_pitch_yaw([0.5, -0.3, 0.2]),
    np.array([0.0, 0.1, 0.1]))

ax = plot_transform(A2B=origin, s=0.4)
plot_transform(ax=ax, A2B=concat(A2B, origin), s=0.2)
plot_screw(ax=ax,
           q=q,
           s_axis=s_axis,
           h=h,
           theta=theta,
           A2B=origin,
           s=1.5,
           alpha=0.6)
pose1 = pt.random_transform(random_state)
pose2 = pt.random_transform(random_state)
dq1 = pt.dual_quaternion_from_transform(pose1)
dq2 = -pt.dual_quaternion_from_transform(pose2)
Stheta1 = pt.exponential_coordinates_from_transform(pose1)
Stheta2 = pt.exponential_coordinates_from_transform(pose2)

n_steps = 100

# Ground truth screw motion: linear interpolation of rotation about and
# translation along the screw axis
pose12pose2 = pt.concat(pose2, pt.invert_transform(pose1))
screw_axis, theta = pt.screw_axis_from_exponential_coordinates(
    pt.exponential_coordinates_from_transform(pose12pose2))
offsets = np.array([
    pt.transform_from_exponential_coordinates(screw_axis * t * theta)
    for t in np.linspace(0, 1, n_steps)
])
interpolated_poses = np.array([pt.concat(offset, pose1) for offset in offsets])

# Linear interpolation of dual quaternions
interpolated_dqs = (np.linspace(1, 0, n_steps)[:, np.newaxis] * dq1 +
                    np.linspace(0, 1, n_steps)[:, np.newaxis] * dq2)
# renormalization (not required here because it will be done with conversion)
interpolated_dqs /= np.linalg.norm(interpolated_dqs[:, :4], axis=1)[:,
                                                                    np.newaxis]
interpolated_poses_from_dqs = np.array(
    [pt.transform_from_dual_quaternion(dq) for dq in interpolated_dqs])

# Screw linear interpolation of dual quaternions (ScLERP)
sclerp_interpolated_dqs = np.vstack([