Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add type hint to classes and functions #432

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open
13 changes: 13 additions & 0 deletions src/compas_fab/backends/interfaces/backend_features.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@
from __future__ import division
from __future__ import print_function

import compas

if not compas.IPY:
from typing import TYPE_CHECKING

if TYPE_CHECKING:
from typing import Optional # noqa: F401
from typing import Dict # noqa: F401
from compas_fab.robots import Robot # noqa: F401
from compas_robots import Configuration # noqa: F401
from compas.geometry import Frame # noqa: F401


class ForwardKinematics(object):
"""Interface for a Planner's forward kinematics feature. Any implementation of
Expand All @@ -16,6 +28,7 @@ def __call__(self, robot, configuration, group=None, options=None):
return self.forward_kinematics(robot, configuration, group, options)

def forward_kinematics(self, robot, configuration, group=None, options=None):
# type: (Robot, Configuration, Optional[str], Optional[Dict]) -> Frame
"""Calculate the robot's forward kinematic.

Parameters
Expand Down
79 changes: 65 additions & 14 deletions src/compas_fab/robots/constraints.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,28 @@
from __future__ import division
from __future__ import print_function

import compas

from compas.data import Data
from compas.geometry import Rotation
from compas.geometry import Scale
from compas.geometry import Sphere

from compas_fab.utilities import from_tcf_to_t0cf

if not compas.IPY:
from typing import TYPE_CHECKING

if TYPE_CHECKING:
from typing import Optional # noqa: F401
from typing import Union # noqa: F401
from compas.datastructures import Mesh # noqa: F401
from compas.geometry import Box # noqa: F401
from compas.geometry import Frame # noqa: F401
from compas.geometry import Point # noqa: F401
from compas.geometry import Transformation # noqa: F401
from compas_robots import Configuration # noqa: F401

__all__ = ["BoundingVolume", "Constraint", "JointConstraint", "OrientationConstraint", "PositionConstraint"]


Expand Down Expand Up @@ -56,6 +71,7 @@ class BoundingVolume(Data):
VOLUME_TYPES = (BOX, SPHERE, MESH)

def __init__(self, volume_type, volume):
# type: (int, Union[Box, Sphere, Mesh]) -> None
if volume_type not in self.VOLUME_TYPES:
raise ValueError("Type must be one of {}".format(self.VOLUME_TYPES))
self.type = volume_type
Expand All @@ -69,6 +85,7 @@ def __data__(self):

@classmethod
def from_box(cls, box):
# type: (Box) -> BoundingVolume
"""Create a :class:`BoundingVolume` from a :class:`compas.geometry.Box`.

Parameters
Expand All @@ -94,6 +111,7 @@ def from_box(cls, box):

@classmethod
def from_sphere(cls, sphere):
# type: (Sphere) -> BoundingVolume
"""Create a :class:`BoundingVolume` from a :class:`compas.geometry.Sphere`.

Parameters
Expand All @@ -118,6 +136,7 @@ def from_sphere(cls, sphere):

@classmethod
def from_mesh(cls, mesh):
# type: (Mesh) -> BoundingVolume
"""Create a :class:`BoundingVolume` from a :class:`compas.datastructures.Mesh`.

Parameters
Expand All @@ -142,6 +161,7 @@ def from_mesh(cls, mesh):
return cls(cls.MESH, mesh)

def scale(self, scale_factor):
# type: (float) -> None
"""Scale the volume uniformly.

Parameters
Expand All @@ -153,6 +173,7 @@ def scale(self, scale_factor):
self.transform(S)

def transform(self, transformation):
# type: (Transformation) -> None
"""Transform the volume using a :class:`compas.geometry.Transformation`.

Parameters
Expand All @@ -167,6 +188,7 @@ def __repr__(self):
return "BoundingVolume({!r}, {!r})".format(self.type, self.volume)

def copy(self):
# type: () -> BoundingVolume
"""Make a copy of this :class:`BoundingVolume`.

Returns
Expand Down Expand Up @@ -221,6 +243,7 @@ class Constraint(Data):
CONSTRAINT_TYPES = (JOINT, POSITION, ORIENTATION)

def __init__(self, constraint_type, weight=1.0):
# type: (int, Optional[float]) -> None
if constraint_type not in self.CONSTRAINT_TYPES:
raise ValueError("Type must be %d, %d or %d" % self.CONSTRAINT_TYPES)
self.type = constraint_type
Expand All @@ -233,14 +256,17 @@ def __data__(self):
}

def transform(self, transformation):
# type: (Transformation) -> None
"""Transform the :class:`Constraint`."""
pass

def scale(self, scale_factor):
# type: (float) -> None
"""Scale the :class:`Constraint`."""
pass

def scaled(self, scale_factor):
# type: (float) -> Constraint
"""Get a scaled copy of this :class:`Constraint`.

Parameters
Expand All @@ -253,6 +279,7 @@ def scaled(self, scale_factor):
return c

def copy(self):
# type: () -> Constraint
"""Create a copy of this :class:`Constraint`.

Returns
Expand All @@ -269,7 +296,7 @@ class JointConstraint(Constraint):
Parameters
----------
joint_name : :obj:`str`
The name of the joint this contraint refers to.
The name of the joint this constraint refers to.
value : :obj:`float`
The targeted value for that joint.
tolerance_above : :obj:`float`
Expand All @@ -284,7 +311,7 @@ class JointConstraint(Constraint):
Attributes
----------
joint_name : :obj:`str`
The name of the joint this contraint refers to.
The name of the joint this constraint refers to.
value : :obj:`float`
The targeted value for that joint.
tolerance_above : :obj:`float`
Expand All @@ -302,6 +329,7 @@ class JointConstraint(Constraint):
"""

def __init__(self, joint_name, value, tolerance_above=0.0, tolerance_below=0.0, weight=1.0):
# type: (str, float, Optional[float], Optional[float], Optional[float]) -> None
super(JointConstraint, self).__init__(self.JOINT, weight)
self.joint_name = joint_name
self.value = value
Expand All @@ -318,6 +346,7 @@ def __data__(self):
}

def scale(self, scale_factor):
# type: (float) -> None
"""Scale (multiply) the constraint with a factor.

Parameters
Expand All @@ -336,6 +365,7 @@ def __repr__(self):
)

def copy(self):
# type: () -> JointConstraint
"""Create a copy of this :class:`JointConstraint`.

Returns
Expand All @@ -347,6 +377,7 @@ def copy(self):

@classmethod
def joint_constraints_from_configuration(cls, configuration, tolerances_above, tolerances_below):
# type: (Configuration, list, list) -> list[JointConstraint]
"""Create joint constraints for all joints of the configuration.
One constraint is created for each joint.

Expand Down Expand Up @@ -425,7 +456,7 @@ class OrientationConstraint(Constraint):
Parameters
----------
link_name : :obj:`str`
The name of the link this contraint refers to.
The name of the link this constraint refers to.
quaternion : :obj:`list` of :obj:`float`
The desired orientation of the link specified by a quaternion in the
order of ``[w, x, y, z]``.
Expand All @@ -442,17 +473,19 @@ class OrientationConstraint(Constraint):
Attributes
----------
link_name : :obj:`str`
The name of the link this contraint refers to.
The name of the link this constraint refers to.
quaternion : :obj:`list` of :obj:`float`
The desired orientation of the link specified by a quaternion in the
order of ``[w, x, y, z]``.
tolerances : :obj:`list` of :obj:`float`
tolerances : :obj:`list` of :obj:`float`, optional
Error tolerances :math:`t_{i}` for each of the frame's axes. If only one
value is passed it will be used for all 3 axes. The respective bound to
be achieved is :math:`(a_{i} - t_{i}, a_{i} + t_{i})`.
weight : :obj:`float`
Defaults to ``[0.01, 0.01, 0.01]``.
weight : :obj:`float`, optional
A weighting factor for this constraint. Denotes relative importance to
other constraints. Closer to zero means less important.
Defaults to ``1.0``.

Notes
-----
Expand All @@ -472,10 +505,16 @@ class OrientationConstraint(Constraint):
"""

def __init__(self, link_name, quaternion, tolerances=None, weight=1.0):
# type: (str, list[float], Optional[list[float]], Optional[float]) -> None
super(OrientationConstraint, self).__init__(self.ORIENTATION, weight)
self.link_name = link_name
self.quaternion = [float(a) for a in list(quaternion)]
self.tolerances = [float(a) for a in list(tolerances)] if tolerances else [0.01] * 3
if isinstance(tolerances, list):
self.tolerances = [float(a) for a in list(tolerances)]
elif isinstance(tolerances, float):
self.tolerances = [tolerances] * 3
else:
self.tolerances = [0.01, 0.01, 0.01]

def __data__(self):
return {
Expand All @@ -486,6 +525,7 @@ def __data__(self):
}

def transform(self, transformation):
# type: (Transformation) -> None
"""Transform the volume using a :class:`compas.geometry.Transformation`.

Parameters
Expand All @@ -504,6 +544,7 @@ def __repr__(self):
)

def copy(self):
# type: () -> OrientationConstraint
"""Create a copy of this :class:`OrientationConstraint`.

Returns
Expand All @@ -515,6 +556,7 @@ def copy(self):

@classmethod
def from_frame(cls, frame_WCF, tolerances_orientation, link_name, tool_coordinate_frame=None, weight=1.0):
# type: (Frame, list[float], str, Optional[Frame], Optional[float]) -> OrientationConstraint
"""Create an :class:`OrientationConstraint` from a frame on the group's end-effector link.
Only the orientation of the frame is considered for the constraint, expressed
as a quaternion.
Expand Down Expand Up @@ -584,7 +626,7 @@ class PositionConstraint(Constraint):
Parameters
----------
link_name : :obj:`str`
The name of the link this contraint refers to.
The name of the link this constraint refers to.
bounding_volume : :class:`BoundingVolume`
The volume this constraint refers to.
weight : :obj:`float`, optional
Expand All @@ -595,7 +637,7 @@ class PositionConstraint(Constraint):
Attributes
----------
link_name : :obj:`str`
The name of the link this contraint refers to.
The name of the link this constraint refers to.
bounding_volume : :class:`BoundingVolume`
The volume this constraint refers to.
weight : :obj:`float`
Expand All @@ -612,6 +654,7 @@ class PositionConstraint(Constraint):
"""

def __init__(self, link_name, bounding_volume, weight=1.0):
# type: (str, BoundingVolume, Optional[float]) -> None
super(PositionConstraint, self).__init__(self.POSITION, weight)
self.link_name = link_name
self.bounding_volume = bounding_volume
Expand All @@ -626,6 +669,7 @@ def __data__(self):

@classmethod
def from_frame(cls, frame_WCF, tolerance_position, link_name, tool_coordinate_frame=None, weight=1.0):
# type: (Frame, float, str, Optional[Frame], Optional[float]) -> PositionConstraint
"""Create a :class:`PositionConstraint` from a frame on the group's end-effector link.
Only the position of the frame is considered for the constraint.

Expand Down Expand Up @@ -675,12 +719,13 @@ def from_frame(cls, frame_WCF, tolerance_position, link_name, tool_coordinate_fr

@classmethod
def from_box(cls, link_name, box, weight=1.0):
# type: (str, Box, Optional[float]) -> PositionConstraint
"""Create a :class:`PositionConstraint` from a :class:`compas.geometry.Box`.

Parameters
----------
link_name: :obj:`str`
The name of the link this contraint refers to.
The name of the link this constraint refers to.
box : :class:`compas.geometry.Box`
Box defining the bounding volume this constraint refers to.
weight : :obj:`float`, optional
Expand All @@ -703,12 +748,13 @@ def from_box(cls, link_name, box, weight=1.0):

@classmethod
def from_sphere(cls, link_name, sphere, weight=1.0):
# type: (str, Sphere, Optional[float]) -> PositionConstraint
"""Create a :class:`PositionConstraint` from a :class:`compas.geometry.Sphere`.

Parameters
----------
link_name : :obj:`str`
The name of the link this contraint refers to.
The name of the link this constraint refers to.
sphere : :class:`compas.geometry.Sphere`
Sphere defining the bounding volume this constraint refers to.
weight : :obj:`float`
Expand All @@ -731,12 +777,13 @@ def from_sphere(cls, link_name, sphere, weight=1.0):

@classmethod
def from_point(cls, link_name, point, tolerance_position, weight=1.0):
# type: (str, Point, float, Optional[float]) -> PositionConstraint
"""Create a :class:`PositionConstraint` from a point.

Parameters
----------
link_name : :obj:`str`
The name of the link this contraint refers to.
The name of the link this constraint refers to.
point : :class:`compas.geometry.Point`
Point defining the bounding volume this constraint refers to.
tolerance_position : :obj:`float`
Expand All @@ -756,12 +803,13 @@ def from_point(cls, link_name, point, tolerance_position, weight=1.0):

@classmethod
def from_mesh(cls, link_name, mesh, weight=1.0):
# type: (str, Mesh, Optional[float]) -> PositionConstraint
"""Create a :class:`PositionConstraint` from a :class:`compas.datastructures.Mesh`.

Parameters
----------
link_name : :obj:`str`
The name of the link this contraint refers to.
The name of the link this constraint refers to.
mesh : :class:`compas.datastructures.Mesh`
Mesh defining the bounding volume this constraint refers to.
weight : :obj:`float`
Expand All @@ -784,7 +832,8 @@ def from_mesh(cls, link_name, mesh, weight=1.0):
return cls(link_name, bounding_volume, weight)

def scale(self, scale_factor):
"""Scale the :attr:`bounding_volume` uniformely.
# type: (float) -> None
"""Scale the :attr:`bounding_volume` uniformly.

Parameters
----------
Expand All @@ -794,6 +843,7 @@ def scale(self, scale_factor):
self.bounding_volume.scale(scale_factor)

def transform(self, transformation):
# type: (Transformation) -> None
"""Transform the :attr:`bounding_volume` using a :class:`compas.geometry.Transformation`.

Parameters
Expand All @@ -807,6 +857,7 @@ def __repr__(self):
return "PositionConstraint({!r}, {!r}, {!r})".format(self.link_name, self.bounding_volume, self.weight)

def copy(self):
# type: () -> PositionConstraint
"""Create a copy of this :class:`PositionConstraint`.

Returns
Expand Down
Loading