Folds three previously-separate pieces into one preliminary-example repo for the HAHACS thesis: - thesis/ (submodule) → gitea Thesis.git — the PhD proposal - fret-pipeline/ — FRET requirements to AIGER controller (was ~/Documents/fret_processing/; prior single-commit history abandoned per user decision) - plant-model/ — 10-state PKE + lumped T/H PWR model (was ~/Documents/PKE_Playground/; never version-controlled before) - presentations/2026DICE/ (submodule) → gitea 2026DICE.git - reachability/, hardware/ — empty placeholders for Thrust 3 and HIL - docs/architecture.md — how the discrete and continuous layers compose - claude_memory/ — session notes and scratch knowledge pattern Plant model refactored to thesis naming (x, plant, u, ref); pke_th_rhs now takes u as an explicit arg instead of reading rho_ext from the params struct. First two controllers built to the contract u = ctrl_<mode>(t, x, plant, ref): ctrl_null (baseline) and ctrl_operation (stabilizing, proportional on T_avg). Validated under a 100% -> 80% Q_sg step: ctrl_operation reduces steady-state T_avg drift ~47% vs. the unforced plant. Root CLAUDE.md emphasizes that CLAUDE.md files are living documents and that any knowledge not captured before a session ends is lost forever; claude_memory/ holds the session-level notes that haven't stabilized enough to graduate into a CLAUDE.md. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
51 lines
1.8 KiB
Matlab
51 lines
1.8 KiB
Matlab
%% main.m — closed-loop entry point
|
|
%
|
|
% Scenario: a 100% → 80% SG demand step. Compare the plant's intrinsic
|
|
% feedback response (ctrl_null) against the stabilizing operation-mode
|
|
% controller (ctrl_operation) holding T_avg at the nominal setpoint.
|
|
%
|
|
% Controller signature (thesis naming):
|
|
% u = ctrl_<mode>(t, x, plant, ref)
|
|
% where x is the continuous state vector and u is the external rod reactivity.
|
|
|
|
clear; clc; close all;
|
|
addpath('controllers');
|
|
|
|
%% ===== Plant =====
|
|
plant = pke_params();
|
|
|
|
%% ===== Scenario =====
|
|
|
|
% SG heat removal: step down to 80% at t = 30s, hold.
|
|
Q_sg = @(t) plant.P0 * (1.0 - 0.2 * (t >= 30));
|
|
|
|
% Reference for the operation-mode controller.
|
|
ref = struct();
|
|
ref.T_avg = plant.T_c0; % hold T_avg at steady-state value
|
|
|
|
% Simulation window.
|
|
tspan = [0, 600];
|
|
|
|
%% ===== Baseline: unforced feedback response =====
|
|
fprintf('\n----- Run 1: ctrl_null (plant feedback only) -----\n');
|
|
[t1, X1, U1] = pke_solver(plant, Q_sg, @ctrl_null, [], tspan);
|
|
|
|
%% ===== Closed loop: operation mode =====
|
|
fprintf('\n----- Run 2: ctrl_operation (P on T_avg) -----\n');
|
|
[t2, X2, U2] = pke_solver(plant, Q_sg, @ctrl_operation, ref, tspan);
|
|
|
|
%% ===== Plots =====
|
|
plot_pke_results(t1, X1, U1, plant, Q_sg, 'ctrl_null (baseline)');
|
|
plot_pke_results(t2, X2, U2, plant, Q_sg, 'ctrl_operation (P on T_avg)');
|
|
|
|
%% ===== Quick comparison figure =====
|
|
CtoF = @(T) T*9/5 + 32;
|
|
figure('Position', [100 50 1000 450], 'Name', 'T_avg comparison');
|
|
plot(t1, CtoF(X1(:,9)), 'b-', 'LineWidth', 1.5); hold on;
|
|
plot(t2, CtoF(X2(:,9)), 'r-', 'LineWidth', 1.5);
|
|
yline(CtoF(plant.T_c0), 'k--', 'LineWidth', 1.0);
|
|
xlabel('Time [s]'); ylabel('T_{avg} [F]');
|
|
legend('ctrl\_null', 'ctrl\_operation', 'setpoint', 'Location', 'best');
|
|
title('T_{avg} tracking: baseline vs stabilizing controller');
|
|
grid on;
|