diff --git a/examples/basic_motion.py b/examples/basic_motion.py index 24ed96d..4d6d010 100644 --- a/examples/basic_motion.py +++ b/examples/basic_motion.py @@ -11,6 +11,7 @@ import numpy as np +from opensourceleg.actuators.base import CONTROL_MODES from opensourceleg.actuators.dephy import DephyActuator from opensourceleg.time import SoftRealtimeLoop from opensourceleg.units import units @@ -53,8 +54,8 @@ def make_periodic_trajectory(period, minimum, maximum): input("Homing complete: Press enter to continue") - knee.set_control_mode(knee.CONTROL_MODES.POSITION) - ankle.set_control_mode(ankle.CONTROL_MODES.POSITION) + knee.set_control_mode(CONTROL_MODES.POSITION) + ankle.set_control_mode(CONTROL_MODES.POSITION) knee.set_position_gains(kp=5) ankle.set_position_gains(kp=5) @@ -62,8 +63,8 @@ def make_periodic_trajectory(period, minimum, maximum): knee.update() ankle.update() - knee_setpoint = units.convert_to_default(knee_traj(t), units.position.deg) - ankle_setpoint = units.convert_to_default(ankle_traj(t), units.position.deg) + knee_setpoint = units.convert_to_default(knee_traj(t), units.Position.deg) + ankle_setpoint = units.convert_to_default(ankle_traj(t), units.Position.deg) knee.set_output_position(knee_setpoint) ankle.set_output_position(ankle_setpoint) diff --git a/opensourceleg/actuators/dephy.py b/opensourceleg/actuators/dephy.py index dd9e1db..2945b90 100644 --- a/opensourceleg/actuators/dephy.py +++ b/opensourceleg/actuators/dephy.py @@ -314,7 +314,7 @@ def home( to create one. The encoder map is used to estimate joint position more accurately." ) - def make_encoder_map(self, overwrite=False) -> None: + def make_encoder_map(self, overwrite: bool = False) -> None: """ This method makes a lookup table to calculate the position measured by the joint encoder. This is necessary because the magnetic output encoders are nonlinear. @@ -332,11 +332,11 @@ def make_encoder_map(self, overwrite=False) -> None: if not self.is_homed: LOGGER.warning(msg=f"[{self.__repr__()}] Please home the {self.tag} joint before making the encoder map.") - return + return None if os.path.exists(f"./{self.tag}_encoder_map.npy") and not overwrite: LOGGER.info(msg=f"[{self.__repr__()}] Encoder map exists. Skipping encoder map creation.") - return + return None self.set_control_mode(mode=CONTROL_MODES.CURRENT) self.set_current_gains() @@ -370,7 +370,7 @@ def make_encoder_map(self, overwrite=False) -> None: except KeyboardInterrupt: LOGGER.warning(msg="Encoder map interrupted.") - return + return None LOGGER.info(msg=f"[{self.__repr__()}] You may now stop moving the {self.tag} joint.") @@ -418,7 +418,7 @@ def set_output_torque(self, value: float) -> None: def set_motor_current( self, value: float, - ): + ) -> None: """ Sets the motor current in mA. @@ -601,12 +601,12 @@ def set_motor_impedance( ff=ff, ) - def set_encoder_map(self, encoder_map) -> None: + def set_encoder_map(self, encoder_map: np.polynomial.polynomial.Polynomial) -> None: """Sets the joint encoder map""" - self._encoder_map = encoder_map + self._encoder_map: np.polynomial.polynomial.Polynomial = encoder_map @property - def encoder_map(self): + def encoder_map(self) -> Optional[np.polynomial.polynomial.Polynomial]: """Polynomial coefficients defining the joint encoder map from counts to radians.""" if getattr(self, "_encoder_map", None) is not None: return self._encoder_map @@ -777,7 +777,7 @@ def winding_temperature(self) -> float: return 0.0 @property - def genvars(self): + def genvars(self) -> np.ndarray: """Dephy's 'genvars' object.""" if self._data is not None: return np.array( @@ -1072,7 +1072,7 @@ def update(self) -> None: def set_motor_current( self, value: float, - ): + ) -> None: """ Sets the motor current in mA. @@ -1297,7 +1297,7 @@ def winding_temperature(self) -> float: return 0.0 @property - def genvars(self): + def genvars(self) -> np.ndarray: """Dephy's 'genvars' object.""" if self._data is not None: return np.array( @@ -1387,19 +1387,19 @@ def gyroy(self) -> float: return 0.0 @property - def is_streaming(self): + def is_streaming(self) -> bool: return self._is_streaming @is_streaming.setter - def is_streaming(self, value: bool): + def is_streaming(self, value: bool) -> None: self._is_streaming = value @property - def is_open(self): + def is_open(self) -> bool: return self._is_open @is_open.setter - def is_open(self, value: bool): + def is_open(self, value: bool) -> None: self._is_open = value @property diff --git a/opensourceleg/actuators/moteus.py b/opensourceleg/actuators/moteus.py index f772ac8..efff6c2 100644 --- a/opensourceleg/actuators/moteus.py +++ b/opensourceleg/actuators/moteus.py @@ -274,7 +274,7 @@ async def update(self): self._command = self.make_query() - def home(self): + def home(self) -> None: # TODO: implement homing LOGGER.info(msg=f"[{self.__repr__()}] Homing not implemented.") @@ -309,7 +309,7 @@ def set_joint_torque(self, value: float) -> None: def set_motor_current( self, value: float, - ): + ) -> None: LOGGER.info("Current Mode Not Implemented") def set_motor_velocity(self, value: float) -> None: diff --git a/opensourceleg/collections/validators.py b/opensourceleg/collections/validators.py index 88360a0..966227a 100644 --- a/opensourceleg/collections/validators.py +++ b/opensourceleg/collections/validators.py @@ -1,19 +1,20 @@ from abc import ABC, abstractmethod +from typing import Any class Validator(ABC): - def __set_name__(self, owner, name): + def __set_name__(self, owner, name) -> None: self.private_name = f"_{name}" - def __get__(self, instance, objtype=None): + def __get__(self, instance, objtype=None) -> Any: return getattr(instance, self.private_name) - def __set__(self, instance, value): + def __set__(self, instance, value) -> None: self.validate(value) setattr(instance, self.private_name, value) @abstractmethod - def validate(self, value): + def validate(self, value) -> None: pass @@ -22,7 +23,7 @@ def __init__(self, min_value=None, max_value=None) -> None: self.min_value = min_value self.max_value = max_value - def validate(self, value): + def validate(self, value) -> None: if not isinstance(value, (int, float)): raise TypeError("Value must be an int or float") @@ -38,7 +39,7 @@ def validate(self, value): class Gains: kp = Number(0, 100) - def __init__(self, price): + def __init__(self, price) -> None: self.kp = price g = Gains(200) diff --git a/opensourceleg/robots/osl.py b/opensourceleg/robots/osl.py index f89fc7f..42d9010 100644 --- a/opensourceleg/robots/osl.py +++ b/opensourceleg/robots/osl.py @@ -13,20 +13,20 @@ class OpenSourceLeg(RobotBase[TActuator, TSensor]): - def start(self): + def start(self) -> None: super().start() - def stop(self): + def stop(self) -> None: super().stop() - def update(self): + def update(self) -> None: super().update() - def home(self): + def home(self) -> None: for actuator in self.actuators.values(): actuator.home() - def make_encoder_maps(self): + def make_encoder_maps(self) -> None: pass @property diff --git a/opensourceleg/safety/safety.py b/opensourceleg/safety/safety.py index 71a656f..6429bde 100644 --- a/opensourceleg/safety/safety.py +++ b/opensourceleg/safety/safety.py @@ -6,7 +6,7 @@ class ThermalLimitException(Exception): - def __init__(self, message="Software thermal limit exceeded. Exiting."): + def __init__(self, message="Software thermal limit exceeded. Exiting.") -> None: self.message = message super().__init__(self.message) @@ -16,7 +16,7 @@ def is_changing( max_points: int = 10, threshold: float = 1e-6, proxy_attribute_name: Optional[str] = None, -): +) -> Callable: """ Creates a decorator to check if a property's value is changing. If the standard deviation of the last 'max_points' values is less than 'threshold', @@ -65,7 +65,7 @@ def wrapper(instance, *args, **kwargs): return decorator -def is_negative(clamp: bool = False): +def is_negative(clamp: bool = False) -> Callable: """ Creates a decorator to check if a property's value is negative. diff --git a/opensourceleg/units/units.py b/opensourceleg/units/units.py index 4f67c63..3076878 100644 --- a/opensourceleg/units/units.py +++ b/opensourceleg/units/units.py @@ -33,63 +33,63 @@ class Force(float, Enum): - N: 1.0 - lbf: 4.4482216152605 - kgf: 9.80665 + N = 1.0 + lbf = 4.4482216152605 + kgf = 9.80665 class Torque(float, Enum): - N_m: 1.0 - lbf_inch: 0.1129848290276167 - kgf_cm: 0.0980665 + N_m = 1.0 + lbf_inch = 0.1129848290276167 + kgf_cm = 0.0980665 class Stiffness(float, Enum): - N_m_per_rad: 1.0 - N_m_per_deg: 0.017453292519943295 + N_m_per_rad = 1.0 + N_m_per_deg = 0.017453292519943295 class Damping(float, Enum): - N_m_per_rad_per_s: 1.0 - N_m_per_deg_per_s: 0.017453292519943295 + N_m_per_rad_per_s = 1.0 + N_m_per_deg_per_s = 0.017453292519943295 class Length(float, Enum): - m: 1.0 - cm: 0.01 - inch: 0.0254 + m = 1.0 + cm = 0.01 + inch = 0.0254 class Position(float, Enum): - rad: 1.0 - deg: 0.017453292519943295 + rad = 1.0 + deg = 0.017453292519943295 class Mass(float, Enum): - kg: 1.0 - g: 0.001 - lb: 0.45359237 + kg = 1.0 + g = 0.001 + lb = 0.45359237 class Velocity(float, Enum): - rad_per_s: 1.0 - deg_per_s: 0.017453292519943295 - rpm: 0.10471975511965977 + rad_per_s = 1.0 + deg_per_s = 0.017453292519943295 + rpm = 0.10471975511965977 class Acceleration(float, Enum): - rad_per_s2: 1.0 - deg_per_s2: 0.017453292519943295 + rad_per_s2 = 1.0 + deg_per_s2 = 0.017453292519943295 class Current(float, Enum): - mA: 1 - A: 1000 + mA = 1 + A = 1000 class Voltage(float, Enum): - mV: 1 - V: 1000 + mV = 1 + V = 1000 def convert_to_default(value: float, from_unit: float) -> float: