Newer
Older
RobotCar / src / pc / gui / panels / recovery_panel.py
"""
recovery_panel
コースアウト復帰パラメータ調整 UI パネル
"""

from PySide6.QtCore import Signal
from PySide6.QtWidgets import (
    QCheckBox,
    QDoubleSpinBox,
    QFormLayout,
    QVBoxLayout,
)

from pc.gui.panels.collapsible_group_box import (
    CollapsibleGroupBox,
)
from pc.steering.recovery import RecoveryParams


class RecoveryPanel(CollapsibleGroupBox):
    """コースアウト復帰パラメータ調整 UI"""

    recovery_params_changed = Signal(object)

    def __init__(
        self,
        params: RecoveryParams | None = None,
    ) -> None:
        super().__init__("コースアウト復帰")
        self._params = params or RecoveryParams()
        self._auto_save_enabled = False
        self._setup_ui()
        self._auto_save_enabled = True

    def get_params(self) -> RecoveryParams:
        """現在の復帰パラメータを返す"""
        return self._params

    def _setup_ui(self) -> None:
        """UI を構築する"""
        layout = QVBoxLayout()
        self.setLayout(layout)

        # 有効/無効チェックボックス
        self._enabled_cb = QCheckBox("復帰機能を有効にする")
        self._enabled_cb.setChecked(self._params.enabled)
        self._enabled_cb.toggled.connect(self._on_changed)
        layout.addWidget(self._enabled_cb)

        # パラメータフォーム
        form = QFormLayout()
        layout.addLayout(form)

        self._spin_timeout = QDoubleSpinBox()
        self._spin_timeout.setRange(0.1, 10.0)
        self._spin_timeout.setSingleStep(0.1)
        self._spin_timeout.setDecimals(1)
        self._spin_timeout.setSuffix(" 秒")
        self._spin_timeout.setValue(
            self._params.timeout_sec,
        )
        self._spin_timeout.valueChanged.connect(
            self._on_changed,
        )
        form.addRow(
            "判定時間:", self._spin_timeout,
        )

        self._spin_steer = QDoubleSpinBox()
        self._spin_steer.setRange(0.0, 1.0)
        self._spin_steer.setSingleStep(0.05)
        self._spin_steer.setDecimals(2)
        self._spin_steer.setValue(
            self._params.steer_amount,
        )
        self._spin_steer.valueChanged.connect(
            self._on_changed,
        )
        form.addRow("操舵量:", self._spin_steer)

        self._spin_throttle = QDoubleSpinBox()
        self._spin_throttle.setRange(-1.0, 1.0)
        self._spin_throttle.setSingleStep(0.05)
        self._spin_throttle.setDecimals(2)
        self._spin_throttle.setValue(
            self._params.throttle,
        )
        self._spin_throttle.valueChanged.connect(
            self._on_changed,
        )
        form.addRow("速度:", self._spin_throttle)

    def _on_changed(self) -> None:
        """パラメータ変更時に反映してシグナルを発火する"""
        self._params.enabled = (
            self._enabled_cb.isChecked()
        )
        self._params.timeout_sec = (
            self._spin_timeout.value()
        )
        self._params.steer_amount = (
            self._spin_steer.value()
        )
        self._params.throttle = (
            self._spin_throttle.value()
        )
        if self._auto_save_enabled:
            self.recovery_params_changed.emit(
                self._params,
            )