// =============================================================================
//  pid_inner_task.h -- 50 Hz inner-loop control task (Sprint 2)
// =============================================================================
//
//  Wraps the header-only PidInner controller in a FreeRTOS task pinned to
//  Core 1 (real-time core). Reads the rudder position from hal::rudder_sensor,
//  consumes the setpoint that the outer loop / Modbus client wrote, and
//  commands hal::rudder_actuator. Refuses to act in STANDBY or with master
//  power off (those interlocks live in hal::rudder_command itself).
// =============================================================================

#pragma once

#include "pid_inner.h"

namespace arautopilot::pid {

/// Initialise the controller with the seed gains. Must be called from
/// setup() once.
void pid_inner_task_init();

/// Spawn the FreeRTOS task. Must be called after pid_inner_task_init().
void pid_inner_task_start();

/// Update the setpoint that the inner loop pursues. Called by the Modbus
/// slave (when an operator writes a holding register) and, later, by the
/// outer loop task. Units: degrees, signed.
void pid_inner_set_setpoint_deg(float setpoint_deg);

/// Read the current setpoint (thread-safe).
float pid_inner_setpoint_deg();

/// Read the latest PID output command (signed PWM percent).
float pid_inner_last_output_pct();

/// Read the latest error (deg) the controller saw.
float pid_inner_last_error_deg();

/// Hot-swap gains at runtime (thread-safe).
void pid_inner_update_gains(float kp, float ki, float kd);

/// Read the gains currently in use.
void pid_inner_get_gains(float& kp, float& ki, float& kd);

}  // namespace arautopilot::pid
