rt_flomni: add ConstEmitter client access to RtFlomniController
CI for csaxs_bec / test (push) Successful in 1m35s
CI for csaxs_bec / test (pull_request) Successful in 1m47s

Expose the flOMNI ConstEmitter runtime constants (served over the control-loop
TCP server, command letter 'e') to BEC users. These were previously baked into
Orchestra module parameter files; they can now be read and set live.

New RtFlomniController methods (all added to USER_ACCESS):
  emitter_get()                                  -> dict of the four values
  emitter_show_all()                             -> PrettyTable printout
  emitter_set_tracking_target_y(val)             -> "ey<val>"
  emitter_set_tracking_target_z(val)             -> "ez<val>"
  emitter_set_intensity_threshold_laser(val)     -> "et<val>"
  emitter_set_psd_intensity_threshold_tracking_low(val) -> "el<val>"

emitter_get issues "es" and parses the CSV reply
(targetpos_tracking_y, targetpos_tracking_z, intensity_threshold_laser,
PSD_intensity_threshold_tracking_low), same pattern as the Ts/sr readouts.
Setters use socket_put with a fixed %.4f value, same pattern as the pa
setpoint command; they are fire-and-forget (the server does not ack sets).

The rotation-loop laser threshold (intensity_threshold_rot_laser) is a startup
constant on the server side and is intentionally neither read back nor settable
here.

Named methods were chosen over a single opaque command to match the existing
laser_tracker_* / feedback_* convention and to self-document each value.

Requires the corresponding flOMNI control-loop change (ConstEmitter module +
'e' command in CommunicationServer). Additive change; no existing behaviour
modified.
This commit is contained in:
x12sa
2026-07-06 11:23:30 +02:00
parent 0b019b0490
commit 608708448f
+64 -1
View File
@@ -45,6 +45,12 @@ class RtFlomniController(Controller):
"laser_tracker_check_signalstrength",
"laser_tracker_check_enabled",
"is_axis_moving",
"emitter_show_all",
"emitter_get",
"emitter_set_tracking_target_y",
"emitter_set_tracking_target_z",
"emitter_set_intensity_threshold_laser",
"emitter_set_psd_intensity_threshold_tracking_low",
]
def __init__(
@@ -391,6 +397,63 @@ class RtFlomniController(Controller):
return True
return False
def emitter_get(self) -> dict:
"""Read the runtime constants served by the ConstEmitter Orchestra module.
These are values that used to live in individual module parameter files
(tracking targets and intensity thresholds) and are now emitted centrally
so they can be tweaked live. The rotation-loop laser threshold
(intensity_threshold_rot_laser) is a pure startup constant and is
intentionally not reported here.
Returns:
dict: current emitter values.
"""
ret = self.socket_put_and_receive("es")
# remove trailing \n
ret = ret.split("\n")[0]
values = [float(val) for val in ret.split(",")]
if len(values) != 4:
raise RtCommunicationError(
f"Expected to receive 4 emitter values. Instead received {values}"
)
return {
"targetpos_tracking_y": values[0],
"targetpos_tracking_z": values[1],
"intensity_threshold_laser": values[2],
"PSD_intensity_threshold_tracking_low": values[3],
}
def emitter_show_all(self):
"""Print all ConstEmitter runtime constants as a table."""
t = PrettyTable()
t.title = "ConstEmitter Runtime Constants"
t.field_names = ["Name", "Value"]
for key, val in self.emitter_get().items():
t.add_row([key, val])
print(t)
def emitter_set_tracking_target_y(self, val: float) -> None:
"""Set the y tracking target position (PID_tracking_y)."""
self.socket_put(f"ey{val:.4f}")
def emitter_set_tracking_target_z(self, val: float) -> None:
"""Set the z tracking target position (PID_tracking_z)."""
self.socket_put(f"ez{val:.4f}")
def emitter_set_intensity_threshold_laser(self, val: float) -> None:
"""Set the shared laser intensity threshold.
Wired into the slew-rate limiters (x/y/z) and the PID loops
(x/y/z and the fast FZP x/y loops). Does not affect the
rotation loops, which use a separate fixed threshold.
"""
self.socket_put(f"et{val:.4f}")
def emitter_set_psd_intensity_threshold_tracking_low(self, val: float) -> None:
"""Set the low PSD intensity threshold used by the tracking PIDs (y and z)."""
self.socket_put(f"el{val:.4f}")
def pid_y(self) -> float:
ret = float(self.socket_put_and_receive("G").strip())
return ret
@@ -929,4 +992,4 @@ if __name__ == "__main__":
socket_cls=SocketIO, socket_host="mpc2844.psi.ch", socket_port=2222, device_manager=None
)
rtcontroller.on()
rtcontroller.laser_tracker_on()
rtcontroller.laser_tracker_on()