Repository navigation
Linearize opened signals in trajectory_ss at their trajectory values and correct the batch-linearization tutorial - #86
Merged
Conversation
Opening a loop turns the opened signal into a parameter whose value must be supplied in the operating point. Previously the tutorial held these at 0, which linearizes at the wrong point for systems nonlinear in the opened signal — visible as identical controller linearizations along the whole trajectory in the batch-linearization tutorial. trajectory_ss now maps each opened signal to itself as a symbolic operating- point value, which ModelingToolkit.LinearizationOpPoint resolves from the loop-closed solution at each time point (requires the corresponding MTK support for symbolic op values). User-supplied op entries take precedence. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWPXe76HwiugWWyLP7BYrL
…lues SciML/ModelingToolkit.jl#5265 holds every signal disconnected by a loop opening at the value of its driver at the operating point of the loop-closed system, which along a solution is its value in the solution. `trajectory_ss` therefore no longer maps the opened signals to themselves (`default_loop_opening_op` and `strip_root_namespace` are removed), and `[sources]` points to the branch of that PR until it is released. The batch-linearization tutorial now explains that loop openings do not change the operating point, and corrects the reconstruction of the closed loop from its parts: opening only at `y` reproduces the loop-closed transfer function exactly, opening at `u` omits the dependence of the controller output on the scheduling variable, and the two-input controller must enter the loop with the input loop gain `(C_r - C_v) P`, since the scheduling variable enters the controller with a positive sign. The exact reconstructions are checked against the linearization of the closed loop. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KecV2uixYREhdQWw1XSAC8
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Opening a loop during linearization turns the opened signal into a parameter. The batch-linearization tutorial previously held these signals at
0, which linearizes at the wrong point for systems that are nonlinear in the opened signal. In the tutorial, this was visible as identical controller linearizations along the entire trajectory in the plot "Loop open at v and y", although the scheduling input varies.The semantics are now defined in ModelingToolkit (SciML/ModelingToolkit.jl#5265, summarized in JuliaComputing/DyadControlSystems.jl#817): a loop opening changes the input-output structure of the linearization, not the operating point. A disconnected signal is held at the value of its driver at the operating point of the loop-closed system, which along a solution is its value in the solution at each time point. An entry in
optakes precedence, e.g.,op = Dict(sys.opened_signal => 0).Change
trajectory_ssrelies on this default and no longer constructs its own (default_loop_opening_opandstrip_root_namespace, added in the first version of this PR, are removed). The docstring documentsloop_openingsandopaccordingly.op = Dict(… => 0)entries are removed, and the text explains that the parts are linearized at the operating point of the closed loop. The reconstruction of the closed loop from its parts is corrected and checked against the linearization of the closed loop with@test:yretains the path from the controller output through the plant to the scheduling input, sofeedback(P * C_y)reproduces the loop-closed transfer function fromrtoyexactly.uyields the controller evaluated at the scheduling value, without the derivative of the controller output with respect to the scheduling variable.feedback(P * C_u)omits this path and differs from the closed loop (by up to 7 % in the frequency response on the tutorial model).vandycoincides with opening atu, since the opened scheduling signal keeps its value in the solution.[r, v] -> upreviously entered the loop asfeedback(C * P), which treats the scheduling channel as negative feedback. The scheduling variable enters the controller with a positive sign, so the input loop gain is(C_r - C_v) P(verified against the complementary sensitivity function atucomputed by ModelingToolkit). The tutorial now forms the transfer function fromrtoy,feedback(P, C_r - C_v) * C_r, which reproduces the closed loop exactly.uto obtain the controller itself, and opening only aty, or using the two-input controller, to reconstruct the closed loop.test/test_batchlin.jlchecks that the default equals the explicit mapping of the opened signal to its driving signal.Depends on SciML/ModelingToolkit.jl#5265 (stacked on SciML/ModelingToolkit.jl#5264 and SciML/ModelingToolkit.jl#4894).
[sources]inProject.tomlanddocs/Project.tomlpoints to the branch of SciML/ModelingToolkit.jl#5265 until it is released; it must be reverted tomasterand theModelingToolkitcompat bound raised to the release containing it before this PR is merged.Verification
With the ModelingToolkit branch,
test/test_batchlin.jlpasses locally (Julia 1.13.0). The tutorial code was run without the plotting calls, with the following maximum relative errors of the frequency responses over 81 time points: opening aty3e-14, opening atu6.8e-2, two-input controller 1.5e-12,vandyversusu3e-14. The documentation was not built.Host: demeter2, Claude Code session 5674d4b9-6638-4fc2-bfbf-06ad6aac6235, working directory
/home/baggepinnen/.julia/dev/DyadControlSystems(ControlSystemsMTK edited in a clone in the session scratch directory)🤖 Generated with Claude Code
https://claude.ai/code/session_01KecV2uixYREhdQWw1XSAC8