From e9c95ab2c4d1d93b29db895719d6b7030fd17a44 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Mon, 12 Aug 2024 03:50:24 +0530 Subject: [PATCH] Added week 9 blog. --- src/pages/Week9.jsx | 205 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 199 insertions(+), 6 deletions(-) diff --git a/src/pages/Week9.jsx b/src/pages/Week9.jsx index 1090e17..1860f1e 100644 --- a/src/pages/Week9.jsx +++ b/src/pages/Week9.jsx @@ -2,9 +2,140 @@ import React from "react"; import Navbar from "../Navbar"; import Anchors from "../assets/Anchors"; import { Divider, Typography } from "antd"; +import { FaCodePullRequest } from "react-icons/fa6"; +import Footer from "../assets/Footer"; const { Title, Paragraph, Text, Link } = Typography; const Week9 = () => { + const code1 = + ` + if not sys2: + sys2 = TransferFunction(1, 1, sys1.var) + + if not isinstance(sys1, (TransferFunction, Series, StateSpace, Feedback)): + raise TypeError("Unsupported type for sys1 in Feedback.") + + if not isinstance(sys2, (TransferFunction, Series, StateSpace, Feedback)): + raise TypeError("Unsupported type for sys2 in Feedback.") + + if not (sys1.num_inputs == sys1.num_outputs == sys2.num_inputs == + sys2.num_outputs == 1): + raise ValueError("""To use Feedback connection for MIMO systems + use MIMOFeedback instead.""") + ` + const code2 = ` +if self.is_StateSpace_object: + sys1_ss = self.sys1.doit().rewrite(StateSpace) + sys2_ss = self.sys2.doit().rewrite(StateSpace) + A1, B1, C1, D1 = sys1_ss.A, sys1_ss.B, sys1_ss.C, sys1_ss.D + A2, B2, C2, D2 = sys2_ss.A, sys2_ss.B, sys2_ss.C, sys2_ + # Create identity matrices + I_inputs = eye(self.num_inputs) + I_outputs = eye(self.num_outp + # Compute F and its inverse + F = I_inputs - self.sign * D2 * D1 + E = F.i + # Compute intermediate matrices + E_D2 = E * D2 + E_C2 = E * C2 + T1 = I_outputs + self.sign * D1 * E_D2 + T2 = I_inputs + self.sign * E_D2 * D1 + A = Matrix.vstack( + Matrix.hstack(A1 + self.sign * B1 * E_D2 * C1, self.sign * B1 * E_C2), + Matrix.hstack(B2 * T1 * C1, A2 + self.sign * B2 * D1 * E_C2) + ) + B = Matrix.vstack(B1 * T2, B2 * D1 * T2) + C = Matrix.hstack(T1 * C1, self.sign * D1 * E_C2) + D = D1 * T2 + return StateSpace(A, B, C, D) + ` + const code3 = ` +A1 = np.array([[4, 1], [2, -3]]) +B1 = np.array([[5, 2], [-3, -3]]) +C1 = np.array([[2, -4], [0, 1]]) +D1 = np.array([[3, 2], [1, -1]]) +A2 = np.array([[-3, 4, 2], [-1, -3, 0], [2, 5, 3]]) +B2 = np.array([[1, 4], [-3, -3], [-2, 1]]) +C2 = np.array([[4, 2, -3], [1, 4, 3]]) +D2 = np.array([[-2, 4], [0, 1]]) +ss1 = control.ss(A1, B1, C1, D1) +ss2 = control.ss(A2, B2, C2, D2) +ss1.feedback(ss2) + +>>> print(ss1.feedback(ss2)) +: sys[2] +Inputs (2): ['u[0]', 'u[1]'] +Outputs (2): ['y[0]', 'y[1]'] +States (5): ['x[0]', 'x[1]', 'x[2]', 'x[3]', 'x[4]'] + +A = [[ 3. -0.75 -3.75 -18.5 -15. ] + [ 3.5 -4.875 1.125 9.75 9. ] + [ 3. -10.25 -11.25 -25.5 -19. ] + [ -4.5 16.125 9.125 42.75 36. ] + [ -1.5 5.875 3.875 21.25 18. ]] + +B = [[ -0.25 4.75 ] + [ 0.375 -2.625] + [ 0.25 7.25 ] + [ 0.375 -11.625] + [ 0.625 -4.375]] + +C = [[ 1. -3.75 -1.75 -10.5 -9. ] + [ 0.5 -1.625 -1.625 -4.75 -3. ]] + +D = [[-0.25 2.75 ] + [ 0.125 1.125]] +` + const code4 = ` + >>> A1 = Matrix([[4, 1], [2, -3]]) + >>> B1 = Matrix([[5, 2], [-3, -3]]) + >>> C1 = Matrix([[2, -4], [0, 1]]) + >>> D1 = Matrix([[3, 2], [1, -1]]) + >>> A2 = Matrix([[-3, 4, 2], [-1, -3, 0], [2, 5, 3]]) + >>> B2 = Matrix([[1, 4], [-3, -3], [-2, 1]]) + >>> C2 = Matrix([[4, 2, -3], [1, 4, 3]]) + >>> D2 = Matrix([[-2, 4], [0, 1]]) + >>> ss1 = StateSpace(A1, B1, C1, D1) + >>> ss2 = StateSpace(A2, B2, C2, D2) + >>> F1 = MIMOFeedback(ss1, ss2) + >>> F1 + MIMOFeedback(StateSpace(Matrix([ + [4, 1], + [2, -3]]), Matrix([ + [ 5, 2], + [-3, -3]]), Matrix([ + [2, -4], + [0, 1]]), Matrix([ + [3, 2], + [1, -1]])), StateSpace(Matrix([ + [-3, 4, 2], + [-1, -3, 0], + [ 2, 5, 3]]), Matrix([ + [ 1, 4], + [-3, -3], + [-2, 1]]), Matrix([ + [4, 2, -3], + [1, 4, 3]]), Matrix([ + [-2, 4], + [ 0, 1]])), -1) + doit() can be used to find StateSpace equivalent for the system containing StateSpace objects. + >>> F1.doit() + StateSpace(Matrix([ + [ 3, -3/4, -15/4, -37/2, -15], + [ 7/2, -39/8, 9/8, 39/4, 9], + [ 3, -41/4, -45/4, -51/2, -19], + [-9/2, 129/8, 73/8, 171/4, 36], + [-3/2, 47/8, 31/8, 85/4, 18]]), Matrix([ + [-1/4, 19/4], + [ 3/8, -21/8], + [ 1/4, 29/4], + [ 3/8, -93/8], + [ 5/8, -35/8]]), Matrix([ + [ 1, -15/4, -7/4, -21/2, -9], + [1/2, -13/8, -13/8, -19/4, -3]]), Matrix([ + [-1/4, 11/4], + [ 1/8, 9/8]])) +` return ( <> @@ -13,16 +144,78 @@ const Week9 = () => {
-
+
- Week 9 - Upcoming... + + Week 9: Added Feedback interconnection for <code>StateSpace</code> model. + + + During the 9th week of my GSoc I've worked on Feedback interconnection of StateSpace class. + It was a difficult task as I need to closely moniter every step where the code was breaking. + + + Implementation + + +

For SISO systems

+

+ I've changed the parent class of Feedback which is for SISO from TransferFunction to SISOLinearTimeInvariant. + It was done so that SISO StateSpace systems can be connected easily. + I made some changes by adding a new property to all the interconnection type of objects which is is_StateSpace_object. + This makes sure that the StateSpace objects is treated differently from the connection containing `s` or the Laplace Transform variable. +

+

+ Here I made sure that doit() should return the equivalent StateSpace model if the object is a StateSpace type. +

+

+ For MIMO Systems +

+

+ I've used proper type checking to make sure that the user gets correct message if the user tries to connect unsupported systems. +

+                    {code1}
+                  
+ For using doit() I've used a very complex logic which took me a lot of time to understand. I've referenced it from `python-control` +
{code2}
+ This code snippet follows the following steps : +
    +
  • The algorithm first converts two systems (sys1 and sys2) into their StateSpace representations. These systems are defined by matrices A, B, C and Dwhich describe the dynamics and outputs of the system.
  • +
  • It then creates identity matrices and computes an intermediate matrix F, along with its inverse E. These matrices help manage interactions between the two systems. The algorithm uses these to calculate intermediate matrices that simplify combining the two systems.
  • +
  • Finally, the algorithm calculates the new combined StateSpace representation by stacking and multiplying the matrices. This results in a new system that incorporates the dynamics of both original systems, effectively creating a new, combined StateSpace system.
  • +
+

Testing

+ For testing I've used python-control I've validated everything using it and made test cases for sympy using it. An example for it is +

Python Control Test

+
{code3}
+

Sympy Code

+
{code4}
+

Refrences

+
    +
  1. + Python Control +
  2. +
+

+
+ + Pull Requests + + + (Open) Added support of Feedback to work with StateSpace. +
+ +
+ Abhishek Kumar +
+ GSoC Contributor +
+
+
- ); -}; - + ) +} export default Week9;