control.fishing_control_core

Pure-Python fishing tension controllers ported from the MuJoCo notebooks.

Julie notebook -> AdmittanceController (virtual mass-spring-damper + PD inner loop) Chaoyi notebook -> ForceFeedbackController (asymmetric tension-to-angle mapping)

The notebooks model a single pitch DOF. In ROS2, control_dof=1 maps all q_* setpoints to pitch_joint (Joint_2) while base_joint (Joint_1) is held fixed at joint_1_hold.

Classes

AdmittanceConfig

Julie admittance controller parameters.

AdmittanceControllerCore

Virtual admittance outer loop from mojocowithJulieController.ipynb.

ControllerSnapshot

FishingControllerConfig

Shared configuration for both controller types.

FishingState

Enum where members are also (and must be) ints

ForceFeedbackConfig

Chaoyi proportional force-feedback controller parameters.

ForceFeedbackControllerCore

Asymmetric tension-to-angle controller from mojocowithchaoyi'scontroller.ipynb.

Functions

clip(→ float)

filter_tension(→ float)

get_fishing_state(→ FishingState)

smoothstep(→ float)

Module Contents

class control.fishing_control_core.AdmittanceConfig

Bases: FishingControllerConfig

Julie admittance controller parameters.

b_v: float = 5.5
j_alpha: float = 0.05
k_f: float = 5.0
k_g: float = 9.95
k_v: float = 16.0
kd_track: float = 20.0
ki_track: float = 0.0
kp_track: float = 140.0
m_v: float = 0.6
max_torque: float = 20.0
pos_int_limit: float = 0.15
rod_length: float = 0.185
class control.fishing_control_core.AdmittanceControllerCore(cfg: AdmittanceConfig, dt: float)

Virtual admittance outer loop from mojocowithJulieController.ipynb.

get_jacobian(theta: float, tip_pos: Tuple[float, float, float] | None = None, fish_pos: Tuple[float, float, float] | None = None) float

Map pitch rate to line-length rate (notebook get_jacobian).

hook_set_target(t: float) float
reset(q_actual: float) None
update(t: float, state: FishingState, f_measured: float, theta: float, theta_dot: float, tip_pos: Tuple[float, float, float] | None = None, fish_pos: Tuple[float, float, float] | None = None, control_enabled: bool = True) Tuple[float, float]

Return (position_cmd, velocity_cmd) for Joint_2.

update_tension(tension_raw: float) float
cfg
dt
j_filtered = 0.0
pos_int = 0.0
property tension_filtered: float
theta_cmd
theta_dot_cmd = 0.0
class control.fishing_control_core.ControllerSnapshot
q_cmd: float = 0.0
q_dot_cmd: float = 0.0
state: FishingState
tension_filtered: float = 0.0
tension_raw: float = 0.0
class control.fishing_control_core.FishingControllerConfig

Shared configuration for both controller types.

base_joint: str = 'Joint_1'
bite_time: float = 2.4
control_dof: int = 1
control_rate_hz: float = 50.0
fsm_enabled: bool = True
hook_duration: float = 1.2
joint_1_hold: float = 1.57
pitch_joint: str = 'Joint_2'
q_hook: float = 1.4
q_init: float = 1.745
q_max: float = 2.2
q_min: float = 0.1
q_neutral: float = 1.605
safety_tension_limit: float = 20.0
target_tension: float = 3.5
tension_filter_alpha: float = 0.055
class control.fishing_control_core.FishingState

Bases: enum.IntEnum

Enum where members are also (and must be) ints

Initialize self. See help(type(self)) for accurate signature.

HOOK_SET = 1
MONITOR = 0
REGULATE = 2
class control.fishing_control_core.ForceFeedbackConfig

Bases: FishingControllerConfig

Chaoyi proportional force-feedback controller parameters.

lower_gain: float = 0.8
max_qeq_step: float
qeq_alpha: float = 0.055
raise_gain: float = 1.25
tension_to_angle_gain: float
class control.fishing_control_core.ForceFeedbackControllerCore(cfg: ForceFeedbackConfig)

Asymmetric tension-to-angle controller from mojocowithchaoyi’scontroller.ipynb.

reset() None
update(t: float, state: FishingState, tension_filtered: float, control_enabled: bool = True) Tuple[float, float]

Return (q_eq, q_target) equilibrium pitch angles.

update_tension(tension_raw: float) float
cfg
q_eq
property tension_filtered: float
control.fishing_control_core.clip(value: float, lo: float, hi: float) float
control.fishing_control_core.filter_tension(raw: float, prev_filtered: float, alpha: float) float
control.fishing_control_core.get_fishing_state(t: float, cfg: FishingControllerConfig) FishingState
control.fishing_control_core.smoothstep(s: float) float