From 3a3ca84d61e091b03e734b9df1cdcf8bc079b021 Mon Sep 17 00:00:00 2001 From: mmeijerdfki Date: Sat, 28 Dec 2024 14:21:59 +0100 Subject: [PATCH] add test with more complex encapsulation check --- .../python/gRPC/images/gRPC_fb_sendImages.py | 1 + pyproject.toml | 11 +- .../images/test_gRPC_fb_queryImagePrecise.py | 180 ++++++++++++++++++ 3 files changed, 188 insertions(+), 4 deletions(-) mode change 100644 => 100755 examples/python/gRPC/images/gRPC_fb_sendImages.py create mode 100644 tests/python/gRPC/images/test_gRPC_fb_queryImagePrecise.py diff --git a/examples/python/gRPC/images/gRPC_fb_sendImages.py b/examples/python/gRPC/images/gRPC_fb_sendImages.py old mode 100644 new mode 100755 index df3a3d3a5..6ae956169 --- a/examples/python/gRPC/images/gRPC_fb_sendImages.py +++ b/examples/python/gRPC/images/gRPC_fb_sendImages.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import random import time import uuid diff --git a/pyproject.toml b/pyproject.toml index a21ef2b87..989756554 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,14 +19,17 @@ dependencies = [ ] dynamic = ["version"] -[tool.setuptools_scm] -version_scheme = "no-guess-dev" -local_scheme = "no-local-version" - [project.urls] Repository = "https://github.com/agri-gaia/seerep" Documentation = "https://agri-gaia.github.io/seerep/mkdocs/home/index.html" +[tool.basedpyright] +typeCheckingMode="standard" + +[tool.setuptools_scm] +version_scheme = "no-guess-dev" +local_scheme = "no-local-version" + [tool.pytest.ini_options] minversion = "6.0" addopts = "-ra -q" diff --git a/tests/python/gRPC/images/test_gRPC_fb_queryImagePrecise.py b/tests/python/gRPC/images/test_gRPC_fb_queryImagePrecise.py new file mode 100644 index 000000000..9bfc3af61 --- /dev/null +++ b/tests/python/gRPC/images/test_gRPC_fb_queryImagePrecise.py @@ -0,0 +1,180 @@ +# test file for +# gRPC_fb_sendImages.py +# gRPC_fb_queryImages.py + +from typing import Tuple +from uuid import uuid4 + +import flatbuffers +from grpc import Channel +from gRPC.images import gRPC_fb_queryImages, gRPC_fb_sendImages +from quaternion import quaternion as create_quat +from seerep.fb import ( + camera_intrinsics_service_grpc_fb as camera_intrinsic_service, +) +from seerep.fb import tf_service_grpc_fb as tf_service +from seerep.util.fb_helper import ( + createCameraIntrinsics, + createHeader, + createPoint2d, + createPolygon2D, + createQuaternion, + createRegionOfInterest, + createTimeStamp, + createTransform, + createTransformStamped, + createVector3, +) +from seerep.util.fb_to_dict import SchemaFileNames, fb_flatc_dict + + +def send_simple_camintrinsics( + grpc_channel: Channel, project_uuid: str, frame_id: str = "camera" +) -> str: + """ + Create a simple Camera intrinsics with the Frustum in the form of + a square pyramid with a side length and a height of 1. + + Returns: + str: The uuid of the created camera intrinsics. + """ + fbb = flatbuffers.Builder() + camera_intrinsic_service_stub = ( + camera_intrinsic_service.CameraIntrinsicsServiceStub(grpc_channel) + ) + timestamp = createTimeStamp(fbb, 0, 0) + ci_uuid = str(uuid4()) + header = createHeader(fbb, timestamp, frame_id, project_uuid, ci_uuid) + roi = createRegionOfInterest(fbb, 0, 0, 0, 0, False) + + distortion_matrix: list[float] = [4, 5, 6, 7, 8, 9, 10, 11, 12] + rect_matrix: list[float] = [4, 5, 6, 7, 8, 9, 10, 11, 12] + # important for frustum calculations are the indices 0 and 4 + # the frustum calculation can be found in + # seerep_hdf5/seerep_hdf5_core/src/hdf5_core_image.cpp + intrins_matrix: list[float] = [1, 5, 6, 7, 1, 9, 10, 11, 12] + proj_matrix: list[float] = [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] + + ci_height = 1 + ci_width = 1 + + max_view_dist = 1 + + cameraintrinsics = createCameraIntrinsics( + fbb, + header, + ci_height, + ci_width, + "plumb_bob", + distortion_matrix, + intrins_matrix, + rect_matrix, + proj_matrix, + 4, + 5, + roi, + max_view_dist, + ) + fbb.Finish(cameraintrinsics) + camera_intrinsic_service_stub.TransferCameraIntrinsics(bytes(fbb.Output())) + return ci_uuid + + +def send_tf( + grpc_channel: Channel, + project_uuid: str, + timestamp: Tuple[int, int], + translation: Tuple[float, float, float], + quaternion: Tuple[float, float, float, float], + frame_id: str = "map", + child_frame_id="camera", +) -> bytes: + """ + send a frame_id -> child_frame_id transform. + + Args: + grpc_channel (Channel): The grpc_channel to a SEEREP server. + project_uuid (str): The project target for the transformations. + timestamp (Tuple[int, int]): The timestamp for the sent tf. + translation (Tuple[float, float, float]): the translation vector + in the form (x, y, z) + quaternion (int): the quaternion representing the orientation + of the tf in (w, x, y, z) + frame_id (str): The parent frame for the transformations. + child_frame_id (str): The child frame for the transformations. + + Return: + the serialized tf object + """ + builder = flatbuffers.Builder(1024) + + secs, nanos = timestamp + ts = createTimeStamp(builder, secs, nanos) + + header = createHeader(builder, ts, frame_id, project_uuid, str(uuid4())) + + # make sure the frustum is above the query cube + trans = createVector3(builder, translation) + + # this is equivalent to a Euler XYZ rotation with: + # X = 225° + # Y = 0° + # Z = -45° + quat = createQuaternion(builder, create_quat(*quaternion)) + + tf = createTransform(builder, trans, quat) + tfs = createTransformStamped(builder, child_frame_id, header, tf) + + builder.Finish(tfs) + serialized_tf = bytes(builder.Output()) + tf_service.TfServiceStub(grpc_channel).TransferTransformStamped( + iter([serialized_tf]) + ) + return serialized_tf + + +def test_gRPC_fb_queryImagePrecise(grpc_channel, project_setup): + _, proj_uuid = project_setup + + timestamp_secs = 1661336507 + timestamp_nanos = 1245 + + ts = (timestamp_secs, timestamp_nanos) + + camera_intrinsics_uuid = send_simple_camintrinsics(grpc_channel, proj_uuid) + + sent_images = gRPC_fb_sendImages.send_images( + grpc_channel, + proj_uuid, + camera_intrinsics_uuid, + gRPC_fb_sendImages.generate_image_ressources(8), + 8 * [ts], + ) + + trans = (-0.5, -0.5, 1.5) + rot = (-0.354, 0.854, -0.354, 0.146) + send_tf(grpc_channel, proj_uuid, ts, trans, rot) + + builder = flatbuffers.Builder(1024) + + verts = [ + createPoint2d(builder, *p) for p in [(0, 0), (1, 0), (1, 1), (0, 1)] + ] + + polygon = createPolygon2D(builder, height=1, z=0, vertices=verts) + + queried_images = gRPC_fb_queryImages.query_images_raw( + builder, grpc_channel, proj_uuid, polygon2d=polygon + ) + + sent_images = [ + fb_flatc_dict(img, SchemaFileNames.IMAGE) for img in sent_images + ] + + queried_images = [ + fb_flatc_dict(img, SchemaFileNames.IMAGE) for img in queried_images + ] + + assert sorted( + sent_images, key=lambda img: img["header"]["uuid_msgs"] + ) == sorted(queried_images, key=lambda img: img["header"]["uuid_msgs"])