def test_inverse_inverse(): link = tf.Translation((1, 0), amount=0.5) inv_link = tf.InvertLink(link) inverse_inverse = tf.InvertLink(inv_link) point = (3, 5) result = inverse_inverse.transform(point) expected = link.transform(point) assert np.allclose(result, expected)
def test_keep_joints(): points = np.arange(200 * 3).reshape(200, 3) joint1 = tf.RotationalJoint((0, 1, 0)) joint2 = tf.PrismaticJoint((1, 0, 0)) links: List[tf.Link] = [ tf.Rotation((1, 0, 0), (0, 1, 0)), tf.Translation((1, 0, 0)), joint1, tf.Translation((1, 1, 0)), tf.Translation((1, 1, 1)), tf.InvertLink(joint2), ] simplified_links = tf.simplify_links(links, keep_joints=True) expected = points for link in links: expected = link.transform(expected) result = points for link in simplified_links: result = link.transform(result) assert np.allclose(result, expected) assert joint1 in simplified_links assert joint2 is simplified_links[-1]._forward_link
def test_inverse_links(): points = np.arange(200 * 3).reshape(200, 3) # --- test double_inverse --- link = tf.InvertLink(tf.InvertLink(tf.Translation((1, 0, 0)))) simplified = tf.simplify_links([link])[0] assert isinstance(simplified, tf.Translation) expected = link.transform(points) result = simplified.transform(points) assert np.allclose(result, expected) # --- test translation unwrapping --- link = tf.InvertLink(tf.Translation((1, 0, 0))) simplified = tf.simplify_links([link])[0] assert isinstance(simplified, tf.Translation) expected = link.transform(points) result = simplified.transform(points) assert np.allclose(result, expected) # --- test rotation unwrapping --- link = tf.InvertLink(tf.EulerRotation("X", np.pi / 2)) simplified = tf.simplify_links([link])[0] assert isinstance(simplified, tf.Rotation) expected = link.transform(points) result = simplified.transform(points) assert np.allclose(result, expected) # --- test compound unpacking --- link = tf.InvertLink( tf.CompundLink([tf.Translation((1, 0, 0)), tf.Translation((0, 1, 0))])) simplified_links = tf.simplify_links([link]) expected = link.transform(points) result = points for link in simplified_links: result = link.transform(result) assert np.allclose(result, expected) for link in simplified_links: assert isinstance(link, tf.Translation)
def test_keep_link(): points = np.arange(200 * 3).reshape(200, 3) keep_link = tf.Translation((0, 1, 0)) link = tf.CompundLink([ tf.Translation((1, 0, 0)), tf.CompundLink([keep_link]), tf.EulerRotation("Y", -90, degrees=True), ]) simplified_links = tf.simplify_links([link], keep_links=[keep_link]) assert keep_link in simplified_links expected = link.transform(points) result = points for link in simplified_links: result = link.transform(result) assert np.allclose(result, expected) keep_link = tf.Translation((0, 1, 0)) original_link = tf.CompundLink([ tf.Translation((1, 0, 0)), tf.CompundLink([tf.InvertLink(keep_link)]), tf.EulerRotation("Y", -90, degrees=True), ]) simplified_links = tf.simplify_links([original_link], keep_links=[keep_link]) for link in simplified_links: if isinstance(link, tf.InvertLink): if link._forward_link is keep_link: break else: raise AssertionError("`keep_link` no longer in link chain.") expected = original_link.transform(points) result = points for link in simplified_links: result = link.transform(result) assert np.allclose(result, expected) keep_link = tf.Translation((0, 1, 0)) original_link = tf.CompundLink([ tf.Translation((1, 0, 0)), tf.Translation((1, 1, 0)), keep_link, tf.EulerRotation("Y", -90, degrees=True), ]) simplified_links = tf.simplify_links([original_link], keep_links=[keep_link]) assert keep_link in simplified_links expected = original_link.transform(points) result = points for link in simplified_links: result = link.transform(result) assert np.allclose(result, expected)
def test_inverted_custom_link(): class Custom(tf.Link): def transform(self, x: ArrayLike) -> np.ndarray: return x def __inverse_transform__(self, x: ArrayLike) -> np.ndarray: return x points = np.arange(200 * 3).reshape(200, 3) link = tf.InvertLink(Custom(3, 3)) simplified_links = tf.simplify_links([link]) expected = link.transform(points) result = points for link in simplified_links: result = link.transform(result) assert np.allclose(result, expected)
def test_joints_between(): joint1 = tf.RotationalJoint((0, 1, 0)) joint2 = tf.PrismaticJoint((1, 0, 0)) start = tf.Frame(3) x = tf.Rotation((1, 0, 0), (0, 1, 0))(start) x = tf.Translation((1, 0, 0))(x) x = joint1(x) x = tf.CompundLink( [joint2, tf.EulerRotation("xy", (90, -90), degrees=True), joint1])(x) x = tf.Translation((1, 1, 0))(x) x = tf.Translation((1, 1, 1))(x) end = tf.InvertLink(joint2)(x) joints = start.joints_between(end) assert joints == [joint1, joint2, joint1, joint2]
# # tf.AxialHexagonTransform() # tf.AxialHexagonTransform(size=4) # a hex grid with larger hexagons # tf.AxialHexagonTransform(flat_top=False) # a hex grid that is rotated by 90 degrees # # When you use this transformation, the result will be a continous value, which # is useful because it keeps all information and can be inverted to go back to # cartesian coordinates. However, often you want to know which hexagon a # coordinate falls into, which is where :class:`tf.HexagonAxisRound # <skbot.transform.HexagonAxisRound>` comes in. As the name suggests, it will # round a vector in hexagon coordinates to the closest hexagon. # # We can use this, for example, to perform rejection sampling on the hexagon grid: to_hex = tf.AxialHexagonTransform() from_hex = tf.InvertLink(to_hex) # a 3x3 hex grid (because we can use a nice colormap in this case) grid = np.stack(np.meshgrid(np.arange(3), np.arange(3)), axis=-1) hex_centers = from_hex.transform(grid) sampling_rectangle = [-1, -1, 7, 5] x, y, w, h = [-1, -1, 7, 5] candidate_points = np.random.rand(150, 2) * (h, w) + (y, x) hex_points = to_hex.transform(candidate_points) hex_points_rounded = tf.HexagonAxisRound().transform(hex_points) is_in_hexagon = np.all(np.isin(hex_points_rounded, [0, 1, 2]), axis=1) points = candidate_points[is_in_hexagon, :] # points are rejected here # %% # We can also use :class:`tf.HexagonAxisRound
def test_inverse_attributes(): link = tf.Translation((1, 0), amount=0.5) inv_link = tf.InvertLink(link) hasattr(inv_link, "amount") assert inv_link.amount == 0.5