UML Diagram
Rough Notes
SecondaryPayload::getDirection()
Python Code
from math import *
class XY:
"""
Useful class for holding pairs of floats
"""
def __init__(self, x: float, y: float):
self.x = x
self.y = y
def __truediv__(self, other):
return XY(self.x / other.x, self.y / other.y)
def __sub__(self, other):
if isinstance(other, XYZ):
return XYZ(self.x - other.x, self.y - other.y, -other.z)
class XYZ:
"""
Useful class for holding triplets of floats
"""
def __init__(self, x: float, y: float, z: float):
self.x = x
self.y = y
self.z = z
def __sub__(self, other):
if isinstance(other, XYZ):
return XYZ(self.x - other.x, self.y - other.y, self.z - other.z)
def __str__(self):
return "({}, {}, {})".format(self.x, self.y, self.z)
class SecondaryPayloadCamera:
screen_resolution: XY = XY(2000.0, 2000.0) # the number of pixels in each direction
screen_size: XY = XY(1000.0, 1000.0) # the size of the screen
relative_position: XYZ = XYZ(500.0, 500.0, 500.0) # the position the laser is pointing at, relative to the camera
relative_orientation: XYZ = XYZ(0, 0, 0) # the orientation of the camera, relative to the satellite
class SecondaryPayload:
# Public interface
def get_direction(self, c1: XY, c2: XY) -> XYZ:
"""
Gets the orientation delta required to move the bright spot from c1 to c2
:param c1: the current coordinates of the bright spot in the camera
:param c2: the target coordinates of the bright spot in the camera
:return:
"""
return self.get_orientation(c2) - self.get_orientation(c1)
# Private helper functions
def calculate_angle(self, opp: float, adj: float) -> float:
"""
Calculates an angle using arctan, given the opposite and adjacent sides of the triangle
:param opp: the length of the side opposite of the angle
:param adj: the length of the side adjacent to the angle
:return: the angle
"""
return atan(opp/adj)
def get_relative_angles(self, c: XY) -> XY:
"""
Returns the relative x and y incident angles of the beam relative to the perpendicular line from the center
:param c: the coordinates of the bright spot
:return: the angle
"""
adj: float = SecondaryPayloadCamera.relative_position.z
factor: XY = SecondaryPayloadCamera.screen_size / SecondaryPayloadCamera.screen_resolution
return XY(
self.calculate_angle(c.x * factor.x, adj),
self.calculate_angle(c.y * factor.y, adj)
)
def get_orientation(self, c: XY) -> XYZ:
"""
Returns the current orientation of the satellite
:param c: the coordinates of the bright spot
:return: the orientation
"""
return self.get_relative_angles(c) - SecondaryPayloadCamera.relative_orientation
o_in_radians = SecondaryPayload().get_direction(XY(-1000, 50), XY(0, 0))
o_in_degrees = XYZ(degrees(o_in_radians.x), degrees(o_in_radians.y), degrees(o_in_radians.z))
print(o_in_degrees)