-
Notifications
You must be signed in to change notification settings - Fork 7
Make the Spherical coordinates useful #302
base: master
Are you sure you want to change the base?
Changes from all commits
fc7bac6
14f1da7
20cc514
84b3d12
7e59e77
7aa295b
6294d47
d58cd69
e196dfa
98dd517
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,17 +1,22 @@ | ||
| from __future__ import annotations | ||
|
|
||
| from zoloto.coords import Coordinates, Orientation, Spherical, ThreeDCoordinates | ||
| from zoloto.coords import ( | ||
| CartesianCoordinates, | ||
| Orientation, | ||
| PixelCoordinates, | ||
| SphericalCoordinates, | ||
| ) | ||
| from zoloto.marker import Marker | ||
| from zoloto.marker_type import MarkerType | ||
|
|
||
| __version__ = "0.9.0" | ||
|
|
||
|
|
||
| __all__ = [ | ||
| "Coordinates", | ||
| "CartesianCoordinates", | ||
| "Orientation", | ||
| "Spherical", | ||
| "ThreeDCoordinates", | ||
| "PixelCoordinates", | ||
| "SphericalCoordinates", | ||
| "Marker", | ||
| "MarkerType", | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,14 +1,20 @@ | ||
| from __future__ import annotations | ||
|
|
||
| import math | ||
| from typing import Iterator, NamedTuple, Tuple | ||
|
|
||
| from cached_property import cached_property | ||
| from cv2 import Rodrigues | ||
| from pyquaternion import Quaternion | ||
|
|
||
|
|
||
| class Coordinates(NamedTuple): | ||
| class PixelCoordinates(NamedTuple): | ||
| """ | ||
| Coordinates within an image made up from pixels. | ||
|
|
||
| This type allows float values to account for computed locations which are | ||
| not limited to exact pixel boundaries. | ||
|
|
||
| :param float x: X coordinate | ||
| :param float y: Y coordinate | ||
| """ | ||
|
|
@@ -17,8 +23,24 @@ class Coordinates(NamedTuple): | |
| y: float | ||
|
|
||
|
|
||
| class ThreeDCoordinates(NamedTuple): | ||
| class CartesianCoordinates(NamedTuple): | ||
| """ | ||
| Cartesian coordinates, rotated on their side. | ||
|
|
||
| The X axis is horizontal relative to the camera's perspective, i.e: left & | ||
| right within the frame of the image. Zero is at the centre of the image. | ||
| Increasing values indicate greater distance to the right. | ||
|
|
||
| The Y axis is vertical relative to the camera's perspective, i.e: up & down | ||
| within the frame of the image. Zero is at the centre of the image. | ||
| Increasing values indicate greater distance below the centre of the image. | ||
|
|
||
| The Z axis extends directly away from the camera. Zero is at the camera. | ||
| Increasing values indicate greater distance from the camera. | ||
|
|
||
| These match traditional cartesian coordinates when the camera is facing | ||
| upwards. | ||
|
|
||
| :param float x: X coordinate | ||
| :param float y: Y coordinate | ||
| :param float z: Z coordinate | ||
|
|
@@ -29,16 +51,54 @@ class ThreeDCoordinates(NamedTuple): | |
| z: float | ||
|
|
||
|
|
||
| class Spherical(NamedTuple): | ||
| class SphericalCoordinates(NamedTuple): | ||
| """ | ||
| :param float rot_x: Rotation around the X-axis, in radians | ||
| :param float rot_y: Rotation around the Y-axis, in radians | ||
| :param float dist: Distance | ||
| SphericalCoordinates coordinates, rotated onto their side. | ||
|
|
||
| This is comparable to the ISO convention for spherical coordinates, applied | ||
| to our rotated axes. Here θ is measured down from the y-axis (rather than | ||
| the usual z-axis) while φ is measured around the y-axis. | ||
|
RealOrangeOne marked this conversation as resolved.
|
||
|
|
||
| See https://en.wikipedia.org/wiki/Spherical_coordinate_system and | ||
| https://studentrobotics.org/docs/programming/sr/vision/#SphericalCoordinates. | ||
|
|
||
| :param float distance: Radial distance from the origin. | ||
| :param float theta: Polar angle, θ, in radians. This is the angle "down" | ||
| from the y-axis to the vector which points to the location. For points | ||
| with zero cartesian x-coordinate value, this can be viewed as the | ||
| rotation about the x-axis. Zero is on the positive y-axis. | ||
| :param float phi: Azimuth angle, φ, in radians. This is the angle from the | ||
| x-axis around the polar (y-axis) to the projection of the point on the | ||
| x-z plane. This can be viewed as rotation about the y-axis. Zero is at | ||
| the centre of the image. | ||
| """ | ||
|
|
||
| rot_x: float | ||
| rot_y: float | ||
| dist: int | ||
| distance: int | ||
|
RealOrangeOne marked this conversation as resolved.
|
||
| theta: float | ||
| phi: float | ||
|
|
||
| @property | ||
| def rot_x(self) -> float: | ||
| """Approximate rotation around the x-axis, an alias for ``self.theta``.""" | ||
| return self.theta | ||
|
|
||
| @property | ||
| def rot_y(self) -> float: | ||
| """Rotation around the y-axis, an alias for ``self.phi``.""" | ||
| return self.phi | ||
|
|
||
| @classmethod | ||
| def from_cartesian(cls, cartesian: CartesianCoordinates) -> SphericalCoordinates: | ||
| if not any(cartesian): | ||
| return SphericalCoordinates(0, 0, 0) | ||
|
|
||
| distance = math.sqrt(sum(x**2 for x in cartesian)) | ||
| x, y, z = cartesian | ||
| return SphericalCoordinates( | ||
| distance=int(distance), | ||
| theta=math.acos(y / distance), | ||
| phi=math.atan2(z, x), | ||
| ) | ||
|
|
||
|
|
||
| ThreeTuple = Tuple[float, float, float] | ||
|
|
@@ -59,17 +119,58 @@ def __init__(self, e_x: float, e_y: float, e_z: float): | |
|
|
||
| @property | ||
| def rot_x(self) -> float: | ||
| """Get rotation angle around x axis in radians.""" | ||
| """ | ||
| Get rotation angle around X axis in radians. | ||
|
|
||
| The X axis is horizontal relative to the camera's perspective, i.e: left | ||
| & right within the frame of the image. | ||
|
|
||
| Increasing values represent an increasing clockwise rotation of the | ||
| marker as seen from the camera's left. | ||
|
|
||
| Zero values for April Tags markers have the marker facing away from the | ||
| camera. The practical effect of this is that an April Tags marker facing | ||
| the camera square-on will have a value of ``pi`` (or equivalently | ||
| ``-pi``) and the value will decrease as the marker diverges from | ||
| square-on. | ||
|
|
||
| For observed markers positive values therefore indicate a rotation of | ||
| the top of the marker away from the camera, such that marker could be | ||
| said to be leaning backwards, with the value decreasing as the marker | ||
| leans back further. | ||
| """ | ||
| return self.roll | ||
|
|
||
| @property | ||
| def rot_y(self) -> float: | ||
| """Get rotation angle around y axis in radians.""" | ||
| """ | ||
| Get rotation angle around Y axis in radians. | ||
|
|
||
| The Y axis is vertical relative to the camera's perspective, i.e: up & | ||
| down within the frame of the image. | ||
|
|
||
| Positive values indicate a rotation of an observed marker towards the | ||
| camera's right. This is a rotation of the marker counter-clockwise about | ||
| the Y axis as seen from above the marker. | ||
|
|
||
| Zero values for April Tags markers have the marker facing the camera | ||
| square-on. | ||
| """ | ||
| return self.pitch | ||
|
|
||
| @property | ||
| def rot_z(self) -> float: | ||
| """Get rotation angle around z axis in radians.""" | ||
| """ | ||
| Get rotation angle around Z axis in radians. | ||
|
|
||
| The Z axis extends directly away from the camera. | ||
|
|
||
| Positive values indicate a rotation counter-clockwise from the | ||
| perspective of the camera. | ||
|
|
||
| Zero values for April Tags markers have the marker reference point at | ||
| the top left. | ||
| """ | ||
| return self.yaw | ||
|
|
||
| @property | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These don't really make sense with the current coordinate system.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you elaborate on what you mean? Both in terms of which version you're referring to as "current" and which of the properties you're referring to here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yaw, pitch and roll do not line up with their standard definition https://en.wikipedia.org/wiki/Aircraft_principal_axes?wprov=sfla1 For instance yaw is a rotation about the vertical axis which is not the case here.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would probably say that the correct fix here is to fix the incorrect convention, as we discussed in the kit team meeting last night.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unfortunately changing the mappings of which axes are which has the potential to be severely breaking to competitors code. |
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.