Skip to content

Commit

Permalink
Fixed all mypy errors. Ignored tmotor and moteus files.
Browse files Browse the repository at this point in the history
  • Loading branch information
senthurayyappan committed Nov 20, 2024
1 parent 35c5028 commit 554e09c
Show file tree
Hide file tree
Showing 21 changed files with 409 additions and 295 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ check: ## Run code quality tools.
@echo "🚀 Static type checking: Running mypy"
@poetry run mypy
@echo "🚀 Checking for obsolete dependencies: Running deptry"
@poetry run deptry .
@poetry run deptry . --ignore DEP002,DEP001

.PHONY: test
test: ## Test the code with pytest
Expand Down
20 changes: 10 additions & 10 deletions opensourceleg/actuators/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class MOTOR_CONSTANTS:
MAX_CASE_TEMPERATURE: float
MAX_WINDING_TEMPERATURE: float

def __post_init__(self):
def __post_init__(self) -> None:
if any(x <= 0 for x in self.__dict__.values()):
raise ValueError("All values in MOTOR_CONSTANTS must be non-zero and positive.")

Expand Down Expand Up @@ -107,13 +107,13 @@ class MethodWithRequiredModes(Protocol):
_required_modes: set[CONTROL_MODES]


def requires(*modes: CONTROL_MODES):
def requires(*modes: CONTROL_MODES) -> Callable[[T], T]:
def decorator(func: T) -> T:
if not all(isinstance(mode, CONTROL_MODES) for mode in modes):
raise TypeError("All arguments to 'requires' must be of type CONTROL_MODES")

if not hasattr(func, "_required_modes"):
func._required_modes = set(modes)
func._required_modes = set(modes) # type: ignore[attr-defined]
else:
func._required_modes.update(modes)

Expand All @@ -130,8 +130,8 @@ def __init__(
motor_constants: MOTOR_CONSTANTS,
frequency: int = 1000,
offline: bool = False,
*args,
**kwargs,
*args: Any,
**kwargs: Any,
) -> None:
self._MOTOR_CONSTANTS: MOTOR_CONSTANTS = motor_constants
self._gear_ratio: float = gear_ratio
Expand All @@ -158,18 +158,18 @@ def __init__(
self._set_original_methods()
self._set_mutated_methods()

def __enter__(self):
def __enter__(self) -> "ActuatorBase":
self.start()
return self

def __exit__(self, exc_type, exc_value, exc_traceback):
def __exit__(self, exc_type: Any, exc_value: Any, exc_traceback: Any) -> None:
self.stop()

def _restricted_method(self, method_name: str, *args, **kwargs):
def _restricted_method(self, method_name: str, *args: Any, **kwargs: Any) -> None:
LOGGER.error(f"{method_name}() is not available in {self._mode.name} mode.")
return None

def _set_original_methods(self):
def _set_original_methods(self) -> None:
for method_name in CONTROL_MODE_METHODS:
try:
method = getattr(self, method_name)
Expand All @@ -178,7 +178,7 @@ def _set_original_methods(self):
except AttributeError:
LOGGER.debug(msg=f"[{self.tag}] {method_name}() is not implemented in {self.tag}.")

def _set_mutated_methods(self):
def _set_mutated_methods(self) -> None:
for method_name, method in self._original_methods.items():
if self._mode in method._required_modes:
setattr(self, method_name, method)
Expand Down
13 changes: 7 additions & 6 deletions opensourceleg/actuators/decorators.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from functools import wraps
from typing import Any, Callable

from opensourceleg.actuators.base import ActuatorBase
from opensourceleg.logging.exceptions import (
Expand All @@ -7,9 +8,9 @@
)


def check_actuator_connection(func):
def check_actuator_connection(func: Callable) -> Callable:
@wraps(func)
def wrapper(self: ActuatorBase, *args, **kwargs):
def wrapper(self: ActuatorBase, *args: Any, **kwargs: Any) -> Any:
if self.is_offline:
raise ActuatorConnectionException(tag=self.tag)

Expand All @@ -18,9 +19,9 @@ def wrapper(self: ActuatorBase, *args, **kwargs):
return wrapper


def check_actuator_open(func):
def check_actuator_open(func: Callable) -> Callable:
@wraps(func)
def wrapper(self: ActuatorBase, *args, **kwargs):
def wrapper(self: ActuatorBase, *args: Any, **kwargs: Any) -> Any:
if not self.is_open:
raise ActuatorConnectionException(tag=self.tag)

Expand All @@ -29,9 +30,9 @@ def wrapper(self: ActuatorBase, *args, **kwargs):
return wrapper


def check_actuator_stream(func):
def check_actuator_stream(func: Callable) -> Callable:
@wraps(func)
def wrapper(self: ActuatorBase, *args, **kwargs):
def wrapper(self: ActuatorBase, *args: Any, **kwargs: Any) -> Any:
if not self.is_streaming:
raise ActuatorStreamException(tag=self.tag)

Expand Down
2 changes: 1 addition & 1 deletion opensourceleg/actuators/dephy.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def _dephy_impedance_mode_exit(dephy_actuator: "DephyActuator") -> None:
)


class DephyActuator(Device, ActuatorBase):
class DephyActuator(Device, ActuatorBase): # type: ignore[no-any-unimported]
def __init__(
self,
tag: str = "DephyActuator",
Expand Down
20 changes: 10 additions & 10 deletions opensourceleg/actuators/tmotor.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ def case_temperature(self) -> float:
Returns:
The most recently updated motor temperature in degrees C.
"""
return self._motor_state.temperature
return float(self._motor_state.temperature)

@property
def winding_temperature(self) -> float:
Expand All @@ -369,7 +369,7 @@ def motor_current(self) -> float:
Returns:
The most recently updated qaxis current in amps
"""
return self._motor_state.current
return float(self._motor_state.current)

@property
def motor_voltage(self) -> float:
Expand All @@ -382,31 +382,31 @@ def output_position(self) -> float:
Returns:
The most recently updated output angle in radians
"""
return self._motor_state.position
return float(self._motor_state.position)

@property
def output_velocity(self) -> float:
"""
Returns:
The most recently updated output velocity in radians per second
"""
return self._motor_state.velocity
return float(self._motor_state.velocity)

@property
def output_acceleration(self) -> float:
"""
Returns:
The most recently updated output acceleration in radians per second per second
"""
return self._motor_state.acceleration
return float(self._motor_state.acceleration)

@property
def output_torque(self) -> float:
"""
Returns:
the most recently updated output torque in Nm
"""
return self.motor_current * MIT_Params[self.type]["Kt_actual"] * MIT_Params[self.type]["GEAR_RATIO"]
return float(self.motor_current * MIT_Params[self.type]["Kt_actual"] * MIT_Params[self.type]["GEAR_RATIO"])

# uses plain impedance mode, will send 0.0 for current command.
def set_impedance_gains(self, kp=0, ki=0, K=0.08922, B=0.0038070, ff=0) -> None:
Expand Down Expand Up @@ -569,7 +569,7 @@ def motor_position(self) -> float:
Returns:
The most recently updated motor-side angle in rad.
"""
return self._motor_state.position * MIT_Params[self.type]["GEAR_RATIO"]
return float(self._motor_state.position * MIT_Params[self.type]["GEAR_RATIO"])

@property
def motor_velocity(self) -> float:
Expand All @@ -579,7 +579,7 @@ def motor_velocity(self) -> float:
Returns:
The most recently updated motor-side velocity in rad/s.
"""
return self._motor_state.velocity * MIT_Params[self.type]["GEAR_RATIO"]
return float(self._motor_state.velocity * MIT_Params[self.type]["GEAR_RATIO"])

@property
def motor_acceleration(self) -> float:
Expand All @@ -589,7 +589,7 @@ def motor_acceleration(self) -> float:
Returns:
The most recently updated motor-side acceleration in rad/s/s.
"""
return self._motor_state.acceleration * MIT_Params[self.type]["GEAR_RATIO"]
return float(self._motor_state.acceleration * MIT_Params[self.type]["GEAR_RATIO"])

@property
def motor_torque(self) -> float:
Expand All @@ -599,7 +599,7 @@ def motor_torque(self) -> float:
Returns:
The most recently updated motor-side torque in Nm.
"""
return self.output_torque * MIT_Params[self.type]["GEAR_RATIO"]
return float(self.output_torque * MIT_Params[self.type]["GEAR_RATIO"])

# Pretty stuff
def __str__(self) -> str:
Expand Down
7 changes: 4 additions & 3 deletions opensourceleg/benchmarks/decorators.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import timeit
from functools import wraps
from typing import Any, Callable


def profile_time(iterations):
def decorator(func):
def profile_time(iterations: int) -> Callable:
def decorator(func: Callable) -> Callable:
@wraps(func)
def wrapper(*args, **kwargs):
def wrapper(*args: Any, **kwargs: Any) -> None:
timer = timeit.Timer(lambda: func(*args, **kwargs))
execution_time = timer.timeit(number=iterations)
print(f"Execution time for {func.__name__} over {iterations} iterations: {execution_time} seconds")
Expand Down
8 changes: 4 additions & 4 deletions opensourceleg/benchmarks/threads.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,21 @@
FREQ = 1000


def core_function():
def core_function() -> None:
global counter
counter += 1
# print("Counter: ", counter)
time.sleep(1 / FREQ)


@profile_time(iterations=PROFILING_ITERATIONS)
def basic_counter():
def basic_counter() -> None:
for _ in range(10):
core_function()


@profile_time(iterations=PROFILING_ITERATIONS)
def threaded_counter():
def threaded_counter() -> None:
threads = []
for _ in range(10):
thread = threading.Thread(target=core_function)
Expand All @@ -33,7 +33,7 @@ def threaded_counter():
thread.join()


def main():
def main() -> None:
basic_counter()
threaded_counter()

Expand Down
39 changes: 23 additions & 16 deletions opensourceleg/control/compiled_controller.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import ctypes
from typing import Any
from typing import Any, Callable, Optional

import numpy.ctypeslib as ctl

Expand Down Expand Up @@ -39,17 +39,16 @@ class CompiledController:

def __init__(
self,
library_name,
library_path,
main_function_name,
initialization_function_name=None,
cleanup_function_name=None,
library_name: str,
library_path: str,
main_function_name: str,
initialization_function_name: Optional[str] = None,
cleanup_function_name: Optional[str] = None,
) -> None:
self.cleanup_func = None
self.lib = ctl.load_library(library_name, library_path)
self.cleanup_func = self._load_function(cleanup_function_name)
self.main_function = self._load_function(main_function_name)
self.init_function = self._load_function(initialization_function_name)
self.lib: Any = ctl.load_library(library_name, library_path)
self.cleanup_func: Callable = self._load_function(cleanup_function_name)
self.main_function: Callable = self._load_function(main_function_name)
self.init_function: Callable = self._load_function(initialization_function_name)
# Note if requested function name is None, returned handle is also none

if self.init_function is not None:
Expand All @@ -71,14 +70,14 @@ def __init__(
self._output_type = None
self.outputs = None

def __del__(self):
def __del__(self) -> None:
if self.cleanup_func is not None:
self.cleanup_func()

def __repr__(self):
def __repr__(self) -> str:
return "CompiledController"

def _load_function(self, function_name):
def _load_function(self, function_name: Optional[str]) -> Any:
if function_name is None:
return None
else:
Expand All @@ -102,6 +101,10 @@ def define_inputs(self, input_list: list[Any]) -> None:
All types can be accessed as CompiledController.types.(type_name)
"""
self._input_type = self.define_type("inputs", input_list)

if self._input_type is None:
raise ValueError("Input type not defined properly. Check define_type() method.")

self.inputs = self._input_type()

def define_outputs(self, output_list: list[Any]) -> None:
Expand All @@ -118,9 +121,13 @@ def define_outputs(self, output_list: list[Any]) -> None:
All types can be accessed as CompiledController.types.(type_name)
"""
self._output_type = self.define_type("outputs", output_list)

if self._output_type is None:
raise ValueError("Output type not defined properly. Check define_type() method.")

self.outputs = self._output_type()

def define_type(self, type_name: str, parameter_list: list[Any]):
def define_type(self, type_name: str, parameter_list: list[Any]) -> Any:
"""
This method defines a new type to be used in the compiled controller.
After calling this method, the datatype with name type_name will be
Expand Down Expand Up @@ -153,7 +160,7 @@ class CustomStructure(ctypes.Structure):
setattr(self.types, type_name, CustomStructure)
return getattr(self.types, type_name)

def run(self):
def run(self) -> Any:
"""
This method calls the main controller function of the library.
Under the hood, it calls library_name.main_function_name(*inputs, *outputs),
Expand Down
Loading

0 comments on commit 554e09c

Please sign in to comment.