diff --git a/bapsf_motion/examples/bapsf_motion.toml b/bapsf_motion/examples/bapsf_motion.toml index 84229216..f7ac0127 100644 --- a/bapsf_motion/examples/bapsf_motion.toml +++ b/bapsf_motion/examples/bapsf_motion.toml @@ -31,22 +31,24 @@ name = "East - Generic XY" type = "lapd_xy" mspace_polarity = [-1, 1] drive_polarity = [1, 1] -pivot_to_center = 62.948 # 53.55 cm + 2.54 cm + 2.5 in -probe_axis_offset = 19.5 +pivot_to_center = 62.948 # 53.55 cm + 2.54 cm + 2.7 in +probe_axis_offset = 19.9898 # 7.87 in pivot_to_drive = 112.7624 # 0.81 in + 22 cm + .75" + 82.5cm + 4.3cm pivot_to_feedthru = 21.6574 # 19.6 cm + 0.81" droop_correct = true +droop_scale = 1.0 [bapsf_motion.defaults.transform.1] name = "Plastic Room XY" type = "lapd_xy" mspace_polarity = [-1, 1] drive_polarity = [1, 1] -pivot_to_center = 62.948 # 53.55 cm + 2.54 cm + 2.5 in -probe_axis_offset = 19.5 +pivot_to_center = 62.948 # 53.55 cm + 2.54 cm + 2.7 in +probe_axis_offset = 19.9898 # 7.87 in pivot_to_drive = 112.7624 # 0.81 in + 22 cm + .75" + 82.5cm + 4.3cm pivot_to_feedthru = 21.6574 # 19.6 cm + 0.81" droop_correct = true +droop_scale = 1.0 [bapsf_motion.defaults.motion_builder] default = "East - Generic XY" diff --git a/bapsf_motion/transform/lapd.py b/bapsf_motion/transform/lapd.py index 08bf6515..0c072335 100644 --- a/bapsf_motion/transform/lapd.py +++ b/bapsf_motion/transform/lapd.py @@ -75,6 +75,13 @@ class LaPDXYTransform(base.BaseTransform): size .375" OD x 0.035" wall. Set `False` for no droop correction. (DEFAULT: `False`) + droop_scale : `float` + (DEFAULT ``1.0``) A float `>= 0.0` indicating how much to scale + the droop calculation by. A value of ``0`` would indicate no + droop. A value between ``0`` and ``1`` indicates a droop less + than the default model. A value of ``1`` indicates the default + model droop. A value ``> 1`` indicates more droop. + Examples -------- @@ -206,6 +213,7 @@ def __init__( drive_polarity: Tuple[int, int] = (1, 1), mspace_polarity: Tuple[int, int] = (-1, 1), droop_correct: bool = False, + droop_scale: Union[int, float] = 1.0, ): self._droop_correct_callable = None self._deployed_side = None @@ -218,6 +226,7 @@ def __init__( drive_polarity=drive_polarity, mspace_polarity=mspace_polarity, droop_correct=droop_correct, + droop_scale=droop_scale, ) def __call__(self, points, to_coords="drive") -> np.ndarray: @@ -266,6 +275,7 @@ def _validate_inputs(self, inputs: Dict[str, Any]) -> Dict[str, Any]: "pivot_to_drive", "pivot_to_feedthru", "probe_axis_offset", + "droop_scale", }: val = inputs[key] if not isinstance(val, (float, np.floating, int, np.integer)): @@ -315,6 +325,7 @@ def _validate_inputs(self, inputs: Dict[str, Any]) -> Dict[str, Any]: self._droop_correct_callable = LaPDXYDroopCorrect( drive=_drive, pivot_to_feedthru=inputs["pivot_to_feedthru"], + droop_scale=inputs["droop_scale"] ) return inputs @@ -455,9 +466,16 @@ def mspace_polarity(self) -> np.ndarray: @property def droop_correct(self) -> Union[DroopCorrectABC, None]: - # return self.inputs["droop_correct"] return self._droop_correct_callable + @property + def droop_scale(self) -> float: + """ + Scale value for how much to adjust the droop from the default + model. + """ + return self.inputs["droop_scale"] + @property def deployed_side(self): return self._deployed_side diff --git a/bapsf_motion/transform/lapd_droop.py b/bapsf_motion/transform/lapd_droop.py index 571d3637..6abd934a 100644 --- a/bapsf_motion/transform/lapd_droop.py +++ b/bapsf_motion/transform/lapd_droop.py @@ -293,6 +293,13 @@ class LaPDXYDroopCorrect(DroopCorrectABC): Distance from the center "pivot" point of the ball valve to the nearest face of the probe drive feed-through. + droop_scale : `float` + (DEFAULT ``1.0``) A float `>= 0.0` indicating how much to scale + the droop calculation by. A value of ``0`` would indicate no + droop. A value between ``0`` and ``1`` indicates a droop less + than the default model. A value of ``1`` indicates the default + model droop. A value ``> 1`` indicates more droop. + Notes ----- @@ -339,10 +346,17 @@ class LaPDXYDroopCorrect(DroopCorrectABC): _probe_shaft_material = "Stainless Steel 304" _dimensionality = 2 - def __init__(self, drive: Drive, *, pivot_to_feedthru: float): + def __init__( + self, + drive: Drive, + *, + pivot_to_feedthru: float, + droop_scale: Union[int, float] = 1.0, + ) -> None: super().__init__( drive=drive, pivot_to_feedthru=pivot_to_feedthru, + droop_scale=droop_scale, ) # this is the unit system used in generating the droop fit polynomial @@ -370,10 +384,11 @@ def __init__(self, drive: Drive, *, pivot_to_feedthru: float): # ds = (a3 * r**3 + a2 * r**2 + a1 * r + a0) r cos(theta) # # coeffs = [a0, a1, a2, a3] + # # self._coeffs = np.array([6.209e-06, -2.211e-07, 2.084e-09, -5.491e-09]) self._coeffs = np.array( [6.208863E-06, -2.210800E-07, 2.083731E-09, -5.490692E-09] - ) + ) * self.droop_scale @property def pivot_to_feedthru(self): @@ -383,6 +398,14 @@ def pivot_to_feedthru(self): """ return self.inputs["pivot_to_feedthru"] + @property + def droop_scale(self) -> float: + """ + Scale value for how much to adjust the droop from the default + model. + """ + return self.inputs["droop_scale"] + @property def coefficients(self) -> np.ndarray: r""" @@ -431,7 +454,7 @@ def _convert_to_deployed_units(self, points: np.ndarray) -> np.ndarray: return points[..., :] * conversion_factor[:] def _validate_inputs(self, inputs: Dict[str, Any]) -> Dict[str, Any]: - for key in {"pivot_to_feedthru"}: + for key in {"pivot_to_feedthru", "droop_scale"}: val = inputs[key] if not isinstance(val, (float, np.floating, int, np.integer)): raise TypeError( @@ -439,8 +462,6 @@ def _validate_inputs(self, inputs: Dict[str, Any]) -> Dict[str, Any]: f"got type {type(val)}." ) elif val < 0.0: - # TODO: HOW (AND SHOULD WE) ALLOW A NEGATIVE OFFSET FOR - # "probe_axis_offset" val = np.abs(val) warn( f"Keyword '{val}' is NOT supposed to be negative, " @@ -462,7 +483,7 @@ def _convert_to_droop_points(self, points: np.ndarray) -> np.ndarray: # - rt => (radius, theta) points_rt = np.empty_like(_points) points_rt[..., 0] = np.linalg.norm(_points, axis=1) + self.pivot_to_feedthru - points_rt[..., 1] = np.tan(_points[..., 1] / _points[..., 0]) + points_rt[..., 1] = np.arctan(_points[..., 1] / _points[..., 0]) # Calculate dx and dy of the droop # - delta will always be negative in the ball valve coords