22from __future__ import annotations
33
44from typing import Any , Optional , Sequence , Sized , Union
5+ import typing
56
67import attr
78import numpy as np
@@ -28,9 +29,9 @@ class Robot(Sized):
2829
2930 kinematic_chain = attr .ib (type = KinematicChain )
3031 tool = attr .ib (factory = lambda : Tool (), type = Tool )
31- world_frame = attr .ib (factory = lambda : np .eye (4 ), type = npt .NDArray [np .float64 ]) # type: ignore
32+ world_frame = attr .ib (factory = lambda : np .eye (4 ), type = npt .NDArray [np .float64 ])
3233 random_state = attr .ib (
33- factory = lambda : np .random .RandomState (), # type: ignore
34+ factory = lambda : np .random .RandomState (),
3435 type = np .random .RandomState ,
3536 )
3637 home_position = attr .ib (
@@ -59,7 +60,9 @@ def to_json(self) -> str:
5960 encoder = JSONEncoder (sort_keys = True )
6061 return encoder .encode (self )
6162
62- def fk (self , q : npt .NDArray [np .float64 ] = None ) -> npt .NDArray [np .float64 ]:
63+ def fk (
64+ self , q : Optional [npt .NDArray [np .float64 ]] = None
65+ ) -> npt .NDArray [np .float64 ]:
6366 """
6467 Compute the forward kinematics of a given position.
6568
@@ -88,16 +91,22 @@ def ik(
8891 self , pose : npt .NDArray [np .float64 ], q : Optional [npt .NDArray [np .float64 ]] = None
8992 ) -> Optional [npt .NDArray [np .float64 ]]:
9093 """Solve the inverse kinematics."""
94+ # set initial value
9195 x0 = self .joints if q is None else q
92- result = scipy .optimize .least_squares (
96+
97+ # solve optimization
98+ optimization_result = scipy .optimize .least_squares (
9399 fun = _ik_cost_function , x0 = x0 , bounds = self .joint_limits , args = (pose , self )
94100 ) # type: scipy.optimize.OptimizeResult
95101
96- if result .success : # pragma: no cover
97- actual_pose = self .fk (result .x )
102+ # set return value
103+ result = None # type: Optional[npt.NDArray[np.float64]]
104+ if optimization_result .success : # pragma: no cover
105+ actual_pose = self .fk (optimization_result .x )
98106 if np .allclose (actual_pose , pose , atol = 1e-3 ):
99- return result .x
100- return None
107+ result = optimization_result .x
108+
109+ return result
101110
102111 @property
103112 def ndof (self ) -> int :
@@ -153,7 +162,7 @@ def jacobian_world(
153162 j_tr [3 :, 3 :] = rotation
154163 j_w = np .dot (j_tr , j_fl ) # type: ignore
155164
156- return j_w
165+ return typing . cast ( npt . NDArray [ np . float64 ], j_w )
157166
158167 def jacobian_flange (
159168 self , q : Optional [npt .NDArray [np .float64 ]] = None
@@ -236,11 +245,12 @@ def compute_joint_torques(
236245 # reverse torques into correct order
237246 return np .array (list (reversed (joint_torques )), dtype = float )
238247
239- def clamp_joints (
240- self , q : npt .NDArray [np .float64 ]
241- ) -> Optional [npt .NDArray [np .float64 ]]:
248+ def clamp_joints (self , q : npt .NDArray [np .float64 ]) -> npt .NDArray [np .float64 ]:
242249 """Limit joints to joint limits."""
243- return np .clip (q , self .joint_limits [0 ], self .joint_limits [1 ])
250+ result = np .clip (
251+ q , self .joint_limits [0 ], self .joint_limits [1 ]
252+ ) # type: npt.NDArray[np.float64]
253+ return result
244254
245255 def random_joints (
246256 self , in_place : bool = False
@@ -250,11 +260,13 @@ def random_joints(
250260 low = self .joint_limits [0 ], high = self .joint_limits [1 ]
251261 )
252262
263+ result = None
253264 if in_place :
254265 self .joints = q
255- return None
256266 else :
257- return q
267+ result = q
268+
269+ return result
258270
259271 @classmethod
260272 def from_parameters (cls , parameters : npt .NDArray [np .float64 ]) -> Robot :
@@ -269,4 +281,5 @@ def _ik_cost_function(
269281) -> npt .NDArray [np .float64 ]:
270282 actual_pose = robot .fk (q )
271283 diff = np .abs (actual_pose - pose )
272- return diff .ravel ()
284+ result = diff .ravel () # type: npt.NDArray[np.float64]
285+ return result
0 commit comments