Skip to content

Commit

Permalink
update all uses of log_rigid3 in python examples
Browse files Browse the repository at this point in the history
  • Loading branch information
Wumpf committed May 12, 2023
1 parent be704a5 commit 5561273
Show file tree
Hide file tree
Showing 11 changed files with 57 additions and 59 deletions.
4 changes: 2 additions & 2 deletions examples/python/api_demo/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,11 @@ def transform_test() -> None:
)
rr.log_affine3(
"transform_test/axis_angle_degrees_only",
parent_from_child=rr.TranslationRotationScale3D(rotation=rr.RotationAxisAngle((0, 1, 0), degrees=10)),
parent_from_child=rr.RotationAxisAngle((0, 1, 0), degrees=10),
)
rr.log_affine3(
"transform_test/axis_angle_radians_only",
parent_from_child=rr.TranslationRotationScale3D(rotation=rr.RotationAxisAngle((0, 0, 1), radians=1)),
parent_from_child=rr.RotationAxisAngle((0, 0, 1), radians=1),
)
rr.log_affine3(
"transform_test/scale_uniform_only",
Expand Down
26 changes: 12 additions & 14 deletions examples/python/arkitscenes/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ def log_line_segments(entity_path: str, bboxes_2d_filtered: npt.NDArray[np.float

def project_3d_bboxes_to_2d_keypoints(
bboxes_3d: npt.NDArray[np.float64],
camera_from_world: Tuple[npt.NDArray[np.float64], npt.NDArray[np.float64]],
camera_from_world: rr.TranslationRotationScale3D,
intrinsic: npt.NDArray[np.float64],
img_width: int,
img_height: int,
Expand All @@ -188,12 +188,12 @@ def project_3d_bboxes_to_2d_keypoints(
are within the image frame.
"""

translation, rotation_q = camera_from_world
rotation = R.from_quat(rotation_q)
translation, rotation_q = camera_from_world.translation, camera_from_world.rotation
rotation = R.from_quat(np.array(rotation_q))

# Transform 3D keypoints from world to camera frame
world_to_camera_rotation = rotation.as_matrix()
world_to_camera_translation = translation.reshape(3, 1)
world_to_camera_translation = np.array(translation).reshape(3, 1)
# Tile translation to match bounding box shape, (nObjects, 1, 3)
world_to_camera_translation_tiled = np.tile(world_to_camera_translation.T, (bboxes_3d.shape[0], 1, 1))
# Transform 3D bounding box keypoints from world to camera frame to filter out points behind the camera
Expand Down Expand Up @@ -229,7 +229,7 @@ def project_3d_bboxes_to_2d_keypoints(
def log_camera(
intri_path: Path,
frame_id: str,
poses_from_traj: Dict[str, Tuple[npt.NDArray[np.float64], npt.NDArray[np.float64]]],
poses_from_traj: Dict[str, rr.TranslationRotationScale3D],
entity_id: str,
bboxes: npt.NDArray[np.float64],
bbox_labels: List[str],
Expand All @@ -249,16 +249,14 @@ def log_camera(
for i, (label, bbox_2d) in enumerate(zip(bbox_labels, bboxes_2d)):
log_line_segments(f"{entity_id}/bbox-2d-segments/{label}", bbox_2d.reshape(-1, 2), colors[i], label)

rr.log_rigid3(
# pathlib makes it easy to get the parent, but log_rigid requires a string
str(PosixPath(entity_id).parent),
child_from_parent=camera_from_world,
xyz="RDF", # X=Right, Y=Down, Z=Forward
)
# pathlib makes it easy to get the parent, but log methods requires a string
camera_path = str(PosixPath(entity_id).parent)
rr.log_affine3(camera_path, child_from_parent=camera_from_world)
rr.log_view_coordinates(camera_path, xyz="RDF") # X=Right, Y=Down, Z=Forward
rr.log_pinhole(f"{entity_id}", child_from_parent=intrinsic, width=w, height=h)


def read_camera_from_world(traj_string: str) -> Tuple[str, Tuple[npt.NDArray[np.float64], npt.NDArray[np.float64]]]:
def read_camera_from_world(traj_string: str) -> Tuple[str, rr.TranslationRotationScale3D]:
"""
Reads out camera_from_world transform from trajectory string.
Expand Down Expand Up @@ -291,8 +289,8 @@ def read_camera_from_world(traj_string: str) -> Tuple[str, Tuple[npt.NDArray[np.
# Extract translation from the fifth to seventh tokens
translation = np.asarray([float(tokens[4]), float(tokens[5]), float(tokens[6])])

# Create tuple in format log_rigid3 expects
camera_from_world = (translation, rotation.as_quat())
# Create tuple in format log_affine3 expects
camera_from_world = rr.TranslationRotationScale3D(translation, rotation.as_quat())

return (ts, camera_from_world)

Expand Down
6 changes: 3 additions & 3 deletions examples/python/car/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ def log_car_data() -> None:
rr.set_time_sequence("frame_nr", sample.frame_idx)

# Log the camera pose:
rr.log_rigid3(
rr.log_affine3(
"world/camera",
parent_from_child=(sample.camera.position, sample.camera.rotation_q),
xyz="RDF", # X=Right, Y=Down, Z=Forward
parent_from_child=rr.TranslationRotationScale3D(sample.camera.position, sample.camera.rotation_q),
)
rr.log_view_coordinates("world/camera", xyz="RDF") # X=Right, Y=Down, Z=Forward

# Log the camera projection matrix:
rr.log_pinhole(
Expand Down
8 changes: 4 additions & 4 deletions examples/python/colmap/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@ def read_and_log_sparse_reconstruction(
frame_idx = int(idx_match.group(0))

quat_xyzw = image.qvec[[1, 2, 3, 0]] # COLMAP uses wxyz quaternions
camera_from_world = (image.tvec, quat_xyzw) # COLMAP's camera transform is "camera from world"
camera = cameras[image.camera_id]
if resize:
camera, scale_factor = scale_camera(camera, resize)
Expand Down Expand Up @@ -144,11 +143,12 @@ def read_and_log_sparse_reconstruction(

rr.log_points("points", points, colors=point_colors, ext={"error": point_errors})

rr.log_rigid3(
# COLMAP's camera transform is "camera from world"
rr.log_affine3(
"camera",
child_from_parent=camera_from_world,
xyz="RDF", # X=Right, Y=Down, Z=Forward
child_from_parent=rr.TranslationRotationScale3D(image.tvec, quat_xyzw),
)
rr.log_view_coordinates("camera", xyz="RDF") # X=Right, Y=Down, Z=Forward

# Log camera intrinsics
rr.log_pinhole(
Expand Down
8 changes: 2 additions & 6 deletions examples/python/dna/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import rerun as rr
from rerun_demo.data import build_color_spiral
from rerun_demo.util import bounce_lerp, interleave
from scipy.spatial.transform import Rotation

_, unknown = __import__("argparse").ArgumentParser().parse_known_args()
[__import__("logging").warning(f"unknown arg: {arg}") for arg in unknown]
Expand Down Expand Up @@ -43,10 +42,7 @@
colors = [[int(bounce_lerp(80, 230, times[n] * 2))] for n in range(NUM_POINTS)]
rr.log_points("dna/structure/scaffolding/beads", beads, radii=0.06, colors=np.repeat(colors, 3, axis=-1))

rr.log_rigid3(
rr.log_affine3(
"dna/structure",
parent_from_child=(
[0, 0, 0],
Rotation.from_euler("z", time / 4.0 * tau).as_quat(),
),
parent_from_child=rr.RotationAxisAngle(axis=[0, 0, 1], radians=time / 4.0 * tau),
)
8 changes: 1 addition & 7 deletions examples/python/nyud/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,7 @@ def log_nyud_data(recording_path: Path, subset_idx: int = 0) -> None:
img_depth = read_image(buf)

# Log the camera transforms:
translation = [0, 0, 0]
rotation_q = [0, 0, 0, 1]
rr.log_rigid3(
"world/camera",
parent_from_child=(translation, rotation_q),
xyz="RDF", # X=Right, Y=Down, Z=Forward
)
rr.log_view_coordinates("world/camera", xyz="RDF") # X=Right, Y=Down, Z=Forward
rr.log_pinhole(
"world/camera/image",
child_from_parent=camera_intrinsics(img_depth),
Expand Down
6 changes: 4 additions & 2 deletions examples/python/objectron/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,11 @@ def log_camera(cam: ARCamera) -> None:

rot = rot * R.from_rotvec((math.tau / 2.0) * X) # TODO(emilk): figure out why this is needed

rr.log_rigid3(
"world/camera", parent_from_child=(translation, rot.as_quat()), xyz="RDF" # X=Right, Y=Down, Z=Forward
rr.log_affine3(
"world/camera",
parent_from_child=rr.TranslationRotationScale3D(translation, rot.as_quat()),
)
rr.log_view_coordinates("world/camera", xyz="RDF") # X=Right, Y=Down, Z=Forward
rr.log_pinhole(
"world/camera/video",
child_from_parent=intrinsics,
Expand Down
16 changes: 8 additions & 8 deletions examples/python/ros/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,9 @@ def __init__(self) -> None:
callback_group=self.callback_group,
)

def log_tf_as_rigid3(self, path: str, time: Time) -> None:
def log_tf_as_affine3(self, path: str, time: Time) -> None:
"""
Helper to look up a transform with tf and log using `log_rigid3`.
Helper to look up a transform with tf and log using `log_affine3`.
Note: we do the lookup on the client side instead of re-logging the raw transforms until
Rerun has support for Derived Transforms [#1533](https://github.com/rerun-io/rerun/issues/1533)
Expand All @@ -158,7 +158,7 @@ def log_tf_as_rigid3(self, path: str, time: Time) -> None:
tf = self.tf_buffer.lookup_transform(parent_frame, child_frame, time, timeout=Duration(seconds=0.1))
t = tf.transform.translation
q = tf.transform.rotation
rr.log_rigid3(path, parent_from_child=([t.x, t.y, t.z], [q.x, q.y, q.z, q.w]))
rr.log_affine3(path, parent_from_child=rr.TranslationRotationScale3D([t.x, t.y, t.z], [q.x, q.y, q.z, q.w]))
except TransformException as ex:
print("Failed to get transform: {}".format(ex))

Expand Down Expand Up @@ -186,15 +186,15 @@ def odom_callback(self, odom: Odometry) -> None:
rr.log_scalar("odometry/ang_vel", odom.twist.twist.angular.z)

# Update the robot pose itself via TF
self.log_tf_as_rigid3("map/robot", time)
self.log_tf_as_affine3("map/robot", time)

def image_callback(self, img: Image) -> None:
"""Log an `Image` with `log_image` using `cv_bridge`."""
time = Time.from_msg(img.header.stamp)
rr.set_time_nanos("ros_time", time.nanoseconds)

rr.log_image("map/robot/camera/img", self.cv_bridge.imgmsg_to_cv2(img))
self.log_tf_as_rigid3("map/robot/camera", time)
self.log_tf_as_affine3("map/robot/camera", time)

def points_callback(self, points: PointCloud2) -> None:
"""Log a `PointCloud2` with `log_points`."""
Expand All @@ -220,15 +220,15 @@ def points_callback(self, points: PointCloud2) -> None:
# Log points once rigidly under robot/camera/points. This is a robot-centric
# view of the world.
rr.log_points("map/robot/camera/points", positions=pts, colors=colors)
self.log_tf_as_rigid3("map/robot/camera/points", time)
self.log_tf_as_affine3("map/robot/camera/points", time)

# Log points a second time after transforming to the map frame. This is a map-centric
# view of the world.
#
# Once Rerun supports fixed-frame aware transforms [#1522](https://github.com/rerun-io/rerun/issues/1522)
# this will no longer be necessary.
rr.log_points("map/points", positions=pts, colors=colors)
self.log_tf_as_rigid3("map/points", time)
self.log_tf_as_affine3("map/points", time)

def scan_callback(self, scan: LaserScan) -> None:
"""
Expand All @@ -251,7 +251,7 @@ def scan_callback(self, scan: LaserScan) -> None:
segs = np.hstack([origin, pts]).reshape(pts.shape[0] * 2, 3)

rr.log_line_segments("map/robot/scan", segs, stroke_width=0.005)
self.log_tf_as_rigid3("map/robot/scan", time)
self.log_tf_as_affine3("map/robot/scan", time)

def urdf_callback(self, urdf_msg: String) -> None:
"""Log a URDF using `log_scene` from `rerun_urdf`."""
Expand Down
13 changes: 7 additions & 6 deletions examples/python/ros/rerun_urdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,13 @@ def log_scene(scene: trimesh.Scene, node: str, path: Optional[str] = None, timel
# Log the transform between this node and its direct parent (if it has one!).
if parent:
world_from_mesh = node_data[0]
t = trimesh.transformations.translation_from_matrix(world_from_mesh)
q = trimesh.transformations.quaternion_from_matrix(world_from_mesh)
# `trimesh` stores quaternions in `wxyz` format, rerun needs `xyzw`
# TODO(jleibs): Remove conversion once [#883](https://github.com/rerun-io/rerun/issues/883) is closed
q = np.array([q[1], q[2], q[3], q[0]])
rr.log_rigid3(path, parent_from_child=(t, q), timeless=timeless)
rr.log_affine3(
path,
parent_from_child=trimesh.transformations.translation_from_matrix(
world_from_mesh, world_from_mesh[0:3, 0:3]
),
timeless=timeless,
)

# Log this node's mesh, if it has one.
mesh = cast(trimesh.Trimesh, scene.geometry.get(node_data[1]))
Expand Down
2 changes: 1 addition & 1 deletion rerun_py/docs/gen_common_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ class Section:
Section(
title="Transforms",
module_summary="log.transform",
func_list=["log_rigid3", "log_pinhole", "log_unknown_transform", "log_view_coordinates"],
func_list=["log_rigid3", "log_affine3", "log_pinhole", "log_unknown_transform", "log_view_coordinates"],
),
Section(
title="Text",
Expand Down
19 changes: 13 additions & 6 deletions rerun_py/rerun_sdk/rerun/log/transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from rerun import bindings
from rerun.components.transform3d import (
DirectedAffine3D,
RotationAxisAngle,
Transform3DArray,
TransformDirection,
TranslationMatrix3x3,
Expand All @@ -24,6 +25,7 @@
"log_view_coordinates",
"log_unknown_transform",
"log_rigid3",
"log_affine3",
]


Expand Down Expand Up @@ -114,8 +116,8 @@ def log_unknown_transform(entity_path: str, timeless: bool = False) -> None:
def log_affine3(
entity_path: str,
*,
parent_from_child: Optional[TranslationMatrix3x3 | TranslationRotationScale3D] = None,
child_from_parent: Optional[TranslationMatrix3x3 | TranslationRotationScale3D] = None,
parent_from_child: Optional[TranslationMatrix3x3 | TranslationRotationScale3D | RotationAxisAngle] = None,
child_from_parent: Optional[TranslationMatrix3x3 | TranslationRotationScale3D | RotationAxisAngle] = None,
timeless: bool = False,
) -> None:
"""
Expand All @@ -128,13 +130,15 @@ def log_affine3(
Example
-------
```
# log scale followed by translation along the Y-axis
rr.log_affine3(
"world/z_rotated_object",
parent_from_child=rr.TranslationRotationScale3D(rotation=rr.RotationAxisAngle((0, 0, 1), degree=20)),
"world/scaled_object",
parent_from_child=rr.TranslationRotationScale3D([0.0, 1.0, 0.0] scale=2),
)
# log a rotation around the z axis.
rr.log_affine3(
"world/scaled_object",
parent_from_child=rr.TranslationRotationScale3D(scale=2),
"world/z_rotated_object",
parent_from_child=rr.RotationAxisAngle((0, 0, 1), degree=20),
)
```
Expand All @@ -161,6 +165,9 @@ def log_affine3(
direction = TransformDirection.ChildFromParent
transform = child_from_parent

if isinstance(transform, RotationAxisAngle):
transform = TranslationRotationScale3D(rotation=transform)

instanced = {"rerun.transform3d": Transform3DArray.from_transform(DirectedAffine3D(transform, direction))}
bindings.log_arrow_msg(entity_path, components=instanced, timeless=timeless)

Expand Down

0 comments on commit 5561273

Please sign in to comment.